diff --git a/CHANGELOG.md b/CHANGELOG.md index 4112fa4a01dedee365bbdcc83eb037be4fc7d4a5..174bd68b91babe9b25850685c8840fa2dc1294fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,110 @@ +2.0.0.0-dev88 +============= +* Fixed bugs: + * Fixed an issue when PayPal Express Checkout Payflow Edition and PayPal Payments Advanced were available for multiple checkout + * Fixed an issue when the Bill me later button did not redirect to https when secure url was enabled for frontend + * Fixed an issue when the Billing agreement option was available in multishipping checkout, even if there were no signed agreements + * Fixed an issue when DoExpressCheckout request instead of DoCapture did not allow to do refund, when using PayPal Express Checkout Payflow Edition + * Fixed an issue when eWay was not present on checkout if Base Currency was set to AUD + * Fixed an issue with fatal error occurring when placing order via SagePay with 3D Secure enabled + * Fixed an issue when the FedEx shipping method had no option to specify unit for weight attribute + * Fixed an issue with inability to create credit memo for PalPal Express Checkout/Payments Pro/Payments Pro Hosted Solution (NVP family), if partial refund was initiated on the PayPal side + * Fixed an issue when a guest user could not return product to store, if product was paid using PayPal + * Fixed an issue when PayPal Payments Pro Hosted Solution Fraud protection did not work properly + * Fixed an issue when JavaScript took values from default config for payment methods and used them on the website scope + * Fixed an issue with incorrect address in request to shipping carrier (DHL International) in case the address contained diacritic letters + * Fixed an issue when it was possible to hack currency in PayPal Website Payments Standard + * Fixed an issue when no rows were added to the PayPal Settlement report grid while fetching it from custom server + * Fixed an issue when order had the Suspected Fraud status after creating partial invoice on the PayPal side + * Fixed an issue when PayPal Payflow Pro did not properly implement CUSTREF and INVNUM + * Fixed an issue with PayPal errors handling during IPN postback + * Fixed an issue when the Paypal Express Checkout button was not available on product page for several product types + * Fixed an issue with PayPal Payflow Pro and Payflow Link broken unit tests + * Fixed an issue when PayPal Payments Pro Hosted Solution had the City parameter duplicated in the State parameter for UK + * Fixed an issue with remove multiple HTTP 100/101 headers + * Fixed an issue when SagePay did not transfer shopping cart information + * Fixed an issue when transaction records were absent on Transaction tab for Ogone + * Fixed an issue when partial cancel with SagePay Direct was unavailable + * Fixed an issue when order did not place using PayPal Payments Pro Hosted Solution + * Fixed an issue when order did not place using Authorize.net Direct Post from backend + * Fixed an issue when sort order for payment methods did not work + * Fixed an issue with multiple schema of language.xml + * Fixed an issue with infinite loop in language inheritance + * Fixed an issue with residual "scopes" logic in i18n implementation + * Fixed an issue when search did not work for the CMS Blocks grid + * Fixed an issue when WSDL for one scope was cached and displayed for all scopes + * Fixed an issue with unit tests coverage build failure + * Fixed an issue when custom options were lost after product import + * Fixed an issue when product did not show in backend grid if store contained several store view + * Fixed an issue when the Recurring Profile section was not updated after changing product template + * Fixed an issue with incorrect discount calculation + * Fixed an issue when customer could not register during Checkout if Guest Checkout was disabled + * Fixed an issue when shopping cart price rule was not applied after updating items and qty in the shopping cart + * Fixed an issue when updated and created dates were not shown for Billing Agreement in the Billing Agreement Grid in the backend + * Fixed an issue with broken design on the multiple addresses order review page + * Fixed an issue when sort by did not work in frontend for Yes/No attributes when Flat catalog was disabled + * Fixed an issue when a new blank CMS page was displayed after saving the CMS page entity + * Fixed an issue when product attributes were absent on the Product page after switching to another product template + * Fixed a 404 error after saving mass update product attributes form + * Fixed an issue when it was impossible to perform search by all tax classes on the Advanced Search page + * Fixed an issue when attribute order for configurable product was not preserved after saving product + * Fixed an issue with no results for the Product Best Sellers report + * Fixed a fatal error when opening tax configuration page in the backend + * Fixed an error occurring when opening the Tax Zones and Rates page in the backend + * Fixed a 404 error occurring while searching products on the New Review page + * Fixed an error when performing search in the Tax rate grid +* Payments implementation: + * Ported correct behaviour for Fraud Management in PayPal Payflow Pro from M1 to M2 + * Implemented ability to use negative line items for PayPal Payflowpro +* Language packs: + * Implemented ability to use multiple packages for the same language from one vendor +* GitHub requests: + * [#587] (https://github.com/magento/magento2/issues/587) -- The "install/Magento/basic/*_*/layout/*.xml" pattern cannot be processed in "/mnt/fs01/test/mdt/htdocs/app/design/" path Warning!Invalid argument supplied for foreach() +* Unit tests coverage: + * Magento\Catalog\Model\Product +* Service layer implementation: + * Created ConfigurableProduct service + * Created CompositeProduct service + * Refactored TaxCalculationService + * Refactored Google Shopping to use tax service + * Exposed TaxRate and TaxRule search functions as WebAPI TaxCalculationService + * Refactored QuoteDetails and QuoteDetailsItem to use tax class name + * Refactored gift wrapping to use tax/weee services + * Performed more tax refactoring for service layer + * Improved unit test coverage +* Indexer-less implementation of URL Rewrites functionality in new UrlRedirect module: + * Implemented URL Rewrites generators for all entities: CMS page, product, category + * Implemented URL Rewrites matching in the frontend +* Added the following functional tests: + * Activate Integration + * Add Compared Products + * Create Bundle Product + * Clear All Compare Products + * Create CMS Block + * Create CMS Page + * Create Custom Variable + * Create Integration + * Create Grouped Product + * Create Search Term + * Delete Assigned to Template Product Attribute + * Delete CMS Block + * Delete CMS Page Rewrite + * Delete Compare Products + * Delete Custom URL Rewrite + * Delete Integration + * Delete Product Template + * Duplicate Product + * Edit Search Term + * Update Bundle Product + * Update CMS Block + * Update CMS Page URL Rewrite + * Update Custom Variable + * Update Custom URL Rewrite + * Update Customer on Frontend + * Update Integration + * Update Product Template + * Update Virtual Product + 2.0.0.0-dev87 ============= * Service layer updates: @@ -12,6 +119,7 @@ * [#584] (https://github.com/magento/magento2/issues/584) -- Merge and minify js - Exception * [#585] (https://github.com/magento/magento2/pull/585) -- Add forgotten return statement * [#592] (https://github.com/magento/magento2/issues/592) -- Module name pattern + * [#618] (https://github.com/magento/magento2/issues/618) -- Fix of unit tests failure on Travis CI * Tax calculation updates: * Separate and display Weee line item totals from Tax * Fixed bugs: @@ -30,18 +138,16 @@ * Fixed an issue when configurable product was out of stock in Google Shopping while being in stock in the Magento backend * Fixed an issue when swipe gesture in menu widget was not supported on mobile * Fixed an issue when it was impossible to enter alpha-numeric zip code on the stage of estimating shipping and tax rates - * Fixed an issue when it was impossible to edit gift card account * Fixed an issue when custom price was not applied when editing an order - * Fixed an issue when items were not returned to stock after unsuccessful order was placed + * Fixed an issue when items were not returned to stock after unsuccessful order was placed * Fixed an issue when error message appeared "Cannot save the credit memo†while creating credit memo * Fixed an issue when Catalog price rule was not shown for the product if price was less than a discount * Indexer implementation: * Implemented a new Stock indexer * Implemented a new EAV indexer - * Fixed failed L1 plan on phpunit 4.1.0 - * Minor updates for integration test framework - * Split action controllers classes into action classes - * Added public MTF repository to the packagist.org +* Minor updates for integration test framework +* Split action controllers classes into action classes +* Added public MTF repository to the packagist.org * Added the following functional tests: * Create Admin User * Create Category diff --git a/app/code/Magento/AdminNotification/Block/System/Messages.php b/app/code/Magento/AdminNotification/Block/System/Messages.php index 0800f20b6029ef2a32d92ec4ac1f4ad8f273d890..19695d3a9e4b5406efbe790fb9721cedfa2b39d9 100644 --- a/app/code/Magento/AdminNotification/Block/System/Messages.php +++ b/app/code/Magento/AdminNotification/Block/System/Messages.php @@ -17,7 +17,7 @@ * Do not edit or add to this file if you wish to upgrade Magento to newer * versions in the future. If you wish to customize Magento for your * needs please refer to http://www.magentocommerce.com for more information. - * + * * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ @@ -129,7 +129,7 @@ class Messages extends \Magento\Backend\Block\Template } /** - * Initialize Syste,Message dialog widget + * Initialize system message dialog widget * * @return string */ diff --git a/app/code/Magento/Authorizenet/view/adminhtml/web/js/direct-post.js b/app/code/Magento/Authorizenet/view/adminhtml/web/js/direct-post.js index a612fdfbe1d99caa2f6ddd7ec0f35f546c787d79..6dd6f9570e0bf38646352d39a04a0ca77b397a41 100644 --- a/app/code/Magento/Authorizenet/view/adminhtml/web/js/direct-post.js +++ b/app/code/Magento/Authorizenet/view/adminhtml/web/js/direct-post.js @@ -138,7 +138,7 @@ directPost.prototype = { loadOrderIframe : function() { if (this.orderRequestSent) { $(this.iframeId).hide(); - var data = $('order-' + this.iframeId).contentWindow.document.body.innerHTML; + var data = $('order-' + this.iframeId).contentWindow.document.body.getElementsByTagName('pre')[0].innerHTML; this.saveAdminOrderSuccess(data); this.orderRequestSent = false; } diff --git a/app/code/Magento/Authorizenet/view/frontend/templates/directpost/form.phtml b/app/code/Magento/Authorizenet/view/frontend/templates/directpost/form.phtml index eaf45cebb7d11433dfa889adc9579a69032606c6..ae67dc82f22185655b393f436862e7d8e88388b3 100644 --- a/app/code/Magento/Authorizenet/view/frontend/templates/directpost/form.phtml +++ b/app/code/Magento/Authorizenet/view/frontend/templates/directpost/form.phtml @@ -91,7 +91,7 @@ $_orderUrl = $this->helper('Magento\Authorizenet\Helper\Data')->getPlaceOrderFro <input type="number" title="<?php echo __('Card Verification Number') ?>" data-container="cc-cvv" class="input-text cvv" id="<?php echo $_code ?>_cc_cid" name="payment[cc_cid]" value="" data-validate='{required:true, "validate-cc-cvn":"#<?php echo $_code ?>_cc_type"}' autocomplete="off"/> <?php $_content = '<img src=\"'.$this->getViewFileUrl('Magento_Checkout::cvv.gif').'\" alt=\"'.__('Card Verification Number Visual Reference').'\" title=\"'.__('Card Verification Number Visual Reference').'\" />'; ?> <div class="note"> - <a href="#" id="directpost-cvv-what-is-this" class="action cvv" title="<?php echo __('What is this?') ?>" data-mage-init='{"tooltip": {"content": "<?php echo $_content ?>"}}'><span><?php echo __('What is this?') ?></span></a> + <a href="#" id="directpost-cvv-what-is-this" class="action cvv" title="<?php echo $this->escapeHtml(__('What is this?'));?>" data-mage-init='{"tooltip": {"content": "<?php echo $_content ?>"}}'><span><?php echo __('What is this?') ?></span></a> </div> </div> </div> diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/AbstractConfig.php b/app/code/Magento/Backend/Controller/Adminhtml/System/AbstractConfig.php index e3943fa0649df6950dc5e2984167f7e73e0bd57e..cfe6a95b4a697be4294e38e3c6c357ad45ee8c7a 100644 --- a/app/code/Magento/Backend/Controller/Adminhtml/System/AbstractConfig.php +++ b/app/code/Magento/Backend/Controller/Adminhtml/System/AbstractConfig.php @@ -27,8 +27,6 @@ */ namespace Magento\Backend\Controller\Adminhtml\System; -use Magento\Framework\App\Action\NotFoundException; - abstract class AbstractConfig extends \Magento\Backend\App\AbstractAction { /** @@ -36,16 +34,25 @@ abstract class AbstractConfig extends \Magento\Backend\App\AbstractAction */ protected $_configStructure; + /** + * @var ConfigSectionChecker + */ + protected $_sectionChecker; + /** * @param \Magento\Backend\App\Action\Context $context * @param \Magento\Backend\Model\Config\Structure $configStructure + * @param ConfigSectionChecker $sectionChecker */ public function __construct( \Magento\Backend\App\Action\Context $context, - \Magento\Backend\Model\Config\Structure $configStructure + \Magento\Backend\Model\Config\Structure $configStructure, + ConfigSectionChecker $sectionChecker ) { parent::__construct($context); $this->_configStructure = $configStructure; + $this->_sectionChecker = $sectionChecker; + } /** @@ -56,12 +63,8 @@ abstract class AbstractConfig extends \Magento\Backend\App\AbstractAction */ public function dispatch(\Magento\Framework\App\RequestInterface $request) { - $section = null; if (!$request->getParam('section')) { - $section = $this->_configStructure->getFirstSection(); - $request->setParam('section', $section->getId()); - } else { - $this->_isSectionAllowed($request->getParam('section')); + $request->setParam('section', $this->_configStructure->getFirstSection()->getId()); } return parent::dispatch($request); } @@ -73,33 +76,9 @@ abstract class AbstractConfig extends \Magento\Backend\App\AbstractAction */ protected function _isAllowed() { - return $this->_authorization->isAllowed('Magento_Adminhtml::config'); - } - - /** - * Check if specified section allowed in ACL - * - * Will forward to deniedAction(), if not allowed. - * - * @param string $sectionId - * @throws \Exception - * @return bool - * @throws NotFoundException - */ - protected function _isSectionAllowed($sectionId) - { - try { - if (false == $this->_configStructure->getElement($sectionId)->isAllowed()) { - throw new \Exception(''); - } - return true; - } catch (\Zend_Acl_Exception $e) { - throw new NotFoundException(); - } catch (\Exception $e) { - $this->deniedAction(); - $this->_actionFlag->set('', self::FLAG_NO_DISPATCH, true); - return false; - } + $sectionId = $this->_request->getParam('section'); + return $this->_authorization->isAllowed('Magento_Adminhtml::config') + || $this->_configStructure->getElement($sectionId)->isAllowed(); } /** diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Config/AbstractScopeConfig.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Config/AbstractScopeConfig.php new file mode 100644 index 0000000000000000000000000000000000000000..5bec8035aa9f01fbd7c8bbb5207921caf2e568ba --- /dev/null +++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Config/AbstractScopeConfig.php @@ -0,0 +1,69 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Backend\Controller\Adminhtml\System\Config; + +use Magento\Backend\Controller\Adminhtml\System\ConfigSectionChecker; + +abstract class AbstractScopeConfig extends \Magento\Backend\Controller\Adminhtml\System\AbstractConfig +{ + /** + * @var \Magento\Backend\Model\Config + */ + protected $_backendConfig; + + /** + * @param \Magento\Backend\App\Action\Context $context + * @param \Magento\Backend\Model\Config\Structure $configStructure + * @param ConfigSectionChecker $sectionChecker + * @param \Magento\Backend\Model\Config $backendConfig + */ + public function __construct( + \Magento\Backend\App\Action\Context $context, + \Magento\Backend\Model\Config\Structure $configStructure, + ConfigSectionChecker $sectionChecker, + \Magento\Backend\Model\Config $backendConfig + ) { + $this->_backendConfig = $backendConfig; + parent::__construct($context, $configStructure, $sectionChecker); + } + + /** + * Sets scope for backend config + * + * @param string $sectionId + * @return bool + */ + protected function isSectionAllowed($sectionId) + { + $website = $this->getRequest()->getParam('website'); + $store = $this->getRequest()->getParam('store'); + if ($store) { + $this->_backendConfig->setStore($store); + } elseif ($website) { + $this->_backendConfig->setWebsite($website); + } + return parent::isSectionAllowed($sectionId); + } +} diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Config/Edit.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Config/Edit.php index fb560afbdb0335662f5518e0b51021817a94c39f..f6d54e520c9fca7a11494477d269889d81ed289a 100644 --- a/app/code/Magento/Backend/Controller/Adminhtml/System/Config/Edit.php +++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Config/Edit.php @@ -24,7 +24,7 @@ */ namespace Magento\Backend\Controller\Adminhtml\System\Config; -class Edit extends \Magento\Backend\Controller\Adminhtml\System\AbstractConfig +class Edit extends AbstractScopeConfig { /** * Edit configuration section diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Config/Index.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Config/Index.php index 157a019c8fa0fd507b7e36cd9836a7fd523146ac..1b5d451e51cdcc22ed21f99d0c15626de640e1ed 100644 --- a/app/code/Magento/Backend/Controller/Adminhtml/System/Config/Index.php +++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Config/Index.php @@ -24,7 +24,7 @@ */ namespace Magento\Backend\Controller\Adminhtml\System\Config; -class Index extends \Magento\Backend\Controller\Adminhtml\System\AbstractConfig +class Index extends AbstractScopeConfig { /** * Index action diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Config/Save.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Config/Save.php index 2c9ca838c87bcb9626e658c4787b3707aaa1cfc1..a0cffac49122b43ee65725e23a548d8e9f9090a4 100644 --- a/app/code/Magento/Backend/Controller/Adminhtml/System/Config/Save.php +++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Config/Save.php @@ -53,6 +53,7 @@ class Save extends AbstractConfig /** * @param \Magento\Backend\App\Action\Context $context * @param \Magento\Backend\Model\Config\Structure $configStructure + * @param \Magento\Backend\Controller\Adminhtml\System\ConfigSectionChecker $sectionChecker * @param \Magento\Backend\Model\Config\Factory $configFactory * @param \Magento\Framework\Cache\FrontendInterface $cache * @param \Magento\Framework\Stdlib\String $string @@ -60,11 +61,12 @@ class Save extends AbstractConfig public function __construct( \Magento\Backend\App\Action\Context $context, \Magento\Backend\Model\Config\Structure $configStructure, + \Magento\Backend\Controller\Adminhtml\System\ConfigSectionChecker $sectionChecker, \Magento\Backend\Model\Config\Factory $configFactory, \Magento\Framework\Cache\FrontendInterface $cache, \Magento\Framework\Stdlib\String $string ) { - parent::__construct($context, $configStructure); + parent::__construct($context, $configStructure, $sectionChecker); $this->_configFactory = $configFactory; $this->_cache = $cache; $this->string = $string; @@ -160,10 +162,6 @@ class Save extends AbstractConfig public function execute() { try { - if (false == $this->_isSectionAllowed($this->getRequest()->getParam('section'))) { - throw new \Exception(__('This section is not allowed.')); - } - // custom save logic $this->_saveSection(); $section = $this->getRequest()->getParam('section'); diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Config/State.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Config/State.php index a43679ee9e6dfa0994ed3b355b0ef69b11d6780d..ed7a44aff92f9eab806518f9a32e368ce0381d95 100644 --- a/app/code/Magento/Backend/Controller/Adminhtml/System/Config/State.php +++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Config/State.php @@ -24,7 +24,7 @@ */ namespace Magento\Backend\Controller\Adminhtml\System\Config; -class State extends \Magento\Backend\Controller\Adminhtml\System\AbstractConfig +class State extends AbstractScopeConfig { /** * Save fieldset state through AJAX diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/ConfigSectionChecker.php b/app/code/Magento/Backend/Controller/Adminhtml/System/ConfigSectionChecker.php new file mode 100644 index 0000000000000000000000000000000000000000..6e3c320d5203151a66fe3a242bfce16e16780a4f --- /dev/null +++ b/app/code/Magento/Backend/Controller/Adminhtml/System/ConfigSectionChecker.php @@ -0,0 +1,67 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Backend\Controller\Adminhtml\System; + +use Magento\Framework\App\Action\NotFoundException; + +class ConfigSectionChecker +{ + /** + * @var \Magento\Backend\Model\Config\Structure + */ + protected $_configStructure; + + /** + * @param \Magento\Backend\Model\Config\Structure $configStructure + */ + public function __construct(\Magento\Backend\Model\Config\Structure $configStructure) + { + $this->_configStructure = $configStructure; + } + + /** + * Check if specified section allowed in ACL + * + * Will forward to deniedAction(), if not allowed. + * + * @param string $sectionId + * @throws \Exception + * @return bool + * @throws NotFoundException + */ + public function isSectionAllowed($sectionId) + { + try { + if (false == $this->_configStructure->getElement($sectionId)->isAllowed()) { + throw new \Exception(''); + } + return true; + } catch (\Zend_Acl_Exception $e) { + throw new NotFoundException(); + } catch (\Exception $e) { + return false; + } + } +} diff --git a/app/code/Magento/Backend/Model/Config.php b/app/code/Magento/Backend/Model/Config.php index 5bee720ba2d6bb516793ee73cb6a246a180db907..4bf70b7a933d523b006ae5f969fe2b20adf3e23c 100644 --- a/app/code/Magento/Backend/Model/Config.php +++ b/app/code/Magento/Backend/Model/Config.php @@ -383,12 +383,12 @@ class Config extends \Magento\Framework\Object $scope = 'stores'; $store = $this->_storeManager->getStore($this->getStore()); $scopeId = (int)$store->getId(); - $scopeCode = $this->getStore(); + $scopeCode = $store->getCode(); } elseif ($this->getWebsite()) { $scope = 'websites'; $website = $this->_storeManager->getWebsite($this->getWebsite()); $scopeId = (int)$website->getId(); - $scopeCode = $this->getWebsite(); + $scopeCode = $website->getCode(); } else { $scope = 'default'; $scopeId = 0; diff --git a/app/code/Magento/Backend/etc/config.xml b/app/code/Magento/Backend/etc/config.xml index 334c5434d44d1ec1f161134f949dd4320669a67c..1a88e36aea2c3d6e4f7e8f198b0a96381b049755 100644 --- a/app/code/Magento/Backend/etc/config.xml +++ b/app/code/Magento/Backend/etc/config.xml @@ -55,6 +55,11 @@ </input_types> </validator_data> </general> + <web> + <seo> + <use_rewrites>0</use_rewrites> + </seo> + </web> </default> <stores> <admin> diff --git a/app/code/Magento/Backend/view/adminhtml/templates/widget/grid.phtml b/app/code/Magento/Backend/view/adminhtml/templates/widget/grid.phtml index eecc6ecb9c8083f6819f2096945ebf9931b72177..2a0da74a661ab296c772469dd87ec03a17a382dd 100644 --- a/app/code/Magento/Backend/view/adminhtml/templates/widget/grid.phtml +++ b/app/code/Magento/Backend/view/adminhtml/templates/widget/grid.phtml @@ -46,7 +46,7 @@ $numColumns = sizeof($this->getColumns()); </div> <?php endif ?> - <div id="<?php echo $this->getId() ?>"> + <div id="<?php echo $this->getId() ?>" data-grid-id="<?php echo $this->getId() ?>"> <?php else: ?> <?php echo $this->getLayout()->getMessagesBlock()->getGroupedHtml() ?> <?php endif; ?> diff --git a/app/code/Magento/Bundle/Block/Adminhtml/Sales/Order/Items/Renderer.php b/app/code/Magento/Bundle/Block/Adminhtml/Sales/Order/Items/Renderer.php index 9ff68dfb5cb5f666143b392e5dc88aa8a27a7bba..029bd9120999a992071b91b06fd24065624ac5cf 100644 --- a/app/code/Magento/Bundle/Block/Adminhtml/Sales/Order/Items/Renderer.php +++ b/app/code/Magento/Bundle/Block/Adminhtml/Sales/Order/Items/Renderer.php @@ -49,16 +49,16 @@ class Renderer extends \Magento\Sales\Block\Adminhtml\Items\Renderer\DefaultRend } /** - * Getting all available childs for Invoice, Shipmen or Creditmemo item + * Getting all available children for Invoice, Shipment or CreditMemo item * * @param \Magento\Framework\Object $item - * @return array + * @return array|null */ public function getChilds($item) { $itemsArray = array(); - $items = false; + $items = null; if ($item instanceof \Magento\Sales\Model\Order\Invoice\Item) { $items = $item->getInvoice()->getAllItems(); } elseif ($item instanceof \Magento\Sales\Model\Order\Shipment\Item) { @@ -99,33 +99,21 @@ class Renderer extends \Magento\Sales\Block\Adminhtml\Items\Renderer\DefaultRend if ($parentItem) { $options = $parentItem->getProductOptions(); if ($options) { - if (isset($options['shipment_type']) - && $options['shipment_type'] == AbstractType::SHIPMENT_SEPARATELY - ) { - return true; - } else { - return false; - } + return (isset($options['shipment_type']) + && $options['shipment_type'] == AbstractType::SHIPMENT_SEPARATELY); } } else { $options = $item->getProductOptions(); if ($options) { - if (isset($options['shipment_type']) - && $options['shipment_type'] == AbstractType::SHIPMENT_SEPARATELY - ) { - return false; - } else { - return true; - } + return !(isset($options['shipment_type']) + && $options['shipment_type'] == AbstractType::SHIPMENT_SEPARATELY); } } } $options = $this->getOrderItem()->getProductOptions(); if ($options) { - if (isset($options['shipment_type']) - && $options['shipment_type'] == AbstractType::SHIPMENT_SEPARATELY - ) { + if (isset($options['shipment_type']) && $options['shipment_type'] == AbstractType::SHIPMENT_SEPARATELY) { return true; } } @@ -146,24 +134,14 @@ class Renderer extends \Magento\Sales\Block\Adminhtml\Items\Renderer\DefaultRend if ($parentItem) { $options = $parentItem->getProductOptions(); if ($options) { - if (isset($options['product_calculations']) - && $options['product_calculations'] == AbstractType::CALCULATE_CHILD - ) { - return true; - } else { - return false; - } + return (isset($options['product_calculations']) + && $options['product_calculations'] == AbstractType::CALCULATE_CHILD); } } else { $options = $item->getProductOptions(); if ($options) { - if (isset($options['product_calculations']) - && $options['product_calculations'] == AbstractType::CALCULATE_CHILD - ) { - return false; - } else { - return true; - } + return !(isset($options['product_calculations']) + && $options['product_calculations'] == AbstractType::CALCULATE_CHILD); } } } diff --git a/app/code/Magento/Bundle/Block/Adminhtml/Sales/Order/View/Items/Renderer.php b/app/code/Magento/Bundle/Block/Adminhtml/Sales/Order/View/Items/Renderer.php index 070b02878a5c3c030c1620885e3c565edfa962d6..90ea6e9622826d5a4246f2006f5732b504fef881 100644 --- a/app/code/Magento/Bundle/Block/Adminhtml/Sales/Order/View/Items/Renderer.php +++ b/app/code/Magento/Bundle/Block/Adminhtml/Sales/Order/View/Items/Renderer.php @@ -59,33 +59,21 @@ class Renderer extends \Magento\Sales\Block\Adminhtml\Order\View\Items\Renderer\ if ($parentItem) { $options = $parentItem->getProductOptions(); if ($options) { - if (isset($options['shipment_type']) - && $options['shipment_type'] == AbstractType::SHIPMENT_SEPARATELY - ) { - return true; - } else { - return false; - } + return (isset($options['shipment_type']) + && $options['shipment_type'] == AbstractType::SHIPMENT_SEPARATELY); } } else { $options = $item->getProductOptions(); if ($options) { - if (isset($options['shipment_type']) - && $options['shipment_type'] == AbstractType::SHIPMENT_SEPARATELY - ) { - return false; - } else { - return true; - } + return !(isset($options['shipment_type']) + && $options['shipment_type'] == AbstractType::SHIPMENT_SEPARATELY); } } } - $options = $this->getOrderItem()->getProductOptions(); + $options = $this->getItem()->getProductOptions(); if ($options) { - if (isset($options['shipment_type']) - && $options['shipment_type'] == AbstractType::SHIPMENT_SEPARATELY - ) { + if (isset($options['shipment_type']) && $options['shipment_type'] == AbstractType::SHIPMENT_SEPARATELY) { return true; } } @@ -103,24 +91,14 @@ class Renderer extends \Magento\Sales\Block\Adminhtml\Order\View\Items\Renderer\ if ($parentItem) { $options = $parentItem->getProductOptions(); if ($options) { - if (isset($options['product_calculations']) - && $options['product_calculations'] == AbstractType::CALCULATE_CHILD - ) { - return true; - } else { - return false; - } + return (isset($options['product_calculations']) + && $options['product_calculations'] == AbstractType::CALCULATE_CHILD); } } else { $options = $item->getProductOptions(); if ($options) { - if (isset($options['product_calculations']) - && $options['product_calculations'] == AbstractType::CALCULATE_CHILD - ) { - return false; - } else { - return true; - } + return !(isset($options['product_calculations']) + && $options['product_calculations'] == AbstractType::CALCULATE_CHILD); } } } diff --git a/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle.php b/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle.php index 5eb6faa3ba8dfdb0ccd33f8a8739e23fdff5a0f8..e9438dd2a5cd0038936b82cc66ae7396dbd52707 100644 --- a/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle.php +++ b/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle.php @@ -24,7 +24,7 @@ namespace Magento\Bundle\Block\Catalog\Product\View\Type; use Magento\Framework\Pricing\PriceCurrencyInterface; -use Magento\Tax\Model\Calculation; +use Magento\Tax\Service\V1\TaxCalculationServiceInterface; /** * Catalog bundle product info block @@ -46,9 +46,9 @@ class Bundle extends \Magento\Catalog\Block\Product\View\AbstractView * @var array */ protected $mapping = [ - Calculation::CALC_UNIT_BASE => self::UNIT_ROUNDING, - Calculation::CALC_ROW_BASE => self::ROW_ROUNDING, - Calculation::CALC_TOTAL_BASE => self::TOTAL_ROUNDING, + TaxCalculationServiceInterface::CALC_UNIT_BASE => self::UNIT_ROUNDING, + TaxCalculationServiceInterface::CALC_ROW_BASE => self::ROW_ROUNDING, + TaxCalculationServiceInterface::CALC_TOTAL_BASE => self::TOTAL_ROUNDING, ]; /** diff --git a/app/code/Magento/Bundle/Block/Sales/Order/Items/Renderer.php b/app/code/Magento/Bundle/Block/Sales/Order/Items/Renderer.php index ec6a182465ad5a9626fa360d603213c855f2e7a2..ac0fb075fd5c5f0c48e5228a4806a63c32a72329 100644 --- a/app/code/Magento/Bundle/Block/Sales/Order/Items/Renderer.php +++ b/app/code/Magento/Bundle/Block/Sales/Order/Items/Renderer.php @@ -23,6 +23,8 @@ */ namespace Magento\Bundle\Block\Sales\Order\Items; +use \Magento\Catalog\Model\Product\Type\AbstractType; + /** * Order item render block * @@ -40,40 +42,25 @@ class Renderer extends \Magento\Sales\Block\Order\Item\Renderer\DefaultRenderer if ($item->getOrderItem()) { $item = $item->getOrderItem(); } - if ($parentItem = $item->getParentItem()) { - if ($options = $parentItem->getProductOptions()) { - if (isset( - $options['shipment_type'] - ) && - $options['shipment_type'] == - \Magento\Catalog\Model\Product\Type\AbstractType::SHIPMENT_SEPARATELY - ) { - return true; - } else { - return false; - } + $parentItem = $item->getParentItem(); + if ($parentItem) { + $options = $parentItem->getProductOptions(); + if ($options) { + return (isset($options['shipment_type']) + && $options['shipment_type'] == AbstractType::SHIPMENT_SEPARATELY); } } else { - if ($options = $item->getProductOptions()) { - if (isset( - $options['shipment_type'] - ) && - $options['shipment_type'] == - \Magento\Catalog\Model\Product\Type\AbstractType::SHIPMENT_SEPARATELY - ) { - return false; - } else { - return true; - } + $options = $item->getProductOptions(); + if ($options) { + return !(isset($options['shipment_type']) + && $options['shipment_type'] == AbstractType::SHIPMENT_SEPARATELY); } } } - if ($options = $this->getOrderItem()->getProductOptions()) { - if (isset( - $options['shipment_type'] - ) && $options['shipment_type'] == \Magento\Catalog\Model\Product\Type\AbstractType::SHIPMENT_SEPARATELY - ) { + $options = $this->getOrderItem()->getProductOptions(); + if ($options) { + if (isset($options['shipment_type']) && $options['shipment_type'] == AbstractType::SHIPMENT_SEPARATELY) { return true; } } @@ -90,39 +77,26 @@ class Renderer extends \Magento\Sales\Block\Order\Item\Renderer\DefaultRenderer if ($item->getOrderItem()) { $item = $item->getOrderItem(); } - if ($parentItem = $item->getParentItem()) { - if ($options = $parentItem->getProductOptions()) { - if (isset( - $options['product_calculations'] - ) && - $options['product_calculations'] == - \Magento\Catalog\Model\Product\Type\AbstractType::CALCULATE_CHILD - ) { - return true; - } else { - return false; - } + $parentItem = $item->getParentItem(); + if ($parentItem) { + $options = $parentItem->getProductOptions(); + if ($options) { + return (isset($options['product_calculations']) + && $options['product_calculations'] == AbstractType::CALCULATE_CHILD); } } else { - if ($options = $item->getProductOptions()) { - if (isset( - $options['product_calculations'] - ) && - $options['product_calculations'] == - \Magento\Catalog\Model\Product\Type\AbstractType::CALCULATE_CHILD - ) { - return false; - } else { - return true; - } + $options = $item->getProductOptions(); + if ($options) { + return !(isset($options['product_calculations']) + && $options['product_calculations'] == AbstractType::CALCULATE_CHILD); } } } - if ($options = $this->getOrderItem()->getProductOptions()) { - if (isset( - $options['product_calculations'] - ) && $options['product_calculations'] == \Magento\Catalog\Model\Product\Type\AbstractType::CALCULATE_CHILD + $options = $this->getOrderItem()->getProductOptions(); + if ($options) { + if (isset($options['product_calculations']) + && $options['product_calculations'] == AbstractType::CALCULATE_CHILD ) { return true; } @@ -154,49 +128,45 @@ class Renderer extends \Magento\Sales\Block\Order\Item\Renderer\DefaultRenderer public function getValueHtml($item) { if ($attributes = $this->getSelectionAttributes($item)) { - return sprintf( - '%d', - $attributes['qty'] - ) . ' x ' . $this->escapeHtml( - $item->getName() - ) . " " . $this->getOrder()->formatPrice( - $attributes['price'] - ); + return sprintf('%d', $attributes['qty']) . ' x ' . $this->escapeHtml($item->getName()) . " " + . $this->getOrder()->formatPrice($attributes['price']); } else { return $this->escapeHtml($item->getName()); } } /** - * Getting all available childs for Invoice, Shipmen or Creditmemo item + * Getting all available children for Invoice, Shipment or CreditMemo item * * @param \Magento\Framework\Object $item * @return array */ public function getChilds($item) { - $_itemsArray = array(); + $itemsArray = array(); + $items = null; if ($item instanceof \Magento\Sales\Model\Order\Invoice\Item) { - $_items = $item->getInvoice()->getAllItems(); - } else if ($item instanceof \Magento\Sales\Model\Order\Shipment\Item) { - $_items = $item->getShipment()->getAllItems(); - } else if ($item instanceof \Magento\Sales\Model\Order\Creditmemo\Item) { - $_items = $item->getCreditmemo()->getAllItems(); + $items = $item->getInvoice()->getAllItems(); + } elseif ($item instanceof \Magento\Sales\Model\Order\Shipment\Item) { + $items = $item->getShipment()->getAllItems(); + } elseif ($item instanceof \Magento\Sales\Model\Order\Creditmemo\Item) { + $items = $item->getCreditmemo()->getAllItems(); } - if ($_items) { - foreach ($_items as $_item) { - if ($parentItem = $_item->getOrderItem()->getParentItem()) { - $_itemsArray[$parentItem->getId()][$_item->getOrderItemId()] = $_item; + if ($items) { + foreach ($items as $value) { + $parentItem = $value->getOrderItem()->getParentItem(); + if ($parentItem) { + $itemsArray[$parentItem->getId()][$value->getOrderItemId()] = $value; } else { - $_itemsArray[$_item->getOrderItem()->getId()][$_item->getOrderItemId()] = $_item; + $itemsArray[$value->getOrderItem()->getId()][$value->getOrderItemId()] = $value; } } } - if (isset($_itemsArray[$item->getOrderItem()->getId()])) { - return $_itemsArray[$item->getOrderItem()->getId()]; + if (isset($itemsArray[$item->getOrderItem()->getId()])) { + return $itemsArray[$item->getOrderItem()->getId()]; } else { return null; } diff --git a/app/code/Magento/Bundle/Helper/Catalog/Product/Configuration.php b/app/code/Magento/Bundle/Helper/Catalog/Product/Configuration.php index 3e19a638c430ef5cc4cec43fbecfe3c76ca4badb..45ce20d519b91fd83f7e1b97858220bf313db2c7 100644 --- a/app/code/Magento/Bundle/Helper/Catalog/Product/Configuration.php +++ b/app/code/Magento/Bundle/Helper/Catalog/Product/Configuration.php @@ -28,7 +28,7 @@ use Magento\Catalog\Model\Product\Configuration\Item\ItemInterface; use Magento\Framework\App\Helper\AbstractHelper; /** - * Helper for fetching properties by product configurational item + * Helper for fetching properties by product configuration item */ class Configuration extends AbstractHelper implements ConfigurationInterface { @@ -37,7 +37,7 @@ class Configuration extends AbstractHelper implements ConfigurationInterface * * @var \Magento\Core\Helper\Data */ - protected $_coreData; + protected $coreData; /** * Catalog product configuration @@ -47,9 +47,11 @@ class Configuration extends AbstractHelper implements ConfigurationInterface protected $productConfiguration; /** + * Escaper + * * @var \Magento\Framework\Escaper */ - protected $_escaper; + protected $escaper; /** * @param \Magento\Framework\App\Helper\Context $context @@ -64,8 +66,8 @@ class Configuration extends AbstractHelper implements ConfigurationInterface \Magento\Framework\Escaper $escaper ) { $this->productConfiguration = $productConfiguration; - $this->_coreData = $coreData; - $this->_escaper = $escaper; + $this->coreData = $coreData; + $this->escaper = $escaper; parent::__construct($context); } @@ -74,10 +76,9 @@ class Configuration extends AbstractHelper implements ConfigurationInterface * * @param \Magento\Catalog\Model\Product $product * @param int $selectionId - * * @return float */ - public function getSelectionQty($product, $selectionId) + public function getSelectionQty(\Magento\Catalog\Model\Product $product, $selectionId) { $selectionQty = $product->getCustomOption('selection_qty_' . $selectionId); if ($selectionQty) { @@ -91,19 +92,21 @@ class Configuration extends AbstractHelper implements ConfigurationInterface * * @param ItemInterface $item * @param \Magento\Catalog\Model\Product $selectionProduct - * * @return float */ - public function getSelectionFinalPrice(ItemInterface $item, $selectionProduct) + public function getSelectionFinalPrice(ItemInterface $item, \Magento\Catalog\Model\Product $selectionProduct) { $selectionProduct->unsetData('final_price'); - /** @var \Magento\Bundle\Model\Product\Price $priceModel */ - $priceModel = $item->getProduct()->getPriceModel(); - return $priceModel->getSelectionFinalTotalPrice( - $item->getProduct(), + + $product = $item->getProduct(); + /** @var \Magento\Bundle\Model\Product\Price $price */ + $price = $product->getPriceModel(); + + return $price->getSelectionFinalTotalPrice( + $product, $selectionProduct, - $item->getQty() * 1, - $this->getSelectionQty($item->getProduct(), $selectionProduct->getSelectionId()), + $item->getQty(), + $this->getSelectionQty($product, $selectionProduct->getSelectionId()), false, true ); @@ -151,11 +154,10 @@ class Configuration extends AbstractHelper implements ConfigurationInterface foreach ($bundleSelections as $bundleSelection) { $qty = $this->getSelectionQty($product, $bundleSelection->getSelectionId()) * 1; if ($qty) { - $option['value'][] = $qty . ' x ' . $this->_escaper->escapeHtml( - $bundleSelection->getName() - ) . ' ' . $this->_coreData->currency( - $this->getSelectionFinalPrice($item, $bundleSelection) - ); + $option['value'][] = $qty . ' x ' + . $this->escaper->escapeHtml($bundleSelection->getName()) + . ' ' + . $this->coreData->currency($this->getSelectionFinalPrice($item, $bundleSelection)); } } diff --git a/app/code/Magento/Bundle/Helper/Data.php b/app/code/Magento/Bundle/Helper/Data.php index a6b9c76ad7b3c99845698dbf5cb50c6e2d0b2409..364e95e4c8e7bfc5f318974361f7d5ce6020ab76 100644 --- a/app/code/Magento/Bundle/Helper/Data.php +++ b/app/code/Magento/Bundle/Helper/Data.php @@ -33,7 +33,7 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper /** * @var \Magento\Catalog\Model\ProductTypes\ConfigInterface */ - protected $_config; + protected $config; /** * @param \Magento\Framework\App\Helper\Context $context @@ -43,7 +43,7 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper \Magento\Framework\App\Helper\Context $context, \Magento\Catalog\Model\ProductTypes\ConfigInterface $config ) { - $this->_config = $config; + $this->config = $config; parent::__construct($context); } @@ -54,7 +54,8 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper */ public function getAllowedSelectionTypes() { - $configData = $this->_config->getType('bundle'); - return isset($configData['allowed_selection_types']) ? $configData['allowed_selection_types'] : array(); + $configData = $this->config->getType(\Magento\Catalog\Model\Product\Type::TYPE_BUNDLE); + + return isset($configData['allowed_selection_types']) ? $configData['allowed_selection_types'] : []; } } diff --git a/app/code/Magento/Bundle/Model/Option.php b/app/code/Magento/Bundle/Model/Option.php index 73df7196d863c53c9f19fa02af6848f7f3bc3f34..6ea371a737ce33580234b3a008895c6328bf9345 100644 --- a/app/code/Magento/Bundle/Model/Option.php +++ b/app/code/Magento/Bundle/Model/Option.php @@ -27,23 +27,23 @@ namespace Magento\Bundle\Model; * Bundle Option Model * * @method int getParentId() - * @method \Magento\Bundle\Model\Option setParentId(int $value) - * @method int getRequired() - * @method \Magento\Bundle\Model\Option setRequired(int $value) * @method int getPosition() - * @method \Magento\Bundle\Model\Option setPosition(int $value) + * @method int getRequired() + * @method null|\Magento\Catalog\Model\Product[] getSelections() * @method string getType() - * @method \Magento\Bundle\Model\Option setType(string $value) - * @method \Magento\Catalog\Model\Product[] getSelections() + * @method Option setParentId(int $value) + * @method Option setPosition(int $value) + * @method Option setRequired(int $value) + * @method Option setType(string $value) */ class Option extends \Magento\Framework\Model\AbstractModel { /** * Default selection object * - * @var Selection + * @var \Magento\Catalog\Model\Product|null */ - protected $_defaultSelection = null; + protected $defaultSelection = null; /** * Initialize resource model @@ -59,18 +59,14 @@ class Option extends \Magento\Framework\Model\AbstractModel /** * Add selection to option * - * @param Selection $selection - * @return $this|false + * @param \Magento\Catalog\Model\Product $selection + * @return void */ - public function addSelection($selection) + public function addSelection(\Magento\Catalog\Model\Product $selection) { - if (!$selection) { - return false; - } - $selections = $this->getDataSetDefault('selections', array()); + $selections = $this->getDataSetDefault('selections', []); $selections[] = $selection; $this->setSelections($selections); - return $this; } /** @@ -80,35 +76,35 @@ class Option extends \Magento\Framework\Model\AbstractModel */ public function isSaleable() { - $saleable = 0; - if ($this->getSelections()) { - foreach ($this->getSelections() as $selection) { + $saleable = false; + $selections = $this->getSelections(); + if ($selections) { + foreach ($selections as $selection) { if ($selection->isSaleable()) { - $saleable++; + $saleable = true; + break; } } - return (bool) $saleable; - } else { - return false; } + return $saleable; } /** * Retrieve default Selection object * - * @return Selection + * @return \Magento\Catalog\Model\Product|null */ public function getDefaultSelection() { - if (!$this->_defaultSelection && $this->getSelections()) { + if (!$this->defaultSelection && $this->getSelections()) { foreach ($this->getSelections() as $selection) { if ($selection->getIsDefault()) { - $this->_defaultSelection = $selection; + $this->defaultSelection = $selection; break; } } } - return $this->_defaultSelection; + return $this->defaultSelection; } /** @@ -118,11 +114,7 @@ class Option extends \Magento\Framework\Model\AbstractModel */ public function isMultiSelection() { - if ($this->getType() == 'checkbox' || $this->getType() == 'multi') { - return true; - } else { - return false; - } + return $this->getType() == 'checkbox' || $this->getType() == 'multi'; } /** @@ -141,15 +133,17 @@ class Option extends \Magento\Framework\Model\AbstractModel * Return selection by it's id * * @param int $selectionId - * @return Selection|false + * @return \Magento\Catalog\Model\Product|null */ public function getSelectionById($selectionId) { - foreach ($this->getSelections() as $option) { - if ($option->getSelectionId() == $selectionId) { - return $option; + $foundSelection = null; + foreach ($this->getSelections() as $selection) { + if ($selection->getSelectionId() == $selectionId) { + $foundSelection = $selection; + break; } } - return false; + return $foundSelection; } } diff --git a/app/code/Magento/Bundle/Model/Plugin/PriceBackend.php b/app/code/Magento/Bundle/Model/Plugin/PriceBackend.php index 61dd8091c80b2c5636d7669e79cf527ce8558b01..1a70af60d6375a3334da66c6bfdb27ccee5b481e 100644 --- a/app/code/Magento/Bundle/Model/Plugin/PriceBackend.php +++ b/app/code/Magento/Bundle/Model/Plugin/PriceBackend.php @@ -32,7 +32,7 @@ class PriceBackend { /** * @param \Magento\Catalog\Model\Product\Attribute\Backend\Price $subject - * @param Closure $proceed + * @param \Closure $proceed * @param \Magento\Catalog\Model\Product $product * @return bool * @SuppressWarnings(PHPMD.UnusedFormalParameter) @@ -42,7 +42,9 @@ class PriceBackend \Closure $proceed, \Magento\Catalog\Model\Product $product ) { - if ($product->getPriceType() == \Magento\Bundle\Model\Product\Price::PRICE_TYPE_DYNAMIC) { + if ($product->getTypeId() == \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE + && $product->getPriceType() == \Magento\Bundle\Model\Product\Price::PRICE_TYPE_DYNAMIC + ) { return true; } else { return $proceed($product); diff --git a/app/code/Magento/Bundle/Model/Product/Attribute/Source/Price/View.php b/app/code/Magento/Bundle/Model/Product/Attribute/Source/Price/View.php index c817d9a99928b6e0214d13d5bc66863f59db6360..36c4b861430a6a2b13f9bcf4c7f00af713b4f093 100644 --- a/app/code/Magento/Bundle/Model/Product/Attribute/Source/Price/View.php +++ b/app/code/Magento/Bundle/Model/Product/Attribute/Source/Price/View.php @@ -23,6 +23,9 @@ */ namespace Magento\Bundle\Model\Product\Attribute\Source\Price; +use Magento\Eav\Model\Resource\Entity\Attribute\OptionFactory; +use Magento\Framework\DB\Ddl\Table; + /** * Bundle Price View Attribute Renderer * @@ -31,27 +34,16 @@ namespace Magento\Bundle\Model\Product\Attribute\Source\Price; class View extends \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource { /** - * Core data - * - * @var \Magento\Core\Helper\Data + * @var OptionFactory */ - protected $_coreData = null; + protected $optionFactory; /** - * @var \Magento\Eav\Model\Resource\Entity\Attribute\OptionFactory + * @param OptionFactory $optionFactory */ - protected $_entityAttribute; - - /** - * @param \Magento\Eav\Model\Resource\Entity\Attribute\OptionFactory $entityAttribute - * @param \Magento\Core\Helper\Data $coreData - */ - public function __construct( - \Magento\Eav\Model\Resource\Entity\Attribute\OptionFactory $entityAttribute, - \Magento\Core\Helper\Data $coreData - ) { - $this->_coreData = $coreData; - $this->_entityAttribute = $entityAttribute; + public function __construct(OptionFactory $optionFactory) + { + $this->optionFactory = $optionFactory; } /** @@ -61,11 +53,11 @@ class View extends \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource */ public function getAllOptions() { - if (is_null($this->_options)) { - $this->_options = array( - array('label' => __('As Low as'), 'value' => 1), - array('label' => __('Price Range'), 'value' => 0) - ); + if (null === $this->_options) { + $this->_options = [ + ['label' => __('As Low as'), 'value' => 1], + ['label' => __('Price Range'), 'value' => 0], + ]; } return $this->_options; } @@ -78,8 +70,7 @@ class View extends \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource */ public function getOptionText($value) { - $options = $this->getAllOptions(); - foreach ($options as $option) { + foreach ($this->getAllOptions() as $option) { if ($option['value'] == $value) { return $option['label']; } @@ -92,16 +83,20 @@ class View extends \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource * * @return array */ - public function getFlatColums() + public function getFlatColumns() { $attributeCode = $this->getAttribute()->getAttributeCode(); - $column = array('unsigned' => false, 'default' => null, 'extra' => null); - - $column['type'] = \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER; - $column['nullable'] = true; - $column['comment'] = 'Bundle Price View ' . $attributeCode . ' column'; - return array($attributeCode => $column); + return [ + $attributeCode => [ + 'unsigned' => false, + 'default' => null, + 'extra' => null, + 'type' => Table::TYPE_INTEGER, + 'nullable' => true, + 'comment' => 'Bundle Price View ' . $attributeCode . ' column', + ], + ]; } /** @@ -112,6 +107,6 @@ class View extends \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource */ public function getFlatUpdateSelect($store) { - return $this->_entityAttribute->create()->getFlatUpdateSelect($this->getAttribute(), $store, false); + return $this->optionFactory->create()->getFlatUpdateSelect($this->getAttribute(), $store, false); } } diff --git a/app/code/Magento/Bundle/Model/Sales/Order/Pdf/Items/AbstractItems.php b/app/code/Magento/Bundle/Model/Sales/Order/Pdf/Items/AbstractItems.php index d78d827df2b857653ad757e125073e6af39e06e5..faaa0036e1244120d6e4bf1be0425dc22d5a507c 100644 --- a/app/code/Magento/Bundle/Model/Sales/Order/Pdf/Items/AbstractItems.php +++ b/app/code/Magento/Bundle/Model/Sales/Order/Pdf/Items/AbstractItems.php @@ -31,7 +31,7 @@ use Magento\Catalog\Model\Product\Type\AbstractType; abstract class AbstractItems extends \Magento\Sales\Model\Order\Pdf\Items\AbstractItems { /** - * Getting all available childs for Invoice, Shipmen or Creditmemo item + * Getting all available children for Invoice, Shipment or CreditMemo item * * @param \Magento\Framework\Object $item * @return array @@ -50,12 +50,12 @@ abstract class AbstractItems extends \Magento\Sales\Model\Order\Pdf\Items\Abstra } if ($items) { - foreach ($items as $invoiceItem) { - $parentItem = $invoiceItem->getOrderItem()->getParentItem(); + foreach ($items as $value) { + $parentItem = $value->getOrderItem()->getParentItem(); if ($parentItem) { - $itemsArray[$parentItem->getId()][$invoiceItem->getOrderItemId()] = $invoiceItem; + $itemsArray[$parentItem->getId()][$value->getOrderItemId()] = $value; } else { - $itemsArray[$invoiceItem->getOrderItem()->getId()][$invoiceItem->getOrderItemId()] = $invoiceItem; + $itemsArray[$value->getOrderItem()->getId()][$value->getOrderItemId()] = $value; } } } @@ -79,31 +79,18 @@ abstract class AbstractItems extends \Magento\Sales\Model\Order\Pdf\Items\Abstra if ($item->getOrderItem()) { $item = $item->getOrderItem(); } - $parentItem = $item->getParentItem(); if ($parentItem) { $options = $parentItem->getProductOptions(); if ($options) { - if (isset( - $options['shipment_type'] - ) && $options['shipment_type'] == AbstractType::SHIPMENT_SEPARATELY - ) { - return true; - } else { - return false; - } + return (isset($options['shipment_type']) + && $options['shipment_type'] == AbstractType::SHIPMENT_SEPARATELY); } } else { $options = $item->getProductOptions(); if ($options) { - if (isset( - $options['shipment_type'] - ) && $options['shipment_type'] == AbstractType::SHIPMENT_SEPARATELY - ) { - return false; - } else { - return true; - } + return !(isset($options['shipment_type']) + && $options['shipment_type'] == AbstractType::SHIPMENT_SEPARATELY); } } } @@ -129,40 +116,26 @@ abstract class AbstractItems extends \Magento\Sales\Model\Order\Pdf\Items\Abstra if ($item->getOrderItem()) { $item = $item->getOrderItem(); } - $parentItem = $item->getParentItem(); if ($parentItem) { $options = $parentItem->getProductOptions(); if ($options) { - if (isset( - $options['product_calculations'] - ) && $options['product_calculations'] == AbstractType::CALCULATE_CHILD - ) { - return true; - } else { - return false; - } + return (isset($options['product_calculations']) + && $options['product_calculations'] == AbstractType::CALCULATE_CHILD); } } else { $options = $item->getProductOptions(); if ($options) { - if (isset( - $options['product_calculations'] - ) && $options['product_calculations'] == AbstractType::CALCULATE_CHILD - ) { - return false; - } else { - return true; - } + return !(isset($options['product_calculations']) + && $options['product_calculations'] == AbstractType::CALCULATE_CHILD); } } } $options = $this->getOrderItem()->getProductOptions(); if ($options) { - if (isset( - $options['product_calculations'] - ) && $options['product_calculations'] == AbstractType::CALCULATE_CHILD + if (isset($options['product_calculations']) + && $options['product_calculations'] == AbstractType::CALCULATE_CHILD ) { return true; } @@ -179,10 +152,8 @@ abstract class AbstractItems extends \Magento\Sales\Model\Order\Pdf\Items\Abstra public function getBundleOptions($item = null) { $options = $this->getOrderItem()->getProductOptions(); - if ($options) { - if (isset($options['bundle_options'])) { - return $options['bundle_options']; - } + if ($options && isset($options['bundle_options'])) { + return $options['bundle_options']; } return array(); } diff --git a/app/code/Magento/Bundle/Pricing/Adjustment/Calculator.php b/app/code/Magento/Bundle/Pricing/Adjustment/Calculator.php index 00438ad0d5db95a2b06714489c7a0be97d255e7d..5cd71e56ce9ac1f7e84c9a45615054a7c5e6b9c6 100644 --- a/app/code/Magento/Bundle/Pricing/Adjustment/Calculator.php +++ b/app/code/Magento/Bundle/Pricing/Adjustment/Calculator.php @@ -31,7 +31,7 @@ use Magento\Bundle\Pricing\Price\BundleSelectionFactory; use Magento\Framework\Pricing\Adjustment\Calculator as CalculatorBase; use Magento\Bundle\Model\Product\Price; use Magento\Bundle\Pricing\Price\BundleOptionPrice; -use Magento\Tax\Model\Calculation as TaxCalculation; +use Magento\Tax\Service\V1\TaxCalculationServiceInterface; use Magento\Store\Model\Store; use Magento\Tax\Helper\Data as TaxHelper; @@ -271,7 +271,7 @@ class Calculator implements BundleCalculatorInterface $roundingMethod = $this->taxHelper->getCalculationAgorithm($store); /** @var \Magento\Framework\Pricing\Amount\AmountInterface $itemAmount */ foreach ($amountList as $itemAmount) { - if ($roundingMethod != TaxCalculation::CALC_TOTAL_BASE) { + if ($roundingMethod != TaxCalculationServiceInterface::CALC_TOTAL_BASE) { //We need to round the individual selection first $fullAmount += $store->roundPrice($itemAmount->getValue()); foreach ($itemAmount->getAdjustmentAmounts() as $code => $adjustment) { diff --git a/app/code/Magento/Bundle/Service/V1/Data/Product/Link/Metadata.php b/app/code/Magento/Bundle/Service/V1/Data/Product/Link/Metadata.php new file mode 100644 index 0000000000000000000000000000000000000000..848048b070522ca74cb48aff27a257f5f7e68b79 --- /dev/null +++ b/app/code/Magento/Bundle/Service/V1/Data/Product/Link/Metadata.php @@ -0,0 +1,112 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Bundle\Service\V1\Data\Product\Link; + +use \Magento\Framework\Service\Data\AbstractObject; + +/** + * @codeCoverageIgnore + */ +class Metadata extends AbstractObject +{ + const SKU = 'sku'; + + const OPTION_ID = 'option_id'; + + const QTY = 'qty'; + + const POSITION = 'position'; + + const DEFINED = 'defined'; + + const IS_DEFAULT = 'default'; + + const PRICE = 'price'; + + const PRICE_TYPE = 'price_type'; + + /** + * @return string|null + */ + public function getSku() + { + return $this->_get(self::SKU); + } + + /** + * @return int|null + */ + public function getOptionId() + { + return $this->_get(self::OPTION_ID); + } + + /** + * @return float|null + */ + public function getQty() + { + return $this->_get(self::QTY); + } + + /** + * @return int|null + */ + public function getPosition() + { + return $this->_get(self::POSITION); + } + + /** + * @return bool + */ + public function isDefined() + { + return (bool)$this->_get(self::DEFINED); + } + + /** + * @return bool + */ + public function isDefault() + { + return (bool)$this->_get(self::IS_DEFAULT); + } + + /** + * @return float + */ + public function getPrice() + { + return $this->_get(self::PRICE); + } + + /** + * @return int + */ + public function getPriceType() + { + return $this->_get(self::PRICE_TYPE); + } +} diff --git a/app/code/Magento/Bundle/Service/V1/Data/Product/Link/MetadataBuilder.php b/app/code/Magento/Bundle/Service/V1/Data/Product/Link/MetadataBuilder.php new file mode 100644 index 0000000000000000000000000000000000000000..1750b820f7f87c3d9c726f873e702534467d61e4 --- /dev/null +++ b/app/code/Magento/Bundle/Service/V1/Data/Product/Link/MetadataBuilder.php @@ -0,0 +1,104 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Bundle\Service\V1\Data\Product\Link; + +use Magento\Framework\Service\Data\AbstractObjectBuilder; + +/** + * @codeCoverageIgnore + */ +class MetadataBuilder extends AbstractObjectBuilder +{ + /** + * @param string $value + * @return $this + */ + public function setSku($value) + { + return $this->_set(Metadata::SKU, $value); + } + + /** + * @param float $value + * @return $this + */ + public function setQty($value) + { + return $this->_set(Metadata::QTY, $value); + } + + /** + * @param int $value + * @return $this + */ + public function setPosition($value) + { + return $this->_set(Metadata::POSITION, $value); + } + + /** + * @param int $value + * @return $this + */ + public function setOptionId($value) + { + return $this->_set(Metadata::OPTION_ID, $value); + } + + /** + * @param bool $value + * @return $this + */ + public function setDefined($value) + { + return $this->_set(Metadata::DEFINED, (bool)$value); + } + + /** + * @param bool $value + * @return $this + */ + public function setDefault($value) + { + return $this->_set(Metadata::IS_DEFAULT, (bool)$value); + } + + /** + * @param float $value + * @return $this + */ + public function setPrice($value) + { + return $this->_set(Metadata::PRICE, $value); + } + + /** + * @param int $value + * @return $this + */ + public function setPriceType($value) + { + return $this->_set(Metadata::PRICE_TYPE, $value); + } +} diff --git a/app/code/Magento/Bundle/Service/V1/Data/Product/Link/MetadataConverter.php b/app/code/Magento/Bundle/Service/V1/Data/Product/Link/MetadataConverter.php new file mode 100644 index 0000000000000000000000000000000000000000..d62167d6aecfeac692ada141d9a28d23f408b3c5 --- /dev/null +++ b/app/code/Magento/Bundle/Service/V1/Data/Product/Link/MetadataConverter.php @@ -0,0 +1,70 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Bundle\Service\V1\Data\Product\Link; + +use Magento\Catalog\Model\Product; + +/** + * @codeCoverageIgnore + */ +class MetadataConverter +{ + /** + * @var MetadataBuilder + */ + private $builder; + + /** + * @param MetadataBuilder $builder + */ + public function __construct(MetadataBuilder $builder) + { + $this->builder = $builder; + } + + /** + * @param Product $product + * @param Product $bundle + * @return Metadata + */ + public function createDataFromModel(Product $product, Product $bundle) + { + $selectionPriceType = $selectionPrice = null; + + /** @var \Magento\Bundle\Model\Selection $product */ + if ($bundle->getPriceType()) { + $selectionPriceType = $product->getSelectionPriceType(); + $selectionPrice = $product->getSelectionPriceValue(); + } + + $this->builder->populateWithArray($product->getData()) + ->setDefault($product->getIsDefault()) + ->setQty($product->getSelectionQty()) + ->setDefined($product->getSelectionCanChangeQty()) + ->setPrice($selectionPrice) + ->setPriceType($selectionPriceType); + return $this->builder->create(); + } +} diff --git a/app/code/Magento/Bundle/Service/V1/Product/Link/Data/ProductLink.php b/app/code/Magento/Bundle/Service/V1/Product/Link/Data/ProductLink.php new file mode 100644 index 0000000000000000000000000000000000000000..9568d0b1e30f3e444171e3247e1dda26327bbd24 --- /dev/null +++ b/app/code/Magento/Bundle/Service/V1/Product/Link/Data/ProductLink.php @@ -0,0 +1,110 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Bundle\Service\V1\Product\Link\Data; + +/** + * Bundle ProductLink Service Data Object + */ +class ProductLink extends \Magento\Framework\Service\Data\Eav\AbstractObject +{ + /** + * Constants for Data Object keys + */ + const SKU = 'product_sku'; + const POSITION = 'position'; + const IS_DEFAULT = 'default'; + const PRICE_TYPE = 'slection_price_type'; + const PRICE_VALUE = 'slection_price_value'; + const QUANTITY = 'selection_qty'; + const CAN_CHANGE_QUANTITY = 'selection_can_change_qty'; + + /** + * Get product sku + * + * @return string + */ + public function getSku() + { + return $this->_get(self::SKU); + } + + /** + * Get product position + * + * @return int + */ + public function getPosition() + { + return $this->_get(self::POSITION); + } + + /** + * @return boolean + */ + public function isDefault() + { + return $this->_get(self::IS_DEFAULT); + } + + /** + * Get price type + * + * @return int + */ + public function getPriceType() + { + return $this->_get(self::PRICE_TYPE); + } + + /** + * Get price value + * + * @return float + */ + public function getPriceValue() + { + return $this->_get(self::PRICE_VALUE); + } + + /** + * Get quantity + * + * @return int + */ + public function getQuantity() + { + return $this->_get(self::QUANTITY); + } + + /** + * Get whether quantity could be changed + * + * @return int + */ + public function getCanChangeQuantity() + { + return $this->_get(self::CAN_CHANGE_QUANTITY); + } +} diff --git a/app/code/Magento/Bundle/Service/V1/Product/Link/Data/ProductLinkBuilder.php b/app/code/Magento/Bundle/Service/V1/Product/Link/Data/ProductLinkBuilder.php new file mode 100644 index 0000000000000000000000000000000000000000..64c5d665f408f04e2f9025b71b8920c0d7412270 --- /dev/null +++ b/app/code/Magento/Bundle/Service/V1/Product/Link/Data/ProductLinkBuilder.php @@ -0,0 +1,141 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Bundle\Service\V1\Product\Link\Data; + +use Magento\Framework\Service\Data\Eav\AttributeValueBuilder; + +/** + * Builder for the ProductLink Service Data Object + * + * @method ProductLink create() + */ +class ProductLinkBuilder extends \Magento\Framework\Service\Data\Eav\AbstractObjectBuilder +{ + /** + * @var array + */ + protected $customAttributes = []; + + /** + * @param \Magento\Framework\Service\Data\ObjectFactory $objectFactory + * @param AttributeValueBuilder $valueBuilder + * @param array $customAttributesCodes + */ + public function __construct( + \Magento\Framework\Service\Data\ObjectFactory $objectFactory, + AttributeValueBuilder $valueBuilder, + array $customAttributesCodes = array() + ) { + $this->customAttributes = $customAttributesCodes; + parent::__construct($objectFactory, $valueBuilder); + } + + /** + * Set product sku + * + * @param string $sku + * @return $this + */ + public function setSku($sku) + { + return $this->_set(ProductLink::SKU, $sku); + } + + /** + * Set product position + * + * @param int $position + * @return $this + */ + public function setPosition($position) + { + return $this->_set(ProductLink::POSITION, $position); + } + + /** + * Get custom attributes codes + * + * @return string[] + */ + public function getCustomAttributesCodes() + { + return array_merge(parent::getCustomAttributesCodes(), $this->customAttributes); + } + + /** + * Set is default + * + * @param boolean $default + * @return $this + */ + public function setDefault($default) + { + return $this->_set(ProductLink::IS_DEFAULT, $default); + } + + /** + * Set price type + * + * @param int $priceType + * @return $this + */ + public function setPriceType($priceType) + { + return $this->_set(ProductLink::PRICE_TYPE, $priceType); + } + + /** + * Set price value + * + * @param float $priceValue + * @return $this + */ + public function setPriceValue($priceValue) + { + return $this->_set(ProductLink::PRICE_VALUE, $priceValue); + } + + /** + * Set quantity + * + * @param int $priceValue + * @return $this + */ + public function setQuantity($quantity) + { + return $this->_set(ProductLink::QUANTITY, $quantity); + } + + /** + * Set can change quantity + * + * @param int $canChangeQuantity + * @return $this + */ + public function setCanChangeQuantity($canChangeQuantity) + { + return $this->_set(ProductLink::CAN_CHANGE_QUANTITY, $canChangeQuantity); + } +} diff --git a/app/code/Magento/Bundle/Service/V1/Product/Link/ReadService.php b/app/code/Magento/Bundle/Service/V1/Product/Link/ReadService.php new file mode 100644 index 0000000000000000000000000000000000000000..2cb313a5759bdd3d4f50c3e50e64c85a403668ef --- /dev/null +++ b/app/code/Magento/Bundle/Service/V1/Product/Link/ReadService.php @@ -0,0 +1,102 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Bundle\Service\V1\Product\Link; + +use Magento\Bundle\Model\Option; +use Magento\Bundle\Service\V1\Data\Product\Link\MetadataConverter; +use Magento\Catalog\Model\Product; +use Magento\Catalog\Model\ProductRepository; +use Magento\Webapi\Exception; + +class ReadService implements ReadServiceInterface +{ + /** + * @var \Magento\Catalog\Model\ProductRepository + */ + private $productRepository; + + /** + * @var \Magento\Bundle\Service\V1\Data\Product\Link\MetadataConverter + */ + private $metadataConverter; + + /** + * @param ProductRepository $productRepository + * @param MetadataConverter $metadataConverter + */ + public function __construct( + ProductRepository $productRepository, + MetadataConverter $metadataConverter + ) { + + $this->productRepository = $productRepository; + $this->metadataConverter = $metadataConverter; + } + + /** + * @inheritdoc + */ + public function getChildren($productId) + { + $product = $this->productRepository->get($productId); + + if ($product->getTypeId() != \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE) { + throw new Exception('Only implemented for bundle product', Exception::HTTP_FORBIDDEN); + } + + $childrenList = []; + foreach ($this->getOptions($product) as $option) { + /** @var \Magento\Catalog\Model\Product $selection */ + foreach ($option->getSelections() as $selection) { + $childrenList[] = $this->metadataConverter->createDataFromModel($selection, $product); + } + } + + return $childrenList; + } + + /** + * @param Product $product + * @return Option[] + */ + private function getOptions(Product $product) + { + /** @var \Magento\Bundle\Model\Product\Type $productTypeInstance */ + $productTypeInstance = $product->getTypeInstance(); + $productTypeInstance->setStoreFilter( + $product->getStoreId(), + $product + ); + + $optionCollection = $productTypeInstance->getOptionsCollection($product); + + $selectionCollection = $productTypeInstance->getSelectionsCollection( + $productTypeInstance->getOptionsIds($product), + $product + ); + + $options = $optionCollection->appendSelections($selectionCollection); + return $options; + } +} diff --git a/app/code/Magento/Bundle/Service/V1/Product/Link/ReadServiceInterface.php b/app/code/Magento/Bundle/Service/V1/Product/Link/ReadServiceInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..82d41f220ea88db92cbb483a60549245697089b5 --- /dev/null +++ b/app/code/Magento/Bundle/Service/V1/Product/Link/ReadServiceInterface.php @@ -0,0 +1,37 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Bundle\Service\V1\Product\Link; + +interface ReadServiceInterface +{ + /** + * Get all children for Bundle product + * + * @param string $productId + * @return \Magento\Bundle\Service\V1\Data\Product\Link\Metadata[] + * @throws \Magento\Framework\Exception\NoSuchEntityException + * @throws \Magento\Webapi\Exception + */ + public function getChildren($productId); +} diff --git a/app/code/Magento/Bundle/Service/V1/Product/Link/WriteService.php b/app/code/Magento/Bundle/Service/V1/Product/Link/WriteService.php new file mode 100644 index 0000000000000000000000000000000000000000..1218d7fcfa70afd466d9eb365b15a2eafd022538 --- /dev/null +++ b/app/code/Magento/Bundle/Service/V1/Product/Link/WriteService.php @@ -0,0 +1,208 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + + +namespace Magento\Bundle\Service\V1\Product\Link; + +use Magento\Catalog\Model\ProductRepository; +use Magento\Framework\Exception\InputException; +use Magento\Framework\Exception\CouldNotSaveException; +use Magento\Bundle\Model\Option; +use Magento\Catalog\Model\Product; +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Webapi\Exception; + +class WriteService implements WriteServiceInterface +{ + /** + * @var \Magento\Catalog\Model\ProductRepository + */ + protected $productRepository; + + /** + * @var \Magento\Bundle\Model\SelectionFactory $bundleSelection + */ + protected $bundleSelection; + + /** + * @var \Magento\Store\Model\StoreManagerInterface + */ + protected $storeManager; + + /** + * @var \Magento\Bundle\Model\Resource\BundleFactory + */ + protected $bundleFactory; + + /** + * @var \Magento\Bundle\Model\Resource\Option\CollectionFactory + */ + protected $optionCollection; + + /** + * @param ProductRepository $productRepository + * @param \Magento\Bundle\Model\SelectionFactory $bundleSelection + * @param \Magento\Bundle\Model\Resource\BundleFactory $bundleFactory + * @param \Magento\Bundle\Model\Resource\Option\CollectionFactory $optionCollection, + * @param \Magento\Store\Model\StoreManagerInterface $storeManager + */ + public function __construct( + ProductRepository $productRepository, + \Magento\Bundle\Model\SelectionFactory $bundleSelection, + \Magento\Bundle\Model\Resource\BundleFactory $bundleFactory, + \Magento\Bundle\Model\Resource\Option\CollectionFactory $optionCollection, + \Magento\Store\Model\StoreManagerInterface $storeManager + ) { + $this->productRepository = $productRepository; + $this->bundleSelection = $bundleSelection; + $this->bundleFactory = $bundleFactory; + $this->optionCollection = $optionCollection; + $this->storeManager = $storeManager; + } + + /** + * {@inheritdoc} + */ + public function addChild($productSku, $optionId, Data\ProductLink $linkedProduct) + { + /** @var \Magento\Catalog\Model\Product $product */ + $product = $this->productRepository->get($productSku); + if ($product->getTypeId() != \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE) { + throw new InputException('Product with specified sku: "%1" is not a bundle product', [$productSku]); + } + + $options = $this->optionCollection->create(); + $options->setProductIdFilter($product->getId())->joinValues($this->storeManager->getStore()->getId()); + $isNewOption = true; + /** @var \Magento\Bundle\Model\Option $option */ + foreach ($options as $option) { + if ($option->getOptionId() == $optionId) { + $isNewOption = false; + break; + } + } + + if ($isNewOption) { + throw new InputException( + 'Product with specified sku: "%1" does not contain option: "%2"', + [$productSku, $optionId] + ); + } + + /* @var $resource \Magento\Bundle\Model\Resource\Bundle */ + $resource = $this->bundleFactory->create(); + $selections = $resource->getSelectionsData($product->getId()); + /** @var \Magento\Catalog\Model\Product $linkProductModel */ + $linkProductModel = $this->productRepository->get($linkedProduct->getSku()); + if ($linkProductModel->isComposite()) { + throw new InputException('Bundle product could not contain another composite product'); + } + if ($selections) { + foreach ($selections as $selection) { + if ($selection['option_id'] == $optionId && $selection['product_id'] == $linkProductModel->getId()) { + throw new CouldNotSaveException( + 'Child with specified sku: "%1" already assigned to product: "%2"', + [$linkedProduct->getSku(), $productSku] + ); + } + } + } + + $selectionModel = $this->bundleSelection->create(); + $selectionModel->setOptionId($optionId) + ->setPosition($linkedProduct->getPosition()) + ->setSelectionQty($linkedProduct->getQuantity()) + ->setSelectionPriceType($linkedProduct->getPriceType()) + ->setSelectionPriceValue($linkedProduct->getPriceValue()) + ->setSelectionCanChangeQty($linkedProduct->getCanChangeQuantity()) + ->setProductId($linkProductModel->getId()) + ->setParentProductId($product->getId()) + ->setIsDefault($linkedProduct->isDefault()) + ->setWebsiteId($this->storeManager->getStore()->getWebsiteId()); + + try { + $selectionModel->save(); + } catch (\Exception $e) { + throw new CouldNotSaveException('Could not save child: "%1"', [$e->getMessage()], $e); + } + + return $selectionModel->getId(); + } + + /** + * @inheritdoc + */ + public function removeChild($productSku, $optionId, $childSku) + { + $product = $this->productRepository->get($productSku); + + if ($product->getTypeId() != \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE) { + throw new Exception( + sprintf('Product with specified sku: %s is not a bundle product', $productSku), + Exception::HTTP_FORBIDDEN + ); + } + + $excludeSelectionIds = array(); + $usedProductIds = array(); + $removeSelectionIds = array(); + foreach ($this->getOptions($product) as $option) { + foreach ($option->getSelections() as $selection) { + if (($selection->getSku() == $childSku) && ($selection->getOptionId() == $optionId)) { + $removeSelectionIds[] = $selection->getSelectionId(); + continue; + } + $excludeSelectionIds[] = $selection->getSelectionId(); + $usedProductIds[] = $selection->getProductId(); + } + } + if (empty($removeSelectionIds)) { + throw new NoSuchEntityException('Requested bundle option product doesn\'t exist'); + } + /* @var $resource \Magento\Bundle\Model\Resource\Bundle */ + $resource = $this->bundleFactory->create(); + $resource->dropAllUnneededSelections($product->getId(), $excludeSelectionIds); + $resource->saveProductRelations($product->getId(), array_unique($usedProductIds)); + + return true; + } + + /** + * @param Product $product + * @return Option[] + */ + private function getOptions(Product $product) + { + $product->getTypeInstance()->setStoreFilter($product->getStoreId(), $product); + + $optionCollection = $product->getTypeInstance()->getOptionsCollection($product); + + $selectionCollection = $product->getTypeInstance()->getSelectionsCollection( + $product->getTypeInstance()->getOptionsIds($product), + $product + ); + + return $optionCollection->appendSelections($selectionCollection); + } +} diff --git a/app/code/Magento/Bundle/Service/V1/Product/Link/WriteServiceInterface.php b/app/code/Magento/Bundle/Service/V1/Product/Link/WriteServiceInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..44246c350baedb033acdaa5b51a1f5b01935d855 --- /dev/null +++ b/app/code/Magento/Bundle/Service/V1/Product/Link/WriteServiceInterface.php @@ -0,0 +1,53 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Bundle\Service\V1\Product\Link; + +interface WriteServiceInterface +{ + /** + * Add child product to specified Bundle option + * + * @param string $productSku + * @param int $optionId + * @param \Magento\Bundle\Service\V1\Product\Link\Data\ProductLink $linkedProduct + * @throws \Magento\Framework\Exception\NoSuchEntityException + * @throws \Magento\Framework\Exception\CouldNotSaveException + * @throws \Magento\Framework\Exception\InputException + * @return int + */ + public function addChild($productSku, $optionId, Data\ProductLink $linkedProduct); + + /** + * Remove product from Bundle product option + * + * @param string $productSku + * @param int $optionId + * @param string $childSku + * @throws \Magento\Framework\Exception\NoSuchEntityException + * @throws \Magento\Webapi\Exception + * @return bool + */ + public function removeChild($productSku, $optionId, $childSku); +} diff --git a/app/code/Magento/Bundle/etc/di.xml b/app/code/Magento/Bundle/etc/di.xml index 375f3cd22712cba1601539b44f4595e6510954e6..fd02cc8f4cc9c6f51757c711d460ddbcfb692bd3 100644 --- a/app/code/Magento/Bundle/etc/di.xml +++ b/app/code/Magento/Bundle/etc/di.xml @@ -24,6 +24,8 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd"> + <preference for="Magento\Bundle\Service\V1\Product\Link\ReadServiceInterface" type="Magento\Bundle\Service\V1\Product\Link\ReadService" /> + <preference for="Magento\Bundle\Service\V1\Product\Link\WriteServiceInterface" type="Magento\Bundle\Service\V1\Product\Link\WriteService" /> <type name="Magento\Bundle\Model\Source\Option\Type"> <arguments> <argument name="options" xsi:type="array"> diff --git a/app/code/Magento/Bundle/etc/module.xml b/app/code/Magento/Bundle/etc/module.xml index 8184420b5d516e152364d5f3b92302d776b4ca05..d91076fb651caba4325311453fff37cb8af74c01 100644 --- a/app/code/Magento/Bundle/etc/module.xml +++ b/app/code/Magento/Bundle/etc/module.xml @@ -43,6 +43,7 @@ <module name="Magento_Weee"/> <module name="Magento_GiftMessage"/> <module name="Magento_Theme"/> + <module name="Magento_Webapi"/> </depends> </module> </config> diff --git a/app/code/Magento/Bundle/etc/webapi.xml b/app/code/Magento/Bundle/etc/webapi.xml new file mode 100644 index 0000000000000000000000000000000000000000..757c74cee5b1333e78145dedf60219d3239f1f0f --- /dev/null +++ b/app/code/Magento/Bundle/etc/webapi.xml @@ -0,0 +1,46 @@ +<?xml version="1.0"?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../app/code/Magento/Webapi/etc/webapi.xsd"> + <route url="/V1/bundle-products/:productSku/links/:optionId" method="POST"> + <service class="Magento\Bundle\Service\V1\Product\Link\WriteServiceInterface" method="addChild"/> + <resources> + <resource ref="Magento_Catalog::products"/> + </resources> + </route> + <route url="/V1/bundle-products/:productId/children" method="GET"> + <service class="Magento\Bundle\Service\V1\Product\Link\ReadServiceInterface" method="getChildren"/> + <resources> + <resource ref="Magento_Catalog::products"/> + </resources> + </route> + <route url="/V1/bundle-products/:productSku/option/:optionId/child/:childSku" method="DELETE"> + <service class="Magento\Bundle\Service\V1\Product\Link\WriteServiceInterface" method="removeChild"/> + <resources> + <resource ref="Magento_Catalog::products"/> + </resources> + </route> +</routes> diff --git a/app/code/Magento/Bundle/view/frontend/layout/catalog_product_view_type_bundle.xml b/app/code/Magento/Bundle/view/frontend/layout/catalog_product_view_type_bundle.xml index 1ac55f7c0a139e32bee81f6ff7cd1502fc1878a5..53f256a2faa9f44f19e11bbe4ea78c528bdb9e60 100644 --- a/app/code/Magento/Bundle/view/frontend/layout/catalog_product_view_type_bundle.xml +++ b/app/code/Magento/Bundle/view/frontend/layout/catalog_product_view_type_bundle.xml @@ -45,7 +45,9 @@ <argument name="zone" xsi:type="string">item_view</argument> </arguments> </block> - <block class="Magento\Catalog\Block\Product\View" name="product.info.addtocart.bundle" as="addtocart" template="product/view/addtocart.phtml"/> + <block class="Magento\Catalog\Block\Product\View" name="product.info.addtocart.bundle" as="addtocart" template="product/view/addtocart.phtml"> + <block class="Magento\Catalog\Block\ShortcutButtons\InCatalog" name="addtocart.shortcut.buttons"/> + </block> <block class="Magento\Catalog\Block\Product\View" name="product.info.addto.bundle" as="addto" template="product/view/addto.phtml"/> </block> </referenceBlock> diff --git a/app/code/Magento/Bundle/view/frontend/templates/sales/order/creditmemo/items/renderer.phtml b/app/code/Magento/Bundle/view/frontend/templates/sales/order/creditmemo/items/renderer.phtml index 4f184dd05239bac1e139fb44fd604bafd0079ea8..c66e9c8e7070c1852be8242538f3dcac810fa2cf 100644 --- a/app/code/Magento/Bundle/view/frontend/templates/sales/order/creditmemo/items/renderer.phtml +++ b/app/code/Magento/Bundle/view/frontend/templates/sales/order/creditmemo/items/renderer.phtml @@ -48,156 +48,129 @@ <?php $_prevOptionId = $attributes['option_id'] ?> <?php endif; ?> <?php endif; ?> -<tr<?php echo (++$_index==$_count && !$_showlastRow)?' class="border"':'' ?> id="order-item-row-<?php echo $_item->getId() ?>"> +<tr id="order-item-row-<?php echo $_item->getId() ?>" class="<?php if ($_item->getOrderItem()->getParentItem()): ?>item-options<?php else: ?>item-parent<?php endif; ?>"> <?php if (!$_item->getOrderItem()->getParentItem()): ?> - <td class="col name"> - <strong class="product name"><?php echo $this->escapeHtml($_item->getName()) ?></strong> + <td class="col name" data-th="<?php echo $this->escapeHtml(__('Product Name')); ?>"> + <strong class="product name product-item-name"><?php echo $this->escapeHtml($_item->getName()) ?></strong> </td> <?php else: ?> - <td class="col option"><?php echo $this->getValueHtml($_item) ?></td> + <td class="col value"><?php echo $this->getValueHtml($_item) ?></td> <?php endif; ?> - <td class="col sku"><?php echo $this->escapeHtml($_item->getSku()) ?></td> - <td class="col price"> + <td class="col sku" data-th="<?php echo $this->escapeHtml(__('SKU')); ?>"><?php echo $this->escapeHtml($_item->getSku()) ?></td> + <td class="col price" data-th="<?php echo $this->escapeHtml(__('Price')); ?>"> <?php if ($this->canShowPriceInfo($_item)): ?> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceExclTax()): ?> - <span class="price excl tax"> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices()): ?> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart price"> - <?php endif; ?> - <span class="label"><?php echo __('Excl. Tax'); ?>:</span> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - </span> - <?php endif; ?> - <?php endif; ?> + <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceInclTax()): ?> + <span class="incl tax" data-th="<?php echo $this->escapeHtml(__('Incl. Tax')); ?>"> + <?php $_incl = $this->helper('Magento\Checkout\Helper\Data')->getPriceInclTax($this->getItem()); ?> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" - data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <span class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#unit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> <?php else: ?> - <span class="cart price"> - <?php endif; ?> + <span class="cart price"> + <?php endif; ?> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()+$this->getItem()->getWeeeTaxAppliedAmount()+$this->getItem()->getWeeeTaxDisposition()); ?> + <?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedAmount()); ?> <?php else: ?> - <?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()) ?> + <?php echo $this->getOrder()->formatPrice($_incl-$this->getItem()->getWeeeTaxDisposition()) ?> <?php endif; ?> - - </span> + </span> <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> - <span class="cart tax info" id="eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display:none;"> + <span class="cart tax info" id="unit-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display: none;"> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount']); ?> - <?php endforeach; ?> - </small> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount']); ?></span> + <?php endforeach; ?> <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <small><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></small> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></span> <?php endforeach; ?> <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?> - <?php endforeach; ?> - </small> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></span> + <?php endforeach; ?> <?php endif; ?> </span> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" - data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> - <?php echo __('Total'); ?>:<br /> <?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()+$this->getItem()->getWeeeTaxAppliedAmount()+$this->getItem()->getWeeeTaxDisposition()); ?> + <span class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#unit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <span class="weee" data-th="<?php echo $this->escapeHtml(__('Total incl. tax')); ?>"><?php echo $this->getOrder()->formatPrice($_incl + $this->getItem()->getWeeeTaxAppliedAmount()); ?></span> </span> <?php endif; ?> <?php endif; ?> </span> - <br /> <?php endif; ?> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceInclTax()): ?> - <span class="price incl tax"> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices()): ?> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart price"> - <?php endif; ?> - <span class="label"><?php echo __('Incl. Tax'); ?>:</span> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - </span> - <?php endif; ?> - <?php endif; ?> - <?php $_incl = $this->helper('Magento\Checkout\Helper\Data')->getPriceInclTax($this->getItem()); ?> + <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceExclTax()): ?> + <span class="excl tax" data-th="<?php echo $this->escapeHtml(__('Excl. Tax')); ?>"> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" - data-tax-toggle='{"itemTaxId" : "#unit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <span class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> <?php else: ?> - <span class="cart price"> - <?php endif; ?> + <span class="cart price"> + <?php endif; ?> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedAmount()); ?> + <?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()+$this->getItem()->getWeeeTaxAppliedAmount()+$this->getItem()->getWeeeTaxDisposition()); ?> <?php else: ?> - <?php echo $this->getOrder()->formatPrice($_incl-$this->getItem()->getWeeeTaxDisposition()) ?> + <?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()) ?> <?php endif; ?> - </span> + </span> <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> - <span class="cart tax info" id="unit-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display:none;"> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount']); ?> - <?php endforeach; ?> - </small> - <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <small><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></small> - <?php endforeach; ?> - <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?> - <?php endforeach; ?> - </small> - <?php endif; ?> + <span class="cart-tax-info" id="eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display: none;"> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount']); ?></span> + <?php endforeach; ?> + <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></span> + <?php endforeach; ?> + <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></span> + <?php endforeach; ?> + <?php endif; ?> </span> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" - data-tax-toggle='{"itemTaxId" : "#unit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> - <?php echo __('Total Incl. Tax'); ?>:<br/> <?php echo $this->getOrder()->formatPrice($_incl + $this->getItem()->getWeeeTaxAppliedAmount()); ?> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <span class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <span class="weee" data-th="<?php echo $this->escapeHtml(__('Total')); ?>"><?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()+$this->getItem()->getWeeeTaxAppliedAmount()+$this->getItem()->getWeeeTaxDisposition()); ?></span> </span> - <?php endif; ?> <?php endif; ?> - </span> + <?php endif; ?> + </span> <?php endif; ?> <?php else: ?> <?php endif; ?> </td> - <td class="col qty"> + <td class="col qty" data-th="<?php echo $this->escapeHtml(__('Qty')); ?>"> <?php if ($this->canShowPriceInfo($_item)): ?> <?php echo $_item->getQty()*1 ?> <?php else: ?> <?php endif; ?> </td> - <td class="col subtotal"> + <td class="col subtotal" data-th="<?php echo $this->escapeHtml(__('Subtotal')); ?>"> <?php if ($this->canShowPriceInfo($_item)): ?> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceExclTax()): ?> - <span class="price excl tax"> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices()): ?> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart price"> - <?php endif; ?> - <span class="label"><?php echo __('Excl. Tax'); ?>:</span> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - </span> + <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceInclTax()): ?> + <span class="incl tax" data-th="<?php echo $this->escapeHtml(__('Incl. Tax')); ?>"> + <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices()): ?> + <?php echo $this->getOrder()->formatPrice($this->helper('Magento\Checkout\Helper\Data')->getSubtotalInclTax($_item)); ?> <?php endif; ?> - <?php endif; ?> + </span> + <?php else: ?> + + <?php endif; ?> + + <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceExclTax()): ?> + <span class="excl tax" data-th="<?php echo $this->escapeHtml(__('Excl. Tax')); ?>"> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" + <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> <?php else: ?> <span class="cart price"> @@ -211,66 +184,43 @@ <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> - <span class="cart tax info" id="esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display:none;"> + <span class="cart-tax-info" id="esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display: none;"> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount']); ?> - <?php endforeach; ?> - </small> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount']); ?></span> + <?php endforeach; ?> <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <small> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?> - </small> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></span> <?php endforeach; ?> <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?> - <?php endforeach; ?> - </small> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></span> + <?php endforeach; ?> <?php endif; ?> </span> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" + <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> - <?php echo __('Total'); ?>:<br/> <?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal() + $this->getItem()->getWeeeTaxAppliedRowAmount() + $this->getItem()->getWeeeTaxRowDisposition()); ?> + <span class="weee" data-th="<?php echo $this->escapeHtml(__('Total')); ?>"><?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal() + $this->getItem()->getWeeeTaxAppliedRowAmount() + $this->getItem()->getWeeeTaxRowDisposition()); ?></span> </span> <?php endif; ?> <?php endif; ?> </span> - <br /> - <?php endif; ?> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceInclTax()): ?> - <span class="price incl tax"> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices()): ?> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart price"> - <?php endif; ?> - <span class="label"><?php echo __('Incl. Tax'); ?>:</span> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - </span> - <?php endif; ?> - <?php echo $this->getOrder()->formatPrice($this->helper('Magento\Checkout\Helper\Data')->getSubtotalInclTax($_item)); ?> - <?php endif; ?> - </span> - <?php else: ?> - <?php endif; ?> <?php else: ?> <?php endif; ?> </td> - <td class="col discount"> + <td class="col discount" data-th="<?php echo $this->escapeHtml(__('Discount Amount')); ?>"> <?php if ($this->canShowPriceInfo($_item)): ?> <?php echo $this->getOrder()->formatPrice(-$_item->getDiscountAmount()) ?> <?php else: ?> <?php endif; ?> </td> - <td class="col rowtotal"> + <td class="col rowtotal" data-th="<?php echo $this->escapeHtml(__('Row Total')); ?>"> <?php if ($this->canShowPriceInfo($_item)): ?> <?php echo $this->getOrder()->formatPrice($_item->getRowTotal()-$_item->getDiscountAmount()+$_item->getTaxAmount()+$_item->getWeeeTaxAppliedRowAmount()) ?> <?php else: ?> diff --git a/app/code/Magento/Bundle/view/frontend/templates/sales/order/invoice/items/renderer.phtml b/app/code/Magento/Bundle/view/frontend/templates/sales/order/invoice/items/renderer.phtml index fa1d2f378e8df9f2c7026ad5c71f5fe445bec949..2515d5a29c3a269a9eb8fde19f5703c3e9ea8444 100644 --- a/app/code/Magento/Bundle/view/frontend/templates/sales/order/invoice/items/renderer.phtml +++ b/app/code/Magento/Bundle/view/frontend/templates/sales/order/invoice/items/renderer.phtml @@ -47,212 +47,122 @@ <?php $_prevOptionId = $attributes['option_id'] ?> <?php endif; ?> <?php endif; ?> - <tr<?php echo (++$_index==$_count && !$_showlastRow)?' class="border"':'' ?> id="order-item-row-<?php echo $_item->getId() ?>"> + <tr id="order-item-row-<?php echo $_item->getId() ?>" class="<?php if ($_item->getOrderItem()->getParentItem()): ?>item-options<?php else: ?>item-parent<?php endif; ?>"> <?php if (!$_item->getOrderItem()->getParentItem()): ?> - <td class="col name"> - <strong class="product name"><?php echo $this->escapeHtml($_item->getName()) ?></strong> + <td class="col name" data-th="<?php echo $this->escapeHtml(__('Product Name')); ?>"> + <strong class="product name product-item-name"><?php echo $this->escapeHtml($_item->getName()) ?></strong> </td> <?php else: ?> <td class="col value"><?php echo $this->getValueHtml($_item) ?></td> <?php endif; ?> - <td class="col sku"><?php echo $this->escapeHtml($_item->getSku()) ?></td> - <td class="col price"> + <td class="col sku" data-th="<?php echo $this->escapeHtml(__('SKU')); ?>"><?php echo $this->escapeHtml($_item->getSku()) ?></td> + <td class="col price" data-th="<?php echo $this->escapeHtml(__('Price')); ?>"> <?php if ($this->canShowPriceInfo($_item)): ?> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceExclTax()): ?> - <span class="price excl tax"> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices()): ?> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart price"> - <?php endif; ?> - <span class="label"><?php echo __('Excl. Tax'); ?>:</span> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - </span> - <?php endif; ?> - <?php endif; ?> + <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceInclTax()): ?> + <span class="incl tax" data-th="<?php echo $this->escapeHtml(__('Incl. Tax')); ?>"> + <?php $_incl = $this->helper('Magento\Checkout\Helper\Data')->getPriceInclTax($this->getItem()); ?> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" - data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <span class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#unit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> <?php else: ?> - <span class="cart price"> - <?php endif; ?> + <span class="cart price"> + <?php endif; ?> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()+$this->getItem()->getWeeeTaxAppliedAmount()+$this->getItem()->getWeeeTaxDisposition()); ?> + <?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedAmount()); ?> <?php else: ?> - <?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()) ?> + <?php echo $this->getOrder()->formatPrice($_incl-$this->getItem()->getWeeeTaxDisposition()) ?> <?php endif; ?> - </span> - - <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> - <span class="cart tax info" id="eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>" - style="display:none;"> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount']); ?> - <?php endforeach; ?> - </small> - <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <small><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></small> - <?php endforeach; ?> - <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?> - <?php endforeach; ?> - </small> - <?php endif; ?> </span> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" - data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> - <?php echo __('Total'); ?>:<br /> <?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()+$this->getItem()->getWeeeTaxAppliedAmount()+$this->getItem()->getWeeeTaxDisposition()); ?> - </span> - <?php endif; ?> + <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> + <span class="cart-tax-info" id="unit-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display: none;"> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount']); ?></span> + <?php endforeach; ?> + <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></span> + <?php endforeach; ?> + <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></span> + <?php endforeach; ?> <?php endif; ?> + </span> + + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <span class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#unit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <span class="weee" data-th="<?php echo $this->escapeHtml(__('Total incl. tax')); ?>"><?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedAmount()); ?></span> </span> - <br /> <?php endif; ?> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceInclTax()): ?> - <span class="price incl tax"> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices()): ?> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart price"> - <?php endif; ?> - <span class="label"><?php echo __('Incl. Tax'); ?>:</span> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - </span> - <?php endif; ?> <?php endif; ?> - <?php $_incl = $this->helper('Magento\Checkout\Helper\Data')->getPriceInclTax($this->getItem()); ?> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" - data-tax-toggle='{"itemTaxId" : "#unit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> - <?php else: ?> - <span class="cart price"> + </span> <?php endif; ?> + <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceExclTax()): ?> + <span class="excl tax" data-th="<?php echo $this->escapeHtml(__('Excl. Tax')); ?>"> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <span class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <?php else: ?> + <span class="cart price"> + <?php endif; ?> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedAmount()); ?> + <?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()+$this->getItem()->getWeeeTaxAppliedAmount()+$this->getItem()->getWeeeTaxDisposition()); ?> <?php else: ?> - <?php echo $this->getOrder()->formatPrice($_incl-$this->getItem()->getWeeeTaxDisposition()) ?> + <?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()) ?> <?php endif; ?> - </span> + </span> <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> - <span class="cart tax info" id="unit-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display:none;"> + <span class="cart-tax-info" id="eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>" + style="display: none;"> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount']); ?> - <?php endforeach; ?> - </small> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount']); ?></span> + <?php endforeach; ?> <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <small><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></small> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></span> <?php endforeach; ?> <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?> - <?php endforeach; ?> - </small> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></span> + <?php endforeach; ?> <?php endif; ?> </span> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" - data-tax-toggle='{"itemTaxId" : "#unit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> - <?php echo __('Total incl. tax'); ?>:<br /> <?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedAmount()); ?> + <span class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <span class="weee" data-th="<?php echo $this->escapeHtml(__('Total')); ?>"><?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()+$this->getItem()->getWeeeTaxAppliedAmount()+$this->getItem()->getWeeeTaxDisposition()); ?></span> </span> + <?php endif; ?> <?php endif; ?> - <?php endif; ?> </span> <?php endif; ?> <?php else: ?> <?php endif; ?> </td> - <td class="col qty"> + <td class="col qty" data-th="<?php echo $this->escapeHtml(__('Qty Invoiced')); ?>"> <?php if ($this->canShowPriceInfo($_item)): ?> <?php echo $_item->getQty()*1 ?> <?php else: ?> <?php endif; ?> </td> - <td class="col subtotal"> + <td class="col subtotal" data-th="<?php echo $this->escapeHtml(__('Subtotal')); ?>"> <?php if ($this->canShowPriceInfo($_item)): ?> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceExclTax()): ?> - <span class="price excl tax"> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices()): ?> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart price"> - <?php endif; ?> - <span class="label"><?php echo __('Excl. Tax'); ?>:</span> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - </span> - <?php endif; ?> - <?php endif; ?> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" - data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> - <?php else: ?> - <span class="cart price"> - <?php endif; ?> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()+$this->getItem()->getWeeeTaxAppliedRowAmount()+$this->getItem()->getWeeeTaxRowDisposition()); ?> - <?php else: ?> - <?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()) ?> - <?php endif; ?> - </span> - - <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> - <span class="cart tax info" id="esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display:none;"> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount']); ?> - <?php endforeach; ?> - </small> - <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <small><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></small> - <?php endforeach; ?> - <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?> - <?php endforeach; ?> - </small> - <?php endif; ?> - </span> - - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" - data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> - <?php echo __('Total'); ?>:<br /> <?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()+$this->getItem()->getWeeeTaxAppliedRowAmount()+$this->getItem()->getWeeeTaxRowDisposition()); ?> - </span> - <?php endif; ?> - <?php endif; ?> - </span> - <br /> - <?php endif; ?> <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceInclTax()): ?> - <span class="price incl tax"> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices()): ?> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart price"> - <?php endif; ?> - <span class="label"><?php echo __('Incl. Tax'); ?>:</span> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - </span> - <?php endif; ?> - <?php endif; ?> + <span class="incl tax" data-th="<?php echo $this->escapeHtml(__('Incl. Tax')); ?>"> <?php $_incl = $this->helper('Magento\Checkout\Helper\Data')->getSubtotalInclTax($this->getItem()); ?> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" - data-tax-toggle='{"itemTaxId" : "#subtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <span class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#subtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> <?php else: ?> <span class="cart price"> <?php endif; ?> @@ -261,38 +171,75 @@ <?php else: ?> <?php echo $this->getOrder()->formatPrice($_incl-$this->getItem()->getWeeeTaxRowDisposition()) ?> <?php endif; ?> - </span> + </span> <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> - <span class="cart tax info" id="subtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display:none;"> + <span class="cart-tax-info" id="subtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display: none;"> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount']); ?> - <?php endforeach; ?> - </small> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount']); ?></span> + <?php endforeach; ?> <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <small><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></small> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></span> <?php endforeach; ?> <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?> - <?php endforeach; ?> - </small> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></span> + <?php endforeach; ?> <?php endif; ?> </span> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" + <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#subtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> - <?php echo __('Total incl. tax'); ?>:<br /> <?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedRowAmount()); ?> + <span class="weee" data-th="<?php echo $this->escapeHtml(__('Total incl. tax')); ?>"><?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedRowAmount()); ?></span> </span> <?php endif; ?> <?php endif; ?> </span> <?php endif; ?> + <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceExclTax()): ?> + <span class="excl tax" data-th="<?php echo $this->escapeHtml(__('Excl. Tax')); ?>"> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <span class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <?php else: ?> + <span class="cart price"> + <?php endif; ?> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()+$this->getItem()->getWeeeTaxAppliedRowAmount()+$this->getItem()->getWeeeTaxRowDisposition()); ?> + <?php else: ?> + <?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()) ?> + <?php endif; ?> + </span> + + <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> + <span class="cart-tax-info" id="esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display: none;"> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount']); ?></span> + <?php endforeach; ?> + <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></span> + <?php endforeach; ?> + <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></span> + <?php endforeach; ?> + <?php endif; ?> + </span> + + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <span class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <span class="weee" data-th="<?php echo $this->escapeHtml(__('Total')); ?>"><?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()+$this->getItem()->getWeeeTaxAppliedRowAmount()+$this->getItem()->getWeeeTaxRowDisposition()); ?></span> + </span> + <?php endif; ?> + <?php endif; ?> + </span> + <?php endif; ?> <?php else: ?> <?php endif; ?> diff --git a/app/code/Magento/Bundle/view/frontend/templates/sales/order/items/renderer.phtml b/app/code/Magento/Bundle/view/frontend/templates/sales/order/items/renderer.phtml index a81e2dc7e448a1a68235a809167b01d0ca51c096..1581213677eaf570900524d4a02159261bbbf1f8 100644 --- a/app/code/Magento/Bundle/view/frontend/templates/sales/order/items/renderer.phtml +++ b/app/code/Magento/Bundle/view/frontend/templates/sales/order/items/renderer.phtml @@ -48,122 +48,95 @@ <?php $_prevOptionId = $attributes['option_id'] ?> <?php endif; ?> <?php endif; ?> -<tr<?php echo (++$_index==$_count && !$_showlastRow)?' class="border"':'' ?> id="order-item-row-<?php echo $_item->getId() ?>"> +<tr id="order-item-row-<?php echo $_item->getId() ?>" class="<?php if ($_item->getParentItem()): ?>item-options<?php else: ?>item-parent<?php endif; ?>"> <?php if (!$_item->getParentItem()): ?> - <td class="col name"> - <strong class="product name"><?php echo $this->escapeHtml($_item->getName()) ?></strong> + <td class="col name" data-th="<?php echo $this->escapeHtml(__('Product Name')); ?>"> + <strong class="product name product-item-name"><?php echo $this->escapeHtml($_item->getName()) ?></strong> </td> <?php else: ?> <td class="col value"><?php echo $this->getValueHtml($_item)?></td> <?php endif; ?> - <td class="col sku"><?php echo $this->prepareSku($_item->getSku()) ?></td> - <td class="col price"> + <td class="col sku" data-th="<?php echo $this->escapeHtml(__('SKU')); ?>"><?php echo $this->prepareSku($_item->getSku()) ?></td> + <td class="col price" data-th="<?php echo $this->escapeHtml(__('Price')); ?>"> <?php if (!$_item->getParentItem()): ?> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceExclTax()): ?> - <span class="price excl tax"> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices()): ?> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart price"> - <?php endif; ?> - <span class="label"><?php echo __('Excl. Tax'); ?>:</span> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - </span> - <?php endif; ?> - <?php endif; ?> + <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceInclTax()): ?> + <span class="incl tax" data-th="<?php echo $this->escapeHtml(__('Incl. Tax')); ?>"> + <?php $_incl = $this->helper('Magento\Checkout\Helper\Data')->getPriceInclTax($this->getItem()); ?> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" - data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <span class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#unit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> <?php else: ?> - <span class="cart price"> - <?php endif; ?> + <span class="cart price"> + <?php endif; ?> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()+$this->getItem()->getWeeeTaxAppliedAmount()+$this->getItem()->getWeeeTaxDisposition()); ?> + <?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedAmount()); ?> <?php else: ?> - <?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()) ?> + <?php echo $this->getOrder()->formatPrice($_incl-$this->getItem()->getWeeeTaxDisposition()) ?> <?php endif; ?> - </span> + </span> <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> - <span class="cart tax info" id="eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>" - style="display:none;"> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount']); ?> - <?php endforeach; ?> - </small> - <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <small><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></small> - <?php endforeach; ?> - <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?> - <?php endforeach; ?> - </small> - <?php endif; ?> + <span class="cart-tax-info" id="unit-item-tax-details<?php echo $this->getItem()->getId(); ?>" + style="display: none;"> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount']); ?></span> + <?php endforeach; ?> + <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></span> + <?php endforeach; ?> + <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></span> + <?php endforeach; ?> + <?php endif; ?> </span> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" - data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> - <?php echo __('Total'); ?>:<br /> <?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()+$this->getItem()->getWeeeTaxAppliedAmount()+$this->getItem()->getWeeeTaxDisposition()); ?> + <span class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#unit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <span class="weee" data-th="<?php echo $this->escapeHtml(__('Total incl. tax')); ?>"><?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedAmount()); ?></span> </span> <?php endif; ?> <?php endif; ?> </span> - <br /> <?php endif; ?> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceInclTax()): ?> - <span class="price incl tax"> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices()): ?> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart price"> - <?php endif; ?> - <span class="label"><?php echo __('Incl. Tax'); ?>:</span> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - </span> - <?php endif; ?> - <?php endif; ?> - <?php $_incl = $this->helper('Magento\Checkout\Helper\Data')->getPriceInclTax($this->getItem()); ?> + + <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceExclTax()): ?> + <span class="excl tax" data-th="<?php echo $this->escapeHtml(__('Excl. Tax')); ?>"> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" - data-tax-toggle='{"itemTaxId" : "#unit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <span class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> <?php else: ?> - <span class="cart price"> - <?php endif; ?> + <span class="cart price"> + <?php endif; ?> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedAmount()); ?> + <?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()+$this->getItem()->getWeeeTaxAppliedAmount()+$this->getItem()->getWeeeTaxDisposition()); ?> <?php else: ?> - <?php echo $this->getOrder()->formatPrice($_incl-$this->getItem()->getWeeeTaxDisposition()) ?> + <?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()) ?> <?php endif; ?> - </span> - + </span> <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> - <span class="cart tax info" id="unit-item-tax-details<?php echo $this->getItem()->getId(); ?>" - style="display:none;"> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> + <span class="cart-tax-info" id="eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>" + style="display: none;"> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount']); ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount']); ?></span> <?php endforeach; ?> - </small> - <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <small><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></small> - <?php endforeach; ?> - <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> + <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></span> <?php endforeach; ?> - </small> - <?php endif; ?> + <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></span> + <?php endforeach; ?> + <?php endif; ?> </span> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" - data-tax-toggle='{"itemTaxId" : "#unit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> - <?php echo __('Total incl. tax'); ?>:<br /> <?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedAmount()); ?> + <span class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <span class="weee" data-th="<?php echo $this->escapeHtml(__('Total')); ?>"><?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()+$this->getItem()->getWeeeTaxAppliedAmount()+$this->getItem()->getWeeeTaxDisposition()); ?></span> </span> <?php endif; ?> <?php endif; ?> @@ -173,140 +146,139 @@ <?php endif; ?> </td> - <td class="col qty"> + <td class="col qty" data-th="<?php echo $this->escapeHtml(__('Qty')); ?>"> + <?php if ( + ($_item->getParentItem() && $this->isChildCalculated()) || + (!$_item->getParentItem() && !$this->isChildCalculated()) || ($_item->getQtyShipped() > 0 && $_item->getParentItem() && $this->isShipmentSeparately())):?> + <ul class="items-qty"> + <?php endif; ?> <?php if (($_item->getParentItem() && $this->isChildCalculated()) || (!$_item->getParentItem() && !$this->isChildCalculated())): ?> <?php if ($_item->getQtyOrdered() > 0): ?> - <?php echo __('Ordered'); ?>: <strong><?php echo $_item->getQtyOrdered()*1 ?></strong><br /> + <li class="item"> + <span class="title"><?php echo __('Ordered'); ?></span> + <span class="content"><?php echo $_item->getQtyOrdered()*1 ?></span> + </li> + <?php endif; ?> + <?php if ($_item->getQtyShipped() > 0 && !$this->isShipmentSeparately()): ?> + <li class="item"> + <span class="title"><?php echo __('Shipped'); ?></span> + <span class="content"><?php echo $_item->getQtyShipped()*1 ?></span> + </li> + <?php endif; ?> + <?php if ($_item->getQtyCanceled() > 0): ?> + <li class="item"> + <span class="title"><?php echo __('Canceled'); ?></span> + <span class="content"><?php echo $_item->getQtyCanceled()*1 ?></span> + </li> + <?php endif; ?> + <?php if ($_item->getQtyRefunded() > 0): ?> + <li class="item"> + <span class="title"><?php echo __('Refunded'); ?></span> + <span class="content"><?php echo $_item->getQtyRefunded()*1 ?></span> + </li> <?php endif; ?> - <?php if ($_item->getQtyShipped() > 0 && !$this->isShipmentSeparately()): ?> - <?php echo __('Shipped'); ?>: <strong><?php echo $_item->getQtyShipped()*1 ?></strong><br /> - <?php endif; ?> - <?php if ($_item->getQtyCanceled() > 0): ?> - <?php echo __('Canceled'); ?>: <strong><?php echo $_item->getQtyCanceled()*1 ?></strong><br /> - <?php endif; ?> - <?php if ($_item->getQtyRefunded() > 0): ?> - <?php echo __('Refunded'); ?>: <strong><?php echo $_item->getQtyRefunded()*1 ?></strong> - <?php endif; ?> <?php elseif ($_item->getQtyShipped() > 0 && $_item->getParentItem() && $this->isShipmentSeparately()): ?> - <?php echo __('Shipped'); ?>: <strong><?php echo $_item->getQtyShipped()*1 ?></strong> + <li class="item"> + <span class="title"><?php echo __('Shipped'); ?></span> + <span class="content"><?php echo $_item->getQtyShipped()*1 ?></span> + </li> <?php else: ?> <?php endif; ?> + <?php if ( + ($_item->getParentItem() && $this->isChildCalculated()) || + (!$_item->getParentItem() && !$this->isChildCalculated()) || ($_item->getQtyShipped() > 0 && $_item->getParentItem() && $this->isShipmentSeparately())):?> + </ul> + <?php endif; ?> </td> - <td class="col subtotal"> + <td class="col subtotal" data-th="<?php echo $this->escapeHtml(__('Subtotal')); ?>"> <?php if (!$_item->getParentItem()): ?> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceExclTax()): ?> - <span class="price excl tax"> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices()): ?> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart price"> - <?php endif; ?> - <span class="label"><?php echo __('Excl. Tax'); ?>:</span> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - </span> - <?php endif; ?> - <?php endif; ?> + <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceInclTax()): ?> + <span class="incl tax" data-th="<?php echo $this->escapeHtml(__('Incl. Tax')); ?>"> + <?php $_incl = $this->helper('Magento\Checkout\Helper\Data')->getSubtotalInclTax($this->getItem()); ?> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" - data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <span class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#subtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> <?php else: ?> - <span class="cart price"> + <span class="cart price"> <?php endif; ?> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()+$this->getItem()->getWeeeTaxAppliedRowAmount()+$this->getItem()->getWeeeTaxRowDisposition()); ?> + <?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedRowAmount()); ?> <?php else: ?> - <?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()) ?> + <?php echo $this->getOrder()->formatPrice($_incl-$this->getItem()->getWeeeTaxRowDisposition()) ?> <?php endif; ?> - </span> + </span> - <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> - <span class="cart tax info" id="esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>" - style="display:none;"> + <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> + <span class="cart-tax-info" + id="subtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>" + style="display: none;"> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount']); ?> - <?php endforeach; ?> - </small> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount']); ?></span> + <?php endforeach; ?> <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <small><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></small> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></span> <?php endforeach; ?> <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?> - <?php endforeach; ?> - </small> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></span> + <?php endforeach; ?> <?php endif; ?> - </span> - - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" - data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> - <?php echo __('Total'); ?>:<br /> <?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()+$this->getItem()->getWeeeTaxAppliedRowAmount()+$this->getItem()->getWeeeTaxRowDisposition()); ?> </span> - <?php endif; ?> - <?php endif; ?> - </span> - <br /> - <?php endif; ?> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceInclTax()): ?> - <span class="price incl tax"> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices()): ?> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart price"> - <?php endif; ?> - <span class="label"><?php echo __('Incl. Tax'); ?>:</span> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <span class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#subtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <span class="weee" data-th="<?php echo $this->escapeHtml(__('Total incl. tax')); ?>"><?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedRowAmount()); ?></span> </span> <?php endif; ?> <?php endif; ?> - <?php $_incl = $this->helper('Magento\Checkout\Helper\Data')->getSubtotalInclTax($this->getItem()); ?> + </span> + <?php endif; ?> + + <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceExclTax()): ?> + <span class="excl tax" data-th="<?php echo $this->escapeHtml(__('Excl. Tax')); ?>"> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" - data-tax-toggle='{"itemTaxId" : "#subtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <span class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> <?php else: ?> - <span class="cart price"> + <span class="cart price"> <?php endif; ?> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedRowAmount()); ?> + <?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()+$this->getItem()->getWeeeTaxAppliedRowAmount()+$this->getItem()->getWeeeTaxRowDisposition()); ?> <?php else: ?> - <?php echo $this->getOrder()->formatPrice($_incl-$this->getItem()->getWeeeTaxRowDisposition()) ?> + <?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()) ?> <?php endif; ?> - </span> + </span> <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> - <span class="cart tax info" - id="subtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>" - style="display:none;"> + <span class="cart-tax-info" id="esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>" + style="display: none;"> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount']); ?> - <?php endforeach; ?> - </small> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount']); ?></span> + <?php endforeach; ?> <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <small><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></small> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></span> <?php endforeach; ?> <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?> - <?php endforeach; ?> - </small> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></span> + <?php endforeach; ?> <?php endif; ?> </span> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" - data-tax-toggle='{"itemTaxId" : "#subtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> - <?php echo __('Total Incl. Tax'); ?>:<br /> <?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedRowAmount()); ?> + <span class="cart tax total" + data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <span class="weee" data-th="<?php echo $this->escapeHtml(__('Total')); ?>"><?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()+$this->getItem()->getWeeeTaxAppliedRowAmount()+$this->getItem()->getWeeeTaxRowDisposition()); ?></span> </span> - <?php endif; ?> <?php endif; ?> + <?php endif; ?> </span> <?php endif; ?> <?php else: ?> diff --git a/app/code/Magento/Bundle/view/frontend/templates/sales/order/shipment/items/renderer.phtml b/app/code/Magento/Bundle/view/frontend/templates/sales/order/shipment/items/renderer.phtml index d2ee8a251982d5bcfe9a3848ad8b47c7fa4abe41..d47b684a7d80d8891f45eca990aa4bfd502bf86d 100644 --- a/app/code/Magento/Bundle/view/frontend/templates/sales/order/shipment/items/renderer.phtml +++ b/app/code/Magento/Bundle/view/frontend/templates/sales/order/shipment/items/renderer.phtml @@ -47,16 +47,16 @@ <?php $_prevOptionId = $attributes['option_id'] ?> <?php endif; ?> <?php endif; ?> - <tr<?php echo (++$_index==$_count && !$_showlastRow)?' class="border"':'' ?> id="order-item-row-<?php echo $_item->getId() ?>"> + <tr id="order-item-row-<?php echo $_item->getId() ?>" class="<?php if ($_item->getParentItem()): ?>item-options<?php else: ?>item-parent<?php endif; ?>"> <?php if (!$_item->getParentItem()): ?> - <td class="col name"> - <strong class="product name"><?php echo $this->escapeHtml($_item->getName()) ?></strong> + <td class="col name" data-th="<?php echo $this->escapeHtml(__('Product Name')); ?>"> + <strong class="product name product-item-name"><?php echo $this->escapeHtml($_item->getName()) ?></strong> </td> <?php else: ?> <td class="col value"><?php echo $this->getValueHtml($_item) ?></td> <?php endif; ?> - <td class="col sku"><?php echo $this->escapeHtml($_item->getSku()) ?></td> - <td class="col price"> + <td class="col sku" data-th="<?php echo $this->escapeHtml(__('SKU')); ?>"><?php echo $this->escapeHtml($_item->getSku()) ?></td> + <td class="col qty" data-th="<?php echo $this->escapeHtml(__('Qty Shipped')); ?>"> <?php if (($this->isShipmentSeparately() && $_item->getParentItem()) || (!$this->isShipmentSeparately() && !$_item->getParentItem())): ?> <?php if (isset($shipItems[$_item->getId()])): ?> <?php echo $shipItems[$_item->getId()]->getQty()*1 ?> diff --git a/app/code/Magento/Captcha/Controller/Refresh/Index.php b/app/code/Magento/Captcha/Controller/Refresh/Index.php index 7390ed3fe2e4c45543133739ee795bc97a2ae033..aca2ad33b28cf0d66493a37199cbe55e3f04a698 100644 --- a/app/code/Magento/Captcha/Controller/Refresh/Index.php +++ b/app/code/Magento/Captcha/Controller/Refresh/Index.php @@ -42,7 +42,7 @@ class Index extends \Magento\Framework\App\Action\Action */ public function __construct(Context $context, \Magento\Captcha\Helper\Data $captchaHelper) { - $this->captchaHelper; + $this->captchaHelper = $captchaHelper; parent::__construct($context); } diff --git a/app/code/Magento/Catalog/Block/Product/View.php b/app/code/Magento/Catalog/Block/Product/View.php index 0922334fd41aeec981159d8b5869b622a7747977..fbfd9c6a21048766f298b727396d529e27a01b62 100644 --- a/app/code/Magento/Catalog/Block/Product/View.php +++ b/app/code/Magento/Catalog/Block/Product/View.php @@ -46,13 +46,6 @@ class View extends AbstractProduct implements \Magento\Framework\View\Block\Iden */ protected $string; - /** - * Tax calculation - * - * @var \Magento\Tax\Model\Calculation - */ - protected $_taxCalculation; - /** * Product factory * @@ -100,7 +93,6 @@ class View extends AbstractProduct implements \Magento\Framework\View\Block\Iden * @param \Magento\Core\Helper\Data $coreData * @param \Magento\Framework\Json\EncoderInterface $jsonEncoder * @param \Magento\Catalog\Model\ProductFactory $productFactory - * @param \Magento\Tax\Model\Calculation $taxCalculation * @param \Magento\Framework\Stdlib\String $string * @param \Magento\Catalog\Helper\Product $productHelper * @param \Magento\Catalog\Model\ProductTypes\ConfigInterface $productTypeConfig @@ -114,7 +106,6 @@ class View extends AbstractProduct implements \Magento\Framework\View\Block\Iden \Magento\Core\Helper\Data $coreData, \Magento\Framework\Json\EncoderInterface $jsonEncoder, \Magento\Catalog\Model\ProductFactory $productFactory, - \Magento\Tax\Model\Calculation $taxCalculation, \Magento\Framework\Stdlib\String $string, \Magento\Catalog\Helper\Product $productHelper, \Magento\Catalog\Model\ProductTypes\ConfigInterface $productTypeConfig, @@ -127,7 +118,6 @@ class View extends AbstractProduct implements \Magento\Framework\View\Block\Iden $this->_coreData = $coreData; $this->_jsonEncoder = $jsonEncoder; $this->_productFactory = $productFactory; - $this->_taxCalculation = $taxCalculation; $this->productTypeConfig = $productTypeConfig; $this->string = $string; $this->_localeFormat = $localeFormat; @@ -258,13 +248,11 @@ class View extends AbstractProduct implements \Magento\Framework\View\Block\Iden $product = $this->getProduct(); $defaultTax = $this->taxCalculationService->getDefaultCalculatedRate( $product->getTaxClassId(), - $customerId, - null + $customerId ); $currentTax = $this->taxCalculationService->getCalculatedRate( $product->getTaxClassId(), - $customerId, - null + $customerId ); $tierPrices = array(); diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Action/Attribute/Validate.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Action/Attribute/Validate.php index ee694c55342a8781ec3cdfab4ca26ab813dbc4ab..d77522c516bd85bfcb50836541822c6373ac8391 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Action/Attribute/Validate.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Action/Attribute/Validate.php @@ -33,10 +33,10 @@ class Validate extends \Magento\Catalog\Controller\Adminhtml\Product\Action\Attr */ public function execute() { - $response = new \Magento\Framework\Object(); + $response = $this->_objectManager->create('Magento\Framework\Object'); $response->setError(false); $attributesData = $this->getRequest()->getParam('attributes', array()); - $data = new \Magento\Framework\Object(); + $data = $this->_objectManager->create('Magento\Catalog\Model\Product'); try { if ($attributesData) { diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/NewAction.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/NewAction.php index 45e924542f6f6ec16b811559b880c6b4e6784fc8..089cbd4138478c86f3786c2c2f06e5755fcdb5dc 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/NewAction.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/NewAction.php @@ -44,7 +44,7 @@ class NewAction extends \Magento\Catalog\Controller\Adminhtml\Product Product\Builder $productBuilder, Initialization\StockDataFilter $stockFilter ) { - $this->stockFilter; + $this->stockFilter = $stockFilter; parent::__construct($context, $productBuilder); } diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Source/Msrp/Type/Enabled.php b/app/code/Magento/Catalog/Model/Product/Attribute/Source/Msrp/Type/Enabled.php index fe205395509e5efe1c2d047e9b2e4eb6d8a26a43..177277dcb6aa5d431af70ef95387c30510b3ade9 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Source/Msrp/Type/Enabled.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Source/Msrp/Type/Enabled.php @@ -29,6 +29,8 @@ */ namespace Magento\Catalog\Model\Product\Attribute\Source\Msrp\Type; +use Magento\Framework\DB\Ddl\Table; + class Enabled extends \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource { /** @@ -96,17 +98,21 @@ class Enabled extends \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource * * @return array */ - public function getFlatColums() + public function getFlatColumns() { $attributeCode = $this->getAttribute()->getAttributeCode(); - $column = array('unsigned' => false, 'default' => null, 'extra' => null); - - $column['type'] = \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT; - $column['length'] = 1; - $column['nullable'] = true; - $column['comment'] = $attributeCode . ' column'; - return array($attributeCode => $column); + return [ + $attributeCode => [ + 'unsigned' => false, + 'default' => null, + 'extra' => null, + 'type' => Table::TYPE_SMALLINT, + 'length' => 1, + 'nullable' => true, + 'comment' => $attributeCode . ' column', + ], + ]; } /** diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Source/Msrp/Type/Price.php b/app/code/Magento/Catalog/Model/Product/Attribute/Source/Msrp/Type/Price.php index c9ef383e7504989b67c4f28f6c040e9dda138b71..5c3ebf471b81454e4f7c33583b3ffed6647f653d 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Source/Msrp/Type/Price.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Source/Msrp/Type/Price.php @@ -93,16 +93,20 @@ class Price extends \Magento\Catalog\Model\Product\Attribute\Source\Msrp\Type * * @return array */ - public function getFlatColums() + public function getFlatColumns() { $attributeType = $this->getAttribute()->getBackendType(); $attributeCode = $this->getAttribute()->getAttributeCode(); - $column = array('unsigned' => false, 'default' => null, 'extra' => null); - $column['type'] = $this->_eavResourceHelper->getDdlTypeByColumnType($attributeType); - $column['nullable'] = true; - - return array($attributeCode => $column); + return [ + $attributeCode => [ + 'unsigned' => false, + 'default' => null, + 'extra' => null, + 'type' => $this->_eavResourceHelper->getDdlTypeByColumnType($attributeType), + 'nullable' => true, + ], + ]; } /** diff --git a/app/code/Magento/Catalog/Model/Product/Type/AbstractType.php b/app/code/Magento/Catalog/Model/Product/Type/AbstractType.php index 91aba621f5048ec8e7cfc2f4c4280a9da08f5650..232a6ecd2c996b9c807a283f092561b9e13af912 100644 --- a/app/code/Magento/Catalog/Model/Product/Type/AbstractType.php +++ b/app/code/Magento/Catalog/Model/Product/Type/AbstractType.php @@ -239,6 +239,8 @@ abstract class AbstractType * group => array(ids) * ) * + * @deplacated TODO: refactor to child relation manager + * * @param int $parentId * @param bool $required * @return array diff --git a/app/code/Magento/Catalog/Model/Product/Visibility.php b/app/code/Magento/Catalog/Model/Product/Visibility.php index 94599886f1daadf9e98a3f0bf88f9a51050a7138..834236eb0461053319d677605b6014673ae1104b 100644 --- a/app/code/Magento/Catalog/Model/Product/Visibility.php +++ b/app/code/Magento/Catalog/Model/Product/Visibility.php @@ -30,6 +30,8 @@ */ namespace Magento\Catalog\Model\Product; +use Magento\Framework\DB\Ddl\Table; + class Visibility extends \Magento\Framework\Object { const VISIBILITY_NOT_VISIBLE = 1; @@ -167,16 +169,20 @@ class Visibility extends \Magento\Framework\Object * * @return array */ - public function getFlatColums() + public function getFlatColumns() { $attributeCode = $this->getAttribute()->getAttributeCode(); - $column = array('unsigned' => true, 'default' => null, 'extra' => null); - - $column['type'] = \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT; - $column['nullable'] = true; - $column['comment'] = 'Catalog Product Visibility ' . $attributeCode . ' column'; - return array($attributeCode => $column); + return [ + $attributeCode => [ + 'unsigned' => true, + 'default' => null, + 'extra' => null, + 'type' => Table::TYPE_SMALLINT, + 'nullable' => true, + 'comment' => 'Catalog Product Visibility ' . $attributeCode . ' column', + ], + ]; } /** diff --git a/app/code/Magento/Catalog/Model/Resource/AbstractResource.php b/app/code/Magento/Catalog/Model/Resource/AbstractResource.php index 7c76661b2f870983eae9b5cb4b1514a76063d2e4..01ce99b70ceda684f4abd2ca120dfb73cdaeb4bc 100644 --- a/app/code/Magento/Catalog/Model/Resource/AbstractResource.php +++ b/app/code/Magento/Catalog/Model/Resource/AbstractResource.php @@ -323,29 +323,31 @@ abstract class AbstractResource extends \Magento\Eav\Model\Entity\AbstractEntity * save required attributes in global scope every time if store id different from default */ $storeId = (int) $this->_storeManager->getStore($object->getStoreId())->getId(); - if ($attribute->getIsRequired() && $this->getDefaultStoreId() != $storeId) { - $table = $attribute->getBackend()->getTable(); - - $select = $this->_getReadAdapter()->select() - ->from($table) - ->where('entity_type_id = ?', $attribute->getEntityTypeId()) - ->where('attribute_id = ?', $attribute->getAttributeId()) - ->where('store_id = ?', $this->getDefaultStoreId()) - ->where('entity_id = ?', $object->getEntityId()); - $row = $this->_getReadAdapter()->fetchOne($select); - - if (!$row) { - $data = new \Magento\Framework\Object( - array( - 'entity_type_id' => $attribute->getEntityTypeId(), - 'attribute_id' => $attribute->getAttributeId(), - 'store_id' => $this->getDefaultStoreId(), - 'entity_id' => $object->getEntityId(), - 'value' => $this->_prepareValueForSave($value, $attribute) - ) - ); - $bind = $this->_prepareDataForTable($data, $table); - $this->_getWriteAdapter()->insertOnDuplicate($table, $bind, array('value')); + if ($this->getDefaultStoreId() != $storeId) { + if ($attribute->getIsRequired() || $attribute->getIsRequiredInAdminStore()) { + $table = $attribute->getBackend()->getTable(); + + $select = $this->_getReadAdapter()->select() + ->from($table) + ->where('entity_type_id = ?', $attribute->getEntityTypeId()) + ->where('attribute_id = ?', $attribute->getAttributeId()) + ->where('store_id = ?', $this->getDefaultStoreId()) + ->where('entity_id = ?', $object->getEntityId()); + $row = $this->_getReadAdapter()->fetchOne($select); + + if (!$row) { + $data = new \Magento\Framework\Object( + array( + 'entity_type_id' => $attribute->getEntityTypeId(), + 'attribute_id' => $attribute->getAttributeId(), + 'store_id' => $this->getDefaultStoreId(), + 'entity_id' => $object->getEntityId(), + 'value' => $this->_prepareValueForSave($value, $attribute) + ) + ); + $bind = $this->_prepareDataForTable($data, $table); + $this->_getWriteAdapter()->insertOnDuplicate($table, $bind, array('value')); + } } } diff --git a/app/code/Magento/Catalog/Service/V1/Data/Converter.php b/app/code/Magento/Catalog/Service/V1/Data/Converter.php index 69e771ed885a84f15e0c7ca6269e6512af3c29bd..4059993b865b6b822c8fd220cd2a4943b8e69a11 100644 --- a/app/code/Magento/Catalog/Service/V1/Data/Converter.php +++ b/app/code/Magento/Catalog/Service/V1/Data/Converter.php @@ -53,7 +53,7 @@ class Converter */ public function createProductDataFromModel(\Magento\Catalog\Model\Product $productModel) { - $this->_populateBuilderWithAttributes($productModel); + $this->populateBuilderWithAttributes($productModel); return $this->productBuilder->create(); } @@ -63,19 +63,19 @@ class Converter * @param \Magento\Catalog\Model\Product $productModel * @return void */ - protected function _populateBuilderWithAttributes(\Magento\Catalog\Model\Product $productModel) + protected function populateBuilderWithAttributes(\Magento\Catalog\Model\Product $productModel) { $attributes = array(); - foreach ($this->productBuilder->getCustomAttributesCodes() as $attrCode) { - $value = $productModel->getDataUsingMethod($attrCode); - $value = $value ? $value : $productModel->getData($attrCode); + foreach ($productModel->getAttributes() as $attribute) { + $attrCode = $attribute->getAttributeCode(); + $value = $productModel->getDataUsingMethod($attrCode) ?: $productModel->getData($attrCode); if (null !== $value) { if ($attrCode != 'entity_id') { $attributes[$attrCode] = $value; } } } - + $attributes[ProductDataObject::STORE_ID] = $productModel->getStoreId(); $this->productBuilder->populateWithArray($attributes); return; } diff --git a/app/code/Magento/Catalog/data/catalog_setup/data-upgrade-1.6.0.0.27-1.6.0.0.28.php b/app/code/Magento/Catalog/data/catalog_setup/data-upgrade-1.6.0.0.27-1.6.0.0.28.php new file mode 100644 index 0000000000000000000000000000000000000000..7258eeaaefe87cf08d5c1881fb2eb1f043ce97c2 --- /dev/null +++ b/app/code/Magento/Catalog/data/catalog_setup/data-upgrade-1.6.0.0.27-1.6.0.0.28.php @@ -0,0 +1,28 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +/** @var $this \Magento\Catalog\Model\Resource\Setup */ +foreach (['status', 'visibility'] as $attributeCode) { + $this->updateAttribute(\Magento\Catalog\Model\Product::ENTITY, $attributeCode, 'is_required_in_admin_store', '1'); +} diff --git a/app/code/Magento/Catalog/etc/module.xml b/app/code/Magento/Catalog/etc/module.xml index 991c1e63bfc736bfb28d33d0d73e616faf39594e..f9b6b5c0836fea04b2cd45eae300a4f9e486e52f 100644 --- a/app/code/Magento/Catalog/etc/module.xml +++ b/app/code/Magento/Catalog/etc/module.xml @@ -24,7 +24,7 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd"> - <module name="Magento_Catalog" schema_version="1.6.0.0.27" active="true"> + <module name="Magento_Catalog" schema_version="1.6.0.0.28" active="true"> <sequence> <module name="Magento_Eav"/> <module name="Magento_Cms"/> diff --git a/app/code/Magento/Catalog/sql/catalog_setup/upgrade-1.6.0.0.27-1.6.0.0.28.php b/app/code/Magento/Catalog/sql/catalog_setup/upgrade-1.6.0.0.27-1.6.0.0.28.php new file mode 100644 index 0000000000000000000000000000000000000000..1ca835e240afae14c33a0313150cbe364fd1f61b --- /dev/null +++ b/app/code/Magento/Catalog/sql/catalog_setup/upgrade-1.6.0.0.27-1.6.0.0.28.php @@ -0,0 +1,36 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +/** @var $this \Magento\Catalog\Model\Resource\Setup */ +$this->getConnection()->addColumn( + $this->getTable('catalog_eav_attribute'), + 'is_required_in_admin_store', + array( + 'type' => \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT, + 'unsigned' => true, + 'nullable' => false, + 'default' => '0', + 'comment' => 'Is Required In Admin Store' + ) +); diff --git a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit.phtml b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit.phtml index c1b8f640703ed7b9c3c581e48e47e05cdf8a2cdd..8460dbbe28b17ac856e966ca8488f213ec5f56a1 100644 --- a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit.phtml +++ b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit.phtml @@ -77,6 +77,40 @@ jQuery(function($) { var $form = $('[data-form=edit-product]'); $form.data('typeSwitcher', new TypeSwitcher(<?php echo $this->getTypeSwitcherData();?>).bindAll()); + var scriptTagManager = (function($) { + var hiddenPrefix = 'hidden', + scriptTypeRegExp = /((java|ecma)script)/gi, + hiddenScriptType = 'text/' + hiddenPrefix + 'javascript', + changeScriptsType = function(source, callback) { + var isString = (typeof source === 'string'), + div = document.createElement('div'), + scripts, + scriptsLength; + div.innerHTML = isString ? source : $(source).clone().wrap('<p>').parent().html(); + scripts = div.getElementsByTagName('script'); + scriptsLength = scripts.length; + for (var i = 0; i < scriptsLength; i++) { + scripts[i].type = callback(scripts[i].type); + } + return isString ? div.innerHTML : $(div.innerHTML); + }, + disableScripts = function(source) { + enableScripts(source); + return changeScriptsType(source, function(type) { + return type ? type.replace(scriptTypeRegExp, hiddenPrefix + '$1') : hiddenScriptType; + }); + }, + enableScripts = function(source) { + return changeScriptsType(source, function(type) { + return type.replace(hiddenPrefix, ''); + }); + }; + return { + 'disableScripts' : disableScripts, + 'enableScripts' : enableScripts + } + })($); + $('#meta_description').on('change keyup paste', function () { var maxLength = $(this).data('maxLength') || 255; if ($(this).val().length >= maxLength) { @@ -225,6 +259,8 @@ jQuery(function($) { context: $('body'), showLoader: true }).done(function(data) { + //Hide all js scripts to prevent removing them during jQuery object creation + data = scriptTagManager.disableScripts(data); var removedElementClass = 'removed'; var $page = $('body'); @@ -283,6 +319,25 @@ jQuery(function($) { }); }); + //add new fieldsets or reorder + $newPage.find('#product_info_tabs .fieldset.user-defined').each(function(index, newFieldset) { + var fieldsetContainer, newFieldsetContainer, sourceContainer, destinationContainer; + newFieldsetContainer = $(newFieldset).parents('[data-ui-id*=-tab-content-]').first(); + if ($page.find('[data-ui-id=' + newFieldsetContainer.data('uiId') + ']').length === 0) { + fieldsetContainer = newFieldsetContainer + .clone() + .removeClass(removedElementClass) + .removeClass('ignore-validate'); + //Enable hidden js scripts in node. These scripts will be performed after inserting into page + fieldsetContainer = scriptTagManager.enableScripts(fieldsetContainer); + } else { + fieldsetContainer = $page.find('[data-ui-id=' + newFieldsetContainer.data('uiId') + ']').first(); + } + sourceContainer = newFieldsetContainer.parents('[data-ui-id*=-tab-content-]').first(); + destinationContainer = $page.find('[data-ui-id=' + sourceContainer.data('uiId') + ']').first(); + fieldsetContainer.appendTo(destinationContainer); + }); + var nameDataMapper = function() { return $(this).data('attributeCode'); }; diff --git a/app/code/Magento/Catalog/view/frontend/layout/catalog_product_view.xml b/app/code/Magento/Catalog/view/frontend/layout/catalog_product_view.xml index 9ca9601a397d1533444c5d00a4f4ea259cd947c1..f089a3adc09dbfd8481744c15e9a64f73822a573 100644 --- a/app/code/Magento/Catalog/view/frontend/layout/catalog_product_view.xml +++ b/app/code/Magento/Catalog/view/frontend/layout/catalog_product_view.xml @@ -164,6 +164,9 @@ <referenceBlock name="product.info.addtocart"> <block class="Magento\Catalog\Block\ShortcutButtons\InCatalog" name="addtocart.shortcut.buttons"/> </referenceBlock> + <referenceBlock name="product.info.addtocart.additional"> + <block class="Magento\Catalog\Block\ShortcutButtons\InCatalog" name="addtocart.shortcut.buttons.additional"/> + </referenceBlock> <update handle="MAP_popup"/> <update handle="MAP_price_msrp_item"/> </layout> diff --git a/app/code/Magento/Catalog/view/frontend/layout/checkout_cart_item_renderers.xml b/app/code/Magento/Catalog/view/frontend/layout/checkout_cart_item_renderers.xml new file mode 100644 index 0000000000000000000000000000000000000000..6c53eb77e5a9357b92019e39aeeaeb896fc696a0 --- /dev/null +++ b/app/code/Magento/Catalog/view/frontend/layout/checkout_cart_item_renderers.xml @@ -0,0 +1,30 @@ +<?xml version="1.0"?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_single.xsd"> + <referenceBlock name="checkout.cart.item.renderers"> + <block class="Magento\Checkout\Block\Cart\Item\Renderer" as="virtual" template="cart/item/default.phtml"/> + </referenceBlock> +</layout> diff --git a/app/code/Magento/Catalog/view/frontend/templates/product/compare/list.phtml b/app/code/Magento/Catalog/view/frontend/templates/product/compare/list.phtml index 23bce71cbcdce364c0dc6b3652b50875840deebd..e3692359697b63390f34e3e3e0deaa05de0d6c05 100644 --- a/app/code/Magento/Catalog/view/frontend/templates/product/compare/list.phtml +++ b/app/code/Magento/Catalog/view/frontend/templates/product/compare/list.phtml @@ -29,7 +29,7 @@ <span><?php echo __('Print This Page') ?></span> </a> <?php $imageBlock = $this->getLayout()->createBlock('Magento\Catalog\Block\Product\Image'); ?> - <div class="table wrapper comparison"> + <div class="table-wrapper comparison"> <table class="data-table data table comparison" id="product-comparison" data-mage-init='{"compareList":{ "windowPrintSelector":".action.print", diff --git a/app/code/Magento/Catalog/view/frontend/templates/product/list/items.phtml b/app/code/Magento/Catalog/view/frontend/templates/product/list/items.phtml index 173982fc6b11b3b4992c90c0fa705ff1bdc6769e..ad8d2c97953cac878890d816254ad968c32812bb 100644 --- a/app/code/Magento/Catalog/view/frontend/templates/product/list/items.phtml +++ b/app/code/Magento/Catalog/view/frontend/templates/product/list/items.phtml @@ -207,7 +207,7 @@ switch($type = $this->getType()) { <?php if($type == 'related' || $type == 'upsell'): ?> <?php echo ($iterator++==1) ? '<li class="item product product-item" style="display: none;">' : '</li><li class="item product product-item" style="display: none;">' ?> <?php else: ?> - <?php echo ($iterator++==1) ? '<li class="item product product-item">' : '</li><li class="item product">' ?> + <?php echo ($iterator++==1) ? '<li class="item product product-item">' : '</li><li class="item product product-item">' ?> <?php endif; ?> <div class="product-item-info <?php echo $available; ?>"> <?php echo '<!-- ' . $image . '-->' ?> diff --git a/app/code/Magento/Catalog/view/frontend/templates/product/view/attributes.phtml b/app/code/Magento/Catalog/view/frontend/templates/product/view/attributes.phtml index f306387756d7d7d0dc72c44f7d30a1d34bf7fa4f..94886c4777e9f3b4e90c1783a0a383b5497a8ea4 100644 --- a/app/code/Magento/Catalog/view/frontend/templates/product/view/attributes.phtml +++ b/app/code/Magento/Catalog/view/frontend/templates/product/view/attributes.phtml @@ -33,7 +33,7 @@ $_product = $this->getProduct() ?> <?php if($_additional = $this->getAdditionalData()): ?> - <div class="additional attributes table wrapper"> + <div class="additional attributes table-wrapper"> <table class="data table additional attributes" id="product-attribute-specs-table"> <caption class="table caption"><?php echo __('Additional Information') ?></caption> <tbody> diff --git a/app/code/Magento/Catalog/view/frontend/templates/product/view/details.phtml b/app/code/Magento/Catalog/view/frontend/templates/product/view/details.phtml index c554bdf518c75e0114fa1d9cb0610ad18ad744d3..a7f8a836a7be2ebe169b5bf411b835b0a41902ad 100644 --- a/app/code/Magento/Catalog/view/frontend/templates/product/view/details.phtml +++ b/app/code/Magento/Catalog/view/frontend/templates/product/view/details.phtml @@ -31,7 +31,7 @@ $html = $layout->renderElement($name); if (!trim($html)) continue; $alias = $layout->getElementAlias($name); - $label = $this->escapeHtml($this->getChildData($alias, 'title')); + $label = $this->getChildData($alias, 'title'); ?> <div class="data item title" data-role="collapsible"><a class="data switch" data-toggle="switch" href="#<?php echo $alias; ?>"><?php echo $label; ?></a></div> <div class="data item content" id="<?php echo $alias; ?>" data-role="content"><?php echo $html; ?></div> diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product/Option.php b/app/code/Magento/CatalogImportExport/Model/Import/Product/Option.php index 976c73d7c770fdc918f844dcde246917d4a6f79d..168dbb9978aeb8ddfa030d6774da0bd3c4440cc7 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product/Option.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product/Option.php @@ -1118,7 +1118,7 @@ class Option extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity */ protected function _initProductsSku() { - if (!$this->_productsSkuToId) { + if (!$this->_productsSkuToId || !empty($this->_newOptionsNewData)) { $columns = array('entity_id', 'sku'); foreach ($this->_productModel->getProductEntitiesInfo($columns) as $product) { $this->_productsSkuToId[$product['sku']] = $product['entity_id']; diff --git a/app/code/Magento/CatalogSearch/Controller/Advanced/Result.php b/app/code/Magento/CatalogSearch/Controller/Advanced/Result.php index 374328be8e7cc7886385ca1f7ef7014afeec7b3b..804fff22fe29bb90d7b5f51dee72c1eeca4b5fd3 100644 --- a/app/code/Magento/CatalogSearch/Controller/Advanced/Result.php +++ b/app/code/Magento/CatalogSearch/Controller/Advanced/Result.php @@ -69,6 +69,8 @@ class Result extends \Magento\Framework\App\Action\Action { try { $this->_catalogSearchAdvanced->addFilters($this->getRequest()->getQuery()); + $this->_view->loadLayout(); + $this->_view->renderLayout(); } catch (\Magento\Framework\Model\Exception $e) { $this->messageManager->addError($e->getMessage()); $defaultUrl = $this->_urlFactory->create() @@ -76,7 +78,5 @@ class Result extends \Magento\Framework\App\Action\Action ->getUrl('*/*/'); $this->getResponse()->setRedirect($this->_redirect->error($defaultUrl)); } - $this->_view->loadLayout(); - $this->_view->renderLayout(); } } diff --git a/app/code/Magento/CatalogSearch/Controller/Term/Popular.php b/app/code/Magento/CatalogSearch/Controller/Term/Popular.php index dda99ef9f635877cef3fb7941e00798023f36790..915ef9752fa20e03ab795e3cb344516fb3e48906 100644 --- a/app/code/Magento/CatalogSearch/Controller/Term/Popular.php +++ b/app/code/Magento/CatalogSearch/Controller/Term/Popular.php @@ -23,6 +23,7 @@ */ namespace Magento\CatalogSearch\Controller\Term; +use Magento\Framework\App\Action\Context; use Magento\Framework\App\RequestInterface; use Magento\Framework\App\ResponseInterface; @@ -34,11 +35,13 @@ class Popular extends \Magento\Framework\App\Action\Action protected $scopeConfig; /** + * @param Context $context * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig */ - public function __construct(\Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig) + public function __construct(Context $context, \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig) { $this->scopeConfig = $scopeConfig; + parent::__construct($context); } /** diff --git a/app/code/Magento/CatalogSearch/view/frontend/templates/advanced/result.phtml b/app/code/Magento/CatalogSearch/view/frontend/templates/advanced/result.phtml index b6bfb179e686f49910c2ea7a6f9ce6376c4b1539..6be10698250f9d1c31deaa4f3dded164e9cb5f72 100644 --- a/app/code/Magento/CatalogSearch/view/frontend/templates/advanced/result.phtml +++ b/app/code/Magento/CatalogSearch/view/frontend/templates/advanced/result.phtml @@ -22,6 +22,11 @@ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) */ ?> +<?php +/** + * @var $this \Magento\CatalogSearch\Block\Advanced\Result + */ +?> <?php if($results = $this->getResultCount()): ?> <div class="search found"> <?php if ($results == 1) : ?> diff --git a/app/code/Magento/CatalogUrlRewrite/Helper/Data.php b/app/code/Magento/CatalogUrlRewrite/Helper/Data.php new file mode 100644 index 0000000000000000000000000000000000000000..74ab3e84de1f8603a57e39b5e72e300ea00ae7c2 --- /dev/null +++ b/app/code/Magento/CatalogUrlRewrite/Helper/Data.php @@ -0,0 +1,277 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\CatalogUrlRewrite\Helper; + +use Magento\Catalog\Helper\Category as CategoryHelper; +use Magento\Catalog\Helper\Product as ProductHelper; +use Magento\Catalog\Model\Category; +use Magento\Catalog\Model\Product; +use Magento\Eav\Model\Config; +use Magento\Framework\App\Resource; +use Magento\Store\Model\Store; +use Magento\Store\Model\StoreManagerInterface; +use Magento\UrlRedirect\Service\V1\Data\Converter; +use Magento\UrlRedirect\Service\V1\Data\UrlRewrite; + +/** + * Helper Data + */ +class Data +{ + /** + * Url slash + */ + const URL_SLASH = '/'; + + /** + * @var \Magento\Eav\Model\Config + */ + protected $eavConfig; + + /** + * @var false|\Magento\Framework\DB\Adapter\AdapterInterface + */ + protected $connection; + + /** + * @var \Magento\Catalog\Helper\Product + */ + protected $productHelper; + + /** + * Store manager + * + * @var \Magento\Store\Model\StoreManagerInterface + */ + protected $storeManager; + + /** + * Catalog category helper + * + * @var CategoryHelper + */ + protected $categoryHelper; + + /** + * @var Converter + */ + protected $converter; + + /** + * @param Config $eavConfig + * @param Resource $resource + * @param \Magento\Catalog\Helper\Product $productHelper + * @param StoreManagerInterface $storeManager + * @param CategoryHelper $categoryHelper + * @param Converter $converter + */ + public function __construct( + Config $eavConfig, + Resource $resource, + ProductHelper $productHelper, + StoreManagerInterface $storeManager, + CategoryHelper $categoryHelper, + Converter $converter + ) { + $this->eavConfig = $eavConfig; + $this->connection = $resource->getConnection(Resource::DEFAULT_READ_RESOURCE); + $this->productHelper = $productHelper; + $this->storeManager = $storeManager; + $this->categoryHelper = $categoryHelper; + $this->converter = $converter; + } + + /** + * If product saved on default store view, then need to check specific url_key for other stores + * + * @param int $storeId + * @param int $productId + * @return bool + */ + public function isNeedCreateUrlRewrite($storeId, $productId) + { + $attribute = $this->eavConfig->getAttribute(Product::ENTITY, 'url_key'); + $select = $this->connection->select() + ->from($attribute->getBackendTable(), 'store_id') + ->where('attribute_id = ?', $attribute->getId()) + ->where('entity_id = ?', $productId); + + return !in_array($storeId, $this->connection->fetchCol($select)); + } + + /** + * Whether the store is default + * + * @param int|null $storeId + * @return bool + */ + public function isDefaultStore($storeId) + { + return null === $storeId || $storeId == Store::DEFAULT_STORE_ID; + } + + /** + * Get canonical product url path + * + * @param Product $product + * @return string + */ + public function getProductCanonicalUrlPath(Product $product) + { + return 'catalog/product/view/id/' . $product->getId(); + } + + /** + * Get canonical product url path with category + * + * @param Product $product + * @param Category $category + * @return string + */ + public function getProductCanonicalUrlPathWithCategory(Product $product, Category $category) + { + return $this->getProductCanonicalUrlPath($product) . '/category/' . $category->getId(); + } + + /** + * Get product url key path + * + * @param Product $product + * @param int $storeId + * @return string + */ + public function getProductUrlKeyPath(Product $product, $storeId) + { + return $product->getUrlModel()->getUrlPath($product) . $this->productHelper->getProductUrlSuffix($storeId); + } + + /** + * Get product url key path with category + * + * @param Product $product + * @param Category $category + * @param int $storeId + * @return string + */ + public function getProductUrlKeyPathWithCategory(Product $product, Category $category, $storeId) + { + return $product->getUrlModel()->getUrlPath($product, $category) + . $this->productHelper->getProductUrlSuffix($storeId); + } + + /** + * Get canonical category url + * + * @param Category $category + * @return string + */ + public function getCategoryCanonicalUrlPath(Category $category) + { + return 'catalog/category/view/id/' . $category->getId(); + } + + /** + * Get category url path + * + * @param Category $category + * @return string + */ + public function getCategoryUrlKeyPath(Category $category) + { + return $category->getUrlPath(); + } + + /** + * Check is root category + * + * @param Category $category + * @return string + */ + public function isRootCategory(Category $category) + { + $store = $this->storeManager->getStore($category->getStoreId()); + + return $category->getId() == $store->getRootCategoryId(); + } + + /** + * Generate category url key path + * + * @param \Magento\Catalog\Model\Category $category + * @return string + */ + public function generateCategoryUrlKeyPath($category) + { + $parentPath = $this->categoryHelper->getCategoryUrlPath('', true, $category->getStoreId()); + + $urlKey = $category->getUrlKey() == '' + ? $category->formatUrlKey($category->getName()) : $category->formatUrlKey($category->getUrlKey()); + + return $parentPath . $urlKey; + } + + /** + * Generate product url key path + * + * @param \Magento\Catalog\Model\Product $product + * @return string + */ + public function generateProductUrlKeyPath($product) + { + $urlKey = $product->getUrlKey() == '' + ? $product->formatUrlKey($product->getName()) + : $product->formatUrlKey($product->getUrlKey()); + + return $urlKey; + } + + /** + * Create url rewrite object + * + * @param string $entityType + * @param int $entityId + * @param int $storeId + * @param string $requestPath + * @param string $targetPath + * @param string|null $redirectType Null or one of OptionProvider const + * @return UrlRewrite + */ + public function createUrlRewrite( + $entityType, + $entityId, + $storeId, + $requestPath, + $targetPath, + $redirectType = null + ) { + return $this->converter->convertArrayToObject([ + UrlRewrite::ENTITY_TYPE => $entityType, + UrlRewrite::ENTITY_ID => $entityId, + UrlRewrite::STORE_ID => $storeId, + UrlRewrite::REQUEST_PATH => $requestPath, + UrlRewrite::TARGET_PATH => $targetPath, + UrlRewrite::REDIRECT_TYPE => $redirectType, + ]); + } +} diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Category/Observer.php b/app/code/Magento/CatalogUrlRewrite/Model/Category/Observer.php new file mode 100644 index 0000000000000000000000000000000000000000..c2387d36e4bb60211f8d7abb97076d9cb720da64 --- /dev/null +++ b/app/code/Magento/CatalogUrlRewrite/Model/Category/Observer.php @@ -0,0 +1,102 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\CatalogUrlRewrite\Model\Category; + +use Magento\CatalogUrlRewrite\Helper\Data as CatalogUrlRewriteHelper; +use Magento\CatalogUrlRewrite\Service\V1\CategoryUrlGeneratorInterface; +use Magento\CatalogUrlRewrite\Service\V1\ProductUrlGeneratorInterface; +use Magento\Framework\Event\Observer as EventObserver; +use Magento\UrlRedirect\Service\V1\UrlSaveInterface; + +class Observer +{ + /** + * @var CategoryUrlGeneratorInterface + */ + protected $categoryUrlGenerator; + + /** + * @var CategoryUrlGeneratorInterface + */ + protected $productUrlGenerator; + + /** + * @var UrlSaveInterface + */ + protected $urlSave; + + /** + * @var CatalogUrlRewriteHelper + */ + protected $catalogUrlRewriteHelper; + + /** + * @param CategoryUrlGeneratorInterface $categoryUrlGenerator + * @param ProductUrlGeneratorInterface $productUrlGenerator + * @param UrlSaveInterface $urlSave + * @param CatalogUrlRewriteHelper $catalogUrlRewriteHelper + */ + public function __construct( + CategoryUrlGeneratorInterface $categoryUrlGenerator, + ProductUrlGeneratorInterface $productUrlGenerator, + UrlSaveInterface $urlSave, + CatalogUrlRewriteHelper $catalogUrlRewriteHelper + ) { + $this->categoryUrlGenerator = $categoryUrlGenerator; + $this->productUrlGenerator = $productUrlGenerator; + $this->urlSave = $urlSave; + $this->catalogUrlRewriteHelper = $catalogUrlRewriteHelper; + } + + /** + * Generate urls for UrlRewrite and save it in storage + * + * @param \Magento\Framework\Event\Observer $observer + * @return void + */ + public function processUrlRewriteSaving(EventObserver $observer) + { + /** @var \Magento\Catalog\Model\Category $category */ + $category = $observer->getEvent()->getCategory(); + + if (!$this->catalogUrlRewriteHelper->isRootCategory($category) + && (!$category->getData('url_key') || $category->getOrigData('url_key') != $category->getData('url_key')) + ) { + $this->urlSave->save($this->categoryUrlGenerator->generate($category)); + + $products = $category->getProductCollection() + ->addAttributeToSelect('url_key') + ->addAttributeToSelect('url_path'); + + foreach ($products as $product) { + $product->setData('save_rewrites_history', $category->getData('save_rewrites_history')); + + $this->urlSave->save($this->productUrlGenerator->generateWithChangedCategories( + $product, + [$category->getId() => $category] + )); + } + } + } +} diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Product/Observer.php b/app/code/Magento/CatalogUrlRewrite/Model/Product/Observer.php new file mode 100644 index 0000000000000000000000000000000000000000..9dfbb358ce570d98b6fc0c536b82c63278db0d58 --- /dev/null +++ b/app/code/Magento/CatalogUrlRewrite/Model/Product/Observer.php @@ -0,0 +1,82 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\CatalogUrlRewrite\Model\Product; + +use Magento\CatalogUrlRewrite\Helper\Data as CatalogUrlRewriteHelper; +use Magento\CatalogUrlRewrite\Service\V1\ProductUrlGeneratorInterface; +use Magento\Framework\Event\Observer as EventObserver; +use Magento\UrlRedirect\Service\V1\UrlSaveInterface; + +class Observer +{ + /** + * @var ProductUrlGeneratorInterface + */ + protected $productUrlGenerator; + + /** + * @var UrlSaveInterface + */ + protected $urlSave; + + /** + * @var CatalogUrlRewriteHelper + */ + protected $catalogUrlRewriteHelper; + + /** + * @param ProductUrlGeneratorInterface $productUrlGenerator + * @param UrlSaveInterface $urlSave + * @param CatalogUrlRewriteHelper $catalogUrlRewriteHelper + */ + public function __construct( + ProductUrlGeneratorInterface $productUrlGenerator, + UrlSaveInterface $urlSave, + CatalogUrlRewriteHelper $catalogUrlRewriteHelper + ) { + $this->productUrlGenerator = $productUrlGenerator; + $this->urlSave = $urlSave; + $this->catalogUrlRewriteHelper = $catalogUrlRewriteHelper; + } + + /** + * Generate urls for UrlRewrite and save it in storage + * + * @param \Magento\Framework\Event\Observer $observer + * @return void + */ + public function processUrlRewriteSaving(EventObserver $observer) + { + /** @var \Magento\Catalog\Model\Product $product */ + $product = $observer->getEvent()->getProduct(); + + if (!$product->getUrlPath() || $product->getOrigData('url_key') != $product->getData('url_key')) { + $product->setUrlPath($this->catalogUrlRewriteHelper->generateProductUrlKeyPath($product)); + } + + if (!$product->getData('url_key') || $product->getOrigData('url_key') != $product->getData('url_key')) { + $this->urlSave->save($this->productUrlGenerator->generate($product)); + } + } +} diff --git a/app/code/Magento/CatalogUrlRewrite/Service/V1/AbstractUrlGenerator.php b/app/code/Magento/CatalogUrlRewrite/Service/V1/AbstractUrlGenerator.php new file mode 100644 index 0000000000000000000000000000000000000000..3a6925dee2eab674d280e83ce30d3a43b3bd706f --- /dev/null +++ b/app/code/Magento/CatalogUrlRewrite/Service/V1/AbstractUrlGenerator.php @@ -0,0 +1,40 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\CatalogUrlRewrite\Service\V1; + +use Magento\Catalog\Model\ProductFactory; +use Magento\CatalogUrlRewrite\Helper\Data as CatalogUrlRewriteHelper; +use Magento\Store\Model\StoreManagerInterface; +use Magento\UrlRedirect\Model\OptionProvider; +use Magento\UrlRedirect\Service\V1\Data\Converter; +use Magento\UrlRedirect\Service\V1\Data\FilterFactory; +use Magento\UrlRedirect\Service\V1\Data\UrlRewrite; +use Magento\UrlRedirect\Service\V1\UrlMatcherInterface; + +/** + * Product Generator + */ +abstract class AbstractUrlGenerator +{ +} diff --git a/app/code/Magento/CatalogUrlRewrite/Service/V1/CategoryUrlGenerator.php b/app/code/Magento/CatalogUrlRewrite/Service/V1/CategoryUrlGenerator.php new file mode 100644 index 0000000000000000000000000000000000000000..cbb770f46f0af4abd836579aa61c265b0209ff13 --- /dev/null +++ b/app/code/Magento/CatalogUrlRewrite/Service/V1/CategoryUrlGenerator.php @@ -0,0 +1,213 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\CatalogUrlRewrite\Service\V1; + +use Magento\CatalogUrlRewrite\Helper\Data as CatalogUrlRewriteHelper; +use Magento\Store\Model\StoreManagerInterface; +use Magento\UrlRedirect\Model\OptionProvider; +use Magento\UrlRedirect\Service\V1\Data\FilterFactory; +use Magento\UrlRedirect\Service\V1\UrlMatcherInterface; +use Magento\UrlRedirect\Service\V1\Data\UrlRewrite; + +/** + * Product Generator + */ +class CategoryUrlGenerator implements CategoryUrlGeneratorInterface +{ + /** + * Entity type + */ + const ENTITY_TYPE_CATEGORY = 'category'; + + /** + * @var FilterFactory + */ + protected $filterFactory; + + /** + * Store manager + * + * @var StoreManagerInterface + */ + protected $storeManager; + + /** + * @var UrlMatcherInterface + */ + protected $urlMatcher; + + /** + * @var CatalogUrlRewriteHelper + */ + protected $catalogUrlRewriteHelper; + + /** + * @var \Magento\Catalog\Model\Category + */ + protected $category; + + /** + * @var null|\Magento\Catalog\Model\Resource\Category\Collection + */ + protected $categories; + + /** + * @param FilterFactory $filterFactory + * @param StoreManagerInterface $storeManager + * @param UrlMatcherInterface $urlMatcher + * @param CatalogUrlRewriteHelper $catalogUrlRewriteHelper + */ + public function __construct( + FilterFactory $filterFactory, + StoreManagerInterface $storeManager, + UrlMatcherInterface $urlMatcher, + CatalogUrlRewriteHelper $catalogUrlRewriteHelper + ) { + $this->filterFactory = $filterFactory; + $this->storeManager = $storeManager; + $this->urlMatcher = $urlMatcher; + $this->catalogUrlRewriteHelper = $catalogUrlRewriteHelper; + } + + /** + * {@inheritdoc} + */ + public function generate($category) + { + $this->category = $category; + $storeId = $this->category->getStoreId(); + + $urls = $this->catalogUrlRewriteHelper->isDefaultStore($storeId) + ? $this->generateForDefaultStore() : $this->generateForStore($storeId); + + $this->category = null; + return $urls; + } + + /** + * Generate list of urls for default store + * + * @return UrlRewrite[] + */ + protected function generateForDefaultStore() + { + $urls = []; + foreach ($this->storeManager->getStores() as $store) { + if ($this->catalogUrlRewriteHelper->isNeedCreateUrlRewrite( + $store->getStoreId(), + $this->category->getId() + )) { + $urls = array_merge($urls, $this->generateForStore($store->getStoreId())); + } + } + return $urls; + } + + /** + * Generate list of urls per store + * + * @param int $storeId + * @return UrlRewrite[] + */ + protected function generateForStore($storeId) + { + $urls[] = $this->createUrlRewrite( + $storeId, + $this->catalogUrlRewriteHelper->getCategoryUrlKeyPath($this->category), + $this->catalogUrlRewriteHelper->getCategoryCanonicalUrlPath($this->category) + ); + + return array_merge($urls, $this->generateRewritesBasedOnCurrentRewrites($storeId)); + } + + /** + * Generate permanent rewrites based on current rewrites + * + * @param int $storeId + * @return array + */ + protected function generateRewritesBasedOnCurrentRewrites($storeId) + { + $urls = []; + foreach ($this->urlMatcher->findAllByFilter($this->createCurrentUrlRewritesFilter($storeId)) as $url) { + $targetPath = null; + if ($url->getRedirectType()) { + $targetPath = str_replace( + $this->category->getOrigData('url_key'), + $this->category->getData('url_key'), + $url->getTargetPath() + ); + $redirectType = $url->getRedirectType(); + } elseif ($this->category->getData('save_rewrites_history')) { + $targetPath = str_replace( + $this->category->getOrigData('url_key'), + $this->category->getData('url_key'), + $url->getRequestPath() + ); + $redirectType = OptionProvider::PERMANENT; + } + + if ($targetPath && $url->getRequestPath() != $targetPath) { + $urls[] = $this->createUrlRewrite($storeId, $url->getRequestPath(), $targetPath, $redirectType); + } + } + return $urls; + } + + /** + * @param int $storeId + * @return \Magento\UrlRedirect\Service\V1\Data\Filter + */ + protected function createCurrentUrlRewritesFilter($storeId) + { + /** @var \Magento\UrlRedirect\Service\V1\Data\Filter $filter */ + $filter = $this->filterFactory->create(); + + $filter->setStoreId($storeId); + $filter->setEntityId($this->category->getId()); + $filter->setEntityType(self::ENTITY_TYPE_CATEGORY); + return $filter; + } + + /** + * Create url rewrite object + * + * @param int $storeId + * @param string $requestPath + * @param string $targetPath + * @param string|null $redirectType Null or one of OptionProvider const + * @return UrlRewrite + */ + protected function createUrlRewrite($storeId, $requestPath, $targetPath, $redirectType = null) + { + return $this->catalogUrlRewriteHelper->createUrlRewrite( + self::ENTITY_TYPE_CATEGORY, + $this->category->getId(), + $storeId, + $requestPath, + $targetPath, + $redirectType + ); + } +} diff --git a/app/code/Magento/CatalogUrlRewrite/Service/V1/CategoryUrlGeneratorInterface.php b/app/code/Magento/CatalogUrlRewrite/Service/V1/CategoryUrlGeneratorInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..c9288d01e6e74f34c264f1028b44595530153fc8 --- /dev/null +++ b/app/code/Magento/CatalogUrlRewrite/Service/V1/CategoryUrlGeneratorInterface.php @@ -0,0 +1,38 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\CatalogUrlRewrite\Service\V1; + +/** + * Product Generator + */ +interface CategoryUrlGeneratorInterface +{ + /** + * Generate list of urls + * + * @param \Magento\Catalog\Model\Category $category + * @return \Magento\UrlRedirect\Service\V1\Data\UrlRewrite[] + */ + public function generate($category); +} diff --git a/app/code/Magento/CatalogUrlRewrite/Service/V1/ProductUrlGenerator.php b/app/code/Magento/CatalogUrlRewrite/Service/V1/ProductUrlGenerator.php new file mode 100644 index 0000000000000000000000000000000000000000..a6991bc1c0f24b2d1504526b05f49f0c7bc3b072 --- /dev/null +++ b/app/code/Magento/CatalogUrlRewrite/Service/V1/ProductUrlGenerator.php @@ -0,0 +1,254 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\CatalogUrlRewrite\Service\V1; + +use Magento\CatalogUrlRewrite\Helper\Data as CatalogUrlRewriteHelper; +use Magento\Store\Model\StoreManagerInterface; +use Magento\UrlRedirect\Model\OptionProvider; +use Magento\UrlRedirect\Service\V1\Data\FilterFactory; +use Magento\UrlRedirect\Service\V1\UrlMatcherInterface; + +/** + * Product Generator + */ +class ProductUrlGenerator implements ProductUrlGeneratorInterface +{ + /** + * Entity type + */ + const ENTITY_TYPE_PRODUCT = 'product'; + + /** + * @var FilterFactory + */ + protected $filterFactory; + + /** + * Store manager + * + * @var StoreManagerInterface + */ + protected $storeManager; + + /** + * @var UrlMatcherInterface + */ + protected $urlMatcher; + + /** + * @var CatalogUrlRewriteHelper + */ + protected $catalogUrlRewriteHelper; + + /** + * @var \Magento\Catalog\Model\Product + */ + protected $product; + + /** + * @var null|\Magento\Catalog\Model\Resource\Category\Collection + */ + protected $categories; + + /** + * @var \Magento\Catalog\Model\Category[] + */ + protected $changedCategories; + + /** + * @param FilterFactory $filterFactory + * @param StoreManagerInterface $storeManager + * @param UrlMatcherInterface $urlMatcher + * @param CatalogUrlRewriteHelper $catalogUrlRewriteHelper + */ + public function __construct( + FilterFactory $filterFactory, + StoreManagerInterface $storeManager, + UrlMatcherInterface $urlMatcher, + CatalogUrlRewriteHelper $catalogUrlRewriteHelper + ) { + $this->filterFactory = $filterFactory; + $this->storeManager = $storeManager; + $this->urlMatcher = $urlMatcher; + $this->catalogUrlRewriteHelper = $catalogUrlRewriteHelper; + } + + /** + * {@inheritdoc} + */ + public function generate($product) + { + $this->product = $product; + $storeId = $this->product->getStoreId(); + + $urls = $this->catalogUrlRewriteHelper->isDefaultStore($storeId) + ? $this->generateForDefaultStore() : $this->generateForStore($storeId); + + $this->product = null; + $this->categories = null; + return $urls; + } + + /** + * {@inheritdoc} + */ + public function generateWithChangedCategories($product, $changedCategories) + { + $this->changedCategories = $changedCategories; + + return $this->generate($product); + } + + /** + * Generate list of urls for default store + * + * @return \Magento\UrlRedirect\Service\V1\Data\UrlRewrite[] + */ + protected function generateForDefaultStore() + { + $urls = []; + foreach ($this->storeManager->getStores() as $store) { + if ($this->catalogUrlRewriteHelper->isNeedCreateUrlRewrite($store->getStoreId(), $this->product->getId())) { + $urls = array_merge($urls, $this->generateForStore($store->getStoreId())); + } + } + return $urls; + } + + /** + * Generate list of urls per store + * + * @param int $storeId + * @return \Magento\UrlRedirect\Service\V1\Data\UrlRewrite[] + */ + protected function generateForStore($storeId) + { + $urls[] = $this->createUrlRewrite( + $storeId, + $this->catalogUrlRewriteHelper->getProductUrlKeyPath($this->product, $storeId), + $this->catalogUrlRewriteHelper->getProductCanonicalUrlPath($this->product) + ); + + foreach ($this->getCategories() as $category) { + if (isset($this->changedCategories[$category->getId()])) { + $category = $this->changedCategories[$category->getId()]; + } + + if ($this->catalogUrlRewriteHelper->isRootCategory($category)) { + continue; + } + $urls[] = $this->createUrlRewrite( + $storeId, + $this->catalogUrlRewriteHelper->getProductUrlKeyPathWithCategory($this->product, $category, $storeId), + $this->catalogUrlRewriteHelper->getProductCanonicalUrlPathWithCategory($this->product, $category) + ); + } + return array_merge($urls, $this->generateRewritesBasedOnCurrentRewrites($storeId)); + } + + /** + * Generate permanent rewrites based on current rewrites + * + * @param int $storeId + * @return array + */ + protected function generateRewritesBasedOnCurrentRewrites($storeId) + { + $urls = []; + foreach ($this->urlMatcher->findAllByFilter($this->createCurrentUrlRewritesFilter($storeId)) as $url) { + $targetPath = null; + if ($url->getRedirectType()) { + $targetPath = str_replace( + $this->product->getOrigData('url_key'), + $this->product->getData('url_key'), + $url->getTargetPath() + ); + $redirectType = $url->getRedirectType(); + } elseif ($this->product->getData('save_rewrites_history')) { + $targetPath = str_replace( + $this->product->getOrigData('url_key'), + $this->product->getData('url_key'), + $url->getRequestPath() + ); + $redirectType = OptionProvider::PERMANENT; + } + + if ($targetPath && $url->getRequestPath() != $targetPath) { + $urls[] = $this->createUrlRewrite($storeId, $url->getRequestPath(), $targetPath, $redirectType); + } + } + return $urls; + } + + /** + * @param int $storeId + * @return \Magento\UrlRedirect\Service\V1\Data\Filter + */ + protected function createCurrentUrlRewritesFilter($storeId) + { + /** @var \Magento\UrlRedirect\Service\V1\Data\Filter $filter */ + $filter = $this->filterFactory->create(); + + $filter->setStoreId($storeId); + $filter->setEntityId($this->product->getId()); + $filter->setEntityType(self::ENTITY_TYPE_PRODUCT); + return $filter; + } + + /** + * Get categories assigned to product + * + * @return \Magento\Catalog\Model\Resource\Category\Collection + */ + protected function getCategories() + { + if (!$this->categories) { + $this->categories = $this->product->getCategoryCollection(); + $this->categories->addAttributeToSelect('url_key'); + $this->categories->addAttributeToSelect('url_path'); + } + return $this->categories; + } + + /** + * Create url rewrite object + * + * @param int $storeId + * @param string $requestPath + * @param string $targetPath + * @param string|null $redirectType Null or one of OptionProvider const + * @return \Magento\UrlRedirect\Service\V1\Data\UrlRewrite + */ + protected function createUrlRewrite($storeId, $requestPath, $targetPath, $redirectType = null) + { + return $this->catalogUrlRewriteHelper->createUrlRewrite( + self::ENTITY_TYPE_PRODUCT, + $this->product->getId(), + $storeId, + $requestPath, + $targetPath, + $redirectType + ); + } +} diff --git a/app/code/Magento/CatalogUrlRewrite/Service/V1/ProductUrlGeneratorInterface.php b/app/code/Magento/CatalogUrlRewrite/Service/V1/ProductUrlGeneratorInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..75daa35a4df708f764fcb2d4128b6a885f3315df --- /dev/null +++ b/app/code/Magento/CatalogUrlRewrite/Service/V1/ProductUrlGeneratorInterface.php @@ -0,0 +1,45 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\CatalogUrlRewrite\Service\V1; + +/** + * Product Generator + */ +interface ProductUrlGeneratorInterface +{ + /** + * Generate list of urls + * + * @param \Magento\Catalog\Model\Product $product + * @return \Magento\UrlRedirect\Service\V1\Data\UrlRewrite[] + */ + public function generate($product); + + /** + * @param \Magento\Catalog\Model\Product $product + * @param \Magento\Catalog\Model\Category[] $changedCategories + * @return \Magento\UrlRedirect\Service\V1\Data\UrlRewrite[] + */ + public function generateWithChangedCategories($product, $changedCategories); +} diff --git a/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/di.xml b/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/di.xml new file mode 100644 index 0000000000000000000000000000000000000000..7f2e29067ac836fa117e1645677497b8ebec9fb8 --- /dev/null +++ b/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/di.xml @@ -0,0 +1,29 @@ +<?xml version="1.0"?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd"> + <preference for="Magento\CatalogUrlRewrite\Service\V1\ProductUrlGeneratorInterface" type="Magento\CatalogUrlRewrite\Service\V1\ProductUrlGenerator"/> + <preference for="Magento\CatalogUrlRewrite\Service\V1\CategoryUrlGeneratorInterface" type="Magento\CatalogUrlRewrite\Service\V1\CategoryUrlGenerator"/> +</config> diff --git a/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/events.xml b/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/events.xml new file mode 100644 index 0000000000000000000000000000000000000000..1b6588ba2931193f230cfc78ef32009049fe2bb6 --- /dev/null +++ b/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/events.xml @@ -0,0 +1,33 @@ +<?xml version="1.0"?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/Event/etc/events.xsd"> + <event name="catalog_product_save_after"> + <observer name="process_url_rewrite_saving" instance="Magento\CatalogUrlRewrite\Model\Product\Observer" method="processUrlRewriteSaving"/> + </event> + <event name="catalog_category_save_after"> + <observer name="process_url_rewrite_saving" instance="Magento\CatalogUrlRewrite\Model\Category\Observer" method="processUrlRewriteSaving"/> + </event> +</config> diff --git a/app/code/Magento/CatalogUrlRewrite/etc/module.xml b/app/code/Magento/CatalogUrlRewrite/etc/module.xml new file mode 100644 index 0000000000000000000000000000000000000000..1ff2849f6f22e96e533e60c75e483909077f2929 --- /dev/null +++ b/app/code/Magento/CatalogUrlRewrite/etc/module.xml @@ -0,0 +1,35 @@ +<?xml version="1.0"?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd"> + <module name="Magento_CatalogUrlRewrite" schema_version="1.0.0.0" active="false"> + <depends> + <module name="Magento_Catalog"/> + <module name="Magento_Eav"/> + <module name="Magento_Store"/> + <module name="Magento_UrlRedirect"/> + </depends> + </module> +</config> diff --git a/app/code/Magento/Checkout/view/frontend/templates/cart/coupon.phtml b/app/code/Magento/Checkout/view/frontend/templates/cart/coupon.phtml index e19ec443adb485dd4fdd099836c6ea48ce8a3b06..4108d230e9a531efe1e87629972edeb8c57e0f8d 100644 --- a/app/code/Magento/Checkout/view/frontend/templates/cart/coupon.phtml +++ b/app/code/Magento/Checkout/view/frontend/templates/cart/coupon.phtml @@ -37,7 +37,7 @@ <div class="field"> <label for="coupon_code" class="label"><span><?php echo __('Enter your code') ?></span></label> <div class="control"> - <input type="text" class="input-text" id="coupon_code" name="coupon_code" value="<?php echo $this->escapeHtml($this->getCouponCode()) ?>" /> + <input type="text" class="input-text" id="coupon_code" name="coupon_code" value="<?php echo $this->escapeHtml($this->getCouponCode()) ?>" placeholder="<?php echo $this->escapeHtml(__('Enter your code'));?>" /> </div> </div> <div class="actions-toolbar"> diff --git a/app/code/Magento/Checkout/view/frontend/templates/cart/form.phtml b/app/code/Magento/Checkout/view/frontend/templates/cart/form.phtml index 30cc87289a9d382b1508dc9bfe6712b1a140d2fb..d6f57db2366577c59f8b139e2e3b75c977beb0dd 100644 --- a/app/code/Magento/Checkout/view/frontend/templates/cart/form.phtml +++ b/app/code/Magento/Checkout/view/frontend/templates/cart/form.phtml @@ -32,27 +32,19 @@ data-mage-init='{"validation":{}}' class="form cart"> <?php echo $this->getBlockHtml('formkey'); ?> - <div class="cart table wrapper<?php echo $mergedCells == 2 ? ' detailed' : ''; ?>"> + <div class="cart table-wrapper<?php echo $mergedCells == 2 ? ' detailed' : ''; ?>"> <table id="shopping-cart-table" class="cart items data" data-mage-init='{"shoppingCart":{"emptyCartButton": "action.clear", - "updateCartActionContainer": "#update_cart_action_container"}}'> + "updateCartActionContainer": "#update_cart_action_container"}}'> <caption><?php echo __('Shopping Cart Items') ?></caption> <thead> <tr> - <th class="col item" rowspan="<?php echo $mergedCells; ?>"><span><?php echo __('Item') ?></span></th> - <th class="col price" colspan="<?php echo $mergedCells; ?>"><span><?php echo __('Unit Price') ?></span></th> - <th class="col qty" rowspan="<?php echo $mergedCells; ?>"><span><?php echo __('Qty') ?></span></th> - <th class="col subtotal" colspan="<?php echo $mergedCells; ?>"><span><?php echo __('Subtotal') ?></span></th> + <th class="col item"><span><?php echo __('Item') ?></span></th> + <th class="col price"><span><?php echo __('Price') ?></span></th> + <th class="col qty"><span><?php echo __('Qty') ?></span></th> + <th class="col subtotal"><span><?php echo __('Subtotal') ?></span></th> </tr> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displayCartBothPrices()): ?> - <tr> - <th class="col price excl tax"><?php echo $this->helper('Magento\Tax\Helper\Data')->getIncExcTaxLabel(false) ?></th> - <th class="col price incl tax"><?php echo $this->helper('Magento\Tax\Helper\Data')->getIncExcTaxLabel(true) ?></th> - <th class="col subtotal excl tax"><?php echo $this->helper('Magento\Tax\Helper\Data')->getIncExcTaxLabel(false) ?></th> - <th class="col subtotal incl tax"><?php echo $this->helper('Magento\Tax\Helper\Data')->getIncExcTaxLabel(true) ?></th> - </tr> - <?php endif; ?> </thead> <?php foreach($this->getItems() as $_item): ?> <?php echo $this->getItemHtml($_item) ?> @@ -77,10 +69,3 @@ </div> </form> <?php echo $this->getChildHtml('shopping.cart.table.after'); ?> -<script type="text/javascript"> - (function($) { - $('.cart-summary').mage('sticky', { - container: '.cart-container' - }); - })(jQuery) -</script> diff --git a/app/code/Magento/Checkout/view/frontend/templates/cart/item/configure/updatecart.phtml b/app/code/Magento/Checkout/view/frontend/templates/cart/item/configure/updatecart.phtml index 5ec4ce2d625ef110cecf29180b1406e962f3b276..8f2ea4fd355d080ec51e05f63483bed13e7a451d 100644 --- a/app/code/Magento/Checkout/view/frontend/templates/cart/item/configure/updatecart.phtml +++ b/app/code/Magento/Checkout/view/frontend/templates/cart/item/configure/updatecart.phtml @@ -60,5 +60,3 @@ })(jQuery); </script> <?php endif; ?> - - diff --git a/app/code/Magento/Checkout/view/frontend/templates/cart/item/default.phtml b/app/code/Magento/Checkout/view/frontend/templates/cart/item/default.phtml index 113d146ae00faab5a88d94647742bb76d32a3802..b6c4a68dd0aa340207fd25d07f9adb0bf19ff06b 100644 --- a/app/code/Magento/Checkout/view/frontend/templates/cart/item/default.phtml +++ b/app/code/Magento/Checkout/view/frontend/templates/cart/item/default.phtml @@ -29,16 +29,16 @@ $isVisibleProduct = $_item->getProduct()->isVisibleInSiteVisibility(); $canApplyMsrp = $this->helper('Magento\Catalog\Helper\Data')->canApplyMsrp($_item->getProduct(), \Magento\Catalog\Model\Product\Attribute\Source\Msrp\Type::TYPE_BEFORE_ORDER_CONFIRM); ?> <tbody class="cart item"> -<tr class="item info"> +<tr class="item info item-info"> <td class="col item"> - <?php if ($this->hasProductUrl()):?><a href="<?php echo $this->getProductUrl() ?>" title="<?php echo $this->escapeHtml($this->getProductName()) ?>" class="product photo"> + <?php if ($this->hasProductUrl()):?><a href="<?php echo $this->getProductUrl() ?>" title="<?php echo $this->escapeHtml($this->getProductName()) ?>" class="product photo product-item-photo"> <?php else:?> - <span class="product photo"> + <span class="product photo product-item-photo"> <?php endif;?> <?php echo $this->getLayout()->createBlock('Magento\Catalog\Block\Product\Image')->init($this->getProductForThumbnail(), 'cart_page_product_thumbnail')->toHtml(); ?> <?php if ($this->hasProductUrl()):?></a><?php else: ?></span><?php endif; ?> - <div class="product details"> - <strong class="product name"> + <div class="product details product-item-details"> + <strong class="product name product-item-name"> <?php if ($this->hasProductUrl()):?> <a href="<?php echo $this->getProductUrl() ?>"><?php echo $this->escapeHtml($this->getProductName()) ?></a> <?php else: ?> @@ -46,7 +46,7 @@ $canApplyMsrp = $this->helper('Magento\Catalog\Helper\Data')->canApplyMsrp($_ite <?php endif; ?> </strong> <?php if ($_options = $this->getOptionList()):?> - <dl class="cart item options"> + <dl class="cart-item-options"> <?php foreach ($_options as $_option) : ?> <?php $_formatedOptionValue = $this->getFormatedOptionValue($_option) ?> <dt><?php echo $this->escapeHtml($_option['label']) ?></dt> @@ -78,7 +78,7 @@ $canApplyMsrp = $this->helper('Magento\Catalog\Helper\Data')->canApplyMsrp($_ite </td> <?php if ($canApplyMsrp): ?> - <td class="col msrp"<?php if ($this->helper('Magento\Tax\Helper\Data')->displayCartBothPrices()): ?> colspan="2"<?php endif; ?>> + <td class="col msrp" data-th="<?php echo $this->escapeHtml(__('Price')); ?>"> <span class="pricing msrp"> <span class="msrp notice"><?php echo __('See price before order confirmation.'); ?></span> <?php $helpLinkId = 'cart-msrp-help-' . $_item->getId(); ?> @@ -97,198 +97,201 @@ $canApplyMsrp = $this->helper('Magento\Catalog\Helper\Data')->canApplyMsrp($_ite </td> <?php else: ?> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displayCartPriceExclTax() || $this->helper('Magento\Tax\Helper\Data')->displayCartBothPrices()): ?> - <td class="col price excl tax" data-th="<?php echo __('Unit Price Excl. Tax'); ?>"> + <?php if ($this->helper('Magento\Tax\Helper\Data')->displayCartPriceExclTax() || $this->helper('Magento\Tax\Helper\Data')->displayCartPriceInclTax() || $this->helper('Magento\Tax\Helper\Data')->displayCartBothPrices()): ?> + <td class="col price" data-th="<?php echo $this->escapeHtml(__('Price')); ?>"> + <?php if ($this->helper('Magento\Tax\Helper\Data')->displayCartPriceInclTax() || $this->helper('Magento\Tax\Helper\Data')->displayCartBothPrices()): ?> + <span class="incl tax" data-th="<?php echo $this->escapeHtml(__('Incl. Tax')); ?>"> + <?php $_incl = $this->helper('Magento\Checkout\Helper\Data')->getPriceInclTax($_item); ?> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $_item->getId(); ?>"}'> - <?php else: ?> - <span class="cart price"> - <?php endif; ?> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> - <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_item->getCalculationPrice()+$_item->getWeeeTaxAppliedAmount()+$_item->getWeeeTaxDisposition()); ?> - <?php else: ?> - <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_item->getCalculationPrice()) ?> - <?php endif; ?> + <span class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#unit-item-tax-details<?php echo $_item->getId(); ?>"}'> + <?php else: ?> + <span class="cart price"> + <?php endif; ?> + + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> + <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_incl+$_item->getWeeeTaxAppliedAmount()); ?> + <?php else: ?> + <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_incl-$_item->getWeeeTaxDisposition()) ?> + <?php endif; ?> </span> <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item)): ?> - - <div class="cart tax info" id="eunit-item-tax-details<?php echo $_item->getId(); ?>" style="display:none;"> + <div class="cart-tax-info" id="unit-item-tax-details<?php echo $_item->getId(); ?>" style="display: none;"> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item) as $tax): ?> - <span class="weee"><?php echo $tax['title']; ?>: <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['amount'],true,true); ?></span> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['amount'],true,true); ?></span> <?php endforeach; ?> <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item) as $tax): ?> - <span class="weee"><?php echo $tax['title']; ?>: <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['amount'],true,true); ?></span> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['amount_incl_tax'],true,true); ?></span> <?php endforeach; ?> <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item) as $tax): ?> - <span class="weee"><?php echo $tax['title']; ?>: <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['amount'],true,true); ?></span> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['amount_incl_tax'],true,true); ?></span> <?php endforeach; ?> <?php endif; ?> </div> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> - <div class="cart tax total" data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $_item->getId(); ?>"}'> - <span class="weee"><?php echo __('Total'); ?>: <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_item->getCalculationPrice()+$_item->getWeeeTaxAppliedAmount()+$_item->getWeeeTaxDisposition()); ?></span> + <div class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#unit-item-tax-details<?php echo $_item->getId(); ?>"}'> + <span class="weee" data-th="<?php echo $this->escapeHtml(__('Total incl. tax')); ?>"><?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_incl+$_item->getWeeeTaxAppliedAmount()); ?></span> </div> <?php endif; ?> <?php endif; ?> - <?php $cols++; ?> - </td> + </span> + <?php endif; ?> + <?php if ($this->helper('Magento\Tax\Helper\Data')->displayCartPriceExclTax() || $this->helper('Magento\Tax\Helper\Data')->displayCartBothPrices()): ?> + <span class="excl tax" data-th="<?php echo $this->escapeHtml(__('Excl. Tax')); ?>"> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> + <span class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $_item->getId(); ?>"}'> + <?php else: ?> + <span class="cart price"> + <?php endif; ?> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> + <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_item->getCalculationPrice() + $_item->getWeeeTaxAppliedAmount() + $_item->getWeeeTaxDisposition()); ?> + <?php else: ?> + <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_item->getCalculationPrice()) ?> <?php endif; ?> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displayCartPriceInclTax() || $this->helper('Magento\Tax\Helper\Data')->displayCartBothPrices()): ?> - <td class="col price incl tax" data-th="<?php echo __('Unit Price Incl. Tax'); ?>"> - <?php $_incl = $this->helper('Magento\Checkout\Helper\Data')->getPriceInclTax($_item); ?> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" data-tax-toggle='{"itemTaxId" : "#unit-item-tax-details<?php echo $_item->getId(); ?>"}'> - <?php else: ?> - <span class="cart price"> - <?php endif; ?> - - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> - <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_incl+$_item->getWeeeTaxAppliedAmountInclTax()); ?> - <?php else: ?> - <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_incl-$_item->getWeeeTaxDisposition()) ?> - <?php endif; ?> - </span> <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item)): ?> - - <div class="cart tax info" id="unit-item-tax-details<?php echo $_item->getId(); ?>" style="display:none;"> + <div class="cart-tax-info" id="eunit-item-tax-details<?php echo $_item->getId(); ?>" style="display:none;"> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item) as $tax): ?> - <span class="weee"><?php echo $tax['title']; ?>: <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['amount_incl_tax'],true,true); ?></span> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['amount'], true, true); ?></span> <?php endforeach; ?> <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item) as $tax): ?> - <span class="weee"><?php echo $tax['title']; ?>: <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['amount_incl_tax'],true,true); ?></span> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['amount_incl_tax'], true, true); ?></span> <?php endforeach; ?> <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item) as $tax): ?> - <span class="weee"><?php echo $tax['title']; ?>: <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['amount_incl_tax'],true,true); ?></span> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['amount_incl_tax'], true, true); ?></span> <?php endforeach; ?> <?php endif; ?> </div> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> - <div class="cart tax total" data-tax-toggle='{"itemTaxId" : "#unit-item-tax-details<?php echo $_item->getId(); ?>"}'> - <span class="weee"><?php echo __('Total incl. tax'); ?>: <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_incl+$_item->getWeeeTaxAppliedAmountInclTax()); ?></span> + <div class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $_item->getId(); ?>"}'> + <span class="weee" data-th="<?php echo $this->escapeHtml(__('Total')); ?>"><?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_item->getCalculationPrice() + $_item->getWeeeTaxAppliedAmount() + $_item->getWeeeTaxDisposition()); ?></span> </div> <?php endif; ?> <?php endif; ?> - <?php $cols++; ?> - </td> - <?php endif; ?> + </span> + <?php endif; ?> + <?php $cols++; ?> + </td> + <?php endif; ?> + <?php endif; ?> - <td class="col qty"> + <td class="col qty" data-th="<?php echo $this->escapeHtml(__('Qty')); ?>"> <div class="control qty"> <input name="cart[<?php echo $_item->getId() ?>][qty]" value="<?php echo $this->getQty() ?>" type="number" size="4" title="<?php echo __('Qty') ?>" class="input-text qty" maxlength="12" data-validate="{required:true,'validate-greater-than-zero':true}"/> </div> <?php $cols++; ?> </td> - <?php if (($this->helper('Magento\Tax\Helper\Data')->displayCartPriceExclTax() || $this->helper('Magento\Tax\Helper\Data')->displayCartBothPrices()) && !$_item->getNoSubtotal()): ?> - <td class="col subtotal excl tax" data-th="<?php echo __('Subtotal Excl. Tax'); ?>"> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $_item->getId(); ?>"}'> - <?php else: ?> - <span class="cart price"> - <?php endif; ?> + <?php if (($this->helper('Magento\Tax\Helper\Data')->displayCartPriceInclTax() || $this->helper('Magento\Tax\Helper\Data')->displayCartPriceExclTax() || $this->helper('Magento\Tax\Helper\Data')->displayCartBothPrices()) && !$_item->getNoSubtotal()): ?> + <td class="col subtotal" data-th="<?php echo $this->escapeHtml(__('Subtotal'));?>"> + <?php if (($this->helper('Magento\Tax\Helper\Data')->displayCartPriceInclTax() || $this->helper('Magento\Tax\Helper\Data')->displayCartBothPrices()) && !$_item->getNoSubtotal()): ?> + <span class="incl tax" data-th="<?php echo $this->escapeHtml(__('Incl. Tax'));?>"> + <?php $_incl = $this->helper('Magento\Checkout\Helper\Data')->getSubtotalInclTax($_item); ?> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> + <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#subtotal-item-tax-details<?php echo $_item->getId(); ?>"}'> + <?php else: ?> + <span class="cart price"> + <?php endif; ?> <?php if ($canApplyMsrp): ?> <span class="cart msrp subtotal">--</span> <?php else: ?> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> - <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_item->getRowTotal()+$_item->getWeeeTaxAppliedRowAmount()+$_item->getWeeeTaxRowDisposition()); ?> + <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_incl+$_item->getWeeeTaxAppliedRowAmount()); ?> <?php else: ?> - <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_item->getRowTotal()) ?> + <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_incl-$_item->getWeeeTaxRowDisposition()) ?> <?php endif; ?> <?php endif; ?> + </span> - </span> - <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item)): ?> + <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item)): ?> + <div class="cart-tax-info" id="subtotal-item-tax-details<?php echo $_item->getId(); ?>" style="display:none;"> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['row_amount'],true,true); ?></span> + <?php endforeach; ?> + <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['row_amount_incl_tax'],true,true); ?></span> + <?php endforeach; ?> + <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['row_amount_incl_tax'],true,true); ?></span> + <?php endforeach; ?> + <?php endif; ?> + </div> - <div class="cart tax info" id="esubtotal-item-tax-details<?php echo $_item->getId(); ?>" style="display:none;"> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item) as $tax): ?> - <span class="weee"><?php echo $tax['title']; ?>: <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['row_amount'],true,true); ?></span> - <?php endforeach; ?> - <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item) as $tax): ?> - <span class="weee"><?php echo $tax['title']; ?>: <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['row_amount'],true,true); ?></span> - <?php endforeach; ?> - <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item) as $tax): ?> - <span class="weee"><?php echo $tax['title']; ?>: <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['row_amount'],true,true); ?></span> - <?php endforeach; ?> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> + <div class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#subtotal-item-tax-details<?php echo $_item->getId(); ?>"}'> + <span class="weee" data-th="<?php echo __('Total incl. tax'); ?>"><?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_incl+$_item->getWeeeTaxAppliedRowAmount()); ?></span> + </div> <?php endif; ?> - </div> - - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> - <div class="cart tax total" data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $_item->getId(); ?>"}'> - <span class="weee"><?php echo __('Total'); ?>: <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_item->getRowTotal()+$_item->getWeeeTaxAppliedRowAmount()+$_item->getWeeeTaxRowDisposition()); ?></span> - </div> <?php endif; ?> - <?php endif; ?> - <?php $cols++; ?> - </td> - <?php endif; ?> - <?php if (($this->helper('Magento\Tax\Helper\Data')->displayCartPriceInclTax() || $this->helper('Magento\Tax\Helper\Data')->displayCartBothPrices()) && !$_item->getNoSubtotal()): ?> - <td class="col subtotal incl tax" data-th="<?php echo __('Subtotal Incl. Tax'); ?>"> - <?php $_incl = $this->helper('Magento\Checkout\Helper\Data')->getSubtotalInclTax($_item); ?> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" data-tax-toggle='{"itemTaxId" : "#subtotal-item-tax-details<?php echo $_item->getId(); ?>"}'> - <?php else: ?> - <span class="cart price"> + </span> <?php endif; ?> + <?php if (($this->helper('Magento\Tax\Helper\Data')->displayCartPriceExclTax() || $this->helper('Magento\Tax\Helper\Data')->displayCartBothPrices()) && !$_item->getNoSubtotal()): ?> + <span class="excl tax" data-th="<?php echo $this->escapeHtml(__('Excl. Tax'));?>"> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> + <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $_item->getId(); ?>"}'> + <?php else: ?> + <span class="cart price"> + <?php endif; ?> <?php if ($canApplyMsrp): ?> <span class="cart msrp subtotal">--</span> <?php else: ?> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> - <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_incl+$_item->getWeeeTaxAppliedRowAmountInclTax()); ?> + <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_item->getRowTotal()+$_item->getWeeeTaxAppliedRowAmount()+$_item->getWeeeTaxRowDisposition()); ?> <?php else: ?> - <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_incl-$_item->getWeeeTaxRowDisposition()) ?> + <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_item->getRowTotal()) ?> <?php endif; ?> <?php endif; ?> + </span> - </span> - - - <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item)): ?> + <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item)): ?> + <div class="cart-tax-info" id="esubtotal-item-tax-details<?php echo $_item->getId(); ?>" style="display:none;"> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['row_amount'],true,true); ?></span> + <?php endforeach; ?> + <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['row_amount_incl_tax'],true,true); ?></span> + <?php endforeach; ?> + <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['row_amount_incl_tax'],true,true); ?></span> + <?php endforeach; ?> + <?php endif; ?> + </div> - <div class="cart tax info" id="subtotal-item-tax-details<?php echo $_item->getId(); ?>" style="display:none;"> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item) as $tax): ?> - <span class="weee"><?php echo $tax['title']; ?>: <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['row_amount_incl_tax'],true,true); ?></span> - <?php endforeach; ?> - <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item) as $tax): ?> - <span class="weee"><?php echo $tax['title']; ?>: <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['row_amount_incl_tax'],true,true); ?></span> - <?php endforeach; ?> - <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item) as $tax): ?> - <span class="weee"><?php echo $tax['title']; ?>: <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['row_amount_incl_tax'],true,true); ?></span> - <?php endforeach; ?> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> + <div class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $_item->getId(); ?>"}'> + <span class="weee" data-th="<?php echo __('Total'); ?>"><?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_item->getRowTotal()+$_item->getWeeeTaxAppliedRowAmount()+$_item->getWeeeTaxRowDisposition()); ?></span> + </div> <?php endif; ?> - </div> - - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> - <div class="cart tax total" data-tax-toggle='{"itemTaxId" : "#subtotal-item-tax-details<?php echo $_item->getId(); ?>"}'> - <span class="weee"><?php echo __('Total incl. tax'); ?>: <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_incl+$_item->getWeeeTaxAppliedRowAmountInclTax()); ?></span> - </div> <?php endif; ?> + </span> <?php endif; ?> <?php $cols++; ?> </td> <?php endif; ?> </tr> -<tr class="item actions"> +<tr class="item actions item-actions"> <td colspan="<?php echo $cols;?>"> <div class="actions"> - <?php if ($this->helper('Magento\Wishlist\Helper\Data')->isAllowInCart()) : ?> <?php if ($isVisibleProduct): ?> <a href="#" data-post='<?php echo $this->helper('Magento\Wishlist\Helper\Data')->getMoveFromCartParams($_item->getId()); ?>' class="use-ajax action towishlist"> diff --git a/app/code/Magento/Checkout/view/frontend/templates/cart/methods.phtml b/app/code/Magento/Checkout/view/frontend/templates/cart/methods.phtml index 56379e7a857ed6d0c18d8ba64d453993f9b4de63..30509d55c06f130af30d626a77172b63935d000f 100644 --- a/app/code/Magento/Checkout/view/frontend/templates/cart/methods.phtml +++ b/app/code/Magento/Checkout/view/frontend/templates/cart/methods.phtml @@ -27,7 +27,7 @@ ?> <?php if(!$this->hasError()): ?> <?php $methods = $this->getMethods('methods') ? : $this->getMethods('top_methods') ?> -<ul class="checkout methods items"> +<ul class="checkout methods items checkout-methods-items"> <?php foreach ($methods as $method): ?> <?php if ($methodHtml = $this->getMethodHtml($method)): ?> <li class="item"><?php echo $methodHtml; ?></li> diff --git a/app/code/Magento/Checkout/view/frontend/templates/cart/noItems.phtml b/app/code/Magento/Checkout/view/frontend/templates/cart/noItems.phtml index 386c6c249dbed68ab3db79bd179de85766d70e6d..dad5681619f5cd60bbef06c728a84d441782a72f 100644 --- a/app/code/Magento/Checkout/view/frontend/templates/cart/noItems.phtml +++ b/app/code/Magento/Checkout/view/frontend/templates/cart/noItems.phtml @@ -24,7 +24,7 @@ /** @var $this \Magento\Checkout\Block\Cart */ ?> -<div class="cart empty"> +<div class="cart-empty"> <?php echo $this->getChildHtml('checkout_cart_empty_widget'); ?> <p><?php echo __('You have no items in your shopping cart.') ?></p> <p><?php echo __('Click <a href="%1">here</a> to continue shopping.', $this->getContinueShoppingUrl()) ?></p> diff --git a/app/code/Magento/Checkout/view/frontend/templates/cart/shipping.phtml b/app/code/Magento/Checkout/view/frontend/templates/cart/shipping.phtml index 60e0be53b1696aa69733037843bbdaa4326c29a0..90e954f4e40e033c3279bfc0abb810423b5d3229 100644 --- a/app/code/Magento/Checkout/view/frontend/templates/cart/shipping.phtml +++ b/app/code/Magento/Checkout/view/frontend/templates/cart/shipping.phtml @@ -57,7 +57,7 @@ <div class="field postcode<?php if ($this->isZipCodeRequired()) echo ' required' ?>"> <label for="postcode" class="label"><span><?php echo __('Zip/Postal Code') ?></span></label> <div class="control"> - <input class="input-text" data-validate="{<?php if ($this->isZipCodeRequired()):?> 'required-entry':true,<?php endif;?>'validate-zip':true}" type="text" id="postcode" name="estimate_postcode" value="<?php echo $this->escapeHtml($this->getEstimatePostcode()) ?>" /> + <input class="input-text" data-validate="{<?php if ($this->isZipCodeRequired()):?> 'required-entry':true,<?php endif;?>'validate-zip-international':true}" type="text" id="postcode" name="estimate_postcode" value="<?php echo $this->escapeHtml($this->getEstimatePostcode()) ?>" /> </div> </div> <div class="actions-toolbar"> @@ -88,8 +88,8 @@ <fieldset class="fieldset rates"> <dl class="items methods"> <?php foreach ($_shippingRateGroups as $code => $_rates): ?> - <dt class="item title"><span><?php echo $this->escapeHtml($this->getCarrierName($code)) ?></span></dt> - <dd class="item options"> + <dt class="item-title"><span><?php echo $this->escapeHtml($this->getCarrierName($code)) ?></span></dt> + <dd class="item-options"> <?php foreach ($_rates as $_rate): ?> <div class="<?php if ($_rate->getErrorMessage()): echo ' message error'; else: echo 'field choice item'; endif; ?>"> diff --git a/app/code/Magento/Checkout/view/frontend/templates/cart/sidebar/default.phtml b/app/code/Magento/Checkout/view/frontend/templates/cart/sidebar/default.phtml index 3ab2e4df3ed6e9c948d983a867d2d038c4712784..13f9c393be0a0a320dd5231253f560321784587e 100644 --- a/app/code/Magento/Checkout/view/frontend/templates/cart/sidebar/default.phtml +++ b/app/code/Magento/Checkout/view/frontend/templates/cart/sidebar/default.phtml @@ -27,14 +27,14 @@ <?php $_item = $this->getItem() ?> <?php $canApplyMsrp = $this->helper('Magento\Catalog\Helper\Data')->canApplyMsrp($_item->getProduct(), \Magento\Catalog\Model\Product\Attribute\Source\Msrp\Type::TYPE_BEFORE_ORDER_CONFIRM); ?> <?php $imageBlock = $this->getLayout()->createBlock('Magento\Catalog\Block\Product\Image')?> -<li class="item product"> +<li class="item product product-item"> <div class="product"> <?php if ($this->hasProductUrl()): ?> - <a href="<?php echo $this->getProductUrl()?>" title="<?php echo $this->escapeHtml($this->getProductName()) ?>" class="product photo"> + <a href="<?php echo $this->getProductUrl()?>" title="<?php echo $this->escapeHtml($this->getProductName()) ?>" class="product photo product-item-photo"> <?php echo $imageBlock->init($this->getProductForThumbnail(), 'mini_cart_product_thumbnail')->toHtml() ?> </a> <?php else: ?> - <span class="product photo"> + <span class="product photo product-item-photo"> <?php echo $imageBlock->init($this->getProductForThumbnail(), 'mini_cart_product_thumbnail')->toHtml() ?> </span> <?php endif; ?> diff --git a/app/code/Magento/Checkout/view/frontend/templates/onepage/login.phtml b/app/code/Magento/Checkout/view/frontend/templates/onepage/login.phtml index 71ba691841e03aab7d4eca86d684b600f8a7c845..5d50197db264553264b91798f59038dd96830d32 100644 --- a/app/code/Magento/Checkout/view/frontend/templates/onepage/login.phtml +++ b/app/code/Magento/Checkout/view/frontend/templates/onepage/login.phtml @@ -97,12 +97,10 @@ <?php if( $this->isAllowedGuestCheckout() ): ?> <fieldset class="fieldset guest"> - <?php if( $this->isAllowedGuestCheckout() ): ?> <div class="field choice"> <input type="radio" name="checkout_method" data-role="checkout-method-guest" id="login:guest" value="guest"<?php if($this->getQuote()->getCheckoutMethod()==Magento\Checkout\Model\Type\Onepage::METHOD_GUEST): ?> checked="checked"<?php endif; ?> class="radio" /> <label class="label" for="login:guest"><span><?php echo __('Checkout as Guest') ?></span></label> </div> - <?php endif; ?> <?php if( $this->helper('Magento\Customer\Helper\Data')->isRegistrationAllowed() ): ?> <div class="field choice"> <input type="radio" name="checkout_method" data-role="checkout-method-register" id="login:register" value="register"<?php if($this->getQuote()->getCheckoutMethod()==Magento\Checkout\Model\Type\Onepage::METHOD_REGISTER || !$this->isAllowedGuestCheckout()): ?> checked="checked"<?php endif ?> class="radio" /> @@ -110,21 +108,21 @@ </div> <?php endif; ?> </fieldset> - <?php else: ?> - <input type="hidden" name="checkout_method" id="login:register" value="register" checked="checked" /> <?php endif; ?> - <div class="actions-toolbar"> + <div class="actions toolbar"> <div class="primary"> <?php if ($this->isAllowedGuestCheckout()): ?> <button data-role="opc-continue" id="onepage-guest-register-button" type="button" class="action continue primary" data-checkout='{"isGuestCheckoutAllowed":true}'><span><?php echo __('Continue') ?></span></button> <?php elseif ($this->helper('Magento\Checkout\Helper\Data')->isCustomerMustBeLogged()): ?> + <input type="hidden" name="checkout_method" id="login:register" value="register" checked="checked" /> <button data-role="opc-continue" id="onepage-guest-register-button" type="button" class="action register primary" data-checkout='{"isGuestCheckoutAllowed":false, "registrationUrl":"<?php echo $this->helper('Magento\Customer\Helper\Data')->getRegisterUrl();?>"}'><span><?php echo __('Register') ?></span></button> <?php else: ?> - <input type="hidden" name="checkout_method" id="login:register" value="register" checked="checked" /> + <input type="hidden" name="checkout_method" data-role="checkout-method-register" id="login:register" value="register" checked="checked" /> <button data-role="opc-continue" id="onepage-guest-register-button" type="button" class="action register primary" data-checkout='{"isGuestCheckoutAllowed":true}'><span><?php echo __('Register') ?></span></button> <?php endif; ?> </div> </div> + </div> </div> <?php endif; ?> diff --git a/app/code/Magento/Checkout/view/frontend/templates/onepage/review/info.phtml b/app/code/Magento/Checkout/view/frontend/templates/onepage/review/info.phtml index 3fd1100c57e5f5a0372b9dae863c6e133e7c4c85..9c541610eccb00a6b49971d5f580657b5f5557cc 100644 --- a/app/code/Magento/Checkout/view/frontend/templates/onepage/review/info.phtml +++ b/app/code/Magento/Checkout/view/frontend/templates/onepage/review/info.phtml @@ -25,7 +25,7 @@ /** @var $this \Magento\Checkout\Block\Onepage\Review\Info */ ?> <?php echo $this->getChildHtml('items_before'); ?> -<div id="checkout-review-table-wrapper" class="review table wrapper"> +<div id="checkout-review-table-wrapper" class="review table-wrapper"> <?php if ($this->helper('Magento\Tax\Helper\Data')->displayCartBothPrices()): $colspan = $rowspan = 2; else: $colspan = $rowspan = 1; endif; ?> <table class="data table order review items" id="checkout-review-table"> <caption>Order Review</caption> diff --git a/app/code/Magento/Checkout/view/frontend/templates/total/tax.phtml b/app/code/Magento/Checkout/view/frontend/templates/total/tax.phtml index 925a5586c12443e64286bb2abe583c6157d64dbf..7689b84c361a67338d8299d53aeda2d2d92ad1b5 100644 --- a/app/code/Magento/Checkout/view/frontend/templates/total/tax.phtml +++ b/app/code/Magento/Checkout/view/frontend/templates/total/tax.phtml @@ -23,39 +23,11 @@ */ ?> <?php global $taxIter; $taxIter++; ?> -<?php if ($this->helper('Magento\Tax\Helper\Data')->displayFullSummary() && $this->getTotal()->getValue()!=0): ?> -<?php $isTop = 1; ?> - <?php foreach ($this->getTotal()->getFullInfo() as $info): ?> - <?php if (isset($info['hidden']) && $info['hidden']) continue; ?> - <?php $percent = $info['percent']; ?> - <?php $amount = $info['amount']; ?> - <?php $rates = $info['rates']; ?> - <?php $isFirst = 1; ?> - <?php foreach ($rates as $rate): ?> - <tr class="totals tax details details-<?php echo $taxIter; ?>"> - <td class="mark" style="<?php echo $this->getTotal()->getStyle() ?>" colspan="<?php echo $this->getColspan(); ?>"> - <?php echo $this->escapeHtml($rate['title']); ?> - <?php if (!is_null($rate['percent'])): ?> - (<?php echo (float)$rate['percent']; ?>%) - <?php endif; ?> - <br /> - </td> - <?php if ($isFirst): ?> - <td class="amount" rowspan="<?php echo count($rates); ?>" class="a-right" style="<?php echo $this->getTotal()->getStyle() ?>"> - <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($amount); ?> - </td> - <?php endif; ?> - </tr> - <?php $isFirst = 0; ?> - <?php $isTop = 0; ?> - <?php endforeach; ?> - <?php endforeach; ?> -<?php endif;?> <?php - $attributes = 'class="totals tax"'; + $attributes = 'class="totals-tax"'; if ($this->helper('Magento\Tax\Helper\Data')->displayFullSummary() && $this->getTotal()->getValue()!=0) { - $attributes = 'class="totals tax summary"'; + $attributes = 'class="totals-tax-summary"'; } ?> <tr <?php echo $attributes; ?>> @@ -70,3 +42,33 @@ <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($this->getTotal()->getValue()) ?> </td> </tr> + +<?php if ($this->helper('Magento\Tax\Helper\Data')->displayFullSummary() && $this->getTotal()->getValue()!=0): ?> + <?php $isTop = 1; ?> + <?php foreach ($this->getTotal()->getFullInfo() as $info): ?> + <?php if (isset($info['hidden']) && $info['hidden']) continue; ?> + <?php $percent = $info['percent']; ?> + <?php $amount = $info['amount']; ?> + <?php $rates = $info['rates']; ?> + <?php $isFirst = 1; ?> + + <?php foreach ($rates as $rate): ?> + <tr class="totals tax details details-<?php echo $taxIter; ?>"> + <td class="mark" style="<?php echo $this->getTotal()->getStyle() ?>" colspan="<?php echo $this->getColspan(); ?>"> + <?php echo $this->escapeHtml($rate['title']); ?> + <?php if (!is_null($rate['percent'])): ?> + (<?php echo (float)$rate['percent']; ?>%) + <?php endif; ?> + <br /> + </td> + <?php if ($isFirst): ?> + <td class="amount" rowspan="<?php echo count($rates); ?>" style="<?php echo $this->getTotal()->getStyle() ?>"> + <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($amount); ?> + </td> + <?php endif; ?> + </tr> + <?php $isFirst = 0; ?> + <?php $isTop = 0; ?> + <?php endforeach; ?> + <?php endforeach; ?> +<?php endif;?> diff --git a/app/code/Magento/Checkout/view/frontend/web/js/opc-checkout-method.js b/app/code/Magento/Checkout/view/frontend/web/js/opc-checkout-method.js index b104a0425b0372c9829aa274f6bb118776d80607..483a9a4781be7a54585185319f6c59c3e00d4911 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/opc-checkout-method.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/opc-checkout-method.js @@ -161,19 +161,35 @@ * @return {Boolean} */ _continue: function(elem) { - var json = elem.data('checkout'); + var json = elem.data('checkout'), + checkout = this.options.checkout, + guestChecked = $( checkout.loginGuestSelector ).is( ':checked' ), + loginRegister = $( checkout.loginRegisterSelector )[0], + method = 'register', + action = 'show'; + if (json.isGuestCheckoutAllowed) { - if ($(this.options.checkout.loginGuestSelector).is(':checked')) { - this._ajaxContinue(this.options.checkout.saveUrl, {method:'guest'}, this.options.billingSection); - this.element.find(this.options.checkout.registerCustomerPasswordSelector).hide(); - } else if ($(this.options.checkout.loginRegisterSelector).is(':checked')) { - this._ajaxContinue(this.options.checkout.saveUrl, {method:'register'}, this.options.billingSection); - this.element.find(this.options.checkout.registerCustomerPasswordSelector).show(); - } else { - alert($.mage.__('Please choose to register or to checkout as a guest.')); + + if( !guestChecked && !(loginRegister && loginRegister.checked) ){ + alert( $.mage.__('Please choose to register or to checkout as a guest.') ); + return false; } + + if( guestChecked ){ + method = 'guest'; + action = 'hide'; + } + + this._ajaxContinue( + checkout.saveUrl, + { method: method }, + this.options.billingSection + ); + + this.element.find( checkout.registerCustomerPasswordSelector )[action](); } + this.element.trigger('login'); }, diff --git a/app/code/Magento/CheckoutAgreements/Controller/Adminhtml/Agreement/Save.php b/app/code/Magento/CheckoutAgreements/Controller/Adminhtml/Agreement/Save.php index 24073ded5ab984ff14becf1cf3a8d504e578d2ec..69ebc01f68567846811c1eaa5b8f2bd1e650417e 100644 --- a/app/code/Magento/CheckoutAgreements/Controller/Adminhtml/Agreement/Save.php +++ b/app/code/Magento/CheckoutAgreements/Controller/Adminhtml/Agreement/Save.php @@ -37,12 +37,17 @@ class Save extends \Magento\CheckoutAgreements\Controller\Adminhtml\Agreement $model->setData($postData); try { - $model->save(); - - $this->messageManager->addSuccess(__('The condition has been saved.')); - $this->_redirect('checkout/*/'); - - return; + $validationResult = $model->validateData(new \Magento\Framework\Object($postData)); + if ($validationResult !== true) { + foreach ($validationResult as $message) { + $this->messageManager->addError($message); + } + } else { + $model->save(); + $this->messageManager->addSuccess(__('The condition has been saved.')); + $this->_redirect('checkout/*/'); + return; + } } catch (\Magento\Framework\Model\Exception $e) { $this->messageManager->addError($e->getMessage()); } catch (\Exception $e) { diff --git a/app/code/Magento/CheckoutAgreements/Model/Agreement.php b/app/code/Magento/CheckoutAgreements/Model/Agreement.php index 009cadb5696204c1a68b8c7e374c3ce445a73e7b..c62dd5167d1c340ac46485d927091b68d726a5be 100644 --- a/app/code/Magento/CheckoutAgreements/Model/Agreement.php +++ b/app/code/Magento/CheckoutAgreements/Model/Agreement.php @@ -42,6 +42,13 @@ namespace Magento\CheckoutAgreements\Model; */ class Agreement extends \Magento\Framework\Model\AbstractModel { + /** + * Allowed CSS units for height field + * + * @var array + */ + protected $allowedCssUnits = array('px', 'pc', 'pt', 'ex', 'em', 'mm', 'cm', 'in', '%'); + /** * @return void */ @@ -49,4 +56,43 @@ class Agreement extends \Magento\Framework\Model\AbstractModel { $this->_init('Magento\CheckoutAgreements\Model\Resource\Agreement'); } + + /** + * @param \Magento\Framework\Object $agreementData + * @return array|bool + */ + public function validateData($agreementData) + { + $errors = []; + + $contentHeight = $agreementData->getContentHeight(); + if ($contentHeight !== '' + && !preg_match('/^[0-9]*\.*[0-9]+(' . implode("|", $this->allowedCssUnits) . ')?$/', $contentHeight) + ) { + $errors[] = "Please input a valid CSS-height. For example 100px or 77pt or 20em or .5ex or 50%."; + } + + return (count($errors)) ? $errors : true; + } + + /** + * Processing object before save data + * + * @return $this + */ + protected function _beforeSave() + { + if ($this->getContentHeight() == 0) { + $this->setContentHeight(''); //converting zero Content-Height + } + + if ($this->getContentHeight() + && !preg_match('/('. implode("|", $this->allowedCssUnits) . ')/', $this->getContentHeight()) + ) { + $contentHeight = $this->getContentHeight() . 'px'; //setting default units for Content-Height + $this->setContentHeight($contentHeight); + } + + return parent::_beforeSave(); + } } diff --git a/app/code/Magento/CheckoutAgreements/i18n/en_US.csv b/app/code/Magento/CheckoutAgreements/i18n/en_US.csv index 64927202823e9ca19f4b2082acf8b48a0b675e62..b5db8f403645334ceaec1080ed9a4ce55ba9ac07 100644 --- a/app/code/Magento/CheckoutAgreements/i18n/en_US.csv +++ b/app/code/Magento/CheckoutAgreements/i18n/en_US.csv @@ -30,3 +30,4 @@ Sales,Sales "Checkout Conditions","Checkout Conditions" "Checkout Terms and Conditions","Checkout Terms and Conditions" "Enable Terms and Conditions","Enable Terms and Conditions" +"Please input a valid CSS-height. For example 100px or 77pt or 20em or .5ex or 50%.","Please input a valid CSS-height. For example 100px or 77pt or 20em or .5ex or 50%." diff --git a/app/code/Magento/Cms/Model/Resource/Block/Grid/Collection.php b/app/code/Magento/Cms/Model/Resource/Block/Grid/Collection.php index f22e1ec4bcdbedcd42f764b73d8b7dc802c53783..151b002fe6a7f437df1ddc24fcee67b2a5d7aa9b 100644 --- a/app/code/Magento/Cms/Model/Resource/Block/Grid/Collection.php +++ b/app/code/Magento/Cms/Model/Resource/Block/Grid/Collection.php @@ -37,14 +37,15 @@ class Collection extends \Magento\Cms\Model\Resource\Block\Collection } /** - * @param string $field - * @param null $condition + * @param string|array $field + * @param string|int|array|null $condition * @return \Magento\Cms\Model\Resource\Block\Grid\Collection */ public function addFieldToFilter($field, $condition = null) { if ($field == 'store_id') { - return $this->addStoreFilter($field); + return $this->addStoreFilter($condition, false); } + return parent::addFieldToFilter($field, $condition); } } diff --git a/app/code/Magento/CmsUrlRewrite/Model/Observer.php b/app/code/Magento/CmsUrlRewrite/Model/Observer.php new file mode 100644 index 0000000000000000000000000000000000000000..e5278ac34beb11a2c2cd5176ce9e47c192e7f89e --- /dev/null +++ b/app/code/Magento/CmsUrlRewrite/Model/Observer.php @@ -0,0 +1,76 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\CmsUrlRewrite\Model; + +use Magento\Framework\Event\Observer as EventObserver; +use Magento\CmsUrlRewrite\Service\V1\CmsPageUrlGeneratorInterface; +use Magento\UrlRedirect\Service\V1\UrlSaveInterface; +use Magento\Framework\Model\Exception; + +class Observer +{ + /** + * @var CmsPageUrlGeneratorInterface + */ + protected $urlGenerator; + + /** + * @var \Magento\UrlRedirect\Service\V1\UrlSaveInterface + */ + protected $urlSave; + + /** + * @param CmsPageUrlGeneratorInterface $urlGenerator + * @param UrlSaveInterface $urlSave + */ + public function __construct(CmsPageUrlGeneratorInterface $urlGenerator, UrlSaveInterface $urlSave) + { + $this->urlGenerator = $urlGenerator; + $this->urlSave = $urlSave; + } + + /** + * Generate urls for UrlRewrite and save it in storage + * + * @param \Magento\Framework\Event\Observer $observer + * @return void + * @throws Exception|\Exception + */ + public function processUrlRewriteSaving(EventObserver $observer) + { + /** @var $cmsPage \Magento\Cms\Model\Page */ + $cmsPage = $observer->getEvent()->getObject(); + if ($cmsPage->getOrigData('identifier') !== $cmsPage->getData('identifier')) { + $urls = $this->urlGenerator->generate($cmsPage); + try { + $this->urlSave->save($urls); + } catch (\Exception $e) { + if ($e->getCode() === 23000) { // Integrity constraint violation: 1062 Duplicate entry + throw new Exception(__('A page URL key for specified store already exists.')); + } + throw $e; + } + } + } +} diff --git a/app/code/Magento/CmsUrlRewrite/Service/V1/CmsPageUrlGenerator.php b/app/code/Magento/CmsUrlRewrite/Service/V1/CmsPageUrlGenerator.php new file mode 100644 index 0000000000000000000000000000000000000000..eda0815e280a78a810040769996f8119177ddea8 --- /dev/null +++ b/app/code/Magento/CmsUrlRewrite/Service/V1/CmsPageUrlGenerator.php @@ -0,0 +1,130 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\CmsUrlRewrite\Service\V1; + +use Magento\Store\Model\StoreManagerInterface; +use Magento\UrlRedirect\Service\V1\Data\Converter; +use Magento\UrlRedirect\Service\V1\Data\UrlRewrite; + +class CmsPageUrlGenerator implements CmsPageUrlGeneratorInterface +{ + /** + * Entity type code + */ + const ENTITY_TYPE = 'cms-page'; + + /** + * @var Converter + */ + protected $converter; + + /** + * Store manager + * + * @var StoreManagerInterface + */ + protected $storeManager; + + /** + * @var \Magento\Cms\Model\Page + */ + protected $cmsPage; + + /** + * @param Converter $converter + * @param StoreManagerInterface $storeManager + */ + public function __construct( + Converter $converter, + StoreManagerInterface $storeManager + ) { + $this->converter = $converter; + $this->storeManager = $storeManager; + } + + /** + * {@inheritdoc} + */ + public function generate($cmsPage) + { + $stores = $cmsPage->getStores(); + $this->cmsPage = $cmsPage; + $urls = array_search('0', $stores) === false ? $this->generateForSpecificStores($stores) + : $this->generateForAllStores(); + $this->cmsPage = null; + return $urls; + } + + /** + * Generate list of urls for default store + * + * @return UrlRewrite[] + */ + protected function generateForAllStores() + { + $urls = []; + foreach ($this->storeManager->getStores() as $store) { + $urls[] = $this->createUrlRewrite($store->getStoreId()); + } + return $urls; + } + + /** + * Generate list of urls per store + * + * @param int[] $storeIds + * @return UrlRewrite[] + */ + protected function generateForSpecificStores($storeIds) + { + $urls = []; + $existingStores = $this->storeManager->getStores(); + foreach ($storeIds as $storeId) { + if (!isset($existingStores[$storeId])) { + continue; + } + $urls[] = $this->createUrlRewrite($storeId); + } + return $urls; + } + + /** + * Create url rewrite object + * + * @param int $storeId + * @param string|null $redirectType Null or one of OptionProvider const + * @return UrlRewrite + */ + protected function createUrlRewrite($storeId, $redirectType = null) + { + return $this->converter->convertArrayToObject([ + UrlRewrite::ENTITY_TYPE => self::ENTITY_TYPE, + UrlRewrite::ENTITY_ID => $this->cmsPage->getId(), + UrlRewrite::STORE_ID => $storeId, + UrlRewrite::REQUEST_PATH => $this->cmsPage->getIdentifier(), + UrlRewrite::TARGET_PATH => 'cms/page/view/page_id/' . $this->cmsPage->getId(), + UrlRewrite::REDIRECT_TYPE => $redirectType, + ]); + } +} diff --git a/app/code/Magento/CmsUrlRewrite/Service/V1/CmsPageUrlGeneratorInterface.php b/app/code/Magento/CmsUrlRewrite/Service/V1/CmsPageUrlGeneratorInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..a1b81e914ce91dbd17a7d29988784338f3429cd6 --- /dev/null +++ b/app/code/Magento/CmsUrlRewrite/Service/V1/CmsPageUrlGeneratorInterface.php @@ -0,0 +1,38 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\CmsUrlRewrite\Service\V1; + +/** + * Product Generator + */ +interface CmsPageUrlGeneratorInterface +{ + /** + * Generate list of urls + * + * @param \Magento\Cms\Model\Page $cmsPage + * @return \Magento\UrlRedirect\Service\V1\Data\UrlRewrite[] + */ + public function generate($cmsPage); +} diff --git a/app/code/Magento/UrlRewrite/etc/config.xml b/app/code/Magento/CmsUrlRewrite/etc/adminhtml/di.xml similarity index 80% rename from app/code/Magento/UrlRewrite/etc/config.xml rename to app/code/Magento/CmsUrlRewrite/etc/adminhtml/di.xml index 0a3ac66124610c9df411ff79cf9cf66a4ae092aa..8f4ed44ca657e545f4e0524534d11bae41f17a41 100644 --- a/app/code/Magento/UrlRewrite/etc/config.xml +++ b/app/code/Magento/CmsUrlRewrite/etc/adminhtml/di.xml @@ -23,12 +23,6 @@ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) */ --> -<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../Core/etc/config.xsd"> - <default> - <web> - <seo> - <use_rewrites>0</use_rewrites> - </seo> - </web> - </default> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd"> + <preference for="Magento\CmsUrlRewrite\Service\V1\CmsPageUrlGeneratorInterface" type="Magento\CmsUrlRewrite\Service\V1\CmsPageUrlGenerator"/> </config> diff --git a/app/code/Magento/CmsUrlRewrite/etc/adminhtml/events.xml b/app/code/Magento/CmsUrlRewrite/etc/adminhtml/events.xml new file mode 100644 index 0000000000000000000000000000000000000000..49aaf665802d9eef2983ec116f3779488b141df6 --- /dev/null +++ b/app/code/Magento/CmsUrlRewrite/etc/adminhtml/events.xml @@ -0,0 +1,30 @@ +<?xml version="1.0"?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/Event/etc/events.xsd"> + <event name="cms_page_save_after"> + <observer name="process_url_rewrite_saving" instance="Magento\CmsUrlRewrite\Model\Observer" method="processUrlRewriteSaving" /> + </event> +</config> diff --git a/app/code/Magento/CmsUrlRewrite/etc/module.xml b/app/code/Magento/CmsUrlRewrite/etc/module.xml new file mode 100644 index 0000000000000000000000000000000000000000..8df04efdd0440c97e3c5324681c1ef535259fa43 --- /dev/null +++ b/app/code/Magento/CmsUrlRewrite/etc/module.xml @@ -0,0 +1,33 @@ +<?xml version="1.0"?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd"> + <module name="Magento_CmsUrlRewrite" schema_version="1.0.0.0" active="false"> + <depends> + <module name="Magento_Store"/> + <module name="Magento_UrlRedirect"/> + </depends> + </module> +</config> diff --git a/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Super/Config.php b/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Super/Config.php index bc628d19e76ade2264d39a9e09772bf31843ff8f..a27a2dec5b0965ba4b255a6f194b4fef774e1618 100644 --- a/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Super/Config.php +++ b/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Super/Config.php @@ -257,15 +257,14 @@ class Config extends Widget implements TabInterface $productData = (array)$this->getRequest()->getParam('product'); if (isset($productData['configurable_attributes_data'])) { $configurableData = $productData['configurable_attributes_data']; - foreach ($attributes as $key => &$attribute) { + foreach ($attributes as $key => $attribute) { if (isset($configurableData[$key])) { - $attribute['values'] = array_merge( + $attributes[$key] = array_replace_recursive($attribute, $configurableData[$key]); + $attributes[$key]['values'] = array_merge( isset($attribute['values']) ? $attribute['values'] : array(), - isset( - $configurableData[$key]['values'] - ) ? array_filter( - $configurableData[$key]['values'] - ) : array() + isset($configurableData[$key]['values']) + ? array_filter($configurableData[$key]['values']) + : array() ); } } diff --git a/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Super/Config/Matrix.php b/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Super/Config/Matrix.php index 74bb63b1fa1c651d50805d03f5cc99c6b78f5013..bcf30c8e1b6443d030e00c23c6bd9e1a415757e6 100644 --- a/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Super/Config/Matrix.php +++ b/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Super/Config/Matrix.php @@ -29,6 +29,9 @@ namespace Magento\ConfigurableProduct\Block\Adminhtml\Product\Edit\Tab\Super\Con use Magento\Catalog\Model\Product; +/** + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ class Matrix extends \Magento\Backend\Block\Template { /** @@ -63,6 +66,11 @@ class Matrix extends \Magento\Backend\Block\Template */ protected $stockItemService; + /** + * @var \Magento\ConfigurableProduct\Model\Product\Type\VariationMatrix + */ + protected $variationMatrix; + /** * @param \Magento\Backend\Block\Template\Context $context * @param \Magento\ConfigurableProduct\Model\Product\Type\Configurable $configurableType @@ -71,6 +79,7 @@ class Matrix extends \Magento\Backend\Block\Template * @param \Magento\Framework\Registry $coreRegistry * @param \Magento\Framework\Locale\CurrencyInterface $localeCurrency * @param \Magento\CatalogInventory\Service\V1\StockItemServiceInterface $stockItemService + * @param \Magento\ConfigurableProduct\Model\Product\Type\VariationMatrix $variationMatrix * @param array $data */ public function __construct( @@ -81,8 +90,10 @@ class Matrix extends \Magento\Backend\Block\Template \Magento\Framework\Registry $coreRegistry, \Magento\Framework\Locale\CurrencyInterface $localeCurrency, \Magento\CatalogInventory\Service\V1\StockItemServiceInterface $stockItemService, + \Magento\ConfigurableProduct\Model\Product\Type\VariationMatrix $variationMatrix, array $data = array() ) { + parent::__construct($context, $data); $this->_configurableType = $configurableType; $this->_productFactory = $productFactory; $this->_config = $config; @@ -90,6 +101,7 @@ class Matrix extends \Magento\Backend\Block\Template $this->_localeCurrency = $localeCurrency; $this->stockItemService = $stockItemService; parent::__construct($context, $data); + $this->variationMatrix = $variationMatrix; } /** @@ -121,60 +133,10 @@ class Matrix extends \Magento\Backend\Block\Template * Retrieve all possible attribute values combinations * * @return array - * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ public function getVariations() { - $variationalAttributes = array(); - $usedProductAttributes = $this->getAttributes(); - foreach ($usedProductAttributes as $attribute) { - $options = array(); - foreach ($attribute['options'] as $valueInfo) { - foreach ($attribute['values'] as $priceData) { - if ($priceData['value_index'] == $valueInfo['value'] && (!isset( - $priceData['include'] - ) || $priceData['include']) - ) { - $valueInfo['price'] = $priceData; - $options[] = $valueInfo; - } - } - } - /** @var $attribute \Magento\Catalog\Model\Resource\Eav\Attribute */ - $variationalAttributes[] = array('id' => $attribute['attribute_id'], 'values' => $options); - } - - $attributesCount = count($variationalAttributes); - if ($attributesCount === 0) { - return array(); - } - - $variations = array(); - $currentVariation = array_fill(0, $attributesCount, 0); - $variationalAttributes = array_reverse($variationalAttributes); - $lastAttribute = $attributesCount - 1; - do { - for ($attributeIndex = 0; $attributeIndex < $attributesCount - 1; ++$attributeIndex) { - if ($currentVariation[$attributeIndex] >= count($variationalAttributes[$attributeIndex]['values'])) { - $currentVariation[$attributeIndex] = 0; - ++$currentVariation[$attributeIndex + 1]; - } - } - if ($currentVariation[$lastAttribute] >= count($variationalAttributes[$lastAttribute]['values'])) { - break; - } - - $filledVariation = array(); - for ($attributeIndex = $attributesCount; $attributeIndex--;) { - $currentAttribute = $variationalAttributes[$attributeIndex]; - $currentVariationValue = $currentVariation[$attributeIndex]; - $filledVariation[$currentAttribute['id']] = $currentAttribute['values'][$currentVariationValue]; - } - - $variations[] = $filledVariation; - $currentVariation[0]++; - } while (1); - return $variations; + return $this->variationMatrix->getVariations($this->getAttributes()); } /** @@ -200,15 +162,14 @@ class Matrix extends \Magento\Backend\Block\Template $productData = (array)$this->getRequest()->getParam('product'); if (isset($productData['configurable_attributes_data'])) { $configurableData = $productData['configurable_attributes_data']; - foreach ($attributes as $key => &$attribute) { + foreach ($attributes as $key => $attribute) { if (isset($configurableData[$key])) { - $attribute['values'] = array_merge( + $attributes[$key] = array_replace_recursive($attribute, $configurableData[$key]); + $attributes[$key]['values'] = array_merge( isset($attribute['values']) ? $attribute['values'] : array(), - isset( - $configurableData[$key]['values'] - ) ? array_filter( - $configurableData[$key]['values'] - ) : array() + isset($configurableData[$key]['values']) + ? array_filter($configurableData[$key]['values']) + : array() ); } } diff --git a/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Super/Config/Simple.php b/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Super/Config/Simple.php deleted file mode 100644 index 38d234e96bac7d79ab68b38dcee63ff5c7bfa0be..0000000000000000000000000000000000000000 --- a/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Super/Config/Simple.php +++ /dev/null @@ -1,250 +0,0 @@ -<?php -/** - * Magento - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://opensource.org/licenses/osl-3.0.php - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@magentocommerce.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade Magento to newer - * versions in the future. If you wish to customize Magento for your - * needs please refer to http://www.magentocommerce.com for more information. - * - * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) - */ - -/** - * Quick simple product creation - */ -namespace Magento\ConfigurableProduct\Block\Adminhtml\Product\Edit\Tab\Super\Config; - -use Magento\Catalog\Model\Product; -use Magento\Catalog\Model\ProductFactory; - -class Simple extends \Magento\Catalog\Block\Adminhtml\Product\Edit\Tab\Attributes -{ - /** - * Link to currently editing product - * - * @var Product - */ - protected $_product = null; - - /** - * @var ProductFactory - */ - protected $_productFactory; - - /** - * @param \Magento\Backend\Block\Template\Context $context - * @param \Magento\Framework\Registry $registry - * @param \Magento\Framework\Data\FormFactory $formFactory - * @param \Magento\Cms\Model\Wysiwyg\Config $wysiwygConfig - * @param \Magento\Catalog\Helper\Data $catalogData - * @param ProductFactory $productFactory - * @param array $data - */ - public function __construct( - \Magento\Backend\Block\Template\Context $context, - \Magento\Framework\Registry $registry, - \Magento\Framework\Data\FormFactory $formFactory, - \Magento\Cms\Model\Wysiwyg\Config $wysiwygConfig, - \Magento\Catalog\Helper\Data $catalogData, - ProductFactory $productFactory, - array $data = array() - ) { - $this->_productFactory = $productFactory; - parent::__construct($context, $registry, $formFactory, $wysiwygConfig, $catalogData, $data); - } - - /** - * Prepare form - * - * @return null|void - * @SuppressWarnings(PHPMD.CyclomaticComplexity) - * @SuppressWarnings(PHPMD.ExcessiveMethodLength) - */ - protected function _prepareForm() - { - /** @var \Magento\Framework\Data\Form $form */ - $form = $this->_formFactory->create(); - - $form->setFieldNameSuffix('simple_product'); - $form->setDataObject($this->getProduct()); - - $fieldset = $form->addFieldset('simple_product', array('legend' => __('Quick simple product creation'))); - $this->_addElementTypes($fieldset); - $attributesConfig = array( - 'autogenerate' => array('name', 'sku'), - 'additional' => array('name', 'sku', 'visibility', 'status') - ); - - $availableTypes = array('text', 'select', 'multiselect', 'textarea', 'price', 'weight'); - - $attributes = $this->_productFactory->create()->setTypeId( - \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE - )->setAttributeSetId( - $this->getProduct()->getAttributeSetId() - )->getAttributes(); - - /* Standard attributes */ - foreach ($attributes as $attribute) { - if (($attribute->getIsRequired() && $attribute->getApplyTo() - // If not applied to configurable - && !in_array( - \Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE, - $attribute->getApplyTo() - ) - // If not used in configurable - && !in_array( - $attribute->getId(), - $this->getProduct()->getTypeInstance()->getUsedProductAttributeIds($this->getProduct()) - ) - ) - // Or in additional - || in_array($attribute->getAttributeCode(), $attributesConfig['additional']) - ) { - $inputType = $attribute->getFrontend()->getInputType(); - if (!in_array($inputType, $availableTypes)) { - continue; - } - $attributeCode = $attribute->getAttributeCode(); - $attribute->setAttributeCode('simple_product_' . $attributeCode); - $element = $fieldset->addField( - 'simple_product_' . $attributeCode, - $inputType, - array( - 'label' => $attribute->getFrontend()->getLabel(), - 'name' => $attributeCode, - 'required' => $attribute->getIsRequired() - ) - )->setEntityAttribute( - $attribute - ); - - if (in_array($attributeCode, $attributesConfig['autogenerate'])) { - $element->setDisabled('true'); - $element->setValue($this->getProduct()->getData($attributeCode)); - $element->setAfterElementHtml( - '<input type="checkbox" id="simple_product_' . - $attributeCode . - '_autogenerate" ' . - 'name="simple_product[' . - $attributeCode . - '_autogenerate]" value="1" ' . - 'onclick="toggleValueElements(this, this.parentNode)" checked="checked" /> ' . - '<label for="simple_product_' . - $attributeCode . - '_autogenerate" >' . - __( - 'Autogenerate' - ) . '</label>' - ); - } - - - if ($inputType == 'select' || $inputType == 'multiselect') { - $element->setValues($attribute->getFrontend()->getSelectOptions()); - } - } - } - - /* Configurable attributes */ - $usedAttributes = $this->getProduct()->getTypeInstance()->getUsedProductAttributes($this->getProduct()); - foreach ($usedAttributes as $attribute) { - $attributeCode = $attribute->getAttributeCode(); - $fieldset->addField( - 'simple_product_' . $attributeCode, - 'select', - array( - 'label' => $attribute->getFrontend()->getLabel(), - 'name' => $attributeCode, - 'values' => $attribute->getSource()->getAllOptions(true, true), - 'required' => true, - 'class' => 'validate-configurable', - 'onchange' => 'superProduct.showPricing(this, \'' . $attributeCode . '\')' - ) - ); - - $fieldset->addField( - 'simple_product_' . $attributeCode . '_pricing_value', - 'hidden', - array('name' => 'pricing[' . $attributeCode . '][value]') - ); - - $fieldset->addField( - 'simple_product_' . $attributeCode . '_pricing_type', - 'hidden', - array('name' => 'pricing[' . $attributeCode . '][is_percent]') - ); - } - - /* Inventory Data */ - $fieldset->addField( - 'simple_product_inventory_qty', - 'text', - array( - 'label' => __('Qty'), - 'name' => 'stock_data[qty]', - 'class' => 'validate-number', - 'required' => true, - 'value' => 0 - ) - ); - - $fieldset->addField( - 'simple_product_inventory_is_in_stock', - 'select', - array( - 'label' => __('Stock Availability'), - 'name' => 'stock_data[is_in_stock]', - 'values' => array( - array('value' => 1, 'label' => __('In Stock')), - array('value' => 0, 'label' => __('Out of Stock')) - ), - 'value' => 1 - ) - ); - - $stockHiddenFields = array( - 'use_config_min_qty' => 1, - 'use_config_min_sale_qty' => 1, - 'use_config_max_sale_qty' => 1, - 'use_config_backorders' => 1, - 'use_config_notify_stock_qty' => 1, - 'is_qty_decimal' => 0 - ); - - foreach ($stockHiddenFields as $fieldName => $fieldValue) { - $fieldset->addField( - 'simple_product_inventory_' . $fieldName, - 'hidden', - array('name' => 'stock_data[' . $fieldName . ']', 'value' => $fieldValue) - ); - } - - $this->setForm($form); - } - - /** - * Retrieve currently edited product object - * - * @return Product - */ - public function getProduct() - { - if (!$this->_product) { - $this->_product = $this->_coreRegistry->registry('current_product'); - } - return $this->_product; - } -} diff --git a/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Builder/Plugin.php b/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Builder/Plugin.php index 0a86b955948898a8e8b6575636176c2f51199b3a..2f8ea42594c219e5e2aae3673f703545ee53974b 100644 --- a/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Builder/Plugin.php +++ b/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Builder/Plugin.php @@ -85,16 +85,10 @@ class Plugin } } - if ($request->getParam( - 'popup' - ) && $request->getParam( - 'product' - ) && !is_array( - $request->getParam('product') - ) && $request->getParam( - 'id', - false - ) === false + if ($request->getParam('popup') + && $request->getParam('product') + && !is_array($request->getParam('product')) + && $request->getParam('id', false) === false ) { $configProduct = $this->productFactory->create(); $configProduct->setStoreId(0)->load($request->getParam('product'))->setTypeId($request->getParam('type')); diff --git a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php index 62c0296a03e3b244a5e74cd08fbac3def800899b..040930fe74861d9a85b8d1f39104c61d16dc710d 100644 --- a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php +++ b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php @@ -359,7 +359,7 @@ class Configurable extends \Magento\Catalog\Model\Product\Type\AbstractType * Retrieve configurable attributes data * * @param \Magento\Catalog\Model\Product $product - * @return array + * @return \Magento\ConfigurableProduct\Model\Product\Type\Configurable\Attribute[] */ public function getConfigurableAttributes($product) { @@ -455,11 +455,9 @@ class Configurable extends \Magento\Catalog\Model\Product\Type\AbstractType } $usedProducts = array(); - $collection = $this->getUsedProductCollection( - $product - )->addAttributeToSelect( - '*' - )->addFilterByRequiredOptions(); + $collection = $this->getUsedProductCollection($product)->addAttributeToSelect('*') + ->addFilterByRequiredOptions() + ->setStoreId($product->getStoreId()); if (is_array($requiredAttributeIds)) { foreach ($requiredAttributeIds as $attributeId) { diff --git a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Plugin.php b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Plugin.php index 3b3ae2f8e0ffbc49687d800b4b106b03c9225533..648a6f3b09de5983a18690e5adf95a843e63e3a7 100644 --- a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Plugin.php +++ b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Plugin.php @@ -42,7 +42,7 @@ class Plugin } /** - * Remove grouped product from list of visible product types + * Remove configurable product type from list of visible product types * * @param \Magento\Catalog\Model\Product\Type $subject * @param array $result diff --git a/app/code/Magento/ConfigurableProduct/Model/Product/Type/VariationMatrix.php b/app/code/Magento/ConfigurableProduct/Model/Product/Type/VariationMatrix.php new file mode 100644 index 0000000000000000000000000000000000000000..18f93795bf5f281be11d7ea03e9f3d53887d7a11 --- /dev/null +++ b/app/code/Magento/ConfigurableProduct/Model/Product/Type/VariationMatrix.php @@ -0,0 +1,110 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\ConfigurableProduct\Model\Product\Type; + +class VariationMatrix +{ + /** + * Generate matrix of variation + * + * @param array $usedProductAttributes + * @return array + */ + public function getVariations($usedProductAttributes) + { + $variationalAttributes = $this->combineVariationalAttributes($usedProductAttributes); + + $attributesCount = count($variationalAttributes); + if ($attributesCount === 0) { + return []; + } + + $variations = []; + $currentVariation = array_fill(0, $attributesCount, 0); + $variationalAttributes = array_reverse($variationalAttributes); + $lastAttribute = $attributesCount - 1; + do { + $this->incrementVariationalIndex($attributesCount, $variationalAttributes, $currentVariation); + if ($currentVariation[$lastAttribute] >= count($variationalAttributes[$lastAttribute]['values'])) { + break; + } + + $filledVariation = []; + for ($attributeIndex = $attributesCount; $attributeIndex--;) { + $currentAttribute = $variationalAttributes[$attributeIndex]; + $currentVariationValue = $currentVariation[$attributeIndex]; + $filledVariation[$currentAttribute['id']] = $currentAttribute['values'][$currentVariationValue]; + } + + $variations[] = $filledVariation; + $currentVariation[0]++; + } while (true); + + return $variations; + } + + /** + * Combine variational attributes + * + * @param array $usedProductAttributes + * @return array + */ + private function combineVariationalAttributes($usedProductAttributes) + { + $variationalAttributes = []; + foreach ($usedProductAttributes as $attribute) { + $options = array(); + foreach ($attribute['options'] as $valueInfo) { + foreach ($attribute['values'] as $priceData) { + if ($priceData['value_index'] == $valueInfo['value'] + && (!isset($priceData['include']) || $priceData['include']) + ) { + $valueInfo['price'] = $priceData; + $options[] = $valueInfo; + } + } + } + $variationalAttributes[] = array('id' => $attribute['attribute_id'], 'values' => $options); + } + return $variationalAttributes; + } + + /** + * Increment index in variation with shift if overflow + * + * @param int $attributesCount + * @param array $variationalAttributes + * @param array $currentVariation + * @return void + */ + private function incrementVariationalIndex($attributesCount, $variationalAttributes, &$currentVariation) + { + for ($attributeIndex = 0; $attributeIndex < $attributesCount - 1; ++$attributeIndex) { + if ($currentVariation[$attributeIndex] >= count($variationalAttributes[$attributeIndex]['values'])) { + $currentVariation[$attributeIndex] = 0; + ++$currentVariation[$attributeIndex + 1]; + } + } + } +} diff --git a/app/code/Magento/ConfigurableProduct/Service/V1/Data/ConfigurableAttribute.php b/app/code/Magento/ConfigurableProduct/Service/V1/Data/ConfigurableAttribute.php new file mode 100644 index 0000000000000000000000000000000000000000..99e92729f394e705900da888d17d7aa82561537a --- /dev/null +++ b/app/code/Magento/ConfigurableProduct/Service/V1/Data/ConfigurableAttribute.php @@ -0,0 +1,74 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\ConfigurableProduct\Service\V1\Data; + +class ConfigurableAttribute extends \Magento\Framework\Service\Data\AbstractObject +{ + const ID = 'id'; + const LABEL = 'label'; + const USE_DEFAULT = 'use_default'; + const POSITION = 'position'; + const VALUES = 'values'; + const ATTRIBUTE_ID = 'attribute_id'; + + /** + * @return int|null + */ + public function getId() + { + return $this->_get(self::ID); + } + + /** + * @return string + */ + public function getAttributeId() + { + return $this->_get(self::ATTRIBUTE_ID); + } + + /** + * @return string|null + */ + public function getLabel() + { + return $this->_get(self::LABEL); + } + + /** + * @return bool|null + */ + public function isUseDefault() + { + return $this->_get(self::USE_DEFAULT); + } + + /** + * @return \Magento\ConfigurableProduct\Service\V1\Data\ConfigurableAttribute\Value[] + */ + public function getValues() + { + return $this->_get(self::VALUES); + } +} diff --git a/app/code/Magento/ConfigurableProduct/Service/V1/Data/ConfigurableAttribute/Value.php b/app/code/Magento/ConfigurableProduct/Service/V1/Data/ConfigurableAttribute/Value.php new file mode 100644 index 0000000000000000000000000000000000000000..6b88e10b4ac8b6f335ced46690ecc0e14087c1d8 --- /dev/null +++ b/app/code/Magento/ConfigurableProduct/Service/V1/Data/ConfigurableAttribute/Value.php @@ -0,0 +1,55 @@ +<?php +namespace Magento\ConfigurableProduct\Service\V1\Data\ConfigurableAttribute; + +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +class Value extends \Magento\Framework\Service\Data\AbstractObject +{ + const INDEX = 'value_index'; + const PRICE = 'pricing_value'; + const PRICE_IS_PERCENT = 'is_percent'; + + /** + * @return float|null + */ + public function getPrice() + { + return $this->_get(self::PRICE); + } + + /** + * @return int|null + */ + public function getPriceIsPercent() + { + return $this->_get(self::PRICE_IS_PERCENT); + } + + /** + * @return int + */ + public function getIndex() + { + return $this->_get(self::INDEX); + } +} diff --git a/app/code/Magento/ConfigurableProduct/Service/V1/Data/ConfigurableAttribute/ValueBuilder.php b/app/code/Magento/ConfigurableProduct/Service/V1/Data/ConfigurableAttribute/ValueBuilder.php new file mode 100644 index 0000000000000000000000000000000000000000..511e1c33b15f7296a58870a5e4e0afc10ab8237f --- /dev/null +++ b/app/code/Magento/ConfigurableProduct/Service/V1/Data/ConfigurableAttribute/ValueBuilder.php @@ -0,0 +1,56 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\ConfigurableProduct\Service\V1\Data\ConfigurableAttribute; + +use Magento\Framework\Service\Data\AbstractObjectBuilder; + +class ValueBuilder extends AbstractObjectBuilder +{ + /** + * @param float $value + * @return self + */ + public function setPrice($value) + { + return $this->_set(Value::PRICE, $value); + } + + /** + * @param int $value + * @return self + */ + public function setPriceIsPercent($value) + { + return $this->_set(Value::PRICE_IS_PERCENT, $value); + } + + /** + * @param int $value + * @return self + */ + public function setIndex($value) + { + return $this->_set(Value::INDEX, $value); + } +} diff --git a/app/code/Magento/ConfigurableProduct/Service/V1/Data/ConfigurableAttributeBuilder.php b/app/code/Magento/ConfigurableProduct/Service/V1/Data/ConfigurableAttributeBuilder.php new file mode 100644 index 0000000000000000000000000000000000000000..a50a266156f4f1a7bd39c0ca8b30f1a9c7d107ed --- /dev/null +++ b/app/code/Magento/ConfigurableProduct/Service/V1/Data/ConfigurableAttributeBuilder.php @@ -0,0 +1,72 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\ConfigurableProduct\Service\V1\Data; + +class ConfigurableAttributeBuilder extends \Magento\Framework\Service\Data\AbstractObjectBuilder +{ + /** + * @param int $value + * @return self + */ + public function setId($value) + { + return $this->_set(ConfigurableAttribute::ID, $value); + } + + /** + * @param string $value + * @return self + */ + public function setAttributeId($value) + { + return $this->_set(ConfigurableAttribute::ATTRIBUTE_ID, $value); + } + + /** + * @param string $value + * @return self + */ + public function setLabel($value) + { + return $this->_set(ConfigurableAttribute::LABEL, $value); + } + + /** + * @param bool $value + * @return self + */ + public function useDefault($value) + { + return $this->_set(ConfigurableAttribute::USE_DEFAULT, $value); + } + + /** + * @param \Magento\ConfigurableProduct\Service\V1\Data\ConfigurableAttribute\Value[] $value + * @return self + */ + public function setValues($value) + { + return $this->_set(ConfigurableAttribute::VALUES, $value); + } +} diff --git a/app/code/Magento/ConfigurableProduct/Service/V1/Product/Link/ReadService.php b/app/code/Magento/ConfigurableProduct/Service/V1/Product/Link/ReadService.php new file mode 100644 index 0000000000000000000000000000000000000000..c1729e605fff2ad82127bf7b7dfca72796467408 --- /dev/null +++ b/app/code/Magento/ConfigurableProduct/Service/V1/Product/Link/ReadService.php @@ -0,0 +1,79 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\ConfigurableProduct\Service\V1\Product\Link; + +use Magento\Catalog\Model\Product; +use Magento\Catalog\Model\ProductRepository; +use Magento\Catalog\Service\V1\Data\Converter; + +class ReadService implements ReadServiceInterface +{ + /** + * @var \Magento\Catalog\Model\ProductRepository + */ + private $productRepository; + + /** + * @var Converter + */ + private $productConverter; + + /** + * @param ProductRepository $productRepository + * @param Converter $productConverter + */ + public function __construct( + ProductRepository $productRepository, + Converter $productConverter + ) { + $this->productRepository = $productRepository; + $this->productConverter = $productConverter; + } + + /** + * {@inheritdoc} + */ + public function getChildren($productId) + { + $product = $this->productRepository->get($productId); + if ($product->getTypeId() != \Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE) { + return []; + } + + $childrenList = []; + + /** @var \Magento\ConfigurableProduct\Model\Product\Type\Configurable $productTypeInstance */ + $productTypeInstance = $product->getTypeInstance(); + $productTypeInstance->setStoreFilter( + $product->getStoreId(), + $product + ); + + foreach ($productTypeInstance->getUsedProducts($product) as $child) { + $childrenList[] = $this->productConverter->createProductDataFromModel($child); + } + + return $childrenList; + } +} diff --git a/app/code/Magento/ConfigurableProduct/Service/V1/Product/Link/ReadServiceInterface.php b/app/code/Magento/ConfigurableProduct/Service/V1/Product/Link/ReadServiceInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..fbed7b387fb580c7c905553893a0ce5ce53e9a52 --- /dev/null +++ b/app/code/Magento/ConfigurableProduct/Service/V1/Product/Link/ReadServiceInterface.php @@ -0,0 +1,36 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\ConfigurableProduct\Service\V1\Product\Link; + + +interface ReadServiceInterface +{ + /** + * Get all children for Bundle product + * + * @param string $productId + * @return \Magento\Catalog\Service\V1\Data\Product[] + */ + public function getChildren($productId); +} diff --git a/app/code/Magento/ConfigurableProduct/Service/V1/Product/Link/WriteService.php b/app/code/Magento/ConfigurableProduct/Service/V1/Product/Link/WriteService.php new file mode 100644 index 0000000000000000000000000000000000000000..a013337833146db23303c66279316ddcfbc32bad --- /dev/null +++ b/app/code/Magento/ConfigurableProduct/Service/V1/Product/Link/WriteService.php @@ -0,0 +1,107 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\ConfigurableProduct\Service\V1\Product\Link; + +use \Magento\Catalog\Model\ProductRepository; +use \Magento\ConfigurableProduct\Model\Resource\Product\Type\Configurable; +use Magento\Framework\Exception\StateException; +use Magento\Catalog\Model\Product; +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Webapi\Exception; + +class WriteService implements WriteServiceInterface +{ + /** + * @var \Magento\Catalog\Model\ProductRepository + */ + protected $productRepository; + + /** + * @var Configurable + */ + protected $configurableType; + + /** + * @param ProductRepository $productRepository + * @param Configurable $configurableType + * @internal param ConfigurableFactory $typeConfigurableFactory + */ + public function __construct( + ProductRepository $productRepository, + Configurable $configurableType + ) { + $this->productRepository = $productRepository; + $this->configurableType = $configurableType; + } + + /** + * {@inheritdoc} + */ + public function addChild($productSku, $childSku) + { + $product = $this->productRepository->get($productSku); + $child = $this->productRepository->get($childSku); + + $childrenIds = array_values($this->configurableType->getChildrenIds($product->getId())[0]); + if (in_array($child->getId(), $childrenIds)) { + throw new StateException('Product has been already attached'); + } + + $childrenIds[] = $child->getId(); + $product->setAssociatedProductIds($childrenIds); + $product->save(); + return true; + } + + /** + * {@inheritdoc} + */ + public function removeChild($productSku, $childSku) + { + $product = $this->productRepository->get($productSku); + + if ($product->getTypeId() != \Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE) { + throw new Exception( + sprintf('Product with specified sku: %s is not a configurable product', $productSku), + Exception::HTTP_FORBIDDEN + ); + } + + $options = $product->getTypeInstance()->getUsedProducts($product); + $ids = array(); + foreach ($options as $option) { + if ($option->getSku() == $childSku) { + continue; + } + $ids[] = $option->getId(); + } + if (count($options) == count($ids)) { + throw new NoSuchEntityException('Requested option doesn\'t exist'); + } + $product->addData(['associated_product_ids' => $ids]); + $product->save(); + + return true; + } +} diff --git a/app/code/Magento/ConfigurableProduct/Service/V1/Product/Link/WriteServiceInterface.php b/app/code/Magento/ConfigurableProduct/Service/V1/Product/Link/WriteServiceInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..edbb1b0fdff8a2ccf5f99c86fad8b394ee8fb051 --- /dev/null +++ b/app/code/Magento/ConfigurableProduct/Service/V1/Product/Link/WriteServiceInterface.php @@ -0,0 +1,45 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\ConfigurableProduct\Service\V1\Product\Link; + +interface WriteServiceInterface +{ + /** + * @param string $productSku + * @param string $childSku + * @return bool + */ + public function addChild($productSku, $childSku); + + /** + * Remove configurable product option + * + * @param string $productSku + * @param string $childSku + * @throws \Magento\Framework\Exception\NoSuchEntityException + * @throws \Magento\Webapi\Exception + * @return bool + */ + public function removeChild($productSku, $childSku); +} diff --git a/app/code/Magento/ConfigurableProduct/Service/V1/ReadService.php b/app/code/Magento/ConfigurableProduct/Service/V1/ReadService.php new file mode 100644 index 0000000000000000000000000000000000000000..d79190379d38b2a7a4bd79fa89cd80ac2db69679 --- /dev/null +++ b/app/code/Magento/ConfigurableProduct/Service/V1/ReadService.php @@ -0,0 +1,126 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\ConfigurableProduct\Service\V1; + +use Magento\Catalog\Service\V1\Data\Product; +use Magento\Catalog\Service\V1\Data\ProductBuilder; +use Magento\Catalog\Service\V1\Product\Attribute; +use Magento\ConfigurableProduct\Model\Product\Type\VariationMatrix; + +class ReadService implements ReadServiceInterface +{ + /** + * @var VariationMatrix + */ + private $variationMatrix; + + /** + * @var ProductBuilder + */ + private $productBuilder; + + /** + * @var Attribute\ReadServiceInterface + */ + private $attributeReadService; + + /** + * @param Attribute\ReadServiceInterface $attributeReadService + * @param ProductBuilder $productBuilder + * @param VariationMatrix $variationMatrix + */ + public function __construct( + Attribute\ReadServiceInterface $attributeReadService, + ProductBuilder $productBuilder, + VariationMatrix $variationMatrix + ) { + $this->variationMatrix = $variationMatrix; + $this->productBuilder = $productBuilder; + $this->attributeReadService = $attributeReadService; + } + + /** + * {@inheritdoc} + */ + public function generateVariation(Product $product, $configurableAttributes) + { + $attributes = $this->getAttributesForMatrix($configurableAttributes); + $variations = $this->variationMatrix->getVariations($attributes); + $products = $this->populateProductVariation($product, $variations, $attributes); + return $products; + } + + /** + * Prepare attribute info for variation matrix generation + * + * @param \Magento\ConfigurableProduct\Service\V1\Data\ConfigurableAttribute[] $configurableAttributes + * @return array + */ + private function getAttributesForMatrix($configurableAttributes) + { + $attributes = []; + foreach ($configurableAttributes as $configurableAttribute) { + $configurable = $configurableAttribute->__toArray(); + $attribute = $this->attributeReadService->info($configurableAttribute->getAttributeId()); + $configurable['options'] = $attribute->__toArray()['options']; + $configurable['attribute_code'] = $attribute->getAttributeCode(); + $attributes[$configurableAttribute->getAttributeId()] = $configurable; + } + return $attributes; + } + + /** + * Populate product with variation of attributes + * + * @param Product $product + * @param array $variations + * @param array $attributes + * @return array + */ + private function populateProductVariation(Product $product, $variations, $attributes) + { + $products = []; + foreach ($variations as $attributeId => $variation) { + $price = $product->getPrice(); + $this->productBuilder->populate($product); + $suffix = ''; + foreach ($variation as $attributeId => $valueInfo) { + $suffix .= '-' . $valueInfo['value']; + $this->productBuilder->setCustomAttribute( + $attributes[$attributeId]['attribute_code'], + $valueInfo['value'] + ); + $priceInfo = $valueInfo['price']; + $price += (!empty($priceInfo['is_percent']) ? $product->getPrice() / 100.0 : 1.0) + * $priceInfo['pricing_value']; + } + $this->productBuilder->setPrice($price); + $this->productBuilder->setName($product->getName() . $suffix); + $this->productBuilder->setSku($product->getSku() . $suffix); + $this->productBuilder->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_NOT_VISIBLE); + $products[] = $this->productBuilder->create(); + } + return $products; + } +} diff --git a/app/code/Magento/ConfigurableProduct/Service/V1/ReadServiceInterface.php b/app/code/Magento/ConfigurableProduct/Service/V1/ReadServiceInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..49ac8f1ff90f143624ab5a3baf68a2a170ed60de --- /dev/null +++ b/app/code/Magento/ConfigurableProduct/Service/V1/ReadServiceInterface.php @@ -0,0 +1,39 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\ConfigurableProduct\Service\V1; + +interface ReadServiceInterface +{ + /** + * Generate variation based on same product + * + * @param \Magento\Catalog\Service\V1\Data\Product $product + * @param \Magento\ConfigurableProduct\Service\V1\Data\ConfigurableAttribute[] $configurableAttributes + * @return \Magento\Catalog\Service\V1\Data\Product[] + */ + public function generateVariation( + \Magento\Catalog\Service\V1\Data\Product $product, + $configurableAttributes + ); +} diff --git a/app/code/Magento/ConfigurableProduct/etc/di.xml b/app/code/Magento/ConfigurableProduct/etc/di.xml index 35789f99cbee9806ca1d6eee5f9420def464a0a9..472fdd85bdc1eb857a6c76bd10c34545d5588c82 100644 --- a/app/code/Magento/ConfigurableProduct/etc/di.xml +++ b/app/code/Magento/ConfigurableProduct/etc/di.xml @@ -24,6 +24,9 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd"> + <preference for="Magento\ConfigurableProduct\Service\V1\Product\Link\ReadServiceInterface" type="Magento\ConfigurableProduct\Service\V1\Product\Link\ReadService" /> + <preference for="Magento\ConfigurableProduct\Service\V1\Product\Link\WriteServiceInterface" type="Magento\ConfigurableProduct\Service\V1\Product\Link\WriteService" /> + <preference for="Magento\ConfigurableProduct\Service\V1\ReadServiceInterface" type="Magento\ConfigurableProduct\Service\V1\ReadService" /> <type name="Magento\CatalogInventory\Model\Quote\Item\QuantityValidator\Initializer\Option"> <plugin name="configurable_product" type="Magento\ConfigurableProduct\Model\Quote\Item\QuantityValidator\Initializer\Option\Plugin\ConfigurableProduct" sortOrder="50" /> </type> diff --git a/app/code/Magento/ConfigurableProduct/etc/module.xml b/app/code/Magento/ConfigurableProduct/etc/module.xml index 7601658945adb91731dd8a60c247e99213dc93e4..71ed9ee44314bda417fd1aa6420b9e5da6a98b26 100644 --- a/app/code/Magento/ConfigurableProduct/etc/module.xml +++ b/app/code/Magento/ConfigurableProduct/etc/module.xml @@ -42,12 +42,12 @@ <module name="Magento_Theme" /> <module name="Magento_Backend" /> <module name="Magento_Eav" /> - <module name="Magento_Cms" /> <module name="Magento_Customer" /> <module name="Magento_CatalogRule" /> <module name="Magento_Directory" /> <module name="Magento_Weee" /> <module name="Magento_RequireJs" /> + <module name="Magento_Webapi"/> </depends> </module> </config> diff --git a/app/code/Magento/ConfigurableProduct/etc/webapi.xml b/app/code/Magento/ConfigurableProduct/etc/webapi.xml new file mode 100644 index 0000000000000000000000000000000000000000..fd11c2f6b29fa57723920d2784465e14c0596480 --- /dev/null +++ b/app/code/Magento/ConfigurableProduct/etc/webapi.xml @@ -0,0 +1,52 @@ +<?xml version="1.0"?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../app/code/Magento/Webapi/etc/webapi.xsd"> + <route url="/V1/configurable-products/:productId/children" method="GET"> + <service class="Magento\ConfigurableProduct\Service\V1\Product\Link\ReadServiceInterface" method="getChildren"/> + <resources> + <resource ref="Magento_Catalog::products"/> + </resources> + </route> + <route url="/V1/configurable-products/:productSku/child/:childSku" method="DELETE"> + <service class="Magento\ConfigurableProduct\Service\V1\Product\Link\WriteServiceInterface" method="removeChild"/> + <resources> + <resource ref="Magento_Catalog::products"/> + </resources> + </route> + <route url="/V1/configurable-products/variation" method="PUT"> + <service class="Magento\ConfigurableProduct\Service\V1\ReadServiceInterface" method="generateVariation" /> + <resources> + <resource ref="Magento_Catalog::products" /> + </resources> + </route> + <route url="/V1/configurable-products/:productSku/child" method="POST"> + <service class="Magento\ConfigurableProduct\Service\V1\Product\Link\WriteServiceInterface" method="addChild" /> + <resources> + <resource ref="Magento_Catalog::products" /> + </resources> + </route> +</routes> diff --git a/app/code/Magento/Core/Model/View/Design.php b/app/code/Magento/Core/Model/View/Design.php index 8bfb62a8be3be845b74a37f5e50bf472894b5a7e..7d7d7bf61ca6210d5917fe82c4379169999bea3e 100644 --- a/app/code/Magento/Core/Model/View/Design.php +++ b/app/code/Magento/Core/Model/View/Design.php @@ -22,11 +22,11 @@ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ +namespace Magento\Core\Model\View; + /** * Keeps design settings for current request */ -namespace Magento\Core\Model\View; - class Design implements \Magento\Framework\View\DesignInterface { /** @@ -177,14 +177,18 @@ class Design implements \Magento\Framework\View\DesignInterface $store = isset($params['store']) ? $params['store'] : null; if ($this->_isThemePerStoveView($area)) { - $theme = $this->_storeManager->isSingleStoreMode() ? $this->_scopeConfig->getValue( - self::XML_PATH_THEME_ID, - \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT - ) : (string)$this->_scopeConfig->getValue( - self::XML_PATH_THEME_ID, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE, - $store - ); + if ($this->_storeManager->isSingleStoreMode()) { + $theme = $this->_scopeConfig->getValue( + self::XML_PATH_THEME_ID, + \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT + ); + } else { + $theme = (string) $this->_scopeConfig->getValue( + self::XML_PATH_THEME_ID, + \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + $store + ); + } } if (!$theme && isset($this->_themes[$area])) { diff --git a/app/code/Magento/Customer/Block/Adminhtml/Form/Element/Image.php b/app/code/Magento/Customer/Block/Adminhtml/Form/Element/Image.php index 5381bdd33389f0e40e65dfcc1c429713331f3832..fbab79b2aac2c7487c94ff49ae62336ea400faba 100644 --- a/app/code/Magento/Customer/Block/Adminhtml/Form/Element/Image.php +++ b/app/code/Magento/Customer/Block/Adminhtml/Form/Element/Image.php @@ -90,12 +90,9 @@ class Image extends \Magento\Customer\Block\Adminhtml\Form\Element\File */ protected function _getPreviewUrl() { - if (is_array($this->getValue())) { - return false; - } return $this->_adminhtmlData->getUrl( 'customer/index/viewfile', - array('image' => $this->_escaper->urlEncode($this->getValue())) + array('image' => $this->_adminhtmlData->urlEncode($this->getValue())) ); } } diff --git a/app/code/Magento/Customer/view/frontend/templates/account/dashboard/address.phtml b/app/code/Magento/Customer/view/frontend/templates/account/dashboard/address.phtml index 119de95d8f5de7ba0172b9dfd0ec27a1621639e5..b92be230b99e6c8f82cc84b2e84547e86622514c 100644 --- a/app/code/Magento/Customer/view/frontend/templates/account/dashboard/address.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/account/dashboard/address.phtml @@ -24,29 +24,37 @@ /** @var \Magento\Customer\Block\Account\Dashboard\Address $this */ ?> -<div class="block dashboard addresses"> - <div class="title"> +<div class="block block-dashboard-addresses"> + <div class="block-title"> <strong><?php echo __('Address Book') ?></strong> <a class="action edit" href="<?php echo $this->getAddressBookUrl() ?>"><span><?php echo __('Manage Addresses') ?></span></a> </div> - <div class="content"> - <div class="box address billing"> - <strong class="subtitle"> + <div class="block-content"> + <div class="box box-address-billing"> + <strong class="box-title"> <span><?php echo __('Default Billing Address') ?></span> - <a class="action edit" href="<?php echo $this->getPrimaryBillingAddressEditUrl() ?>" data-ui-id="default-billing-edit-link"><span><?php echo __('Edit Address') ?></span></a> </strong> - <address> - <?php echo $this->getPrimaryBillingAddressHtml() ?> - </address> + <div class="box-content"> + <address> + <?php echo $this->getPrimaryBillingAddressHtml() ?> + </address> + </div> + <div class="box-actions"> + <a class="action edit" href="<?php echo $this->getPrimaryBillingAddressEditUrl() ?>" data-ui-id="default-billing-edit-link"><span><?php echo __('Edit Address') ?></span></a> + </div> </div> - <div class="box address shipping"> - <strong class="subtitle"> + <div class="box box-address-shipping"> + <strong class="box-title"> <span><?php echo __('Default Shipping Address') ?></span> - <a class="action edit" href="<?php echo $this->getPrimaryShippingAddressEditUrl() ?>" data-ui-id="default-shipping-edit-link"><span><?php echo __('Edit Address') ?></span></a> </strong> - <address> - <?php echo $this->getPrimaryShippingAddressHtml() ?> - </address> + <div class="box-content"> + <address> + <?php echo $this->getPrimaryShippingAddressHtml() ?> + </address> + </div> + <div class="box-actions"> + <a class="action edit" href="<?php echo $this->getPrimaryShippingAddressEditUrl() ?>" data-ui-id="default-shipping-edit-link"><span><?php echo __('Edit Address') ?></span></a> + </div> </div> </div> </div> diff --git a/app/code/Magento/Customer/view/frontend/templates/account/dashboard/hello.phtml b/app/code/Magento/Customer/view/frontend/templates/account/dashboard/hello.phtml index 26b5a5081c6809a6d34a4e9a81664dec65d2d95b..9ed5b2ffd2b7e843faab8c452178489376dca81f 100644 --- a/app/code/Magento/Customer/view/frontend/templates/account/dashboard/hello.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/account/dashboard/hello.phtml @@ -24,9 +24,9 @@ /** @var \Magento\Customer\Block\Account\Dashboard\Hello $this */ ?> -<div class="block dashboard welcome"> - <div class="title"><strong><?php echo __('Hello, %1!', $this->escapeHtml($this->getCustomerName())) ?></strong></div> - <div class="content"> +<div class="block block-dashboard-welcome"> + <div class="block-title"><strong><?php echo __('Hello, %1!', $this->escapeHtml($this->getCustomerName())) ?></strong></div> + <div class="block-content"> <p><?php echo __('From your My Account Dashboard you have the ability to view a snapshot of your recent account activity and update your account information. Select a link below to view or edit information.') ?></p> </div> </div> diff --git a/app/code/Magento/Customer/view/frontend/templates/account/dashboard/info.phtml b/app/code/Magento/Customer/view/frontend/templates/account/dashboard/info.phtml index 49189b893d8ff95c104a6570a1ebdddcaba02246..4deeac8f86c0a318cf91532f4159e5c5063e2148 100644 --- a/app/code/Magento/Customer/view/frontend/templates/account/dashboard/info.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/account/dashboard/info.phtml @@ -24,35 +24,47 @@ /** @var \Magento\Customer\Block\Account\Dashboard\Info $this */ ?> -<div class="block dashboard info"> - <div class="title"><strong><?php echo __('Account Information') ?></strong></div> - <div class="content"> - <div class="box information"> - <strong class="subtitle"> - <?php echo __('Contact Information') ?> - <a class="action edit" href="<?php echo $this->getUrl('customer/account/edit') ?>"><span><?php echo __('Edit') ?></span></a> +<div class="block block-dashboard-info"> + <div class="block-title"><strong><?php echo __('Account Information') ?></strong></div> + <div class="block-content"> + <div class="box box-information"> + <strong class="box-title"> + <span><?php echo __('Contact Information') ?></span> </strong> - <p> - <?php echo $this->escapeHtml($this->getName()) ?><br> - <?php echo $this->escapeHtml($this->getCustomer()->getEmail()) ?><br> - <a href="<?php echo $this->getChangePasswordUrl() ?>"><?php echo __('Change Password') ?></a> - </p> + <div class="box-content"> + <p> + <?php echo $this->escapeHtml($this->getName()) ?><br> + <?php echo $this->escapeHtml($this->getCustomer()->getEmail()) ?><br> + </p> + </div> + <div class="box-actions"> + <a class="action edit" href="<?php echo $this->getUrl('customer/account/edit') ?>"> + <span><?php echo __('Edit') ?></span> + </a> + <a href="<?php echo $this->getChangePasswordUrl() ?>" class="action change-password"> + <?php echo __('Change Password') ?> + </a> + </div> </div> <?php if( $this->isNewsletterEnabled() ): ?> - <div class="box newsletter"> - <strong class="subtitle"> - <?php echo __('Newsletters') ?> - <a class="action edit" href="<?php echo $this->getUrl('newsletter/manage') ?>"><span><?php echo __('Edit') ?></span></a> + <div class="box box-newsletter"> + <strong class="box-title"> + <span><?php echo __('Newsletters') ?></span> </strong> - <p> - <?php if( $this->getIsSubscribed() ): ?> - <?php echo __("You are currently subscribed to 'General Subscription'.") ?> - <?php else: ?> - <?php echo __('You are currently not subscribed to any newsletter.') ?> - <?php endif; ?> - </p> - <?php /* Extensions placeholder */ ?> - <?php echo $this->getChildHtml('customer.account.dashboard.info.extra')?> + <div class="box-content"> + <p> + <?php if( $this->getIsSubscribed() ): ?> + <?php echo __("You are currently subscribed to 'General Subscription'.") ?> + <?php else: ?> + <?php echo __('You are currently not subscribed to any newsletter.') ?> + <?php endif; ?> + </p> + <?php /* Extensions placeholder */ ?> + <?php echo $this->getChildHtml('customer.account.dashboard.info.extra')?> + </div> + <div class="box-actions"> + <a class="action edit" href="<?php echo $this->getUrl('newsletter/manage') ?>"><span><?php echo __('Edit') ?></span></a> + </div> </div> <?php endif; ?> </div> diff --git a/app/code/Magento/Customer/view/frontend/templates/account/navigation.phtml b/app/code/Magento/Customer/view/frontend/templates/account/navigation.phtml index fbac1f6bf7d055fa554e9ccdb85d48b28c684091..33a10b372e627f2ebfeb7b0d8d119cbcf716d850 100644 --- a/app/code/Magento/Customer/view/frontend/templates/account/navigation.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/account/navigation.phtml @@ -24,12 +24,12 @@ /** @var $this \Magento\Framework\View\Element\Html\Links */ ?> <?php /** @var $this \Magento\Customer\Block\Account\Navigation */ ?> -<div class="block account nav"> +<div class="block account-nav"> <div class="title"> <strong><?php echo __('My Account'); ?></strong> </div> <div class="content"> - <nav class="account nav"> + <nav class="account-nav"> <ul class="nav items"> <?php echo $this->getChildHtml();?> </ul> diff --git a/app/code/Magento/Customer/view/frontend/templates/address/book.phtml b/app/code/Magento/Customer/view/frontend/templates/address/book.phtml index f1b08dcae13b345b3035bb0efc4c30b8fcfdd901..b39c39eb4bed6638d73054103682024f64c46c36 100644 --- a/app/code/Magento/Customer/view/frontend/templates/address/book.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/address/book.phtml @@ -28,52 +28,64 @@ * @var $this \Magento\Customer\Block\Address\Book */ ?> -<div class="block addresses default"> - <div class="title"><strong><?php echo __('Default Addresses') ?></strong></div> - <div class="content"> +<div class="block block-addresses-default"> + <div class="block-title"><strong><?php echo __('Default Addresses') ?></strong></div> + <div class="block-content"> <?php if($_pAddsses = $this->getDefaultBilling()): ?> - <div class="box address billing"> - <strong class="subtitle"> + <div class="box box-address-billing"> + <strong class="box-title"> <span><?php echo __('Default Billing Address') ?></span> + </strong> + <div class="box-content"> + <address> + <?php echo $this->getAddressHtml($this->getAddressById($_pAddsses)) ?> + </address> + </div> + <div class="box-actions"> <a class="action edit" href="<?php echo $this->getAddressEditUrl($_pAddsses) ?>"> <span><?php echo __('Change Billing Address') ?></span> </a> - </strong> - <address> - <?php echo $this->getAddressHtml($this->getAddressById($_pAddsses)) ?> - </address> + </div> </div> <?php else: ?> - <div class="box address billing"> - <strong class="subtitle"><span><?php echo __('Default Billing Address') ?></span></strong> - <p><?php echo __('You have no default billing address in your address book.') ?></p> + <div class="box box-address-billing"> + <strong class="box-title"><span><?php echo __('Default Billing Address') ?></span></strong> + <div class="box-content"> + <p><?php echo __('You have no default billing address in your address book.') ?></p> + </div> </div> <?php endif ?> <?php if($_pAddsses = $this->getDefaultShipping()): ?> - <div class="box address shipping"> - <strong class="subtitle"> + <div class="box box-address-shipping"> + <strong class="box-title"> <span><?php echo __('Default Shipping Address') ?></span> + </strong> + <div class="box-content"> + <address> + <?php echo $this->getAddressHtml($this->getAddressById($_pAddsses)) ?> + </address> + </div> + <div class="box-actions"> <a class="action edit" href="<?php echo $this->getAddressEditUrl($_pAddsses) ?>"> <span><?php echo __('Change Shipping Address') ?></span> </a> - </strong> - <address> - <?php echo $this->getAddressHtml($this->getAddressById($_pAddsses)) ?> - </address> + </div> </div> <?php else: ?> - <div class="box address shipping"> - <strong class="subtitle"><span><?php echo __('Default Shipping Address') ?></span></strong> - <p><?php echo __('You have no default shipping address in your address book.') ?></p> + <div class="box box-address-shipping"> + <strong class="box-title"><span><?php echo __('Default Shipping Address') ?></span></strong> + <div class="box-content"> + <p><?php echo __('You have no default shipping address in your address book.') ?></p> + </div> </div> <?php endif ?> </div> </div> -<div class="block addresses list"> - <div class="title"><strong><?php echo __('Additional Address Entries') ?></strong></div> - <div class="content"> +<div class="block block-addresses-list"> + <div class="block-title"><strong><?php echo __('Additional Address Entries') ?></strong></div> + <div class="block-content"> <?php if($_pAddsses = $this->getAdditionalAddresses()): ?> <ol class="items addresses"> <?php foreach($_pAddsses as $_address): ?> diff --git a/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml b/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml index e33005da72056fae9528e8392a22c0574e449788..3b5617d2d1d78c98cb64fff2af4e09ca13faef10 100644 --- a/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml @@ -29,7 +29,7 @@ * @var $this \Magento\Customer\Block\Address\Edit */ ?> -<form class="form address edit" action="<?php echo $this->getSaveUrl() ?>" method="post" id="form-validate" enctype="multipart/form-data" data-hasrequired="<?php echo __('* Required Fields') ?>"> +<form class="form-address-edit" action="<?php echo $this->getSaveUrl() ?>" method="post" id="form-validate" enctype="multipart/form-data" data-hasrequired="<?php echo __('* Required Fields') ?>"> <fieldset class="fieldset"> <legend class="legend"><span><?php echo __('Contact Information') ?></span></legend><br> <?php echo $this->getBlockHtml('formkey')?> diff --git a/app/code/Magento/Customer/view/frontend/templates/form/edit.phtml b/app/code/Magento/Customer/view/frontend/templates/form/edit.phtml index a66afc07a49c217628f7ff850c79e97742bab6e3..13ed3a52c04585ba6ffe225442fe072f42cf9c49 100755 --- a/app/code/Magento/Customer/view/frontend/templates/form/edit.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/edit.phtml @@ -24,7 +24,7 @@ /** @var \Magento\Customer\Block\Form\Edit $this */ ?> -<form class="form edit account" action="<?php echo $this->getUrl('customer/account/editPost') ?>" method="post" id="form-validate" enctype="multipart/form-data" data-hasrequired="<?php echo __('* Required Fields') ?>" autocomplete="off"> +<form class="form form-edit-account" action="<?php echo $this->getUrl('customer/account/editPost') ?>" method="post" id="form-validate" enctype="multipart/form-data" data-hasrequired="<?php echo __('* Required Fields') ?>" autocomplete="off"> <fieldset class="fieldset info"> <?php echo $this->getBlockHtml('formkey')?> <legend class="legend"><span><?php echo __('Account Information') ?></span></legend><br> diff --git a/app/code/Magento/Customer/view/frontend/templates/form/newsletter.phtml b/app/code/Magento/Customer/view/frontend/templates/form/newsletter.phtml index 66643d94ef1e7bc45c5a3618e6efc0834d038863..7bcfebe5f80495822e6c1900d0e7b05912553345 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/newsletter.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/newsletter.phtml @@ -23,7 +23,7 @@ */ ?> <?php echo $this->getChildHtml('form_before')?> - <form class="form newsletter manage" action="<?php echo $this->getAction() ?>" method="post" id="form-validate"> + <form class="form form-newsletter-manage" action="<?php echo $this->getAction() ?>" method="post" id="form-validate"> <fieldset class="fieldset"> <?php echo $this->getBlockHtml('formkey')?> <legend class="legend"><span><?php echo __('Subscription option') ?></span></legend><br> diff --git a/app/code/Magento/Dhl/Model/Carrier.php b/app/code/Magento/Dhl/Model/Carrier.php index 6b24d9a09baf9e27332d158fd03a36059c3fae78..7bd9e54369fac9d66dce329cf31546795866e502 100644 --- a/app/code/Magento/Dhl/Model/Carrier.php +++ b/app/code/Magento/Dhl/Model/Carrier.php @@ -1543,7 +1543,9 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin $xml->addChild('LabelImageFormat', 'PDF', ''); $request = $xml->asXML(); - $request = utf8_encode($request); + if (!$request && !mb_detect_encoding($request) == 'UTF-8') { + $request = utf8_encode($request); + } $responseBody = $this->_getCachedQuotes($request); if ($responseBody === null) { @@ -1554,6 +1556,7 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin $client->setConfig(array('maxredirects' => 0, 'timeout' => 30)); $client->setRawData($request); $responseBody = $client->request(\Magento\Framework\HTTP\ZendClient::POST)->getBody(); + $responseBody = utf8_decode($responseBody); $debugData['result'] = $responseBody; $this->_setCachedQuotes($request, $responseBody); } catch (\Exception $e) { diff --git a/app/code/Magento/Downloadable/view/frontend/templates/checkout/cart/item/default.phtml b/app/code/Magento/Downloadable/view/frontend/templates/checkout/cart/item/default.phtml index 282a84c4963e2a3fa5a25f40f3916116b5a19e8d..23e86d8f57de95ea67a222748a55972cf9ce8bcf 100644 --- a/app/code/Magento/Downloadable/view/frontend/templates/checkout/cart/item/default.phtml +++ b/app/code/Magento/Downloadable/view/frontend/templates/checkout/cart/item/default.phtml @@ -29,17 +29,17 @@ $canApplyMsrp = $this->helper('Magento\Catalog\Helper\Data')->canApplyMsrp($_ite ?> <?php echo $this->getChildHtml('item_extra') ?> <tbody class="cart item"> - <tr class="item info"> + <tr class="item info item-info"> <td class="col item"> <?php if ($this->hasProductUrl()): ?> <a href="<?php echo $this->getProductUrl() ?>" title="<?php echo $this->escapeHtml($this->getProductName()) ?>" - class="product photo"> + class="product photo product-item-photo"> <?php endif; ?> <?php echo $this->getLayout()->createBlock('Magento\Catalog\Block\Product\Image')->init($_item->getProduct(), 'cart_page_product_thumbnail')->toHtml(); ?> <?php if ($this->hasProductUrl()):?></a><?php endif;?> - <div class="product details"> - <strong class="product name"> + <div class="product details product-item-details"> + <strong class="product name product-item-name"> <?php if ($this->hasProductUrl()):?> <a href="<?php echo $this->getProductUrl() ?>"><?php echo $this->escapeHtml($this->getProductName()) ?></a> <?php else: ?> @@ -47,7 +47,7 @@ $canApplyMsrp = $this->helper('Magento\Catalog\Helper\Data')->canApplyMsrp($_ite <?php endif; ?> </strong> <?php if ($_options = $this->getOptionList()):?> - <dl class="cart item options"> + <dl class="cart-item-options"> <?php foreach ($_options as $_option) : ?> <?php $_formatedOptionValue = $this->getFormatedOptionValue($_option) ?> <dt><?php echo $this->escapeHtml($_option['label']) ?></dt> @@ -67,7 +67,7 @@ $canApplyMsrp = $this->helper('Magento\Catalog\Helper\Data')->canApplyMsrp($_ite <?php endif;?> <?php if ($messages = $this->getMessages()): ?> <?php foreach ($messages as $message): ?> - <p class="cart item message <?php echo $message['type'] ?>">* <?php echo $this->escapeHtml($message['text']) ?></p> + <div class="cart item message <?php echo $message['type'] ?>"><div><?php echo $this->escapeHtml($message['text']) ?></div></div> <?php endforeach; ?> <?php endif; ?> <?php $addInfoBlock = $this->getProductAdditionalInformationBlock(); ?> @@ -90,89 +90,94 @@ $canApplyMsrp = $this->helper('Magento\Catalog\Helper\Data')->canApplyMsrp($_ite <?php $cols++; ?> </td> <?php else: ?> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displayCartPriceExclTax() || $this->helper('Magento\Tax\Helper\Data')->displayCartBothPrices()): ?> - <td class="col price excl tax" data-th="<?php echo __('Unit Price Excl. Tax'); ?>"> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" - data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $_item->getId(); ?>"}'> - <?php else: ?> - <span class="cart price"> - <?php endif; ?> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> - <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_item->getCalculationPrice()+$_item->getWeeeTaxAppliedAmount()+$_item->getWeeeTaxDisposition()); ?> - <?php else: ?> - <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_item->getCalculationPrice()) ?> - <?php endif; ?> - </span> - <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item)): ?> - <div class="cart tax info" id="eunit-item-tax-details<?php echo $_item->getId(); ?>" style="display:none;"> + <?php if ($this->helper('Magento\Tax\Helper\Data')->displayCartPriceExclTax() || $this->helper('Magento\Tax\Helper\Data')->displayCartPriceInclTax() || $this->helper('Magento\Tax\Helper\Data')->displayCartBothPrices()): ?> + <td class="col price" data-th="<?php echo $this->escapeHtml(__('Price')); ?>"> + <?php if ($this->helper('Magento\Tax\Helper\Data')->displayCartPriceInclTax() || $this->helper('Magento\Tax\Helper\Data')->displayCartBothPrices()): ?> + <span class="incl tax" data-th="<?php echo $this->escapeHtml(__('Incl. Tax')); ?>"> + <?php $_incl = $this->helper('Magento\Checkout\Helper\Data')->getPriceInclTax($_item); ?> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> + <span class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#unit-item-tax-details<?php echo $_item->getId(); ?>"}'> + <?php else: ?> + <span class="cart price"> + <?php endif; ?> + + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> + <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_incl+$_item->getWeeeTaxAppliedAmount()); ?> + <?php else: ?> + <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_incl-$_item->getWeeeTaxDisposition()) ?> + <?php endif; ?> + </span> + <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item)): ?> + + <div class="cart-tax-info" id="unit-item-tax-details<?php echo $_item->getId(); ?>" style="display:none;"> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item) as $tax): ?> - <span class="weee"><?php echo $tax['title']; ?>: <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['amount'],true,true); ?></span> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['amount'],true,true); ?></span> <?php endforeach; ?> <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item) as $tax): ?> - <span class="weee"><?php echo $tax['title']; ?>: <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['amount_incl_tax'],true,true); ?></span> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['amount_incl_tax'],true,true); ?></span> <?php endforeach; ?> <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item) as $tax): ?> - <span class="weee"><?php echo $tax['title']; ?>: <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['amount_incl_tax'],true,true); ?></span> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['amount_incl_tax'],true,true); ?></span> <?php endforeach; ?> <?php endif; ?> </div> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> - <div class="cart tax total" - data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $_item->getId(); ?>"}'> - <span class="weee"><?php echo __('Total'); ?>: <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_item->getCalculationPrice()+$_item->getWeeeTaxAppliedAmount()+$_item->getWeeeTaxDisposition()); ?></span> + + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> + <div class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#unit-item-tax-details<?php echo $_item->getId(); ?>"}'> + <span class="weee" data-th="<?php echo __('Total incl. tax'); ?>"><?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_incl+$_item->getWeeeTaxAppliedAmount()); ?></span> </div> <?php endif; ?> + <?php endif; ?> + <?php $cols++; ?> + </span> <?php endif; ?> - <?php $cols++; ?> - </td> - <?php endif; ?> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displayCartPriceInclTax() || $this->helper('Magento\Tax\Helper\Data')->displayCartBothPrices()): ?> - <td class="col price incl tax" data-th="<?php echo __('Unit Price Incl. Tax'); ?>"> - <?php $_incl = $this->helper('Magento\Checkout\Helper\Data')->getPriceInclTax($_item); ?> + + <?php if ($this->helper('Magento\Tax\Helper\Data')->displayCartPriceExclTax() || $this->helper('Magento\Tax\Helper\Data')->displayCartBothPrices()): ?> + <span class="excl tax" data-th="<?php echo $this->escapeHtml(__('Excl. Tax')); ?>"> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" - data-tax-toggle='{"itemTaxId" : "#unit-item-tax-details<?php echo $_item->getId(); ?>"}'> + <span class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $_item->getId(); ?>"}'> <?php else: ?> - <span class="cart price"> + <span class="cart price"> <?php endif; ?> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> - <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_incl+$_item->getWeeeTaxAppliedAmount()); ?> + <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_item->getCalculationPrice()+$_item->getWeeeTaxAppliedAmount()+$_item->getWeeeTaxDisposition()); ?> <?php else: ?> - <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_incl-$_item->getWeeeTaxDisposition()) ?> + <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_item->getCalculationPrice()) ?> <?php endif; ?> </span> - <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item)): ?> - - <div class="cart tax info" id="unit-item-tax-details<?php echo $_item->getId(); ?>" style="display:none;"> + <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item)): ?> + <div class="cart-tax-info" id="eunit-item-tax-details<?php echo $_item->getId(); ?>" style="display:none;"> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item) as $tax): ?> - <span class="weee"><?php echo $tax['title']; ?>: <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['amount'],true,true); ?></span> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['amount'],true,true); ?></span> <?php endforeach; ?> <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item) as $tax): ?> - <span class="weee"><?php echo $tax['title']; ?>: <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['amount_incl_tax'],true,true); ?></span> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['amount_incl_tax'],true,true); ?></span> <?php endforeach; ?> <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item) as $tax): ?> - <span class="weee"><?php echo $tax['title']; ?>: <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['amount_incl_tax'],true,true); ?></span> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['amount_incl_tax'],true,true); ?></span> <?php endforeach; ?> <?php endif; ?> </div> - - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> - <div class="cart tax total" - data-tax-toggle='{"itemTaxId" : "#unit-item-tax-details<?php echo $_item->getId(); ?>"}'> - <span class="weee"><?php echo __('Total incl. tax'); ?>: <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_incl+$_item->getWeeeTaxAppliedAmount()); ?></span> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> + <div class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $_item->getId(); ?>"}'> + <span class="weee" data-th="<?php echo $this->escapeHtml(__('Total')); ?>"><?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_item->getCalculationPrice()+$_item->getWeeeTaxAppliedAmount()+$_item->getWeeeTaxDisposition()); ?></span> </div> <?php endif; ?> <?php endif; ?> - <?php $cols++; ?> - </td> + </span> + <?php endif; ?> + <?php $cols++; ?> + </td> <?php endif; ?> <?php endif; ?> <td class="col qty"> @@ -181,101 +186,105 @@ $canApplyMsrp = $this->helper('Magento\Catalog\Helper\Data')->canApplyMsrp($_ite </div> <?php $cols++; ?> </td> - <?php if (($this->helper('Magento\Tax\Helper\Data')->displayCartPriceExclTax() || $this->helper('Magento\Tax\Helper\Data')->displayCartBothPrices()) && !$_item->getNoSubtotal()): ?> - <td class="col subtotal excl tax" data-th="<?php echo __('Subtotal Excl. Tax'); ?>"> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" - data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $_item->getId(); ?>"}'> - <?php else: ?> - <span class="cart price"> - <?php endif; ?> - <?php if ($canApplyMsrp): ?> - <span class="cart msrp subtotal">--</span> - <?php else: ?> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> - <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_item->getRowTotal()+$_item->getWeeeTaxAppliedRowAmount()+$_item->getWeeeTaxRowDisposition()); ?> + <?php if (($this->helper('Magento\Tax\Helper\Data')->displayCartPriceInclTax() || $this->helper('Magento\Tax\Helper\Data')->displayCartPriceExclTax() ||$this->helper('Magento\Tax\Helper\Data')->displayCartBothPrices()) && !$_item->getNoSubtotal()): ?> + <td class="col subtotal" data-th="<?php echo $this->escapeHtml(__('Subtotal'));?>"> + <?php if (($this->helper('Magento\Tax\Helper\Data')->displayCartPriceInclTax() || $this->helper('Magento\Tax\Helper\Data')->displayCartBothPrices()) && !$_item->getNoSubtotal()): ?> + <span class="incl tax" data-th="<?php echo __('Incl. Tax'); ?>"> + <?php $_incl = $this->helper('Magento\Checkout\Helper\Data')->getSubtotalInclTax($_item); ?> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> + <span class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#subtotal-item-tax-details<?php echo $_item->getId(); ?>"}'> <?php else: ?> - <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_item->getRowTotal()) ?> + <span class="cart price"> <?php endif; ?> - <?php endif; ?> + <?php if ($canApplyMsrp): ?> + <span class="cart msrp subtotal">--</span> + <?php else: ?> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> + <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_incl+$_item->getWeeeTaxAppliedRowAmount()); ?> + <?php else: ?> + <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_incl-$_item->getWeeeTaxRowDisposition()) ?> + <?php endif; ?> + <?php endif; ?> + </span> - </span> - <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item)): ?> + <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item)): ?> + <div class="cart-tax-info" id="subtotal-item-tax-details<?php echo $_item->getId(); ?>" style="display:none;"> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['row_amount'],true,true); ?></span> + <?php endforeach; ?> + <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['row_amount_incl_tax'],true,true); ?></span> + <?php endforeach; ?> + <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['row_amount_incl_tax'],true,true); ?></span> + <?php endforeach; ?> + <?php endif; ?> + </div> - <div class="cart tax info" id="esubtotal-item-tax-details<?php echo $_item->getId(); ?>" style="display:none;"> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item) as $tax): ?> - <span class="weee"><?php echo $tax['title']; ?>: <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['row_amount'],true,true); ?></span> - <?php endforeach; ?> - <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item) as $tax): ?> - <span class="weee"><?php echo $tax['title']; ?>: <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['row_amount_incl_tax'],true,true); ?></span> - <?php endforeach; ?> - <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item) as $tax): ?> - <span class="weee"><?php echo $tax['title']; ?>: <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['row_amount_incl_tax'],true,true); ?></span> - <?php endforeach; ?> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> + <div class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#subtotal-item-tax-details<?php echo $_item->getId(); ?>"}'> + <span class="weee" data-th="<?php echo __('Total incl. tax'); ?>"><?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_incl+$_item->getWeeeTaxAppliedRowAmount()); ?></span> + </div> <?php endif; ?> - </div> - - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> - <div class="cart tax total" - data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $_item->getId(); ?>"}'> - <span class="weee"><?php echo __('Total'); ?>: <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_item->getRowTotal()+$_item->getWeeeTaxAppliedRowAmount()+$_item->getWeeeTaxRowDisposition()); ?></span> - </div> - <?php endif; ?> + <?php endif; ?> + </span> <?php endif; ?> - <?php $cols++; ?> - </td> - <?php endif; ?> - <?php if (($this->helper('Magento\Tax\Helper\Data')->displayCartPriceInclTax() || $this->helper('Magento\Tax\Helper\Data')->displayCartBothPrices()) && !$_item->getNoSubtotal()): ?> - <td class="col subtotal incl tax" data-th="<?php echo __('Subtotal Incl. Tax'); ?>"> - <?php $_incl = $this->helper('Magento\Checkout\Helper\Data')->getSubtotalInclTax($_item); ?> + + <?php if (($this->helper('Magento\Tax\Helper\Data')->displayCartPriceExclTax() || $this->helper('Magento\Tax\Helper\Data')->displayCartBothPrices()) && !$_item->getNoSubtotal()): ?> + <span class="excl tax" data-th="<?php echo __('Excl. Tax'); ?>"> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" - data-tax-toggle='{"itemTaxId" : "#subtotal-item-tax-details<?php echo $_item->getId(); ?>"}'> - <?php else: ?> - <span class="cart price"> - <?php endif; ?> - <?php if ($canApplyMsrp): ?> - <span class="cart msrp subtotal">--</span> + <span class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $_item->getId(); ?>"}'> <?php else: ?> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> - <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_incl+$_item->getWeeeTaxAppliedRowAmount()); ?> - <?php else: ?> - <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_incl-$_item->getWeeeTaxRowDisposition()) ?> - <?php endif; ?> + <span class="cart price"> <?php endif; ?> - </span> - <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item)): ?> - <div class="cart tax info" id="subtotal-item-tax-details<?php echo $_item->getId(); ?>" style="display:none;"> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item) as $tax): ?> - <span class="weee"><?php echo $tax['title']; ?>: <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['row_amount'],true,true); ?></span> - <?php endforeach; ?> - <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item) as $tax): ?> - <span class="weee"><?php echo $tax['title']; ?>: <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['row_amount_incl_tax'],true,true); ?></span> - <?php endforeach; ?> - <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item) as $tax): ?> - <span class="weee"><?php echo $tax['title']; ?>: <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['row_amount_incl_tax'],true,true); ?></span> - <?php endforeach; ?> + <?php if ($canApplyMsrp): ?> + <span class="cart msrp subtotal">--</span> + <?php else: ?> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> + <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_item->getRowTotal()+$_item->getWeeeTaxAppliedRowAmount()+$_item->getWeeeTaxRowDisposition()); ?> + <?php else: ?> + <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_item->getRowTotal()) ?> + <?php endif; ?> <?php endif; ?> - </div> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> - <div class="cart tax total" - data-tax-toggle='{"itemTaxId" : "#subtotal-item-tax-details<?php echo $_item->getId(); ?>"}'> - <span class="weee"><?php echo __('Total incl. tax'); ?>: <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_incl+$_item->getWeeeTaxAppliedRowAmount()); ?></span> - </div> + </span> + <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item)): ?> + <div class="cart-tax-info" id="esubtotal-item-tax-details<?php echo $_item->getId(); ?>" style="display:none;"> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['row_amount'],true,true); ?></span> + <?php endforeach; ?> + <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['row_amount_incl_tax'],true,true); ?></span> + <?php endforeach; ?> + <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($tax['row_amount_incl_tax'],true,true); ?></span> + <?php endforeach; ?> + <?php endif; ?> + </div> + + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && $_item->getWeeeTaxAppliedAmount()): ?> + <div class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $_item->getId(); ?>"}'> + <span class="weee" data-th="<?php echo __('Total'); ?>"><?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_item->getRowTotal()+$_item->getWeeeTaxAppliedRowAmount()+$_item->getWeeeTaxRowDisposition()); ?></span> + </div> + <?php endif; ?> + <?php endif; ?> + </span> <?php endif; ?> - <?php endif; ?> - <?php $cols++; ?> - </td> - <?php endif; ?> + <?php $cols++; ?> + </td> + <?php endif; ?> </tr> <tr class="item actions"> <td colspan="<?php echo $cols;?>"> diff --git a/app/code/Magento/Downloadable/view/frontend/templates/customer/products/list.phtml b/app/code/Magento/Downloadable/view/frontend/templates/customer/products/list.phtml index 0c27f2d190b65369531400cd59cbffa80dc11ffe..5353cba99ec8a1ebe88c7046b4853bcff6d6337c 100644 --- a/app/code/Magento/Downloadable/view/frontend/templates/customer/products/list.phtml +++ b/app/code/Magento/Downloadable/view/frontend/templates/customer/products/list.phtml @@ -29,43 +29,49 @@ ?> <?php $_items = $this->getItems(); ?> <?php if(count($_items)): ?> - <div class="downloadable products toolbar"> - <?php echo $this->getChildHtml('pager'); ?> - </div> - <div class="wrapper table downloadable products"> - <table id="my-downloadable-products-table" class="data table downloadable products"> + <?php if ($this->getChildHtml('pager')): ?> + <div class="toolbar downloadable-products-toolbar top"> + <?php echo $this->getChildHtml('pager'); ?> + </div> + <?php endif; ?> + <div class="table-wrapper downloadable-products"> + <table id="my-downloadable-products-table" class="data table table-downloadable-products"> <caption class="table caption"><?php echo __('Downloadable Products') ?></caption> <thead> <tr> - <th class="col id"><?php echo __('Order #') ?></th> - <th class="col date"><?php echo __('Date') ?></th> - <th class="col title"><?php echo __('Title') ?></th> - <th class="col status"><?php echo __('Status') ?></th> - <th class="col remaining"><?php echo __('Remaining Downloads') ?></th> + <th scope="col" class="col id"><?php echo __('Order #') ?></th> + <th scope="col" class="col date"><?php echo __('Date') ?></th> + <th scope="col" class="col title"><?php echo __('Title') ?></th> + <th scope="col" class="col status"><?php echo __('Status') ?></th> + <th scope="col" class="col remaining"><?php echo __('Remaining Downloads') ?></th> </tr> </thead> <tbody> <?php foreach ($_items as $_item): ?> <tr> - <td class="col id"> - <a href="<?php echo $this->getOrderViewUrl($_item->getPurchased()->getOrderId()) ?>" title="<?php echo __('View Order') ?>"> + <td data-th="<?php echo $this->escapeHtml(__('Order #')) ?>" class="col id"> + <a href="<?php echo $this->getOrderViewUrl($_item->getPurchased()->getOrderId()) ?>" + title="<?php echo $this->escapeHtml(__('View Order')) ?>"> <?php echo $_item->getPurchased()->getOrderIncrementId() ?> </a> </td> - <td class="col date"><?php echo $this->formatDate($_item->getPurchased()->getCreatedAt()) ?></td> - <td class="col title"> - <?php echo $this->escapeHtml($_item->getPurchased()->getProductName()) ?> - <a href="<?php echo $this->getDownloadUrl($_item) ?>" title="<?php echo __('Start Download') ?>" <?php echo $this->getIsOpenInNewWindow()?'onclick="this.target=\'_blank\'"':''; ?>><?php echo $this->escapeHtml($_item->getLinkTitle()) ?></a> + <td data-th="<?php echo $this->escapeHtml(__('Date')) ?>" class="col date"><?php echo $this->formatDate($_item->getPurchased()->getCreatedAt()) ?></td> + <td data-th="<?php echo $this->escapeHtml(__('Title')) ?>" class="col title"> + <strong class="product-name"><?php echo $this->escapeHtml($_item->getPurchased()->getProductName()) ?></strong> + <a href="<?php echo $this->getDownloadUrl($_item) ?>" title="<?php echo $this->escapeHtml(__('Start Download')) ?>" class="action download" <?php echo $this->getIsOpenInNewWindow()?'onclick="this.target=\'_blank\'"':''; ?>><?php echo $this->escapeHtml($_item->getLinkTitle()) ?></a> </td> - <td class="col status"><?php echo __(ucfirst($_item->getStatus())) ?></td> - <td class="col remaining"><?php echo $this->getRemainingDownloads($_item) ?></td> + <td data-th="<?php echo $this->escapeHtml(__('Status')) ?>" class="col status"><?php echo __(ucfirst($_item->getStatus())) ?></td> + <td data-th="<?php echo $this->escapeHtml(__('Remaining Downloads')) ?>" class="col remaining"><?php echo $this->getRemainingDownloads($_item) ?></td> </tr> <?php endforeach; ?> </tbody> </table> </div> - <div class="downloadable products toolbar"> - <?php echo $this->getChildHtml('pager'); ?> - </div> + <?php if ($this->getChildHtml('pager')): ?> + <div class="toolbar downloadable-products-toolbar bottom"> + <?php echo $this->getChildHtml('pager'); ?> + </div> + <?php endif; ?> <?php else: ?> <div class="message info empty"><span><?php echo __('You have not purchased any downloadable products yet.'); ?></span></div> <?php endif; ?> diff --git a/app/code/Magento/Downloadable/view/frontend/templates/sales/order/creditmemo/items/renderer/downloadable.phtml b/app/code/Magento/Downloadable/view/frontend/templates/sales/order/creditmemo/items/renderer/downloadable.phtml index 57684d83378a187500445ee6b277d28f17a44963..ee4566eed5f24f1800b30725660297a413c33af4 100644 --- a/app/code/Magento/Downloadable/view/frontend/templates/sales/order/creditmemo/items/renderer/downloadable.phtml +++ b/app/code/Magento/Downloadable/view/frontend/templates/sales/order/creditmemo/items/renderer/downloadable.phtml @@ -27,10 +27,10 @@ <?php $_item = $this->getItem() ?> <?php $_order = $this->getItem()->getOrderItem()->getOrder() ?> <tr class="border" id="order-item-row-<?php echo $_item->getId() ?>"> - <td class="col name"> - <strong class="product name"><?php echo $this->escapeHtml($_item->getName()) ?></strong> + <td class="col name" data-th="<?php echo $this->escapeHtml(__('Product Name')); ?>"> + <strong class="product name product-item-name"><?php echo $this->escapeHtml($_item->getName()) ?></strong> <?php if($_options = $this->getItemOptions()): ?> - <dl class="item options"> + <dl class="item options links"> <?php foreach ($_options as $_option) : ?> <dt><?php echo $this->escapeHtml($_option['label']) ?></dt> <?php if (!$this->getPrintStatus()): ?> @@ -54,7 +54,7 @@ <?php endif; ?> <?php /* downloadable */?> <?php if ($links = $this->getLinks()): ?> - <dl class="item options"> + <dl class="item options links"> <dt><?php echo $this->getLinksTitle() ?></dt> <?php foreach ($links->getPurchasedItems() as $link): ?> <dd><?php echo $this->escapeHtml($link->getLinkTitle()); ?></dd> @@ -74,78 +74,13 @@ data-item-id="<?php echo $_item->getId() ?>"><?php echo __('Gift Message') ?></a> <?php endif; ?> </td> - <td class="col sku"><?php echo $this->prepareSku($this->getSku()) ?></td> - <td class="col price"> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceExclTax()): ?> - <span class="price excl tax"> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices()): ?> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart price"> - <?php endif; ?> - <span class="label"><?php echo __('Excl. Tax'); ?>:</span> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - </span> - <?php endif; ?> - <?php endif; ?> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" - data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> - <?php else: ?> - <span class="cart price"> - <?php endif; ?> - - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()+$this->getItem()->getWeeeTaxAppliedAmount()+$this->getItem()->getWeeeTaxDisposition()); ?> - <?php else: ?> - <?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()) ?> - <?php endif; ?> - </span> - - <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> - <span class="cart tax info" id="eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display:none;"> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount']); ?> - <?php endforeach; ?> - </small> - <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <small><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></small> - <?php endforeach; ?> - <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?> - <?php endforeach; ?> - </small> - <?php endif; ?> - </span> - - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" - data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> - <?php echo __('Total'); ?>:<br /> <?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()+$this->getItem()->getWeeeTaxAppliedAmount()+$this->getItem()->getWeeeTaxDisposition()); ?> - </span> - <?php endif; ?> - <?php endif; ?> - </span> - <br /> - <?php endif; ?> + <td class="col sku" data-th="<?php echo $this->escapeHtml(__('SKU')); ?>"><?php echo $this->prepareSku($this->getSku()) ?></td> + <td class="col price" data-th="<?php echo $this->escapeHtml(__('Price')); ?>"> <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceInclTax()): ?> - <span class="price incl tax"> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices()): ?> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart price"> - <?php endif; ?> - <span class="label"><?php echo __('Incl. Tax'); ?>:</span> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - </span> - <?php endif; ?> - <?php endif; ?> + <span class="incl tax" data-th="<?php echo $this->escapeHtml(__('Incl. Tax')); ?>"> <?php $_incl = $this->helper('Magento\Checkout\Helper\Data')->getPriceInclTax($this->getItem()); ?> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" + <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#unit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> <?php else: ?> <span class="cart price"> @@ -158,150 +93,161 @@ </span> <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> - <span class="cart tax info" id="unit-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display:none;"> + <span class="cart tax info" id="unit-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display: none;"> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount']); ?> - <?php endforeach; ?> - </small> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount']); ?></span> + <?php endforeach; ?> <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <small><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></small> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></span> <?php endforeach; ?> <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?> - <?php endforeach; ?> - </small> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></span> + <?php endforeach; ?> <?php endif; ?> </span> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" + <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#unit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> - <?php echo __('Total incl. tax'); ?>:<br /> <?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedAmount()); ?> + <span class="weee" data-th="<?php echo $this->escapeHtml(__('Total incl. tax')); ?>"><?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedAmount()); ?></span> </span> <?php endif; ?> <?php endif; ?> </span> <?php endif; ?> - </td> - <td class="col qty"><?php echo $_item->getQty()*1 ?></td> - <td class="col subtotal"> <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceExclTax()): ?> - <span class="price excl tax"> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices()): ?> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart price"> - <?php endif; ?> - <span class="label"><?php echo __('Excl. Tax'); ?>:</span> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - </span> - <?php endif; ?> - <?php endif; ?> + <span class="excl tax" data-th="<?php echo $this->escapeHtml(__('Excl. Tax')); ?>"> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" - data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <span class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> <?php else: ?> - <span class="cart price"> + <span class="cart price"> <?php endif; ?> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()+$this->getItem()->getWeeeTaxAppliedRowAmount()+$this->getItem()->getWeeeTaxRowDisposition()); ?> + <?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()+$this->getItem()->getWeeeTaxAppliedAmount()+$this->getItem()->getWeeeTaxDisposition()); ?> <?php else: ?> - <?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()) ?> + <?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()) ?> <?php endif; ?> - </span> + </span> <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> - <span class="cart tax info" id="esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display:none;"> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount']); ?> - <?php endforeach; ?> - </small> - <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <small><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></small> - <?php endforeach; ?> - <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?> - <?php endforeach; ?> - </small> - <?php endif; ?> - </span> - - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" - data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> - <?php echo __('Total'); ?>:<br /> <?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()+$this->getItem()->getWeeeTaxAppliedRowAmount()+$this->getItem()->getWeeeTaxRowDisposition()); ?> - </span> + <span class="cart-tax-info" id="eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display: none;"> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount']); ?></span> + <?php endforeach; ?> + <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></span> + <?php endforeach; ?> + <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></span> + <?php endforeach; ?> <?php endif; ?> - <?php endif; ?> </span> - <br /> + + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <span class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <span class="weee" data-th="<?php echo $this->escapeHtml(__('Total')); ?>"><?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()+$this->getItem()->getWeeeTaxAppliedAmount()+$this->getItem()->getWeeeTaxDisposition()); ?></span> + </span> <?php endif; ?> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceInclTax()): ?> - <span class="price incl tax"> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices()): ?> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart price"> - <?php endif; ?> - <span class="label"><?php echo __('Incl. Tax'); ?>:</span> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - </span> - <?php endif; ?> - <?php endif; ?> + <?php endif; ?> + </span> + <?php endif; ?> + </td> + <td class="col qty" data-th="<?php echo $this->escapeHtml(__('Qty')); ?>"><?php echo $_item->getQty()*1 ?></td> + <td class="col subtotal" data-th="<?php echo $this->escapeHtml(__('Subtotal')); ?>"> + <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceInclTax()): ?> + <span class="incl tax" data-th="<?php echo $this->escapeHtml(__('Incl. Tax')); ?>"> <?php $_incl = $this->helper('Magento\Checkout\Helper\Data')->getSubtotalInclTax($this->getItem()); ?> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" + <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#subtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> <?php else: ?> - <span class="cart price"> + <span class="cart price"> <?php endif; ?> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> <?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedRowAmount()); ?> <?php else: ?> <?php echo $this->getOrder()->formatPrice($_incl-$this->getItem()->getWeeeTaxRowDisposition()) ?> <?php endif; ?> - </span> + </span> - <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> - <span class="cart tax info" id="subtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display:none;"> + <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> + <span class="cart-tax-info" id="subtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display: none;"> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount']); ?> - <?php endforeach; ?> - </small> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount']); ?></span> + <?php endforeach; ?> <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <small><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></small> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></span> <?php endforeach; ?> <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?> - <?php endforeach; ?> - </small> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></span> + <?php endforeach; ?> <?php endif; ?> </span> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" + <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#subtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> - <?php echo __('Total incl. tax'); ?>:<br /> <?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedRowAmount()); ?> + <span class="weee" data-th="<?php echo $this->escapeHtml(__('Total incl. tax')); ?>"><?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedRowAmount()); ?></span> </span> <?php endif; ?> <?php endif; ?> </span> <?php endif; ?> + <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceExclTax()): ?> + <span class="excl tax" data-th="<?php echo $this->escapeHtml(__('Excl. Tax')); ?>"> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <span class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <?php else: ?> + <span class="cart price"> + <?php endif; ?> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()+$this->getItem()->getWeeeTaxAppliedRowAmount()+$this->getItem()->getWeeeTaxRowDisposition()); ?> + <?php else: ?> + <?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()) ?> + <?php endif; ?> + </span> + + <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> + <span class="cart-tax-info" id="esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display: none;"> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount']); ?></span> + <?php endforeach; ?> + <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></span> + <?php endforeach; ?> + <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></span> + <?php endforeach; ?> + <?php endif; ?> + </span> + + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <span class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <span class="weee" data-th="<?php echo $this->escapeHtml(__('Total')); ?>"><?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()+$this->getItem()->getWeeeTaxAppliedRowAmount()+$this->getItem()->getWeeeTaxRowDisposition()); ?></span> + </span> + <?php endif; ?> + <?php endif; ?> + </span> + <?php endif; ?> </td> - <td class="col discount"><?php echo $_order->formatPrice(-$_item->getDiscountAmount()) ?></td> - <td class="cot total"> + <td class="col discount" data-th="<?php echo $this->escapeHtml(__('Discount Amount')); ?>"><?php echo $_order->formatPrice(-$_item->getDiscountAmount()) ?></td> + <td class="cot total" data-th="<?php echo $this->escapeHtml(__('Row Total')); ?>"> <?php echo $_order->formatPrice($_item->getRowTotal()-$_item->getDiscountAmount()+$_item->getTaxAmount()+$_item->getWeeeTaxAppliedRowAmount()) ?> </td> </tr> diff --git a/app/code/Magento/Downloadable/view/frontend/templates/sales/order/invoice/items/renderer/downloadable.phtml b/app/code/Magento/Downloadable/view/frontend/templates/sales/order/invoice/items/renderer/downloadable.phtml index 363ed5c6aee041415fe501b652847f56a60be27b..ca56ccf7ff20d02b13df137ac9f9bf08618248d1 100644 --- a/app/code/Magento/Downloadable/view/frontend/templates/sales/order/invoice/items/renderer/downloadable.phtml +++ b/app/code/Magento/Downloadable/view/frontend/templates/sales/order/invoice/items/renderer/downloadable.phtml @@ -27,10 +27,10 @@ <?php $_item = $this->getItem() ?> <?php $_order = $this->getItem()->getOrderItem()->getOrder() ?> <tr id="order-item-row-<?php echo $_item->getId() ?>"> - <td class="col name"> - <strong class="product name"><?php echo $this->escapeHtml($_item->getName()) ?></strong> + <td class="col name" data-th="<?php echo $this->escapeHtml(__('Product Name')); ?>"> + <strong class="product name product-item-name"><?php echo $this->escapeHtml($_item->getName()) ?></strong> <?php if($_options = $this->getItemOptions()): ?> - <dl class="item options"> + <dl class="item options links"> <?php foreach ($_options as $_option) : ?> <dt><?php echo $this->escapeHtml($_option['label']) ?></dt> <?php if (!$this->getPrintStatus()): ?> @@ -54,7 +54,7 @@ <?php endif; ?> <?php /* downloadable */ ?> <?php if ($links = $this->getLinks()): ?> - <dl class="item options"> + <dl class="item options links"> <dt><?php echo $this->getLinksTitle() ?></dt> <?php foreach ($links->getPurchasedItems() as $link): ?> <dd><?php echo $this->escapeHtml($link->getLinkTitle()); ?></dd> @@ -73,236 +73,182 @@ data-item-id="<?php echo $_item->getId() ?>"><?php echo __('Gift Message') ?></a> <?php endif; ?> </td> - <td class="col sku"><?php echo $this->prepareSku($this->getSku()) ?></td> - <td class="col price"> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceExclTax()): ?> - <span class="price excl tax"> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices()): ?> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart price"> - <?php endif; ?> - <span class="label"><?php echo __('Excl. Tax'); ?>:</span> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - </span> - <?php endif; ?> - <?php endif; ?> + <td class="col sku" data-th="<?php echo $this->escapeHtml(__('SKU')); ?>"><?php echo $this->prepareSku($this->getSku()) ?></td> + <td class="col price" data-th="<?php echo $this->escapeHtml(__('Price')); ?>"> + <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceInclTax()): ?> + <span class="incl tax" data-th="<?php echo $this->escapeHtml(__('Incl. Tax')); ?>"> + <?php $_incl = $this->helper('Magento\Checkout\Helper\Data')->getPriceInclTax($this->getItem()); ?> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" - data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <span class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#unit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> <?php else: ?> - <span class="cart price"> + <span class="cart price"> <?php endif; ?> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()+$this->getItem()->getWeeeTaxAppliedAmount()+$this->getItem()->getWeeeTaxDisposition()); ?> + <?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedAmount()); ?> <?php else: ?> - <?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()) ?> + <?php echo $this->getOrder()->formatPrice($_incl-$this->getItem()->getWeeeTaxDisposition()) ?> <?php endif; ?> - </span> - - <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> - <span class="cart tax info" id="eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>" - style="display:none;"> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount']); ?> - <?php endforeach; ?> - </small> - <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <small><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></small> - <?php endforeach; ?> - <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?> - <?php endforeach; ?> - </small> - <?php endif; ?> </span> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" - data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> - <?php echo __('Total'); ?>:<br /> <?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()+$this->getItem()->getWeeeTaxAppliedAmount()+$this->getItem()->getWeeeTaxDisposition()); ?> - </span> - <?php endif; ?> - <?php endif; ?> - </span> - <br /> - <?php endif; ?> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceInclTax()): ?> - <span class="price incl tax"> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices()): ?> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart price"> - <?php endif; ?> - <span class="label"><?php echo __('Incl. Tax'); ?>:</span> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - </span> - <?php endif; ?> - <?php endif; ?> - <?php $_incl = $this->helper('Magento\Checkout\Helper\Data')->getPriceInclTax($this->getItem()); ?> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" - data-tax-toggle='{"itemTaxId" : "#unit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> - <?php else: ?> - <span class="cart price"> - <?php endif; ?> - - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedAmount()); ?> - <?php else: ?> - <?php echo $this->getOrder()->formatPrice($_incl-$this->getItem()->getWeeeTaxDisposition()) ?> - <?php endif; ?> - </span> - - <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> - <span class="cart tax info" id="unit-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display:none;"> + <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> + <span class="cart-tax-info" id="unit-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display: none;"> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount']); ?> - <?php endforeach; ?> - </small> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount']); ?></span> + <?php endforeach; ?> <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <small><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></small> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></span> <?php endforeach; ?> <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?> - <?php endforeach; ?> - </small> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></span> + <?php endforeach; ?> <?php endif; ?> </span> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" + <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#unit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> - <?php echo __('Total incl. tax'); ?>:<br /> <?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedAmount()); ?> + <span class="weee" data-th="<?php echo $this->escapeHtml(__('Total incl. tax')); ?>"><?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedAmount()); ?></span> </span> <?php endif; ?> <?php endif; ?> </span> <?php endif; ?> - </td> - <td class="col qty"> - <span class="qty summary"><?php echo $_item->getQty()*1 ?></span> - </td> - <td class="col subtotal"> <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceExclTax()): ?> - <span class="price excl tax"> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices()): ?> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart price"> - <?php endif; ?> - <span class="label"><?php echo __('Excl. Tax'); ?>:</span> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - </span> - <?php endif; ?> - <?php endif; ?> + <span class="excl tax" data-th="<?php echo $this->escapeHtml(__('Excl. Tax')); ?>"> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" - data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <span class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> <?php else: ?> - <span class="cart price"> + <span class="cart price"> <?php endif; ?> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()+$this->getItem()->getWeeeTaxAppliedRowAmount()+$this->getItem()->getWeeeTaxRowDisposition()); ?> - <?php else: ?> - <?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()) ?> - <?php endif; ?> - </span> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()+$this->getItem()->getWeeeTaxAppliedAmount()+$this->getItem()->getWeeeTaxDisposition()); ?> + <?php else: ?> + <?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()) ?> + <?php endif; ?> + </span> <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> - <span class="cart tax info" id="esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display:none;"> + <span class="cart-tax-info" id="eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>" + style="display: none;"> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount']); ?> - <?php endforeach; ?> - </small> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount']); ?></span> + <?php endforeach; ?> <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <small><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></small> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></span> <?php endforeach; ?> <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?> - <?php endforeach; ?> - </small> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></span> + <?php endforeach; ?> <?php endif; ?> </span> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" - data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> - <?php echo __('Total'); ?>:<br /> <?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()+$this->getItem()->getWeeeTaxAppliedRowAmount()+$this->getItem()->getWeeeTaxRowDisposition()); ?> + <span class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <span class="weee" data-th="<?php echo $this->escapeHtml(__('Total')); ?>"><?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()+$this->getItem()->getWeeeTaxAppliedAmount()+$this->getItem()->getWeeeTaxDisposition()); ?></span> </span> <?php endif; ?> <?php endif; ?> </span> - <br /> <?php endif; ?> + </td> + <td class="col qty" data-th="<?php echo $this->escapeHtml(__('Qty Invoiced')); ?>"> + <span class="qty summary" data-th="<?php echo $this->escapeHtml(__('Qty Invoiced')); ?>"><?php echo $_item->getQty()*1 ?></span> + </td> + <td class="col subtotal" data-th="<?php echo $this->escapeHtml(__('Subtotal')); ?>"> <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceInclTax()): ?> - <span class="price incl tax"> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices()): ?> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart price"> - <?php endif; ?> - <span class="label"><?php echo __('Incl. Tax'); ?>:</span> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - </span> - <?php endif; ?> - <?php endif; ?> + <span class="incl tax" data-th="<?php echo $this->escapeHtml(__('Incl. Tax')); ?>"> <?php $_incl = $this->helper('Magento\Checkout\Helper\Data')->getSubtotalInclTax($this->getItem()); ?> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" - data-tax-toggle='{"itemTaxId" : "#subtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> - <?php else: ?> + <span class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#subtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <?php else: ?> <span class="cart price"> - <?php endif; ?> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedRowAmount()); ?> - <?php else: ?> - <?php echo $this->getOrder()->formatPrice($_incl-$this->getItem()->getWeeeTaxRowDisposition()) ?> - <?php endif; ?> - </span> + <?php endif; ?> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedRowAmount()); ?> + <?php else: ?> + <?php echo $this->getOrder()->formatPrice($_incl-$this->getItem()->getWeeeTaxRowDisposition()) ?> + <?php endif; ?> + </span> <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> - <span class="cart tax info" + <span class="cart-tax-info" id="subtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>" - style="display:none;"> + style="display: none;"> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount']); ?> - <?php endforeach; ?> - </small> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount']); ?></span> + <?php endforeach; ?> <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <small><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></small> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></span> <?php endforeach; ?> <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?> - <?php endforeach; ?> - </small> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></span> + <?php endforeach; ?> <?php endif; ?> </span> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" + <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#subtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> - <?php echo __('Total incl. tax'); ?>:<br /> <?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedRowAmount()); ?> + <span class="weee" data-th="<?php echo $this->escapeHtml(__('Total incl. tax')); ?>"><?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedRowAmount()); ?></span> </span> <?php endif; ?> <?php endif; ?> </span> <?php endif; ?> + <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceExclTax()): ?> + <span class="excl tax" data-th="<?php echo $this->escapeHtml(__('Excl. Tax')); ?>"> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <span class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <?php else: ?> + <span class="cart price"> + <?php endif; ?> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()+$this->getItem()->getWeeeTaxAppliedRowAmount()+$this->getItem()->getWeeeTaxRowDisposition()); ?> + <?php else: ?> + <?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()) ?> + <?php endif; ?> + </span> + + <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> + <span class="cart-tax-info" id="esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display: none;"> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount']); ?></span> + <?php endforeach; ?> + <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></span> + <?php endforeach; ?> + <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></span> + <?php endforeach; ?> + <?php endif; ?> + </span> + + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <span class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <span class="weee" data-th="<?php echo $this->escapeHtml(__('Total')); ?>"><?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()+$this->getItem()->getWeeeTaxAppliedRowAmount()+$this->getItem()->getWeeeTaxRowDisposition()); ?></span> + </span> + <?php endif; ?> + <?php endif; ?> + </span> + <?php endif; ?> </td> </tr> diff --git a/app/code/Magento/Downloadable/view/frontend/templates/sales/order/items/renderer/downloadable.phtml b/app/code/Magento/Downloadable/view/frontend/templates/sales/order/items/renderer/downloadable.phtml index 2848b5b843b2afc3b083b2c6cb731a9fdd0a7683..a532caf89521fd37a3502cfc22c70d9a69f6b925 100644 --- a/app/code/Magento/Downloadable/view/frontend/templates/sales/order/items/renderer/downloadable.phtml +++ b/app/code/Magento/Downloadable/view/frontend/templates/sales/order/items/renderer/downloadable.phtml @@ -26,10 +26,10 @@ ?> <?php $_item = $this->getItem() ?> <tr id="order-item-row-<?php echo $_item->getId() ?>"> - <td class="col name"> - <strong class="product name"><?php echo $this->escapeHtml($_item->getName()) ?></strong> + <td class="col name" data-th="<?php echo $this->escapeHtml(__('Product Name')); ?>"> + <strong class="product name product-item-name"><?php echo $this->escapeHtml($_item->getName()) ?></strong> <?php if($_options = $this->getItemOptions()): ?> - <dl class="item options"> + <dl class="item options links"> <?php foreach ($_options as $_option) : ?> <dt><?php echo $this->escapeHtml($_option['label']) ?></dt> <?php if (!$this->getPrintStatus()): ?> @@ -55,7 +55,7 @@ <?php endif; ?> <?php /* downloadable */ ?> <?php if ($links = $this->getLinks()): ?> - <dl class="item options"> + <dl class="item options links"> <dt><?php echo $this->getLinksTitle() ?></dt> <?php foreach ($links->getPurchasedItems() as $link): ?> <dd><?php echo $this->escapeHtml($link->getLinkTitle()); ?></dd> @@ -78,251 +78,209 @@ </a> <?php endif; ?> </td> - <td class="col sku"><?php echo $this->prepareSku($this->getSku()) ?></td> - <td class="col price"> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceExclTax()): ?> - <span class="price excl tax"> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices()): ?> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart price"> - <?php endif; ?> - <span class="label"><?php echo __('Excl. Tax'); ?>:</span> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - </span> - <?php endif; ?> - <?php endif; ?> + <td class="col sku" data-th="<?php echo $this->escapeHtml(__('SKU')); ?>"><?php echo $this->prepareSku($this->getSku()) ?></td> + <td class="col price" data-th="<?php echo $this->escapeHtml(__('Price')); ?>"> + <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceInclTax()): ?> + <span class="incl tax" data-th="<?php echo $this->escapeHtml(__('Incl. Tax')); ?>"> + <?php $_incl = $this->helper('Magento\Checkout\Helper\Data')->getPriceInclTax($this->getItem()); ?> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" - data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <span class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#unit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> <?php else: ?> - <span class="cart price"> + <span class="cart price"> <?php endif; ?> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()+$this->getItem()->getWeeeTaxAppliedAmount()+$this->getItem()->getWeeeTaxDisposition()); ?> + <?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedAmount()); ?> <?php else: ?> - <?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()) ?> + <?php echo $this->getOrder()->formatPrice($_incl-$this->getItem()->getWeeeTaxDisposition()) ?> <?php endif; ?> - </span> + </span> <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> - <span class="cart tax info" id="eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>" - style="display:none;"> + <span class="cart-tax-info" id="unit-item-tax-details<?php echo $this->getItem()->getId(); ?>" + style="display: none;"> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount']); ?> - <?php endforeach; ?> - </small> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount']); ?></span> + <?php endforeach; ?> <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <small><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></small> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></span> <?php endforeach; ?> <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?> - <?php endforeach; ?> - </small> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></span> + <?php endforeach; ?> <?php endif; ?> - </span> + </span> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" - data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> - <?php echo __('Total'); ?>:<br /> <?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()+$this->getItem()->getWeeeTaxAppliedAmount()+$this->getItem()->getWeeeTaxDisposition()); ?> - </span> - <?php endif; ?> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <span class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#unit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <span class="weee" data-th="<?php echo $this->escapeHtml(__('Total incl. tax')); ?>"><?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedAmount()); ?></span> + </span> + <?php endif; ?> <?php endif; ?> </span> - <br /> <?php endif; ?> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceInclTax()): ?> - <span class="price incl tax"> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices()): ?> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceExclTax()): ?> + <span class="excl tax" data-th="<?php echo $this->escapeHtml(__('Excl. Tax')); ?>"> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <span class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <?php else: ?> <span class="cart price"> <?php endif; ?> - <span class="label"><?php echo __('Incl. Tax'); ?>:</span> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - </span> + + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()+$this->getItem()->getWeeeTaxAppliedAmount()+$this->getItem()->getWeeeTaxDisposition()); ?> + <?php else: ?> + <?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()) ?> <?php endif; ?> - <?php endif; ?> - <?php $_incl = $this->helper('Magento\Checkout\Helper\Data')->getPriceInclTax($this->getItem()); ?> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" - data-tax-toggle='{"itemTaxId" : "#unit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> - <?php else: ?> - <span class="cart price"> - <?php endif; ?> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedAmount()); ?> - <?php else: ?> - <?php echo $this->getOrder()->formatPrice($_incl-$this->getItem()->getWeeeTaxDisposition()) ?> - <?php endif; ?> - </span> + </span> - <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> - <span class="cart tax info" id="unit-item-tax-details<?php echo $this->getItem()->getId(); ?>" - style="display:none;"> + <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> + <span class="cart-tax-info" id="eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>" + style="display: none;"> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount']); ?> - <?php endforeach; ?> - </small> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount']); ?></span> + <?php endforeach; ?> <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <small><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></small> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></span> <?php endforeach; ?> <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?> - <?php endforeach; ?> - </small> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></span> + <?php endforeach; ?> <?php endif; ?> - </span> + </span> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" - data-tax-toggle='{"itemTaxId" : "#unit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> - <?php echo __('Total incl. tax'); ?>:<br /> <?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedAmount()); ?> - </span> - <?php endif; ?> - <?php endif; ?> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <span class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <span class="weee" data-th="<?php echo $this->escapeHtml(__('Total')); ?>"><?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()+$this->getItem()->getWeeeTaxAppliedAmount()+$this->getItem()->getWeeeTaxDisposition()); ?></span> + </span> + <?php endif; ?> + <?php endif; ?> </span> <?php endif; ?> </td> - <td class="col qty"> - <span class="qty summary"> + <td class="col qty" data-th="<?php echo $this->escapeHtml(__('Qty')); ?>"> + <ul class="items-qty"> <?php if ($this->getItem()->getQtyOrdered() > 0): ?> - <?php echo __('Ordered'); ?>: <strong><?php echo $this->getItem()->getQtyOrdered()*1 ?></strong><br /> + <li class="item"> + <span class="title"><?php echo __('Ordered'); ?></span> + <span class="content"><?php echo $this->getItem()->getQtyOrdered()*1 ?></span> + </li> <?php endif; ?> <?php if ($this->getItem()->getQtyShipped() > 0): ?> - <?php echo __('Shipped'); ?>: <strong><?php echo $this->getItem()->getQtyShipped()*1 ?></strong><br /> + <li class="item"> + <span class="title"><?php echo __('Shipped'); ?></span> + <span class="content"><?php echo $this->getItem()->getQtyShipped() * 1 ?></span> + </li> <?php endif; ?> <?php if ($this->getItem()->getQtyCanceled() > 0): ?> - <?php echo __('Canceled'); ?>: <strong><?php echo $this->getItem()->getQtyCanceled()*1 ?></strong><br /> + <li class="item"> + <span class="title"><?php echo __('Canceled'); ?></span> + <span class="content"><?php echo $this->getItem()->getQtyCanceled()*1 ?></span> + </li> <?php endif; ?> <?php if ($this->getItem()->getQtyRefunded() > 0): ?> - <?php echo __('Refunded'); ?>: <strong><?php echo $this->getItem()->getQtyRefunded()*1 ?></strong><br /> + <li class="item"> + <span class="title"><?php echo __('Refunded'); ?></span> + <span class="content"><?php echo $this->getItem()->getQtyRefunded()*1 ?></span> + </li> <?php endif; ?> - </span> + </ul> </td> - <td class="col subtotal"> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceExclTax()): ?> - <span class="price excl tax"> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices()): ?> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart price"> - <?php endif; ?> - <span class="label"><?php echo __('Excl. Tax'); ?>:</span> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - </span> - <?php endif; ?> - <?php endif; ?> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" - data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> - <?php else: ?> - <span class="cart price"> - <?php endif; ?> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()+$this->getItem()->getWeeeTaxAppliedRowAmount()+$this->getItem()->getWeeeTaxRowDisposition()); ?> - <?php else: ?> - <?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()) ?> - <?php endif; ?> - </span> - - <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> - <span class="cart tax info" id="esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>" - style="display:none;"> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount']); ?> - <?php endforeach; ?> - </small> - <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <small><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></small> - <?php endforeach; ?> - <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?> - <?php endforeach; ?> - </small> - <?php endif; ?> - </span> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" - data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> - <?php echo __('Total'); ?>:<br /> <?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()+$this->getItem()->getWeeeTaxAppliedRowAmount()+$this->getItem()->getWeeeTaxRowDisposition()); ?> - </span> - <?php endif; ?> - <?php endif; ?> - </span> - <br /> - <?php endif; ?> + <td class="col subtotal" data-th="<?php echo $this->escapeHtml(__('Subtotal')); ?>"> <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceInclTax()): ?> - <span class="price incl tax"> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices()): ?> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart price"> - <?php endif; ?> - <span class="label"><?php echo __('Incl. Tax'); ?>:</span> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - </span> - <?php endif; ?> - <?php endif; ?> - <?php $_incl = $this->helper('Magento\Checkout\Helper\Data')->getSubtotalInclTax($this->getItem()); ?> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" - data-tax-toggle='{"itemTaxId" : "#subtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <span class="incl tax" data-th="<?php echo $this->escapeHtml(__('Incl. Tax')); ?>"> + <?php $_incl = $this->helper('Magento\Checkout\Helper\Data')->getSubtotalInclTax($this->getItem()); ?> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <span class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#subtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> <?php else: ?> - <span class="cart price"> + <span class="cart price"> <?php endif; ?> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> <?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedRowAmount()); ?> <?php else: ?> <?php echo $this->getOrder()->formatPrice($_incl-$this->getItem()->getWeeeTaxRowDisposition()) ?> <?php endif; ?> - </span> + </span> <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> - <span class="cart tax info" + <span class="cart-tax-info" id="subtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>" - style="display:none;"> + style="display: none;"> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount']); ?> - <?php endforeach; ?> - </small> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount']); ?></span> + <?php endforeach; ?> <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <small><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></small> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></span> <?php endforeach; ?> <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?> - <?php endforeach; ?> - </small> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></span> + <?php endforeach; ?> <?php endif; ?> </span> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart tax total" + <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#subtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> - <?php echo __('Total incl. tax'); ?>:<br /> <?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedRowAmount()); ?> + <span class="weee" data-th="<?php echo $this->escapeHtml(__('Total incl. tax')); ?>"><?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedRowAmount()); ?></span> </span> <?php endif; ?> <?php endif; ?> </span> <?php endif; ?> + <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceExclTax()): ?> + <span class="excl tax" data-th="<?php echo $this->escapeHtml(__('Excl. Tax')); ?>"> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <span class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <?php else: ?> + <span class="cart price"> + <?php endif; ?> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()+$this->getItem()->getWeeeTaxAppliedRowAmount()+$this->getItem()->getWeeeTaxRowDisposition()); ?> + <?php else: ?> + <?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()) ?> + <?php endif; ?> + </span> + + <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> + <span class="cart-tax-info" id="esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>" + style="display: none;"> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount']); ?></span> + <?php endforeach; ?> + <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></span> + <?php endforeach; ?> + <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></span> + <?php endforeach; ?> + <?php endif; ?> + </span> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <span class="cart-tax-total" + data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <span class="weee" data-th="<?php echo $this->escapeHtml(__('Total')); ?>"><?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()+$this->getItem()->getWeeeTaxAppliedRowAmount()+$this->getItem()->getWeeeTaxRowDisposition()); ?></span> + </span> + <?php endif; ?> + <?php endif; ?> + </span> + <?php endif; ?> </td> <?php /* <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceExclTax()): ?> diff --git a/app/code/Magento/Eav/Model/Entity/AbstractEntity.php b/app/code/Magento/Eav/Model/Entity/AbstractEntity.php index 11ea1a7832db51028504ad60d2c5c77f477c2d29..d529aec6484a2a551955ae5f651cbf2afb62f6f8 100644 --- a/app/code/Magento/Eav/Model/Entity/AbstractEntity.php +++ b/app/code/Magento/Eav/Model/Entity/AbstractEntity.php @@ -59,13 +59,6 @@ abstract class AbstractEntity extends \Magento\Framework\Model\Resource\Abstract */ protected $_type; - /** - * Attributes array by attribute id - * - * @var array - */ - protected $_attributesById = array(); - /** * Attributes array by attribute name * @@ -395,7 +388,6 @@ abstract class AbstractEntity extends \Magento\Framework\Model\Resource\Abstract { if ($attributes === null) { $this->_attributesByCode = array(); - $this->_attributesById = array(); $this->_attributesByTable = array(); return $this; } @@ -414,7 +406,6 @@ abstract class AbstractEntity extends \Magento\Framework\Model\Resource\Abstract } $attr = $this->getAttribute($attrCode); - unset($this->_attributesById[$attr->getId()]); unset($this->_attributesByTable[$attr->getBackend()->getTable()][$attrCode]); unset($this->_attributesByCode[$attrCode]); } @@ -448,20 +439,12 @@ abstract class AbstractEntity extends \Magento\Framework\Model\Resource\Abstract $config = $this->_getConfig(); if (is_numeric($attribute)) { $attributeId = $attribute; - - if (isset($this->_attributesById[$attributeId])) { - return $this->_attributesById[$attributeId]; - } $attributeInstance = $config->getAttribute($this->getEntityType(), $attributeId); if ($attributeInstance) { $attributeCode = $attributeInstance->getAttributeCode(); } } elseif (is_string($attribute)) { $attributeCode = $attribute; - - if (isset($this->_attributesByCode[$attributeCode])) { - return $this->_attributesByCode[$attributeCode]; - } $attributeInstance = $config->getAttribute($this->getEntityType(), $attributeCode); if (!$attributeInstance->getAttributeCode() && in_array($attribute, $this->getDefaultAttributes())) { $attributeInstance->setAttributeCode( @@ -481,9 +464,6 @@ abstract class AbstractEntity extends \Magento\Framework\Model\Resource\Abstract } elseif ($attribute instanceof AbstractAttribute) { $attributeInstance = $attribute; $attributeCode = $attributeInstance->getAttributeCode(); - if (isset($this->_attributesByCode[$attributeCode])) { - return $this->_attributesByCode[$attributeCode]; - } } if (empty($attributeInstance) @@ -553,7 +533,6 @@ abstract class AbstractEntity extends \Magento\Framework\Model\Resource\Abstract if ($attribute->isStatic()) { $this->_staticAttributes[$attributeCode] = $attribute; } else { - $this->_attributesById[$attribute->getId()] = $attribute; $this->_attributesByTable[$attribute->getBackendTable()][$attributeCode] = $attribute; } @@ -798,16 +777,6 @@ abstract class AbstractEntity extends \Magento\Framework\Model\Resource\Abstract return $this->_attributesByCode; } - /** - * Get attributes by id array - * - * @return array - */ - public function getAttributesById() - { - return $this->_attributesById; - } - /** * Get attributes by table and name array * diff --git a/app/code/Magento/Eav/Model/Entity/Attribute/AbstractAttribute.php b/app/code/Magento/Eav/Model/Entity/Attribute/AbstractAttribute.php index d83511426262381fb7273f003e60fa58c2ac18be..c289d5d71e25340cf001c527dab0e27383231df0 100644 --- a/app/code/Magento/Eav/Model/Entity/Attribute/AbstractAttribute.php +++ b/app/code/Magento/Eav/Model/Entity/Attribute/AbstractAttribute.php @@ -643,7 +643,7 @@ abstract class AbstractAttribute extends \Magento\Framework\Model\AbstractModel { // If source model exists - get definition from it if ($this->usesSource() && $this->getBackendType() != self::TYPE_STATIC) { - return $this->getSource()->getFlatColums(); + return $this->getSource()->getFlatColumns(); } return $this->_getFlatColumnsDdlDefinition(); } diff --git a/app/code/Magento/Eav/Model/Entity/Attribute/Source/AbstractSource.php b/app/code/Magento/Eav/Model/Entity/Attribute/Source/AbstractSource.php index 58409bed4002ef969595b470ae3d737d3d8c46f5..8a638ffef270ab9065a5c714f24061edb585534e 100644 --- a/app/code/Magento/Eav/Model/Entity/Attribute/Source/AbstractSource.php +++ b/app/code/Magento/Eav/Model/Entity/Attribute/Source/AbstractSource.php @@ -123,7 +123,7 @@ abstract class AbstractSource implements * * @return array */ - public function getFlatColums() + public function getFlatColumns() { return array(); } diff --git a/app/code/Magento/Eav/Model/Entity/Attribute/Source/Boolean.php b/app/code/Magento/Eav/Model/Entity/Attribute/Source/Boolean.php index d46f352430cfee9db95369a3204b664d180c7fb3..78d9b2121e8ee1d53c97b6b469535a477a1d6445 100644 --- a/app/code/Magento/Eav/Model/Entity/Attribute/Source/Boolean.php +++ b/app/code/Magento/Eav/Model/Entity/Attribute/Source/Boolean.php @@ -108,16 +108,21 @@ class Boolean extends \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource * * @return array */ - public function getFlatColums() + public function getFlatColumns() { $attributeCode = $this->getAttribute()->getAttributeCode(); - $column = array('unsigned' => false, 'default' => null, 'extra' => null); - $column['type'] = \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT; - $column['length'] = 1; - $column['nullable'] = true; - $column['comment'] = $attributeCode . ' column'; - return array($attributeCode => $column); + return [ + $attributeCode => [ + 'unsigned' => false, + 'default' => null, + 'extra' => null, + 'type' => \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT, + 'length' => 1, + 'nullable' => true, + 'comment' => $attributeCode . ' column', + ], + ]; } /** @@ -163,4 +168,58 @@ class Boolean extends \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource return parent::getIndexOptionText($value); } + + /** + * Add Value Sort To Collection Select + * + * @param \Magento\Eav\Model\Entity\Collection\AbstractCollection $collection + * @param string $dir + * + * @return \Magento\Eav\Model\Entity\Attribute\Source\Boolean + */ + public function addValueSortToCollection($collection, $dir = \Magento\Framework\DB\Select::SQL_ASC) + { + $attributeCode = $this->getAttribute()->getAttributeCode(); + $attributeId = $this->getAttribute()->getId(); + $attributeTable = $this->getAttribute()->getBackend()->getTable(); + + if ($this->getAttribute()->isScopeGlobal()) { + $tableName = $attributeCode . '_t'; + $collection->getSelect() + ->joinLeft( + array($tableName => $attributeTable), + "e.entity_id={$tableName}.entity_id" + . " AND {$tableName}.attribute_id='{$attributeId}'" + . " AND {$tableName}.store_id='0'", + array() + ); + $valueExpr = $tableName . '.value'; + } else { + $valueTable1 = $attributeCode . '_t1'; + $valueTable2 = $attributeCode . '_t2'; + $collection->getSelect() + ->joinLeft( + array($valueTable1 => $attributeTable), + "e.entity_id={$valueTable1}.entity_id" + . " AND {$valueTable1}.attribute_id='{$attributeId}'" + . " AND {$valueTable1}.store_id='0'", + array() + ) + ->joinLeft( + array($valueTable2 => $attributeTable), + "e.entity_id={$valueTable2}.entity_id" + . " AND {$valueTable2}.attribute_id='{$attributeId}'" + . " AND {$valueTable2}.store_id='{$collection->getStoreId()}'", + array() + ); + $valueExpr = $collection->getConnection()->getCheckSql( + $valueTable2 . '.value_id > 0', + $valueTable2 . '.value', + $valueTable1 . '.value' + ); + } + + $collection->getSelect()->order($valueExpr . ' ' . $dir); + return $this; + } } diff --git a/app/code/Magento/Eav/Model/Entity/Attribute/Source/Table.php b/app/code/Magento/Eav/Model/Entity/Attribute/Source/Table.php index 79e2d56f18cd3d0a3cc0e724bbca9078b9ebcbf8..b159e60b695de34eb1f9e000a7c1a33026535ed9 100644 --- a/app/code/Magento/Eav/Model/Entity/Attribute/Source/Table.php +++ b/app/code/Magento/Eav/Model/Entity/Attribute/Source/Table.php @@ -180,7 +180,7 @@ class Table extends \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource * * @return array */ - public function getFlatColums() + public function getFlatColumns() { $columns = array(); $attributeCode = $this->getAttribute()->getAttributeCode(); diff --git a/app/code/Magento/Fedex/Model/Carrier.php b/app/code/Magento/Fedex/Model/Carrier.php index 8582336c63588e22be78146d49a16898ca2b1462..10a02701ac657da41c907c52bc4c4ae965b49f03 100644 --- a/app/code/Magento/Fedex/Model/Carrier.php +++ b/app/code/Magento/Fedex/Model/Carrier.php @@ -414,7 +414,10 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C 'PackageDetail' => 'INDIVIDUAL_PACKAGES', 'RequestedPackageLineItems' => array( '0' => array( - 'Weight' => array('Value' => (double)$r->getWeight(), 'Units' => 'LB'), + 'Weight' => [ + 'Value' => (double)$r->getWeight(), + 'Units' => $this->getConfigData('unit_of_measure') + ], 'GroupPackageCount' => 1 ) ) @@ -509,7 +512,12 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C if (is_object($response)) { if ($response->HighestSeverity == 'FAILURE' || $response->HighestSeverity == 'ERROR') { - $errorTitle = (string)$response->Notifications->Message; + if (is_array($response->Notifications)) { + $notification = array_pop($response->Notifications); + $errorTitle = (string)$notification->Message; + } else { + $errorTitle = (string)$response->Notifications->Message; + } } elseif (isset($response->RateReplyDetails)) { $allowedMethods = explode(",", $this->getConfigData('allowed_methods')); @@ -916,7 +924,11 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C 'ADULT' => __('Adult'), 'DIRECT' => __('Direct'), 'INDIRECT' => __('Indirect') - ) + ), + 'unit_of_measure' => array( + 'LB' => __('Pounds'), + 'KG' => __('Kilograms'), + ), ); if (!isset($codes[$type])) { diff --git a/app/code/Magento/Fedex/Model/Source/Unitofmeasure.php b/app/code/Magento/Fedex/Model/Source/Unitofmeasure.php new file mode 100644 index 0000000000000000000000000000000000000000..227c35619152e67e49768dacbcccd2d3c8a67e8a --- /dev/null +++ b/app/code/Magento/Fedex/Model/Source/Unitofmeasure.php @@ -0,0 +1,35 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Fedex\Model\Source; + +class Unitofmeasure extends Generic +{ + /** + * Carrier code + * + * @var string + */ + protected $_code = 'unit_of_measure'; +} diff --git a/app/code/Magento/Fedex/etc/adminhtml/system.xml b/app/code/Magento/Fedex/etc/adminhtml/system.xml index c718b28fad57e886abba7e50421ee657787545b0..bac1cfe664e523e7446b196fdfaa9cd092b6929a 100644 --- a/app/code/Magento/Fedex/etc/adminhtml/system.xml +++ b/app/code/Magento/Fedex/etc/adminhtml/system.xml @@ -80,6 +80,10 @@ <label>Dropoff</label> <source_model>Magento\Fedex\Model\Source\Dropoff</source_model> </field> + <field id="unit_of_measure" translate="label" type="select" sortOrder="135" showInDefault="1" showInWebsite="1" showInStore="0"> + <label>Weight Unit</label> + <source_model>Magento\Fedex\Model\Source\Unitofmeasure</source_model> + </field> <field id="max_package_weight" translate="label" type="text" sortOrder="140" showInDefault="1" showInWebsite="1" showInStore="0"> <label>Maximum Package Weight (Please consult your shipping carrier for maximum supported shipping weight)</label> <validate>validate-number validate-zero-or-greater</validate> diff --git a/app/code/Magento/Fedex/etc/config.xml b/app/code/Magento/Fedex/etc/config.xml index a8ceb55fc54c716aec3508166b308588b3e376c3..04ac4ac73ecb293fb7b22c6f36080c432c38f256 100644 --- a/app/code/Magento/Fedex/etc/config.xml +++ b/app/code/Magento/Fedex/etc/config.xml @@ -46,6 +46,7 @@ <packaging>YOUR_PACKAGING</packaging> <title>Federal Express</title> <specificerrmsg>This shipping method is currently unavailable. If you would like to ship using this shipping method, please contact us.</specificerrmsg> + <unit_of_measure>LB</unit_of_measure> <max_package_weight>150</max_package_weight> <handling_type>F</handling_type> <handling_action>O</handling_action> diff --git a/app/code/Magento/GiftMessage/Block/Message/Inline.php b/app/code/Magento/GiftMessage/Block/Message/Inline.php index 988d4a170a949c89d4b41084cef373d5d94ad012..0c4632143976760918191b1980876099c687fb86 100644 --- a/app/code/Magento/GiftMessage/Block/Message/Inline.php +++ b/app/code/Magento/GiftMessage/Block/Message/Inline.php @@ -74,6 +74,13 @@ class Inline extends \Magento\Framework\View\Element\Template */ protected $httpContext; + /** + * Checkout type. 'onepage_checkout' and 'multishipping_address' are standard types + * + * @var string + */ + protected $checkoutType; + /** * @param \Magento\Framework\View\Element\Template\Context $context * @param \Magento\Customer\Model\Session $customerSession @@ -142,6 +149,28 @@ class Inline extends \Magento\Framework\View\Element\Template return $this->_type; } + /** + * Define checkout type + * + * @param $type string + * @return $this + */ + public function setCheckoutType($type) + { + $this->checkoutType = $type; + return $this; + } + + /** + * Return checkout type. Typical values are 'onepage_checkout' and 'multishipping_address' + * + * @return string|null + */ + public function getCheckoutType() + { + return $this->checkoutType; + } + /** * Check if entity has gift message * diff --git a/app/code/Magento/GiftMessage/Helper/Message.php b/app/code/Magento/GiftMessage/Helper/Message.php index 2fda8626750f8704e8954c9b51afbcaeb333c109..89f72ee85a9148e19a76703b23ebc69c6d2429c2 100644 --- a/app/code/Magento/GiftMessage/Helper/Message.php +++ b/app/code/Magento/GiftMessage/Helper/Message.php @@ -135,7 +135,7 @@ class Message extends \Magento\Core\Helper\Data ->setId('giftmessage_form_' . $this->_nextId++) ->setDontDisplayContainer($dontDisplayContainer) ->setEntity($entity) - ->setType($type)->toHtml(); + ->setCheckoutType($type)->toHtml(); } /** diff --git a/app/code/Magento/GiftMessage/Model/Observer.php b/app/code/Magento/GiftMessage/Model/Observer.php index 74e695535a76ab5c73bbeb9e473a7cd5b8fbee25..f8d4830fa280a664a030b742221c7b4d0c080bb5 100644 --- a/app/code/Magento/GiftMessage/Model/Observer.php +++ b/app/code/Magento/GiftMessage/Model/Observer.php @@ -93,12 +93,14 @@ class Observer extends \Magento\Framework\Object $giftMessages = $observer->getEvent()->getRequest()->getParam('giftmessage'); $quote = $observer->getEvent()->getQuote(); /* @var $quote \Magento\Sales\Model\Quote */ - if (is_array($giftMessages)) { - foreach ($giftMessages as $entityId => $message) { - + if (!is_array($giftMessages)) { + return $this; + } + // types are 'quote', 'quote_item', etc + foreach ($giftMessages as $type => $giftMessageEntities) { + foreach ($giftMessageEntities as $entityId => $message) { $giftMessage = $this->_messageFactory->create(); - - switch ($message['type']) { + switch ($type) { case 'quote': $entity = $quote; break; diff --git a/app/code/Magento/GiftMessage/Model/Save.php b/app/code/Magento/GiftMessage/Model/Save.php index f4755a70c55f2ae0a91f3934885a43a3ad0e181f..af93ab1fa55d6b90bcf7409ba69f83f39acac5c2 100644 --- a/app/code/Magento/GiftMessage/Model/Save.php +++ b/app/code/Magento/GiftMessage/Model/Save.php @@ -89,7 +89,7 @@ class Save extends \Magento\Framework\Object } foreach ($giftmessages as $entityId => $giftmessage) { - $this->_saveOne($entityId, $giftmessage); + $this->_saveOne($entityId, $giftmessage, 'quote'); } return $this; @@ -108,14 +108,17 @@ class Save extends \Magento\Framework\Object */ public function saveAllInOrder() { - $giftmessages = $this->getGiftmessages(); + $giftMessages = $this->getGiftmessages(); - if (!is_array($giftmessages)) { + if (!is_array($giftMessages)) { return $this; } - foreach ($giftmessages as $entityId => $giftmessage) { - $this->_saveOne($entityId, $giftmessage); + // types are 'quote', 'quote_item', etc + foreach ($giftMessages as $type => $giftMessageEntities) { + foreach ($giftMessageEntities as $entityId => $giftmessage) { + $this->_saveOne($entityId, $giftmessage, $type); + } } return $this; @@ -126,13 +129,13 @@ class Save extends \Magento\Framework\Object * * @param int $entityId * @param array $giftmessage + * @param string $entityType * @return $this */ - protected function _saveOne($entityId, $giftmessage) + protected function _saveOne($entityId, $giftmessage, $entityType) { /* @var $giftmessageModel \Magento\GiftMessage\Model\Message */ $giftmessageModel = $this->_messageFactory->create(); - $entityType = $this->_getMappedType($giftmessage['type']); switch ($entityType) { case 'quote': @@ -343,23 +346,6 @@ class Save extends \Magento\Framework\Object return $this; } - /** - * Retrieve mapped type for entity - * - * @param string $type - * @return string|null - */ - protected function _getMappedType($type) - { - $map = array('main' => 'quote', 'item' => 'quote_item', 'order' => 'order', 'order_item' => 'order_item'); - - if (isset($map[$type])) { - return $map[$type]; - } - - return null; - } - /** * Retrieve quote object * diff --git a/app/code/Magento/GiftMessage/view/frontend/templates/inline.phtml b/app/code/Magento/GiftMessage/view/frontend/templates/inline.phtml index 42e7020c4666bf3fa8ee464ba746a06a0a052349..a313569ac833bf95804e3467b4867ff9bf87fa78 100644 --- a/app/code/Magento/GiftMessage/view/frontend/templates/inline.phtml +++ b/app/code/Magento/GiftMessage/view/frontend/templates/inline.phtml @@ -29,7 +29,7 @@ </script> <?php endif ?> -<?php switch ($this->getType()): ?> +<?php switch ($this->getCheckoutType()): ?> <?php case 'onepage_checkout': ?> <fieldset class="fieldset gift-message"> <legend class="legend"><span><?php echo __('Do you have any gift items in your order?'); ?></span></legend><br> @@ -50,28 +50,26 @@ <dd id="allow-gift-options-for-order-container" class="order-options"> <div class="options-order-container" id="options-order-container-<?php echo $this->getEntity()->getId() ?>"></div> - <input type="hidden" name="giftoptions[<?php echo $this->getEntity()->getId() ?>][type]" value="quote" /> <a href="#" class="action activate message" data-mage-init='{"toggleAdvanced": {"selectorsToggleClass":"hidden", "toggleContainers":"#allow-gift-messages-for-order-container"}}'><?php echo __('Gift Message') ?></a> <div id="allow-gift-messages-for-order-container" class="gift-messages-order hidden"> <fieldset class="fieldset"> - <input type="hidden" name="giftmessage[<?php echo $this->getEntity()->getId() ?>][type]" value="quote" /> <p><?php echo __('If you don\'t want to leave a gift message for the entire order, leave this box blank.') ?></p> <div class="field from"> <label for="gift-message-whole-from" class="label"><span><?php echo __('From') ?></span></label> <div class="control"> - <input type="text" name="giftmessage[<?php echo $this->getEntity()->getId() ?>][from]" id="gift-message-whole-from" title="<?php echo __('From') ?>" value="<?php echo $this->getEscaped($this->getMessage()->getSender(), $this->getDefaultFrom()) ?>" class="input-text"> + <input type="text" name="giftmessage[quote][<?php echo $this->getEntity()->getId() ?>][from]" id="gift-message-whole-from" title="<?php echo __('From') ?>" value="<?php echo $this->getEscaped($this->getMessage()->getSender(), $this->getDefaultFrom()) ?>" class="input-text"> </div> </div> <div class="field to"> <label for="gift-message-whole-to" class="label"><span><?php echo __('To') ?></span></label> <div class="control"> - <input type="text" name="giftmessage[<?php echo $this->getEntity()->getId() ?>][to]" id="gift-message-whole-to" title="<?php echo __('To') ?>" value="<?php echo $this->getEscaped($this->getMessage()->getRecipient(), $this->getDefaultTo()) ?>" class="input-text"> + <input type="text" name="giftmessage[quote][<?php echo $this->getEntity()->getId() ?>][to]" id="gift-message-whole-to" title="<?php echo __('To') ?>" value="<?php echo $this->getEscaped($this->getMessage()->getRecipient(), $this->getDefaultTo()) ?>" class="input-text"> </div> </div> <div class="field text"> <label for="gift-message-whole-message" class="label"><span><?php echo __('Message') ?></span></label> <div class="control"> - <textarea id="gift-message-whole-message" class="input-text" name="giftmessage[<?php echo $this->getEntity()->getId() ?>][message]" title="<?php echo __('Message') ?>" rows="5" cols="10"><?php echo $this->getEscaped($this->getMessage()->getMessage()) ?></textarea> + <textarea id="gift-message-whole-message" class="input-text" name="giftmessage[quote][<?php echo $this->getEntity()->getId() ?>][message]" title="<?php echo __('Message') ?>" rows="5" cols="10"><?php echo $this->getEscaped($this->getMessage()->getMessage()) ?></textarea> </div> </div> </fieldset> @@ -95,7 +93,6 @@ <?php foreach($this->getItems() as $_index=>$_item): ?> <?php $_product=$_item->getProduct() ?> <li class="item"> - <input type="hidden" name="giftoptions[<?php echo $_item->getId() ?>][type]" value="quote_item" /> <div class="product"> <div class="number"> <?php echo __('<span>Item %1</span> of %2', $_index+1, $this->countItems()) ?> @@ -113,23 +110,22 @@ <div id="gift-messages-for-item-container-<?php echo $_item->getId() ?>" class="block message hidden"> <fieldset class="fieldset"> <p><?php echo __('You can leave a box blank if you don\'t wish to add a gift message for the item.') ?></p> - <input type="hidden" name="giftmessage[<?php echo $_item->getId() ?>][type]" value="quote_item" > <div class="field from"> <label for="gift-message-<?php echo $_item->getId() ?>-from" class="label"><span><?php echo __('From') ?></span></label> <div class="control"> - <input type="text" name="giftmessage[<?php echo $_item->getId() ?>][from]" id="gift-message-<?php echo $_item->getId() ?>-from" title="<?php echo __('From') ?>" value="<?php echo $this->getEscaped($this->getMessage($_item)->getSender(), $this->getDefaultFrom()) ?>" class="input-text"> + <input type="text" name="giftmessage[quote_item][<?php echo $_item->getId() ?>][from]" id="gift-message-<?php echo $_item->getId() ?>-from" title="<?php echo __('From') ?>" value="<?php echo $this->getEscaped($this->getMessage($_item)->getSender(), $this->getDefaultFrom()) ?>" class="input-text"> </div> </div> <div class="field to"> <label for="gift-message-<?php echo $_item->getId() ?>-to" class="label"><span><?php echo __('To') ?></span></label> <div class="control"> - <input type="text" name="giftmessage[<?php echo $_item->getId() ?>][to]" id="gift-message-<?php echo $_item->getId() ?>-to" title="<?php echo __('To') ?>" value="<?php echo $this->getEscaped($this->getMessage($_item)->getRecipient(), $this->getDefaultTo()) ?>" class="input-text"> + <input type="text" name="giftmessage[quote_item][<?php echo $_item->getId() ?>][to]" id="gift-message-<?php echo $_item->getId() ?>-to" title="<?php echo __('To') ?>" value="<?php echo $this->getEscaped($this->getMessage($_item)->getRecipient(), $this->getDefaultTo()) ?>" class="input-text"> </div> </div> <div class="field text"> <label for="gift-message-<?php echo $_item->getId() ?>-message" class="label"><span><?php echo __('Message') ?></span></label> <div class="control"> - <textarea id="gift-message-<?php echo $_item->getId() ?>-message" class="input-text giftmessage-area" name="giftmessage[<?php echo $_item->getId() ?>][message]" title="<?php echo __('Message') ?>" rows="5" cols="40"><?php echo $this->getEscaped($this->getMessage($_item)->getMessage()) ?></textarea> + <textarea id="gift-message-<?php echo $_item->getId() ?>-message" class="input-text giftmessage-area" name="giftmessage[quote_item][<?php echo $_item->getId() ?>][message]" title="<?php echo __('Message') ?>" rows="5" cols="40"><?php echo $this->getEscaped($this->getMessage($_item)->getMessage()) ?></textarea> </div> </div> </fieldset> @@ -173,30 +169,28 @@ <dd id="allow-gift-options-for-order-container-<?php echo $this->getEntity()->getId() ?>" class="order-options"> <div class="options-order-container" id="options-order-container-<?php echo $this->getEntity()->getId() ?>"></div> - <input type="hidden" name="giftoptions[<?php echo $this->getEntity()->getId() ?>][type]" value="quote_address" /> <?php if ($this->isMessagesAvailable()): ?> <?php $_giftMessage = true; ?> <a href="#" class="action activate message" data-mage-init='{"toggleAdvanced": {"selectorsToggleClass":"hidden", "toggleContainers":"#gift-messages-for-order-container-<?php echo $this->getEntity()->getId() ?>"}}'><?php echo __('Gift Message') ?></a> <div id="gift-messages-for-order-container-<?php echo $this->getEntity()->getId() ?>" class="block message hidden"> <fieldset class="fieldset"> <p><?php echo __('You can leave this box blank if you do not wish to add a gift message for this address.') ?></p> - <input type="hidden" name="giftmessage[<?php echo $this->getEntity()->getId() ?>][type]" value="quote_address" /> <div class="field from"> <label for="gift-message-<?php echo $this->getEntity()->getId() ?>-from" class="label"><span><?php echo __('From') ?></span></label> <div class="control"> - <input type="text" name="giftmessage[<?php echo $this->getEntity()->getId() ?>][from]" id="gift-message-<?php echo $this->getEntity()->getId() ?>-from" title="<?php echo __('From') ?>" value="<?php echo $this->getEscaped($this->getMessage()->getSender(), $this->getDefaultFrom()) ?>" class="input-text"> + <input type="text" name="giftmessage[quote_address][<?php echo $this->getEntity()->getId() ?>][from]" id="gift-message-<?php echo $this->getEntity()->getId() ?>-from" title="<?php echo __('From') ?>" value="<?php echo $this->getEscaped($this->getMessage()->getSender(), $this->getDefaultFrom()) ?>" class="input-text"> </div> </div> <div class="field to"> <label for="gift-message-<?php echo $this->getEntity()->getId() ?>-to" class="label"><span><?php echo __('To') ?></span></label> <div class="control"> - <input type="text" name="giftmessage[<?php echo $this->getEntity()->getId() ?>][to]" id="gift-message-<?php echo $this->getEntity()->getId() ?>-to" title="<?php echo __('To') ?>" value="<?php echo $this->getEscaped($this->getMessage()->getRecipient(), $this->getDefaultTo()) ?>" class="input-text"> + <input type="text" name="giftmessage[quote_address][<?php echo $this->getEntity()->getId() ?>][to]" id="gift-message-<?php echo $this->getEntity()->getId() ?>-to" title="<?php echo __('To') ?>" value="<?php echo $this->getEscaped($this->getMessage()->getRecipient(), $this->getDefaultTo()) ?>" class="input-text"> </div> </div> <div class="field text"> <label for="gift-message-<?php echo $this->getEntity()->getId() ?>-message" class="label"><span><?php echo __('Message') ?></span></label> <div class="control"> - <textarea id="gift-message-<?php echo $this->getEntity()->getId() ?>-message" class="input-text" name="giftmessage[<?php echo $this->getEntity()->getId() ?>][message]" title="<?php echo __('Message') ?>" rows="5" cols="40"><?php echo $this->getEscaped($this->getMessage()->getMessage()) ?></textarea> + <textarea id="gift-message-<?php echo $this->getEntity()->getId() ?>-message" class="input-text" name="giftmessage[quote_address][<?php echo $this->getEntity()->getId() ?>][message]" title="<?php echo __('Message') ?>" rows="5" cols="40"><?php echo $this->getEscaped($this->getMessage()->getMessage()) ?></textarea> </div> </div> </fieldset> @@ -228,8 +222,7 @@ </div> <div class="item options"> <div class="options-items-container" id="options-items-container-<?php echo $this->getEntity()->getId() ?>-<?php echo $_item->getId() ?>"></div> - <input type="hidden" name="giftoptions[<?php echo $_item->getId() ?>][type]" value="quote_address_item" /> - <input type="hidden" name="giftoptions[<?php echo $_item->getId() ?>][address]" value="<?php echo $this->getEntity()->getId()?>" /> + <input type="hidden" name="giftoptions[quote_address_item][<?php echo $_item->getId() ?>][address]" value="<?php echo $this->getEntity()->getId()?>" /> <?php if ($this->isItemMessagesAvailable($_item)): ?> <?php $_giftMessage = true; ?> @@ -237,24 +230,23 @@ <div id="gift-messages-for-item-container-<?php echo $_item->getId() ?>" class="block message hidden"> <fieldset class="fieldset"> <p><?php echo __('You can leave this box blank if you do not wish to add a gift message for the item.') ?></p> - <input type="hidden" name="giftmessage[<?php echo $_item->getId() ?>][type]" value="quote_address_item" /> - <input type="hidden" name="giftmessage[<?php echo $_item->getId() ?>][address]" value="<?php echo $this->getEntity()->getId()?>" /> + <input type="hidden" name="giftmessage[quote_address_item][<?php echo $_item->getId() ?>][address]" value="<?php echo $this->getEntity()->getId()?>" /> <div class="field from"> <label for="gift-message-<?php echo $_item->getId() ?>-from" class="label"><span><?php echo __('From') ?></span></label> <div class="control"> - <input type="text" name="giftmessage[<?php echo $_item->getId() ?>][from]" id="gift-message-<?php echo $_item->getId() ?>-from" title="<?php echo __('From') ?>" value="<?php echo $this->getEscaped($this->getMessage($_item)->getSender(), $this->getDefaultFrom()) ?>" class="input-text"> + <input type="text" name="giftmessage[quote_address_item][<?php echo $_item->getId() ?>][from]" id="gift-message-<?php echo $_item->getId() ?>-from" title="<?php echo __('From') ?>" value="<?php echo $this->getEscaped($this->getMessage($_item)->getSender(), $this->getDefaultFrom()) ?>" class="input-text"> </div> </div> <div class="field to"> <label for="gift-message-<?php echo $_item->getId() ?>-to" class="label"><span><?php echo __('To') ?></span></label> <div class="control"> - <input type="text" name="giftmessage[<?php echo $_item->getId() ?>][to]" id="gift-message-<?php echo $_item->getId() ?>-to" title="<?php echo __('To') ?>" value="<?php echo $this->getEscaped($this->getMessage($_item)->getRecipient(), $this->getDefaultTo()) ?>" class="input-text"> + <input type="text" name="giftmessage[quote_address_item][<?php echo $_item->getId() ?>][to]" id="gift-message-<?php echo $_item->getId() ?>-to" title="<?php echo __('To') ?>" value="<?php echo $this->getEscaped($this->getMessage($_item)->getRecipient(), $this->getDefaultTo()) ?>" class="input-text"> </div> </div> <div class="field text"> <label for="gift-message-<?php echo $_item->getId() ?>-message" class="label"><span><?php echo __('Message') ?></span></label> <div class="control"> - <textarea id="gift-message-<?php echo $_item->getId() ?>-message" class="input-text giftmessage-area" name="giftmessage[<?php echo $_item->getId() ?>][message]" title="<?php echo __('Message') ?>" rows="5" cols="10"><?php echo $this->getEscaped($this->getMessage($_item)->getMessage()) ?></textarea> + <textarea id="gift-message-<?php echo $_item->getId() ?>-message" class="input-text giftmessage-area" name="giftmessage[quote_address_item][<?php echo $_item->getId() ?>][message]" title="<?php echo __('Message') ?>" rows="5" cols="10"><?php echo $this->getEscaped($this->getMessage($_item)->getMessage()) ?></textarea> </div> </div> </fieldset> diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/LoadAttributeSetsAction.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/LoadAttributeSets.php similarity index 92% rename from app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/LoadAttributeSetsAction.php rename to app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/LoadAttributeSets.php index 45c9a5fed4dc4f897658ef3ecda22b656e749036..0662d2865df6bd0c43f2f2f99cedc7c15e37e01b 100644 --- a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/LoadAttributeSetsAction.php +++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/LoadAttributeSets.php @@ -24,14 +24,14 @@ */ namespace Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\Types; -class LoadAttributeSetsAction extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\Types +class LoadAttributeSets extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\Types { /** * Get available attribute sets * * @return void */ - protected function execute() + public function execute() { try { $this->getResponse()->setBody( diff --git a/app/code/Magento/GoogleShopping/Model/Attribute.php b/app/code/Magento/GoogleShopping/Model/Attribute.php index 04e83ec06952973e094ba9e343a91ca339563aca..39981db43b7f1a3fffd520f682f8b2d44c4acc38 100644 --- a/app/code/Magento/GoogleShopping/Model/Attribute.php +++ b/app/code/Magento/GoogleShopping/Model/Attribute.php @@ -67,7 +67,7 @@ class Attribute extends \Magento\Framework\Model\AbstractModel /** * @var \Magento\GoogleShopping\Helper\Data|null */ - protected $_gsData = null; + protected $_googleShoppingHelper = null; /** * @var \Magento\GoogleShopping\Helper\Product|null @@ -90,7 +90,7 @@ class Attribute extends \Magento\Framework\Model\AbstractModel * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry * @param \Magento\Catalog\Model\ProductFactory $productFactory - * @param \Magento\GoogleShopping\Helper\Data $gsData + * @param \Magento\GoogleShopping\Helper\Data $googleShoppingHelper * @param \Magento\GoogleShopping\Helper\Product $gsProduct * @param \Magento\Catalog\Model\Product\CatalogPrice $catalogPrice * @param \Magento\GoogleShopping\Model\Resource\Attribute $resource @@ -101,7 +101,7 @@ class Attribute extends \Magento\Framework\Model\AbstractModel \Magento\Framework\Model\Context $context, \Magento\Framework\Registry $registry, \Magento\Catalog\Model\ProductFactory $productFactory, - \Magento\GoogleShopping\Helper\Data $gsData, + \Magento\GoogleShopping\Helper\Data $googleShoppingHelper, \Magento\GoogleShopping\Helper\Product $gsProduct, \Magento\Catalog\Model\Product\CatalogPrice $catalogPrice, \Magento\GoogleShopping\Model\Resource\Attribute $resource, @@ -109,7 +109,7 @@ class Attribute extends \Magento\Framework\Model\AbstractModel array $data = array() ) { $this->_productFactory = $productFactory; - $this->_gsData = $gsData; + $this->_googleShoppingHelper = $googleShoppingHelper; $this->_gsProduct = $gsProduct; $this->catalogPrice = $catalogPrice; parent::__construct($context, $registry, $resource, $resourceCollection, $data); diff --git a/app/code/Magento/GoogleShopping/Model/Attribute/Content.php b/app/code/Magento/GoogleShopping/Model/Attribute/Content.php index b750290f0f9762b72fcb30a19acfdfdbbcbb0b0e..d1667bbd47f5ee8335de9d261c3b669fc74faf56 100644 --- a/app/code/Magento/GoogleShopping/Model/Attribute/Content.php +++ b/app/code/Magento/GoogleShopping/Model/Attribute/Content.php @@ -53,7 +53,7 @@ class Content extends \Magento\GoogleShopping\Model\Attribute\DefaultAttribute } else { $descrText = 'no description'; } - $descrText = $this->_gsData->cleanAtomAttribute($descrText); + $descrText = $this->_googleShoppingHelper->cleanAtomAttribute($descrText); $entry->setContent($entry->getService()->newContent()->setText($descrText)); return $entry; diff --git a/app/code/Magento/GoogleShopping/Model/Attribute/ContentLanguage.php b/app/code/Magento/GoogleShopping/Model/Attribute/ContentLanguage.php index 899e8ca3dc4813448e4139a0d34fa4696aed58f3..ced7722ed051a356e4bee98ec7f36eaef57abf87 100644 --- a/app/code/Magento/GoogleShopping/Model/Attribute/ContentLanguage.php +++ b/app/code/Magento/GoogleShopping/Model/Attribute/ContentLanguage.php @@ -41,7 +41,7 @@ class ContentLanguage extends \Magento\GoogleShopping\Model\Attribute\DefaultAtt * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry * @param \Magento\Catalog\Model\ProductFactory $productFactory - * @param \Magento\GoogleShopping\Helper\Data $gsData + * @param \Magento\GoogleShopping\Helper\Data $googleShoppingHelper * @param \Magento\GoogleShopping\Helper\Product $gsProduct * @param \Magento\Catalog\Model\Product\CatalogPrice $catalogPrice * @param \Magento\GoogleShopping\Model\Resource\Attribute $resource @@ -53,7 +53,7 @@ class ContentLanguage extends \Magento\GoogleShopping\Model\Attribute\DefaultAtt \Magento\Framework\Model\Context $context, \Magento\Framework\Registry $registry, \Magento\Catalog\Model\ProductFactory $productFactory, - \Magento\GoogleShopping\Helper\Data $gsData, + \Magento\GoogleShopping\Helper\Data $googleShoppingHelper, \Magento\GoogleShopping\Helper\Product $gsProduct, \Magento\Catalog\Model\Product\CatalogPrice $catalogPrice, \Magento\GoogleShopping\Model\Resource\Attribute $resource, @@ -66,7 +66,7 @@ class ContentLanguage extends \Magento\GoogleShopping\Model\Attribute\DefaultAtt $context, $registry, $productFactory, - $gsData, + $googleShoppingHelper, $gsProduct, $catalogPrice, $resource, diff --git a/app/code/Magento/GoogleShopping/Model/Attribute/Destinations.php b/app/code/Magento/GoogleShopping/Model/Attribute/Destinations.php index f11012039661b5edc1506a15fe7f31fc91f5c624..a553543885b21582daecea287bed55eae6d5a7fa 100644 --- a/app/code/Magento/GoogleShopping/Model/Attribute/Destinations.php +++ b/app/code/Magento/GoogleShopping/Model/Attribute/Destinations.php @@ -41,7 +41,7 @@ class Destinations extends \Magento\GoogleShopping\Model\Attribute\DefaultAttrib * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry * @param \Magento\Catalog\Model\ProductFactory $productFactory - * @param \Magento\GoogleShopping\Helper\Data $gsData + * @param \Magento\GoogleShopping\Helper\Data $googleShoppingHelper * @param \Magento\GoogleShopping\Helper\Product $gsProduct * @param \Magento\Catalog\Model\Product\CatalogPrice $catalogPrice * @param \Magento\GoogleShopping\Model\Resource\Attribute $resource @@ -53,7 +53,7 @@ class Destinations extends \Magento\GoogleShopping\Model\Attribute\DefaultAttrib \Magento\Framework\Model\Context $context, \Magento\Framework\Registry $registry, \Magento\Catalog\Model\ProductFactory $productFactory, - \Magento\GoogleShopping\Helper\Data $gsData, + \Magento\GoogleShopping\Helper\Data $googleShoppingHelper, \Magento\GoogleShopping\Helper\Product $gsProduct, \Magento\Catalog\Model\Product\CatalogPrice $catalogPrice, \Magento\GoogleShopping\Model\Resource\Attribute $resource, @@ -66,7 +66,7 @@ class Destinations extends \Magento\GoogleShopping\Model\Attribute\DefaultAttrib $context, $registry, $productFactory, - $gsData, + $googleShoppingHelper, $gsProduct, $catalogPrice, $resource, diff --git a/app/code/Magento/GoogleShopping/Model/Attribute/GoogleProductCategory.php b/app/code/Magento/GoogleShopping/Model/Attribute/GoogleProductCategory.php index 86d2631920a59e3cf7aafb58061765391a6499e1..9034b81b2c68725e88a02fe955094487b4d232be 100644 --- a/app/code/Magento/GoogleShopping/Model/Attribute/GoogleProductCategory.php +++ b/app/code/Magento/GoogleShopping/Model/Attribute/GoogleProductCategory.php @@ -48,7 +48,7 @@ class GoogleProductCategory extends \Magento\GoogleShopping\Model\Attribute\Defa * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry * @param \Magento\Catalog\Model\ProductFactory $productFactory - * @param \Magento\GoogleShopping\Helper\Data $gsData + * @param \Magento\GoogleShopping\Helper\Data $googleShoppingHelper * @param \Magento\GoogleShopping\Helper\Product $gsProduct * @param \Magento\Catalog\Model\Product\CatalogPrice $catalogPrice * @param \Magento\GoogleShopping\Model\Resource\Attribute $resource @@ -61,7 +61,7 @@ class GoogleProductCategory extends \Magento\GoogleShopping\Model\Attribute\Defa \Magento\Framework\Model\Context $context, \Magento\Framework\Registry $registry, \Magento\Catalog\Model\ProductFactory $productFactory, - \Magento\GoogleShopping\Helper\Data $gsData, + \Magento\GoogleShopping\Helper\Data $googleShoppingHelper, \Magento\GoogleShopping\Helper\Product $gsProduct, \Magento\Catalog\Model\Product\CatalogPrice $catalogPrice, \Magento\GoogleShopping\Model\Resource\Attribute $resource, @@ -76,7 +76,7 @@ class GoogleProductCategory extends \Magento\GoogleShopping\Model\Attribute\Defa $context, $registry, $productFactory, - $gsData, + $googleShoppingHelper, $gsProduct, $catalogPrice, $resource, diff --git a/app/code/Magento/GoogleShopping/Model/Attribute/Id.php b/app/code/Magento/GoogleShopping/Model/Attribute/Id.php index 3115a0cdec9846d38fabb08f212d55dc5dc414a3..781f6b0e2086ad139b86a1715c9e93a54f3e61af 100644 --- a/app/code/Magento/GoogleShopping/Model/Attribute/Id.php +++ b/app/code/Magento/GoogleShopping/Model/Attribute/Id.php @@ -40,7 +40,7 @@ class Id extends \Magento\GoogleShopping\Model\Attribute\DefaultAttribute */ public function convertAttribute($product, $entry) { - $value = $this->_gsData->buildContentProductId($product->getId(), $product->getStoreId()); + $value = $this->_googleShoppingHelper->buildContentProductId($product->getId(), $product->getStoreId()); return $this->_setAttribute($entry, 'id', self::ATTRIBUTE_TYPE_TEXT, $value); } } diff --git a/app/code/Magento/GoogleShopping/Model/Attribute/ImageLink.php b/app/code/Magento/GoogleShopping/Model/Attribute/ImageLink.php index 07c16720f5e4f9e91ef4d53cdbb0a750cd228c13..ece4dc9a56ec7eda7fd678b6deaa4759867f865b 100644 --- a/app/code/Magento/GoogleShopping/Model/Attribute/ImageLink.php +++ b/app/code/Magento/GoogleShopping/Model/Attribute/ImageLink.php @@ -39,7 +39,7 @@ class ImageLink extends \Magento\GoogleShopping\Model\Attribute\DefaultAttribute * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry * @param \Magento\Catalog\Model\ProductFactory $productFactory - * @param \Magento\GoogleShopping\Helper\Data $gsData + * @param \Magento\GoogleShopping\Helper\Data $googleShoppingHelper * @param \Magento\GoogleShopping\Helper\Product $gsProduct * @param \Magento\Catalog\Model\Product\CatalogPrice $catalogPrice * @param \Magento\GoogleShopping\Model\Resource\Attribute $resource @@ -51,7 +51,7 @@ class ImageLink extends \Magento\GoogleShopping\Model\Attribute\DefaultAttribute \Magento\Framework\Model\Context $context, \Magento\Framework\Registry $registry, \Magento\Catalog\Model\ProductFactory $productFactory, - \Magento\GoogleShopping\Helper\Data $gsData, + \Magento\GoogleShopping\Helper\Data $googleShoppingHelper, \Magento\GoogleShopping\Helper\Product $gsProduct, \Magento\Catalog\Model\Product\CatalogPrice $catalogPrice, \Magento\GoogleShopping\Model\Resource\Attribute $resource, @@ -64,7 +64,7 @@ class ImageLink extends \Magento\GoogleShopping\Model\Attribute\DefaultAttribute $context, $registry, $productFactory, - $gsData, + $googleShoppingHelper, $gsProduct, $catalogPrice, $resource, diff --git a/app/code/Magento/GoogleShopping/Model/Attribute/Link.php b/app/code/Magento/GoogleShopping/Model/Attribute/Link.php index f2c290a7884468901d9f425bd9740bedbfe3dfd9..3705a74a250d4f0830d4300038e620f729054f9b 100644 --- a/app/code/Magento/GoogleShopping/Model/Attribute/Link.php +++ b/app/code/Magento/GoogleShopping/Model/Attribute/Link.php @@ -39,7 +39,7 @@ class Link extends \Magento\GoogleShopping\Model\Attribute\DefaultAttribute * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry * @param \Magento\Catalog\Model\ProductFactory $productFactory - * @param \Magento\GoogleShopping\Helper\Data $gsData + * @param \Magento\GoogleShopping\Helper\Data $googleShoppingHelper * @param \Magento\GoogleShopping\Helper\Product $gsProduct * @param \Magento\Catalog\Model\Product\CatalogPrice $catalogPrice * @param \Magento\GoogleShopping\Model\Resource\Attribute $resource @@ -51,7 +51,7 @@ class Link extends \Magento\GoogleShopping\Model\Attribute\DefaultAttribute \Magento\Framework\Model\Context $context, \Magento\Framework\Registry $registry, \Magento\Catalog\Model\ProductFactory $productFactory, - \Magento\GoogleShopping\Helper\Data $gsData, + \Magento\GoogleShopping\Helper\Data $googleShoppingHelper, \Magento\GoogleShopping\Helper\Product $gsProduct, \Magento\Catalog\Model\Product\CatalogPrice $catalogPrice, \Magento\GoogleShopping\Model\Resource\Attribute $resource, @@ -64,7 +64,7 @@ class Link extends \Magento\GoogleShopping\Model\Attribute\DefaultAttribute $context, $registry, $productFactory, - $gsData, + $googleShoppingHelper, $gsProduct, $catalogPrice, $resource, diff --git a/app/code/Magento/GoogleShopping/Model/Attribute/Price.php b/app/code/Magento/GoogleShopping/Model/Attribute/Price.php index cb8f296c2f378aceafab1c4f7521c245357b7a9a..305eec75a9990971b715de07324e18f95817e409 100644 --- a/app/code/Magento/GoogleShopping/Model/Attribute/Price.php +++ b/app/code/Magento/GoogleShopping/Model/Attribute/Price.php @@ -69,7 +69,7 @@ class Price extends \Magento\GoogleShopping\Model\Attribute\DefaultAttribute * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry * @param \Magento\Catalog\Model\ProductFactory $productFactory - * @param \Magento\GoogleShopping\Helper\Data $gsData + * @param \Magento\GoogleShopping\Helper\Data $googleShoppingHelper * @param \Magento\GoogleShopping\Helper\Product $gsProduct * @param \Magento\Catalog\Model\Product\CatalogPrice $catalogPrice * @param \Magento\GoogleShopping\Model\Resource\Attribute $resource @@ -86,7 +86,7 @@ class Price extends \Magento\GoogleShopping\Model\Attribute\DefaultAttribute \Magento\Framework\Model\Context $context, \Magento\Framework\Registry $registry, \Magento\Catalog\Model\ProductFactory $productFactory, - \Magento\GoogleShopping\Helper\Data $gsData, + \Magento\GoogleShopping\Helper\Data $googleShoppingHelper, \Magento\GoogleShopping\Helper\Product $gsProduct, \Magento\Catalog\Model\Product\CatalogPrice $catalogPrice, \Magento\GoogleShopping\Model\Resource\Attribute $resource, @@ -106,7 +106,7 @@ class Price extends \Magento\GoogleShopping\Model\Attribute\DefaultAttribute $context, $registry, $productFactory, - $gsData, + $googleShoppingHelper, $gsProduct, $catalogPrice, $resource, diff --git a/app/code/Magento/GoogleShopping/Model/Attribute/ProductType.php b/app/code/Magento/GoogleShopping/Model/Attribute/ProductType.php index 50ee7841461afe837e957a30488a0dcfe727abf3..0b175b63f22fa5cac4b0023e5ca26133c3de51cd 100644 --- a/app/code/Magento/GoogleShopping/Model/Attribute/ProductType.php +++ b/app/code/Magento/GoogleShopping/Model/Attribute/ProductType.php @@ -41,7 +41,7 @@ class ProductType extends \Magento\GoogleShopping\Model\Attribute\DefaultAttribu * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry * @param \Magento\Catalog\Model\ProductFactory $productFactory - * @param \Magento\GoogleShopping\Helper\Data $gsData + * @param \Magento\GoogleShopping\Helper\Data $googleShoppingHelper * @param \Magento\GoogleShopping\Helper\Product $gsProduct * @param \Magento\Catalog\Model\Product\CatalogPrice $catalogPrice * @param \Magento\GoogleShopping\Model\Resource\Attribute $resource @@ -53,7 +53,7 @@ class ProductType extends \Magento\GoogleShopping\Model\Attribute\DefaultAttribu \Magento\Framework\Model\Context $context, \Magento\Framework\Registry $registry, \Magento\Catalog\Model\ProductFactory $productFactory, - \Magento\GoogleShopping\Helper\Data $gsData, + \Magento\GoogleShopping\Helper\Data $googleShoppingHelper, \Magento\GoogleShopping\Helper\Product $gsProduct, \Magento\Catalog\Model\Product\CatalogPrice $catalogPrice, \Magento\GoogleShopping\Model\Resource\Attribute $resource, @@ -66,7 +66,7 @@ class ProductType extends \Magento\GoogleShopping\Model\Attribute\DefaultAttribu $context, $registry, $productFactory, - $gsData, + $googleShoppingHelper, $gsProduct, $catalogPrice, $resource, diff --git a/app/code/Magento/GoogleShopping/Model/Attribute/TargetCountry.php b/app/code/Magento/GoogleShopping/Model/Attribute/TargetCountry.php index 9963f95fa5e257b19fc019cd5b381e45b987f0da..82c8e61e9d1d9fb3e71c43465d1609625370a064 100644 --- a/app/code/Magento/GoogleShopping/Model/Attribute/TargetCountry.php +++ b/app/code/Magento/GoogleShopping/Model/Attribute/TargetCountry.php @@ -41,7 +41,7 @@ class TargetCountry extends \Magento\GoogleShopping\Model\Attribute\DefaultAttri * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry * @param \Magento\Catalog\Model\ProductFactory $productFactory - * @param \Magento\GoogleShopping\Helper\Data $gsData + * @param \Magento\GoogleShopping\Helper\Data $googleShoppingHelper * @param \Magento\GoogleShopping\Helper\Product $gsProduct * @param \Magento\Catalog\Model\Product\CatalogPrice $catalogPrice * @param \Magento\GoogleShopping\Model\Resource\Attribute $resource @@ -53,7 +53,7 @@ class TargetCountry extends \Magento\GoogleShopping\Model\Attribute\DefaultAttri \Magento\Framework\Model\Context $context, \Magento\Framework\Registry $registry, \Magento\Catalog\Model\ProductFactory $productFactory, - \Magento\GoogleShopping\Helper\Data $gsData, + \Magento\GoogleShopping\Helper\Data $googleShoppingHelper, \Magento\GoogleShopping\Helper\Product $gsProduct, \Magento\Catalog\Model\Product\CatalogPrice $catalogPrice, \Magento\GoogleShopping\Model\Resource\Attribute $resource, @@ -66,7 +66,7 @@ class TargetCountry extends \Magento\GoogleShopping\Model\Attribute\DefaultAttri $context, $registry, $productFactory, - $gsData, + $googleShoppingHelper, $gsProduct, $catalogPrice, $resource, diff --git a/app/code/Magento/GoogleShopping/Model/Attribute/Tax.php b/app/code/Magento/GoogleShopping/Model/Attribute/Tax.php index f2e4c0173dd3877504c92050f0fa8a3956094e0d..6a9a1c1251c02bc337746af7a6ea83e1ff292e06 100644 --- a/app/code/Magento/GoogleShopping/Model/Attribute/Tax.php +++ b/app/code/Magento/GoogleShopping/Model/Attribute/Tax.php @@ -23,6 +23,10 @@ */ namespace Magento\GoogleShopping\Model\Attribute; +use Magento\Store\Model\Store; +use Magento\Framework\Parse\Zip; +use Magento\Tax\Service\V1\Data\TaxClassKey; + /** * Tax attribute model * @@ -40,11 +44,6 @@ class Tax extends \Magento\GoogleShopping\Model\Attribute\DefaultAttribute */ protected $_taxData = null; - /** - * @var \Magento\Tax\Model\Calculation - */ - protected $calculation; - /** * Config * @@ -52,17 +51,71 @@ class Tax extends \Magento\GoogleShopping\Model\Attribute\DefaultAttribute */ protected $_config; + /** + * Tax Rule Service + * + * @var \Magento\Tax\Service\V1\TaxRuleService + */ + protected $_taxRuleService; + + /** + * Tax Calculation Service + * + * @var \Magento\Tax\Service\V1\TaxCalculationService + */ + protected $_taxCalculationService; + + /** + * Quote Details Builder + * + * @var \Magento\Tax\Service\V1\Data\QuoteDetailsBuilder + */ + protected $_quoteDetailsBuilder; + + /** + * Quote Details Item Builder + * + * @var \Magento\Tax\Service\V1\Data\QuoteDetails\ItemBuilder + */ + protected $_quoteDetailsItemBuilder; + + /** + * Group Service Interface + * + * @var \Magento\Customer\Service\V1\CustomerGroupServiceInterface + */ + protected $_groupService; + + /** + * Default customer tax classId + * + * @var int + */ + protected $_defaultCustomerTaxClassId; + + /** + * Region factory + * + * @var \Magento\Directory\Model\RegionFactory + */ + protected $_regionFactory; + /** * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry * @param \Magento\Catalog\Model\ProductFactory $productFactory - * @param \Magento\GoogleShopping\Helper\Data $gsData + * @param \Magento\GoogleShopping\Helper\Data $googleShoppingHelper * @param \Magento\GoogleShopping\Helper\Product $gsProduct * @param \Magento\Catalog\Model\Product\CatalogPrice $catalogPrice * @param \Magento\GoogleShopping\Model\Resource\Attribute $resource * @param \Magento\GoogleShopping\Model\Config $config * @param \Magento\Tax\Helper\Data $taxData - * @param \Magento\Tax\Model\Calculation $calculation + * @param \Magento\Tax\Service\V1\TaxRuleService $taxRuleService + * @param \Magento\Tax\Service\V1\TaxCalculationService $taxCalculationService + * @param \Magento\Tax\Service\V1\Data\QuoteDetailsBuilder $quoteDetailsBuilder + * @param \Magento\Tax\Service\V1\Data\QuoteDetails\ItemBuilder $quoteDetailsItemBuilder + * @param \Magento\Customer\Service\V1\CustomerGroupServiceInterface $groupServiceInterface + * @param \Magento\Directory\Model\RegionFactory $regionFactory * @param \Magento\Framework\Data\Collection\Db $resourceCollection * @param array $data */ @@ -70,24 +123,34 @@ class Tax extends \Magento\GoogleShopping\Model\Attribute\DefaultAttribute \Magento\Framework\Model\Context $context, \Magento\Framework\Registry $registry, \Magento\Catalog\Model\ProductFactory $productFactory, - \Magento\GoogleShopping\Helper\Data $gsData, + \Magento\GoogleShopping\Helper\Data $googleShoppingHelper, \Magento\GoogleShopping\Helper\Product $gsProduct, \Magento\Catalog\Model\Product\CatalogPrice $catalogPrice, \Magento\GoogleShopping\Model\Resource\Attribute $resource, \Magento\GoogleShopping\Model\Config $config, \Magento\Tax\Helper\Data $taxData, - \Magento\Tax\Model\Calculation $calculation, + \Magento\Tax\Service\V1\TaxRuleService $taxRuleService, + \Magento\Tax\Service\V1\TaxCalculationService $taxCalculationService, + \Magento\Tax\Service\V1\Data\QuoteDetailsBuilder $quoteDetailsBuilder, + \Magento\Tax\Service\V1\Data\QuoteDetails\ItemBuilder $quoteDetailsItemBuilder, + \Magento\Customer\Service\V1\CustomerGroupServiceInterface $groupServiceInterface, + \Magento\Directory\Model\RegionFactory $regionFactory, \Magento\Framework\Data\Collection\Db $resourceCollection = null, array $data = array() ) { $this->_config = $config; $this->_taxData = $taxData; - $this->calculation = $calculation; + $this->_taxRuleService = $taxRuleService; + $this->_taxCalculationService = $taxCalculationService; + $this->_quoteDetailsBuilder = $quoteDetailsBuilder; + $this->_quoteDetailsItemBuilder = $quoteDetailsItemBuilder; + $this->_groupService = $groupServiceInterface; + $this->_regionFactory = $regionFactory; parent::__construct( $context, $registry, $productFactory, - $gsData, + $googleShoppingHelper, $gsProduct, $catalogPrice, $resource, @@ -102,6 +165,7 @@ class Tax extends \Magento\GoogleShopping\Model\Attribute\DefaultAttribute * @param \Magento\Catalog\Model\Product $product * @param \Magento\Framework\Gdata\Gshopping\Entry $entry * @return \Magento\Framework\Gdata\Gshopping\Entry + * @throws \Magento\Framework\Model\Exception */ public function convertAttribute($product, $entry) { @@ -110,14 +174,18 @@ class Tax extends \Magento\GoogleShopping\Model\Attribute\DefaultAttribute return $entry; } - $calc = $this->calculation; - $customerTaxClass = $calc->getDefaultCustomerTaxClass($product->getStoreId()); - $rates = $calc->getRatesByCustomerAndProductTaxClasses($customerTaxClass, $product->getTaxClassId()); + $defaultCustomerTaxClassId = $this->_getDefaultCustomerTaxClassId($product->getStoreId()); + $rates = $this->_taxRuleService->getRatesByCustomerAndProductTaxClassId( + $defaultCustomerTaxClassId, + $product->getTaxClassId() + ); $targetCountry = $this->_config->getTargetCountry($product->getStoreId()); $ratesTotal = 0; foreach ($rates as $rate) { - if ($targetCountry == $rate['country']) { - $regions = $this->_parseRegions($rate['state'], $rate['postcode']); + $countryId = $rate->getCountryId(); + $postcode = $rate->getPostcode(); + if ($targetCountry == $countryId) { + $regions = $this->_getRegionsByRegionId($rate->getRegionId(), $postcode); $ratesTotal += count($regions); if ($ratesTotal > self::RATES_MAX) { throw new \Magento\Framework\Model\Exception( @@ -125,12 +193,65 @@ class Tax extends \Magento\GoogleShopping\Model\Attribute\DefaultAttribute ); } foreach ($regions as $region) { + $adjustments = $product->getPriceInfo()->getAdjustments(); + if (array_key_exists('tax', $adjustments)) { + $taxIncluded = true; + } else { + $taxIncluded = false; + } + + $quoteDetailsItemDataArray = [ + 'code' => $product->getSku(), + 'type' => 'product', + 'tax_class_key' => [ + TaxClassKey::KEY_TYPE => TaxClassKey::TYPE_ID, + TaxClassKey::KEY_VALUE => $product->getTaxClassId(), + ], + 'unit_price' => $product->getPrice(), + 'quantity' => 1, + 'tax_included' => $taxIncluded, + 'short_description' => $product->getName(), + ]; + + $billingAddressDataArray = [ + 'country_id' => $countryId, + 'region' => ['region_id' => $rate->getRegionId()], + 'postcode' => $postcode, + ]; + + $shippingAddressDataArray = [ + 'country_id' => $countryId, + 'region' => ['region_id' => $rate->getRegionId()], + 'postcode' => $postcode, + ]; + + $quoteDetailsDataArray = [ + 'billing_address' => $billingAddressDataArray, + 'shipping_address' => $shippingAddressDataArray, + 'customer_tax_class_key' => [ + TaxClassKey::KEY_TYPE => TaxClassKey::TYPE_ID, + TaxClassKey::KEY_VALUE => $defaultCustomerTaxClassId, + ], + 'items' => [ + $quoteDetailsItemDataArray, + ], + ]; + + $quoteDetailsObject = $this->_quoteDetailsBuilder + ->populateWithArray($quoteDetailsDataArray) + ->create(); + + $taxDetails = $this->_taxCalculationService + ->calculateTax($quoteDetailsObject, $product->getStoreId()); + + $taxRate = ($taxDetails->getTaxAmount() / $taxDetails->getSubtotal()) * 100; + $entry->addTax( - array( - 'tax_rate' => $rate['value'] * 100, - 'tax_country' => empty($rate['country']) ? '*' : $rate['country'], - 'tax_region' => $region - ) + [ + 'tax_rate' => $taxRate, + 'tax_country' => $countryId, + 'tax_region' => $region, + ] ); } } @@ -140,137 +261,35 @@ class Tax extends \Magento\GoogleShopping\Model\Attribute\DefaultAttribute } /** - * Retrieve array of regions characterized by provided params - * - * @param string $state - * @param string $zip - * @return string[] - */ - protected function _parseRegions($state, $zip) - { - return !empty($zip) && $zip != '*' ? $this->_parseZip($zip) : ($state ? array($state) : array('*')); - } - - /** - * Retrieve array of regions characterized by provided zip code + * Fetch default customer tax classId * - * @param string $zip - * @return string[] + * @param null|Store|string|int $store + * @return int */ - protected function _parseZip($zip) + private function _getDefaultCustomerTaxClassId($store = null) { - if (strpos($zip, '-') == -1) { - return array($zip); - } else { - return $this->zipRangeToZipPattern($zip); + if (is_null($this->_defaultCustomerTaxClassId)) { + //Not catching the exception here since default group is expected + $defaultCustomerGroup = $this->_groupService->getDefaultGroup($store); + $this->_defaultCustomerTaxClassId = $defaultCustomerGroup->getTaxClassId(); } + return $this->_defaultCustomerTaxClassId; } /** - * Convert Magento zip range to array of Google Shopping zip-patterns - * (e.g., 12000-13999 -> [12*, 13*]) + * Get regions by region ID * - * @param string $zipRange - * @return array + * @param int $regionId + * @param string $postalCode + * @return String[] */ - private function zipRangeToZipPattern($zipRange) + private function _getRegionsByRegionId($regionId, $postalCode) { - $zipLength = 5; - $zipPattern = array(); - - if (!preg_match("/^(.+)-(.+)$/", $zipRange, $zipParts)) { - return array($zipRange); + $regions = []; + $regionCode = $this->_regionFactory->create()->load($regionId)->getCode(); + if (!is_null($regionCode)) { + $regions = Zip::parseRegions($regionCode, $postalCode); } - - if ($zipParts[1] == $zipParts[2]) { - return array($zipParts[1]); - } - - if ($zipParts[1] > $zipParts[2]) { - list($zipParts[2], $zipParts[1]) = array($zipParts[1], $zipParts[2]); - } - - $from = str_split($zipParts[1]); - $to = str_split($zipParts[2]); - - $startZip = ''; - $diffPosition = null; - for ($pos = 0; $pos < $zipLength; $pos++) { - if ($from[$pos] == $to[$pos]) { - $startZip .= $from[$pos]; - } else { - $diffPosition = $pos; - break; - } - } - - /* - * calculate zip-patterns - */ - if (min(array_slice($to, $diffPosition)) == 9 && max(array_slice($from, $diffPosition)) == 0) { - // particular case like 11000-11999 -> 11* - return array($startZip . '*'); - } else { - // calculate approximate zip-patterns - $start = $from[$diffPosition]; - $finish = $to[$diffPosition]; - if ($diffPosition < $zipLength - 1) { - $start++; - $finish--; - } - $end = $diffPosition < $zipLength - 1 ? '*' : ''; - for ($digit = $start; $digit <= $finish; $digit++) { - $zipPattern[] = $startZip . $digit . $end; - } - } - - if ($diffPosition == $zipLength - 1) { - return $zipPattern; - } - - $nextAsteriskFrom = true; - $nextAsteriskTo = true; - for ($pos = $zipLength - 1; $pos > $diffPosition; $pos--) { - // calculate zip-patterns based on $from value - if ($from[$pos] == 0 && $nextAsteriskFrom) { - $nextAsteriskFrom = true; - } else { - $subZip = ''; - for ($k = $diffPosition; $k < $pos; $k++) { - $subZip .= $from[$k]; - } - $delta = $nextAsteriskFrom ? 0 : 1; - $end = $pos < $zipLength - 1 ? '*' : ''; - for ($i = $from[$pos] + $delta; $i <= 9; $i++) { - $zipPattern[] = $startZip . $subZip . $i . $end; - } - $nextAsteriskFrom = false; - } - - // calculate zip-patterns based on $to value - if ($to[$pos] == 9 && $nextAsteriskTo) { - $nextAsteriskTo = true; - } else { - $subZip = ''; - for ($k = $diffPosition; $k < $pos; $k++) { - $subZip .= $to[$k]; - } - $delta = $nextAsteriskTo ? 0 : 1; - $end = $pos < $zipLength - 1 ? '*' : ''; - for ($i = 0; $i <= $to[$pos] - $delta; $i++) { - $zipPattern[] = $startZip . $subZip . $i . $end; - } - $nextAsteriskTo = false; - } - } - - if ($nextAsteriskFrom) { - $zipPattern[] = $startZip . $from[$diffPosition] . '*'; - } - if ($nextAsteriskTo) { - $zipPattern[] = $startZip . $to[$diffPosition] . '*'; - } - - return $zipPattern; + return $regions; } } diff --git a/app/code/Magento/GoogleShopping/Model/Attribute/Title.php b/app/code/Magento/GoogleShopping/Model/Attribute/Title.php index f43f1c8f6b96a57983a125001f65a7c44e1728e5..8c6174fe97c103c4714e8abf657da2cf3783ea82 100644 --- a/app/code/Magento/GoogleShopping/Model/Attribute/Title.php +++ b/app/code/Magento/GoogleShopping/Model/Attribute/Title.php @@ -53,7 +53,7 @@ class Title extends \Magento\GoogleShopping\Model\Attribute\DefaultAttribute } else { $titleText = 'no title'; } - $titleText = $this->_gsData->cleanAtomAttribute($titleText); + $titleText = $this->_googleShoppingHelper->cleanAtomAttribute($titleText); $entry->setTitle($entry->getService()->newTitle()->setText($titleText)); return $entry; diff --git a/app/code/Magento/GoogleShopping/Model/AttributeFactory.php b/app/code/Magento/GoogleShopping/Model/AttributeFactory.php index 348007fc95184517b3869cacc3d393be4e5be8c2..6bf5a8df2e7187a2b74a093fce6d77d3c63586a7 100644 --- a/app/code/Magento/GoogleShopping/Model/AttributeFactory.php +++ b/app/code/Magento/GoogleShopping/Model/AttributeFactory.php @@ -42,7 +42,7 @@ class AttributeFactory * * @var \Magento\GoogleShopping\Helper\Data */ - protected $_gsData; + protected $_googleShoppingHelper; /** * @var \Magento\Framework\Stdlib\String @@ -51,16 +51,16 @@ class AttributeFactory /** * @param \Magento\Framework\ObjectManager $objectManager - * @param \Magento\GoogleShopping\Helper\Data $gsData + * @param \Magento\GoogleShopping\Helper\Data $googleShoppingHelper * @param \Magento\Framework\Stdlib\String $string */ public function __construct( \Magento\Framework\ObjectManager $objectManager, - \Magento\GoogleShopping\Helper\Data $gsData, + \Magento\GoogleShopping\Helper\Data $googleShoppingHelper, \Magento\Framework\Stdlib\String $string ) { $this->_objectManager = $objectManager; - $this->_gsData = $gsData; + $this->_googleShoppingHelper = $googleShoppingHelper; $this->_string = $string; } @@ -73,7 +73,7 @@ class AttributeFactory public function createAttribute($name) { $modelName = 'Magento\GoogleShopping\Model\Attribute\\' . $this->_string->upperCaseWords( - $this->_gsData->normalizeName($name) + $this->_googleShoppingHelper->normalizeName($name) ); try { /** @var \Magento\GoogleShopping\Model\Attribute\DefaultAttribute $attributeModel */ diff --git a/app/code/Magento/GoogleShopping/Model/Service/Item.php b/app/code/Magento/GoogleShopping/Model/Service/Item.php index c019a452f088dc9d901628d52fd04684fff3d5c7..4290b98084ab456b6bee55fbf121ac86d7c2447f 100644 --- a/app/code/Magento/GoogleShopping/Model/Service/Item.php +++ b/app/code/Magento/GoogleShopping/Model/Service/Item.php @@ -33,7 +33,7 @@ class Item extends \Magento\GoogleShopping\Model\Service /** * @var \Magento\GoogleShopping\Helper\Data|null */ - protected $_gsData = null; + protected $_googleShoppingHelper = null; /** * Date @@ -48,7 +48,7 @@ class Item extends \Magento\GoogleShopping\Model\Service * @param \Magento\GoogleShopping\Model\Config $config * @param \Magento\Framework\Gdata\Gshopping\ContentFactory $contentFactory * @param \Magento\Framework\Stdlib\DateTime\DateTime $date - * @param \Magento\GoogleShopping\Helper\Data $gsData + * @param \Magento\GoogleShopping\Helper\Data $googleShoppingHelper * @param array $data */ public function __construct( @@ -57,11 +57,11 @@ class Item extends \Magento\GoogleShopping\Model\Service \Magento\GoogleShopping\Model\Config $config, \Magento\Framework\Gdata\Gshopping\ContentFactory $contentFactory, \Magento\Framework\Stdlib\DateTime\DateTime $date, - \Magento\GoogleShopping\Helper\Data $gsData, + \Magento\GoogleShopping\Helper\Data $googleShoppingHelper, array $data = array() ) { $this->_date = $date; - $this->_gsData = $gsData; + $this->_googleShoppingHelper = $googleShoppingHelper; parent::__construct($logAdapterFactory, $coreRegistry, $config, $contentFactory, $data); } @@ -179,7 +179,7 @@ class Item extends \Magento\GoogleShopping\Model\Service $service = $this->getService($storeId); $countryInfo = $this->getConfig()->getTargetCountryInfo($storeId); - $itemId = $this->_gsData->buildContentProductId($item->getProductId(), $item->getStoreId()); + $itemId = $this->_googleShoppingHelper->buildContentProductId($item->getProductId(), $item->getStoreId()); $query = $service->newItemQuery()->setId( $itemId diff --git a/app/code/Magento/GoogleShopping/Model/Type.php b/app/code/Magento/GoogleShopping/Model/Type.php index a28b53898a8ad7ff1103bd94688f3f2cf71dc635..0b6abaaa80aa9986d64e388e0f382799e0e0a213 100644 --- a/app/code/Magento/GoogleShopping/Model/Type.php +++ b/app/code/Magento/GoogleShopping/Model/Type.php @@ -48,7 +48,7 @@ class Type extends \Magento\Framework\Model\AbstractModel /** * @var \Magento\GoogleShopping\Helper\Data */ - protected $_gsData; + protected $_googleShoppingHelper; /** * Config @@ -78,7 +78,7 @@ class Type extends \Magento\Framework\Model\AbstractModel * @param \Magento\GoogleShopping\Model\AttributeFactory $attributeFactory * @param \Magento\GoogleShopping\Model\Config $config * @param \Magento\GoogleShopping\Helper\Product $gsProduct - * @param \Magento\GoogleShopping\Helper\Data $gsData + * @param \Magento\GoogleShopping\Helper\Data $googleShoppingHelper * @param \Magento\GoogleShopping\Model\Resource\Type $resource * @param \Magento\Framework\Data\Collection\Db $resourceCollection * @param array $data @@ -90,7 +90,7 @@ class Type extends \Magento\Framework\Model\AbstractModel \Magento\GoogleShopping\Model\AttributeFactory $attributeFactory, \Magento\GoogleShopping\Model\Config $config, \Magento\GoogleShopping\Helper\Product $gsProduct, - \Magento\GoogleShopping\Helper\Data $gsData, + \Magento\GoogleShopping\Helper\Data $googleShoppingHelper, \Magento\GoogleShopping\Model\Resource\Type $resource, \Magento\Framework\Data\Collection\Db $resourceCollection = null, array $data = array() @@ -99,7 +99,7 @@ class Type extends \Magento\Framework\Model\AbstractModel $this->_attributeFactory = $attributeFactory; $this->_config = $config; $this->_gsProduct = $gsProduct; - $this->_gsData = $gsData; + $this->_googleShoppingHelper = $googleShoppingHelper; parent::__construct($context, $registry, $resource, $resourceCollection, $data); } @@ -167,7 +167,7 @@ class Type extends \Magento\Framework\Model\AbstractModel } if (!is_null($name)) { - $name = $this->_gsData->normalizeName($name); + $name = $this->_googleShoppingHelper->normalizeName($name); if (isset($group[$name])) { // if attribute is in the group if (!isset($result[$group[$name]])) { @@ -271,7 +271,7 @@ class Type extends \Magento\Framework\Model\AbstractModel $contentAttributes = $entry->getContentAttributes(); foreach ($contentAttributes as $contentAttribute) { - $name = $this->_gsData->normalizeName($contentAttribute->getName()); + $name = $this->_googleShoppingHelper->normalizeName($contentAttribute->getName()); if (!in_array($name, $ignoredAttributes) && !in_array($existAttributes, $existAttributes)) { $entry->removeContentAttribute($name); } diff --git a/app/code/Magento/GoogleShopping/etc/module.xml b/app/code/Magento/GoogleShopping/etc/module.xml index f9ef0d68485ea0cb2c2dbef90f8fcc78eee13c16..e7a52ba4ee9d9cb341176533db76eaff10f58ae9 100644 --- a/app/code/Magento/GoogleShopping/etc/module.xml +++ b/app/code/Magento/GoogleShopping/etc/module.xml @@ -35,6 +35,7 @@ <module name="Magento_Backend"/> <module name="Magento_Catalog"/> <module name="Magento_Customer"/> + <module name="Magento_Directory"/> <module name="Magento_Eav"/> <module name="Magento_Tax"/> <module name="Magento_Theme"/> diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/templates/product/grouped/grouped.phtml b/app/code/Magento/GroupedProduct/view/adminhtml/templates/product/grouped/grouped.phtml index 938cfd1d7b822fde5cbf5157c7ca3e82a0b3ca05..e5b190893d849e3b47e5a25fbff46593a8dc8b45 100644 --- a/app/code/Magento/GroupedProduct/view/adminhtml/templates/product/grouped/grouped.phtml +++ b/app/code/Magento/GroupedProduct/view/adminhtml/templates/product/grouped/grouped.phtml @@ -30,7 +30,7 @@ $_gridPopupBlock->setRowClickCallback('function(){}'); /** @var $_helper \Magento\Core\Helper\Data */ $_helper = $this->helper('Magento\Core\Helper\Data'); ?> -<div id="grouped-product-container" data-mage-init='{"groupedProduct":{"gridPopup":"window.<?php echo $_gridPopupBlock->getJsObjectName() ?>"}}'> +<div id="grouped-product-container" data-mage-init='{"groupedProduct":{"gridPopup":"[data-grid-id=<?php echo $_gridPopupBlock->getId() ?>]"}}'> <div class="no-products-message"> <?php echo __('There are no grouped products.')?> </div> diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product.js b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product.js index 7658e52cc489496b40986ac19de3f35f2eb18c48..fb5593438531047e5947e4c4e939373cc1169351 100644 --- a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product.js +++ b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product.js @@ -159,7 +159,7 @@ }, this) ); - var gridPopup = this.options.gridPopup; + var gridPopup = $(this.options.gridPopup).data('gridObject'); $('[data-role=add-product]').on('click', function(event) { event.preventDefault(); diff --git a/app/code/Magento/GroupedProduct/view/frontend/templates/product/view/type/grouped.phtml b/app/code/Magento/GroupedProduct/view/frontend/templates/product/view/type/grouped.phtml index b942832e44e419dcd0734cfc4399446e9509ebc1..c1ded611880a2d907fc39c3469d4f8a2c3860ac2 100644 --- a/app/code/Magento/GroupedProduct/view/frontend/templates/product/view/type/grouped.phtml +++ b/app/code/Magento/GroupedProduct/view/frontend/templates/product/view/type/grouped.phtml @@ -34,7 +34,7 @@ <?php $_associatedProducts = $this->getAssociatedProducts(); ?> <?php $_hasAssociatedProducts = count($_associatedProducts) > 0; ?> -<div class="wrapper table grouped"> +<div class="table-wrapper grouped"> <table class="table data grouped" id="super-product-table"> <caption class="table caption"><?php echo __('Grouped product items') ?></caption> <thead> diff --git a/app/code/Magento/Multishipping/Controller/Checkout/OverviewPost.php b/app/code/Magento/Multishipping/Controller/Checkout/OverviewPost.php index 0f803c9a62abf8c15c49c9a8a72f1319adc7f02f..7d47d2acc8a837d655e38c05056cd0f04ea11b5d 100644 --- a/app/code/Magento/Multishipping/Controller/Checkout/OverviewPost.php +++ b/app/code/Magento/Multishipping/Controller/Checkout/OverviewPost.php @@ -24,10 +24,36 @@ */ namespace Magento\Multishipping\Controller\Checkout; +use Magento\Checkout\Controller\Action; +use Magento\Customer\Service\V1\CustomerAccountServiceInterface as CustomerAccountService; +use Magento\Customer\Service\V1\CustomerMetadataServiceInterface as CustomerMetadataService; use \Magento\Multishipping\Model\Checkout\Type\Multishipping\State; class OverviewPost extends \Magento\Multishipping\Controller\Checkout { + /** + * @var \Magento\Core\App\Action\FormKeyValidator + */ + protected $formKeyValidator; + + /** + * @param \Magento\Framework\App\Action\Context $context + * @param \Magento\Customer\Model\Session $customerSession + * @param CustomerAccountService $customerAccountService + * @param CustomerMetadataService $customerMetadataService + * @param \Magento\Core\App\Action\FormKeyValidator $formKeyValidator + */ + public function __construct( + \Magento\Framework\App\Action\Context $context, + \Magento\Customer\Model\Session $customerSession, + CustomerAccountService $customerAccountService, + CustomerMetadataService $customerMetadataService, + \Magento\Core\App\Action\FormKeyValidator $formKeyValidator + ) { + $this->formKeyValidator = $formKeyValidator; + parent::__construct($context, $customerSession, $customerAccountService, $customerMetadataService); + } + /** * Overview action * @@ -35,6 +61,10 @@ class OverviewPost extends \Magento\Multishipping\Controller\Checkout */ public function execute() { + if (!$this->formKeyValidator->validate($this->getRequest())) { + $this->_forward('backToAddresses'); + return; + } if (!$this->_validateMinimumAmount()) { return; } diff --git a/app/code/Magento/Multishipping/etc/module.xml b/app/code/Magento/Multishipping/etc/module.xml index 31cfef37fe5e6023aa3c5291575fda9b2e94ba89..2002818416e401d4e75a15ceeda36654b532f3fc 100644 --- a/app/code/Magento/Multishipping/etc/module.xml +++ b/app/code/Magento/Multishipping/etc/module.xml @@ -39,6 +39,7 @@ <module name="Magento_Tax"/> <module name="Magento_Customer"/> <module name="Magento_Weee"/> + <module name="Magento_Theme"/> </depends> </module> </config> diff --git a/app/code/Magento/Multishipping/view/frontend/templates/checkout/addresses.phtml b/app/code/Magento/Multishipping/view/frontend/templates/checkout/addresses.phtml index 67392762626595ce725ef117e7c40f495d3ce5a5..e619ce52635ae346c4797732d200ba74aa1fddf2 100644 --- a/app/code/Magento/Multishipping/view/frontend/templates/checkout/addresses.phtml +++ b/app/code/Magento/Multishipping/view/frontend/templates/checkout/addresses.phtml @@ -36,7 +36,7 @@ </div> <input type="hidden" name="continue" value="0" id="can_continue_flag"/> <input type="hidden" name="new_address" value="0" id="add_new_address_flag"/> - <div class="wrapper table"> + <div class="table-wrapper"> <table class="items data table" id="multiship-addresses-table"> <caption class="table caption"><?php echo __('Please select a shipping address for applicable items.') ?></caption> <thead> diff --git a/app/code/Magento/Multishipping/view/frontend/templates/checkout/overview.phtml b/app/code/Magento/Multishipping/view/frontend/templates/checkout/overview.phtml index 0db201927252e86040a62e524fd91a5c9f5138a2..5a792124164d37b6feaad545c7397fef5287dcf9 100644 --- a/app/code/Magento/Multishipping/view/frontend/templates/checkout/overview.phtml +++ b/app/code/Magento/Multishipping/view/frontend/templates/checkout/overview.phtml @@ -22,8 +22,8 @@ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) */ ?> -<?php /** @var $this \Magento\Multishipping\Block\Checkout\Overview */ ?> <form action="<?php echo $this->getPostActionUrl() ?>" method="post" id="review-order-form" data-mage-init='{"orderOverview": {}}' class="form multicheckout overview"> + <?php echo $this->getBlockHtml('formkey'); ?> <div class="block billing"> <div class="title"><strong><?php echo __('Billing Information') ?></strong></div> <div class="content"> diff --git a/app/code/Magento/Multishipping/view/frontend/templates/checkout/shipping.phtml b/app/code/Magento/Multishipping/view/frontend/templates/checkout/shipping.phtml index 6cf29ce77f7b17fcf0cd1da646c9a480d8f145af..bbd4fa7ef9c46531cfae1682d937a9733874a349 100644 --- a/app/code/Magento/Multishipping/view/frontend/templates/checkout/shipping.phtml +++ b/app/code/Magento/Multishipping/view/frontend/templates/checkout/shipping.phtml @@ -86,7 +86,7 @@ <span><?php echo __('Items') ?></span> <a href="<?php echo $this->getItemsEditUrl($_address) ?>" class="action edit"><span><?php echo __('Edit Items') ?></span></a> </strong> - <div class="wrapper table"> + <div class="table-wrapper"> <table class="items data table" id="shipping-table-<?php echo $_address->getId() ?>"> <caption class="table caption"><?php echo __('Items') ?></caption> <thead> diff --git a/app/code/Magento/OfflinePayments/view/frontend/templates/info/checkmo.phtml b/app/code/Magento/OfflinePayments/view/frontend/templates/info/checkmo.phtml index 0905d2eec6135c39fbba2e90c64a61e274957de9..3aadaa9ce066ad8d0b356f61a591d0e5b2c8dcbd 100644 --- a/app/code/Magento/OfflinePayments/view/frontend/templates/info/checkmo.phtml +++ b/app/code/Magento/OfflinePayments/view/frontend/templates/info/checkmo.phtml @@ -22,7 +22,7 @@ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) */ ?> -<dl class="payment method checkmemo"> +<dl class="payment-method checkmemo"> <dt class="title"><?php echo $this->escapeHtml($this->getMethod()->getTitle()) ?></dt> <?php if($this->getInfo()->getAdditionalData()): ?> <?php if($this->getPayableTo()): ?> diff --git a/app/code/Magento/OfflinePayments/view/frontend/templates/info/purchaseorder.phtml b/app/code/Magento/OfflinePayments/view/frontend/templates/info/purchaseorder.phtml index 209cf87e7f1c9ae9cd8e596a045a9fddd2af72ac..878a144e74507a75c2498f0207e27a0558e92029 100644 --- a/app/code/Magento/OfflinePayments/view/frontend/templates/info/purchaseorder.phtml +++ b/app/code/Magento/OfflinePayments/view/frontend/templates/info/purchaseorder.phtml @@ -22,7 +22,7 @@ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) */ ?> -<dl class="payment method purchase order"> +<dl class="payment-method purchase order"> <dt class="title"><?php echo $this->escapeHtml($this->getMethod()->getTitle()) ?></dt> <dd class="content"> <strong><?php echo __('Purchase Order Number') ?></strong> diff --git a/app/code/Magento/OfflineShipping/Controller/Adminhtml/System/Config/ExportTablerates.php b/app/code/Magento/OfflineShipping/Controller/Adminhtml/System/Config/ExportTablerates.php index 4ff66cddf0d42c36c44d17c11f298be585e4fba4..19468bff577504b0f5c94c5f4f7193a7aa2cea08 100644 --- a/app/code/Magento/OfflineShipping/Controller/Adminhtml/System/Config/ExportTablerates.php +++ b/app/code/Magento/OfflineShipping/Controller/Adminhtml/System/Config/ExportTablerates.php @@ -25,6 +25,7 @@ namespace Magento\OfflineShipping\Controller\Adminhtml\System\Config; use \Magento\Framework\App\ResponseInterface; +use Magento\Backend\Controller\Adminhtml\System\ConfigSectionChecker; class ExportTablerates extends \Magento\Backend\Controller\Adminhtml\System\AbstractConfig { @@ -41,18 +42,20 @@ class ExportTablerates extends \Magento\Backend\Controller\Adminhtml\System\Abst /** * @param \Magento\Backend\App\Action\Context $context * @param \Magento\Backend\Model\Config\Structure $configStructure + * @param ConfigSectionChecker $sectionChecker * @param \Magento\Framework\App\Response\Http\FileFactory $fileFactory * @param \Magento\Store\Model\StoreManagerInterface $storeManager */ public function __construct( \Magento\Backend\App\Action\Context $context, \Magento\Backend\Model\Config\Structure $configStructure, + ConfigSectionChecker $sectionChecker, \Magento\Framework\App\Response\Http\FileFactory $fileFactory, \Magento\Store\Model\StoreManagerInterface $storeManager ) { $this->_storeManager = $storeManager; $this->_fileFactory = $fileFactory; - parent::__construct($context, $configStructure); + parent::__construct($context, $configStructure, $sectionChecker); } /** diff --git a/app/code/Magento/OfflineShipping/Model/SalesRule/Calculator.php b/app/code/Magento/OfflineShipping/Model/SalesRule/Calculator.php index 01f06ce909d35df2b119a9fbebe82b418f802e13..d663064337b7f21e125b9664bfbb01d460d42d77 100644 --- a/app/code/Magento/OfflineShipping/Model/SalesRule/Calculator.php +++ b/app/code/Magento/OfflineShipping/Model/SalesRule/Calculator.php @@ -47,7 +47,7 @@ class Calculator extends \Magento\SalesRule\Model\Validator foreach ($this->_getRules() as $rule) { /* @var $rule \Magento\SalesRule\Model\Rule */ - if (!$this->_canProcessRule($rule, $address)) { + if (!$this->validatorUtility->canProcessRule($rule, $address)) { continue; } diff --git a/app/code/Magento/Ogone/Controller/Api.php b/app/code/Magento/Ogone/Controller/Api.php index 61ab2da4e166aa7ba73ddd4d06be4ff1f24db2c1..0a3493b972842eeba1e5daffbeb13cf4223b30aa 100644 --- a/app/code/Magento/Ogone/Controller/Api.php +++ b/app/code/Magento/Ogone/Controller/Api.php @@ -24,6 +24,7 @@ namespace Magento\Ogone\Controller; use Magento\Sales\Model\Order; +use Magento\Sales\Model\Order\Payment\Transaction as PaymentTransaction; /** * Ogone Api Controller @@ -238,6 +239,8 @@ class Api extends \Magento\Framework\App\Action\Action ); } + $order->getPayment()->addTransaction(PaymentTransaction::TYPE_CAPTURE); + if (!$order->getInvoiceCollection()->getSize()) { $invoice = $order->prepareInvoice(); $invoice->register(); @@ -286,6 +289,8 @@ class Api extends \Magento\Framework\App\Action\Action \Magento\Ogone\Model\Api::PROCESSED_OGONE_STATUS, __('Processed by Ogone') ); + + $order->getPayment()->addTransaction(PaymentTransaction::TYPE_AUTH); } $order->save(); $this->_redirect('checkout/onepage/success'); diff --git a/app/code/Magento/Payment/Helper/Data.php b/app/code/Magento/Payment/Helper/Data.php index 31922a11e37ca55545aa17895f3dd802decdf9ab..8e88cbe898ee6d3985b2ec338ab35f16fb91620e 100644 --- a/app/code/Magento/Payment/Helper/Data.php +++ b/app/code/Magento/Payment/Helper/Data.php @@ -131,7 +131,7 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper { $res = array(); $methods = $this->getPaymentMethods(); - uasort($methods, array($this, '_sortMethods')); + foreach ($methods as $code => $methodConfig) { $prefix = self::XML_PATH_PAYMENT_METHODS . '/' . $code . '/'; if (!($model = $this->_scopeConfig->getValue( @@ -142,10 +142,12 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper ) { continue; } + $methodInstance = $this->_methodFactory->create($model); if (!$methodInstance) { continue; } + $methodInstance->setStore($store); if (!$methodInstance->isAvailable($quote)) { /* if the payment method cannot be used at this time */ @@ -156,22 +158,23 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper $res[] = $methodInstance; } + uasort($res, array($this, '_sortMethods')); + return $res; } /** - * @param $mixed $a - * @param $mixed $b + * Sort payments methods + * + * @param \Magento\Payment\Model\MethodInterface $a + * @param \Magento\Payment\Model\MethodInterface $b * @return int */ protected function _sortMethods($a, $b) { - if (is_object($a)) { - return (int)$a->sort_order < - (int)$b->sort_order ? -1 : ((int)$a->sort_order > - (int)$b->sort_order ? 1 : 0); - } - return 0; + return (int)$a->getSortOrder() < + (int)$b->getSortOrder() ? -1 : ((int)$a->getSortOrder() > + (int)$b->getSortOrder() ? 1 : 0); } /** diff --git a/app/code/Magento/Payment/Model/Cart.php b/app/code/Magento/Payment/Model/Cart.php index ef76137967c28130099864080e013efffd89dba9..6c2331673225755eb19563f0d5b27789ef721b1d 100644 --- a/app/code/Magento/Payment/Model/Cart.php +++ b/app/code/Magento/Payment/Model/Cart.php @@ -330,7 +330,8 @@ class Cart $this->_salesModelItems[] = $this->_createItemFromData( $item->getName(), $item->getQty(), - $item->getPrice() + $item->getPrice(), + $item->getOriginalItem()->getId() ); } diff --git a/app/code/Magento/Payment/view/frontend/templates/info/default.phtml b/app/code/Magento/Payment/view/frontend/templates/info/default.phtml index c97dd7122211a985eb0d96a75b19face49fc6509..ac25bb48acd938630352bd5d510cecbb2dea3f88 100644 --- a/app/code/Magento/Payment/view/frontend/templates/info/default.phtml +++ b/app/code/Magento/Payment/view/frontend/templates/info/default.phtml @@ -27,7 +27,7 @@ * @see \Magento\Payment\Block\Info */ ?> -<dl class="payment method"> +<dl class="payment-method"> <dt class="title"><?php echo $this->escapeHtml($this->getMethod()->getTitle()) ?></dt> <?php if ($_specificInfo = $this->getSpecificInformation()):?> <dd class="content"> diff --git a/app/code/Magento/Payment/view/frontend/templates/info/instructions.phtml b/app/code/Magento/Payment/view/frontend/templates/info/instructions.phtml index 63e96500252fb6995b3a2d3f3d35f2f8d065a7ba..b2c83dfce58bc2cb8a03727ac8d4dea2e89f8603 100644 --- a/app/code/Magento/Payment/view/frontend/templates/info/instructions.phtml +++ b/app/code/Magento/Payment/view/frontend/templates/info/instructions.phtml @@ -27,7 +27,7 @@ * @see \Magento\Payment\Block\Info */ ?> -<dl class="payment method"> +<dl class="payment-method"> <dt class="title"><?php echo $this->escapeHtml($this->getMethod()->getTitle()) ?></dt> <?php if ($this->getInstructions()): ?> <dd class="content"><?php echo nl2br($this->getInstructions()) ?></dd> diff --git a/app/code/Magento/Paypal/Block/Adminhtml/Billing/Agreement/Grid.php b/app/code/Magento/Paypal/Block/Adminhtml/Billing/Agreement/Grid.php index 3daa62dc4a5f1aab7e3cb36745980c30b87e799b..05e2a4b7f49718d4e3cd7b94920307d196c94c82 100644 --- a/app/code/Magento/Paypal/Block/Adminhtml/Billing/Agreement/Grid.php +++ b/app/code/Magento/Paypal/Block/Adminhtml/Billing/Agreement/Grid.php @@ -194,7 +194,7 @@ class Grid extends \Magento\Backend\Block\Widget\Grid\Extended 'created_at', array( 'header' => __('Created'), - 'index' => 'agreement_created_at', + 'index' => 'created_at', 'type' => 'datetime', 'align' => 'center', 'default' => __('N/A'), @@ -208,7 +208,7 @@ class Grid extends \Magento\Backend\Block\Widget\Grid\Extended 'updated_at', array( 'header' => __('Updated'), - 'index' => 'agreement_updated_at', + 'index' => 'updated_at', 'type' => 'datetime', 'align' => 'center', 'default' => __('N/A'), diff --git a/app/code/Magento/Paypal/Block/Iframe.php b/app/code/Magento/Paypal/Block/Iframe.php index 8960bf31dffa3b8ad78b1779bb6420f08b050c82..7d6559dbf5a78e0f91f6cf766188298fd05a1a7d 100644 --- a/app/code/Magento/Paypal/Block/Iframe.php +++ b/app/code/Magento/Paypal/Block/Iframe.php @@ -114,7 +114,7 @@ class Iframe extends \Magento\Payment\Block\Form $directory = $this->_filesystem->getDirectoryRead(\Magento\Framework\App\Filesystem::MODULES_DIR); $file = $this->_viewFileSystem->getTemplateFileName($templateFile, array('module' => 'Magento_Paypal')); - if ($directory->isExist($directory->getRelativePath($file))) { + if ($file && $directory->isExist($directory->getRelativePath($file))) { $this->setTemplate($templateFile); } else { $this->setTemplate('hss/iframe.phtml'); diff --git a/app/code/Magento/Paypal/Controller/Ipn/Index.php b/app/code/Magento/Paypal/Controller/Ipn/Index.php index 6376122263a656d38e210f734422c19c3577fe75..ecf093e08ff25ccf7c10539d45eb7400fdcfe20f 100644 --- a/app/code/Magento/Paypal/Controller/Ipn/Index.php +++ b/app/code/Magento/Paypal/Controller/Ipn/Index.php @@ -22,8 +22,14 @@ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ + namespace Magento\Paypal\Controller\Ipn; +use \Magento\Paypal\UnavailableException; + +/** + * Unified IPN controller for all supported PayPal methods + */ class Index extends \Magento\Framework\App\Action\Action { /** @@ -65,8 +71,14 @@ class Index extends \Magento\Framework\App\Action\Action try { $data = $this->getRequest()->getPost(); $this->_ipnFactory->create(array('data' => $data))->processIpnRequest(); + } catch (UnavailableException $e) { + $this->_logger->logException($e); + $this->getResponse()->setHeader('HTTP/1.1', '503 Service Unavailable')->sendResponse(); + /** @todo eliminate usage of exit statement */ + exit; } catch (\Exception $e) { $this->_logger->logException($e); + $this->getResponse()->setHttpResponseCode(500); } } } diff --git a/app/code/Magento/Paypal/Helper/Shortcut/Validator.php b/app/code/Magento/Paypal/Helper/Shortcut/Validator.php index fdcc41231812da07b8a5b8dea68435fa540b23f1..11b96d814df367d18425d8c2df331756e0973326 100644 --- a/app/code/Magento/Paypal/Helper/Shortcut/Validator.php +++ b/app/code/Magento/Paypal/Helper/Shortcut/Validator.php @@ -118,7 +118,11 @@ class Validator implements ValidatorInterface $currentProduct = $this->_registry->registry('current_product'); if (!is_null($currentProduct)) { $productPrice = (double)$currentProduct->getFinalPrice(); - if (empty($productPrice) && !$this->_productTypeConfig->isProductSet($currentProduct->getTypeId())) { + $typeInstance = $currentProduct->getTypeInstance(); + if (empty($productPrice) + && !$this->_productTypeConfig->isProductSet($currentProduct->getTypeId()) + && !$typeInstance->canConfigure($currentProduct) + ) { return false; } } diff --git a/app/code/Magento/Paypal/Model/AbstractIpn.php b/app/code/Magento/Paypal/Model/AbstractIpn.php index 03fee1cce9f37913e089fd665e43229136dcd189..a05f8caba24f849b7d73457448062b6119046b3d 100644 --- a/app/code/Magento/Paypal/Model/AbstractIpn.php +++ b/app/code/Magento/Paypal/Model/AbstractIpn.php @@ -21,8 +21,11 @@ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ + namespace Magento\Paypal\Model; +use \Magento\Paypal\UnavailableException; + class AbstractIpn { /** @@ -113,6 +116,20 @@ class AbstractIpn throw $e; } + /* + * Handle errors on PayPal side. + */ + $responseCode = \Zend_Http_Response::extractCode($postbackResult); + if (empty($postbackResult) || in_array($responseCode, array('500', '502', '503'))) { + if (empty($postbackResult)) { + $reason = 'Empty response.'; + } else { + $reason = 'Response code: ' . $responseCode . '.'; + } + $this->_debugData['exception'] = 'PayPal IPN postback failure. ' . $reason; + throw new UnavailableException($reason); + } + $response = preg_split('/^\r?$/m', $postbackResult, 2); $response = trim($response[1]); if ($response != 'VERIFIED') { diff --git a/app/code/Magento/Paypal/Model/Api/Nvp.php b/app/code/Magento/Paypal/Model/Api/Nvp.php index 622f5969ea83659fe727e764c1abe52eb25dfbf4..37d9b1cd8ae624ba123d92149348999a9ed9e75b 100644 --- a/app/code/Magento/Paypal/Model/Api/Nvp.php +++ b/app/code/Magento/Paypal/Model/Api/Nvp.php @@ -770,6 +770,13 @@ class Nvp extends \Magento\Paypal\Model\Api\AbstractApi */ protected $_curlFactory; + /** + * API call HTTP headers + * + * @var array + */ + protected $_headers = array(); + /** * @param \Magento\Customer\Helper\Address $customerAddress * @param \Magento\Framework\Logger $logger @@ -1156,24 +1163,30 @@ class Nvp extends \Magento\Paypal\Model\Api\AbstractApi return $request; } - /** - * Retrieve headers for request. - * - * @return array - */ - protected function _getHeaderListForRequest() - { - return array(); - } - /** * Additional response processing. + * Hack to cut off length from API type response params. * - * @param array $response + * @param array $response * @return array */ protected function _postProcessResponse($response) { + foreach ($response as $key => $value) { + $pos = strpos($key, '['); + + if ($pos === false) { + continue; + } + + unset($response[$key]); + + if ($pos !== 0) { + $modifiedKey = substr($key, 0, $pos); + $response[$modifiedKey] = $value; + } + } + return $response; } @@ -1212,7 +1225,7 @@ class Nvp extends \Magento\Paypal\Model\Api\AbstractApi \Zend_Http_Client::POST, $this->getApiEndpoint(), '1.1', - $this->_getHeaderListForRequest(), + $this->_headers, $this->_buildQuery($request) ); $response = $http->read(); @@ -1364,7 +1377,7 @@ class Nvp extends \Magento\Paypal\Model\Api\AbstractApi $errorMessage = $this->_formatErrorMessage( $errorCode, $response["L_SHORTMESSAGE{$i}"], - $response["L_LONGMESSAGE{$i}"] + isset($response["L_LONGMESSAGE{$i}"]) ? $response["L_LONGMESSAGE{$i}"] : null ); $errors[] = array ( 'code' => $errorCode, diff --git a/app/code/Magento/Paypal/Model/Api/PayflowNvp.php b/app/code/Magento/Paypal/Model/Api/PayflowNvp.php index 7961ea26bb4e884d69b261fe46902ee7989a54ad..91efaed0555f7861e38c273a009d508c136212aa 100644 --- a/app/code/Magento/Paypal/Model/Api/PayflowNvp.php +++ b/app/code/Magento/Paypal/Model/Api/PayflowNvp.php @@ -101,6 +101,7 @@ class PayflowNvp extends \Magento\Paypal\Model\Api\Nvp 'PWD' => 'password', 'BUTTONSOURCE' => 'build_notation_code', 'TENDER' => 'tender', + // commands 'RETURNURL' => 'return_url', 'CANCELURL' => 'cancel_url', @@ -110,6 +111,7 @@ class PayflowNvp extends \Magento\Paypal\Model\Api\Nvp 'CUSTIP' => 'ip_address', 'NOTIFYURL' => 'notify_url', 'NOTE' => 'note', + // style settings 'PAGESTYLE' => 'page_style', 'HDRIMG' => 'hdrimg', @@ -120,15 +122,18 @@ class PayflowNvp extends \Magento\Paypal\Model\Api\Nvp // transaction info //We need to store paypal trx id for correct IPN working + 'PPREF' => 'paypal_transaction_id', 'PAYMENTINFO_0_TRANSACTIONID' => 'paypal_transaction_id', 'TRANSACTIONID' => 'paypal_transaction_id', 'REFUNDTRANSACTIONID' => 'paypal_transaction_id', + 'PNREF' => 'transaction_id', 'ORIGID' => 'authorization_id', 'CAPTURECOMPLETE' => 'complete_type', 'AMT' => 'amount', 'AVSADDR' => 'address_verification', 'AVSZIP' => 'postcode_verification', + // payment/billing info 'CURRENCY' => 'currency_code', 'PAYMENTSTATUS' => 'payment_status', @@ -136,9 +141,11 @@ class PayflowNvp extends \Magento\Paypal\Model\Api\Nvp 'PAYERID' => 'payer_id', 'PAYERSTATUS' => 'payer_status', 'EMAIL' => 'email', + // backwards compatibility 'FIRSTNAME' => 'firstname', 'LASTNAME' => 'lastname', + // paypal direct credit card information 'ACCT' => 'credit_card_number', 'EXPDATE' => 'credit_card_expiration_date', @@ -146,6 +153,7 @@ class PayflowNvp extends \Magento\Paypal\Model\Api\Nvp 'CARDSTART' => 'maestro_solo_issue_date', 'CARDISSUE' => 'maestro_solo_issue_number', 'CVV2MATCH' => 'cvv2_check_result', + // cardinal centinel 'AUTHSTATUS3DS' => 'centinel_authstatus', 'MPIVENDOR3DS' => 'centinel_mpivendor', @@ -198,7 +206,7 @@ class PayflowNvp extends \Magento\Paypal\Model\Api\Nvp */ protected $_doDirectPaymentResponse = array( 'PNREF', - 'PAYMENTINFO_0_TRANSACTIONID', + 'PPREF', 'CORRELATIONID', 'CVV2MATCH', 'AVSADDR', @@ -218,7 +226,7 @@ class PayflowNvp extends \Magento\Paypal\Model\Api\Nvp * * @var string[] */ - protected $_doCaptureResponse = array('PNREF', 'TRANSACTIONID'); + protected $_doCaptureResponse = array('PNREF', 'PPREF'); /** * DoVoid request map @@ -246,7 +254,7 @@ class PayflowNvp extends \Magento\Paypal\Model\Api\Nvp * * @var string[] */ - protected $_refundTransactionResponse = array('PNREF', 'REFUNDTRANSACTIONID'); + protected $_refundTransactionResponse = array('PNREF', 'PPREF'); /** * SetExpressCheckout request map @@ -306,7 +314,7 @@ class PayflowNvp extends \Magento\Paypal\Model\Api\Nvp */ protected $_doExpressCheckoutPaymentResponse = array( 'PNREF', - 'PAYMENTINFO_0_TRANSACTIONID', + 'PPREF', 'REPMSG', 'AMT', 'PENDINGREASON', @@ -408,9 +416,9 @@ class PayflowNvp extends \Magento\Paypal\Model\Api\Nvp * @var array */ protected $_lineItemExportItemsFormat = array( - 'name' => 'L_PAYMENTREQUEST_%d_NAME%d', - 'qty' => 'L_PAYMENTREQUEST_%d_QTY%d', - 'amount' => 'L_PAYMENTREQUEST_%d_AMT%d' + 'name' => 'L_NAME%d', + 'qty' => 'L_QTY%d', + 'amount' => 'L_COST%d' ); /** @@ -435,7 +443,7 @@ class PayflowNvp extends \Magento\Paypal\Model\Api\Nvp * @var array */ protected $_requiredResponseParams = array( - self::DO_DIRECT_PAYMENT => array('RESULT', 'PNREF', 'PAYMENTINFO_0_TRANSACTIONID') + self::DO_DIRECT_PAYMENT => array('RESULT', 'PNREF', 'PPREF') ); /** @@ -443,6 +451,11 @@ class PayflowNvp extends \Magento\Paypal\Model\Api\Nvp */ protected $mathRandom; + /** + * @var NvpFactory + */ + protected $nvpFactory; + /** * @param \Magento\Customer\Helper\Address $customerAddress * @param \Magento\Framework\Logger $logger @@ -454,6 +467,7 @@ class PayflowNvp extends \Magento\Paypal\Model\Api\Nvp * @param \Magento\Framework\Model\ExceptionFactory $frameworkExceptionFactory * @param \Magento\Framework\HTTP\Adapter\CurlFactory $curlFactory * @param \Magento\Framework\Math\Random $mathRandom + * @param NvpFactory $nvpFactory * @param array $data */ public function __construct( @@ -467,6 +481,7 @@ class PayflowNvp extends \Magento\Paypal\Model\Api\Nvp \Magento\Framework\Model\ExceptionFactory $frameworkExceptionFactory, \Magento\Framework\HTTP\Adapter\CurlFactory $curlFactory, \Magento\Framework\Math\Random $mathRandom, + NvpFactory $nvpFactory, array $data = array() ) { parent::__construct( @@ -482,6 +497,7 @@ class PayflowNvp extends \Magento\Paypal\Model\Api\Nvp $data ); $this->mathRandom = $mathRandom; + $this->nvpFactory = $nvpFactory; } /** @@ -731,17 +747,6 @@ class PayflowNvp extends \Magento\Paypal\Model\Api\Nvp return $requestFields; } - /** - * Retrieve headers for request. - * This is a hack to make Payflow work with negative values for items like discount has. - * - * @return string[] - */ - protected function _getHeaderListForRequest() - { - return array('PAYPAL-NVP: Y'); - } - /** * Additional response processing. * Hack to cut off length from API type response params. @@ -770,73 +775,55 @@ class PayflowNvp extends \Magento\Paypal\Model\Api\Nvp } /** - * Prepare line items request. - * Returns true if there were line items added. + * Checking negative line items * - * @param array &$request + * @param array $request * @param int $i - * @return bool|null + * @return null|true */ protected function _exportLineItems(array &$request, $i = 0) { - return $this->_preparePaymentRequestLineItems($request, 0, $i); + $requestBefore = $request; + $result = parent::_exportLineItems($request, $i); + if ($this->getIsLineItemsEnabled() && $this->_cart->hasNegativeItemAmount()) { + $this->_lineItemTotalExportMap = array( + Cart::AMOUNT_TAX => 'TAXAMT', + Cart::AMOUNT_SHIPPING => 'FREIGHTAMT', + 'amount' => 'PAYMENTREQUEST_0_ITEMAMT', + ); + $this->_lineItemExportItemsFormat = array( + 'name' => 'L_PAYMENTREQUEST_0_NAME%d', + 'qty' => 'L_PAYMENTREQUEST_0_QTY%d', + 'amount' => 'L_PAYMENTREQUEST_0_AMT%d', + ); + $request = $requestBefore; + $result = parent::_exportLineItems($request, $i); + /** @var Nvp $paypalNvp */ + $paypalNvp = $this->nvpFactory->create(); + $this->_doCaptureResponse = $paypalNvp->_doCaptureResponse; + $this->_refundTransactionResponse = $paypalNvp->_refundTransactionResponse; + $this->_getTransactionDetailsResponse = $paypalNvp->_getTransactionDetailsResponse; + $this->_paymentInformationResponse = $paypalNvp->_paymentInformationResponse; + $this->_headers[] = 'PAYPAL-NVP: Y'; + $this->_setSpecificForNegativeLineItems(); + } + return $result; } /** - * NVP doesn't support passing discount total as a separate amount - add it as a line item. - * This is a hack for proper line items display for order at PP EC side using Payflow through API. - * - * @param array &$request - * @param int $requestNum - * @param int $itemNum - * @return bool|null - * @link https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_api_nvp_r_SetExpressCheckout + * Set specific data when negative line item case + * @return void */ - protected function _preparePaymentRequestLineItems(array &$request, $requestNum = 0, $itemNum = 0) + protected function _setSpecificForNegativeLineItems() { - if (!$this->_cart) { - return; - } - - $this->_cart->setTransferDiscountAsItem(); - - // always add cart totals, even if line items are not requested - if ($this->_lineItemTotalExportMap) { - foreach ($this->_cart->getAmounts() as $key => $total) { - if (isset($this->_lineItemTotalExportMap[$key])) { - // !empty($total) - $privateKey = $this->_lineItemTotalExportMap[$key]; - $request[$privateKey] = $this->_filterAmount($total); - } elseif (isset($this->_lineItemsExportRequestTotalsFormat[$key])) { - $privateKey = sprintf($this->_lineItemsExportRequestTotalsFormat[$key], $requestNum); - $request[$privateKey] = $this->_filterAmount($total); - } - } + /** @var Nvp $paypalNvp */ + $paypalNvp = $this->nvpFactory->create(); + $this->_setExpressCheckoutResponse = $paypalNvp->_setExpressCheckoutResponse; + $index = array_search('PPREF', $this->_doExpressCheckoutPaymentResponse); + if (false !== $index) { + unset($this->_doExpressCheckoutPaymentResponse[$index]); } - - // add cart line items - $items = $this->_cart->getAllItems(); - if (empty($items) || !$this->getIsLineItemsEnabled()) { - return; - } - - $result = null; - foreach ($items as $item) { - foreach ($this->_lineItemExportItemsFormat as $publicKey => $privateFormat) { - $result = true; - $value = $item->getDataUsingMethod($publicKey); - if (isset($this->_lineItemExportItemsFilters[$publicKey])) { - $callback = $this->_lineItemExportItemsFilters[$publicKey]; - $value = call_user_func(array($this, $callback), $value); - } - if (is_float($value)) { - $value = $this->_filterAmount($value); - } - $request[sprintf($privateFormat, $requestNum, $itemNum)] = $value; - } - $itemNum++; - } - - return $result; + $this->_doExpressCheckoutPaymentResponse[] = 'PAYMENTINFO_0_TRANSACTIONID'; + $this->_requiredResponseParams[self::DO_EXPRESS_CHECKOUT_PAYMENT][] = 'PAYMENTINFO_0_TRANSACTIONID'; } } diff --git a/app/code/Magento/Paypal/Model/Cart.php b/app/code/Magento/Paypal/Model/Cart.php index 7fd5a6b01a96c2db4054c8c6c22193b9bac39758..30c2cdb0dbc967795160e9ac6451081dbb256084 100644 --- a/app/code/Magento/Paypal/Model/Cart.php +++ b/app/code/Magento/Paypal/Model/Cart.php @@ -197,4 +197,19 @@ class Cart extends \Magento\Payment\Model\Cart $this->addTax((double)$dataContainer->getBaseHiddenTaxAmount()); $this->addTax((double)$dataContainer->getBaseShippingHiddenTaxAmnt()); } + + /** + * Check whether any item has negative amount + * + * @return bool + */ + public function hasNegativeItemAmount() + { + foreach ($this->_customItems as $item) { + if ($item->getAmount() < 0) { + return true; + } + } + return false; + } } diff --git a/app/code/Magento/Paypal/Model/Express/Checkout.php b/app/code/Magento/Paypal/Model/Express/Checkout.php index b3ca649ad73f3993ca5514bcfb2e4145aefa36d9..83bf85995421fb62f067b75780ce64a84d2b6e38 100644 --- a/app/code/Magento/Paypal/Model/Express/Checkout.php +++ b/app/code/Magento/Paypal/Model/Express/Checkout.php @@ -686,14 +686,10 @@ class Checkout $billingAddress = $quote->getBillingAddress(); } $exportedBillingAddress = $this->_api->getExportedBillingAddress(); - $quote->setCustomerEmail($billingAddress->getEmail()); - $quote->setCustomerPrefix($billingAddress->getPrefix()); - $quote->setCustomerFirstname($billingAddress->getFirstname()); - $quote->setCustomerMiddlename($billingAddress->getMiddlename()); - $quote->setCustomerLastname($billingAddress->getLastname()); - $quote->setCustomerSuffix($billingAddress->getSuffix()); - $quote->setCustomerNote($exportedBillingAddress->getData('note')); + $this->_setExportedAddressData($billingAddress, $exportedBillingAddress); + $billingAddress->setCustomerNote($exportedBillingAddress->getData('note')); + $quote->setBillingAddress($billingAddress); // import payment info $payment = $quote->getPayment(); diff --git a/app/code/Magento/Paypal/Model/Hostedpro/Request.php b/app/code/Magento/Paypal/Model/Hostedpro/Request.php index ca185bc878e364592e38e4220f14fcb44fbad44f..3de3ef174f050f7320dae86779eb0f72353aa25d 100644 --- a/app/code/Magento/Paypal/Model/Hostedpro/Request.php +++ b/app/code/Magento/Paypal/Model/Hostedpro/Request.php @@ -208,11 +208,12 @@ class Request extends \Magento\Framework\Object */ protected function _getShippingAddress(\Magento\Framework\Object $address) { + $region = $address->getRegionCode() ? $address->getRegionCode() : $address->getRegion(); $request = array( 'first_name' => $address->getFirstname(), 'last_name' => $address->getLastname(), 'city' => $address->getCity(), - 'state' => $address->getRegionCode() ? $address->getRegionCode() : $address->getCity(), + 'state' => $region ? $region : $address->getCity(), 'zip' => $address->getPostcode(), 'country' => $address->getCountry() ); @@ -234,11 +235,12 @@ class Request extends \Magento\Framework\Object */ protected function _getBillingAddress(\Magento\Framework\Object $address) { + $region = $address->getRegionCode() ? $address->getRegionCode() : $address->getRegion(); $request = array( 'billing_first_name' => $address->getFirstname(), 'billing_last_name' => $address->getLastname(), 'billing_city' => $address->getCity(), - 'billing_state' => $address->getRegionCode() ? $address->getRegionCode() : $address->getCity(), + 'billing_state' => $region ? $region : $address->getCity(), 'billing_zip' => $address->getPostcode(), 'billing_country' => $address->getCountry() ); diff --git a/app/code/Magento/Paypal/Model/Ipn.php b/app/code/Magento/Paypal/Model/Ipn.php index 493bd9bdee3d3ee827f3fb010c316f313345a001..e871ca462aa007f41425cedc9afba8b6a1c71e16 100644 --- a/app/code/Magento/Paypal/Model/Ipn.php +++ b/app/code/Magento/Paypal/Model/Ipn.php @@ -229,7 +229,7 @@ class Ipn extends \Magento\Paypal\Model\AbstractIpn implements IpnInterface switch ($paymentStatus) { // paid case Info::PAYMENTSTATUS_COMPLETED: - $this->_registerPaymentCapture(); + $this->_registerPaymentCapture(true); break; // the holded payment was denied on paypal side case Info::PAYMENTSTATUS_DENIED: @@ -274,29 +274,38 @@ class Ipn extends \Magento\Paypal\Model\AbstractIpn implements IpnInterface /** * Process completed payment (either full or partial) * + * @param bool $skipFraudDetection * @return void */ - protected function _registerPaymentCapture() + protected function _registerPaymentCapture($skipFraudDetection = false) { if ($this->getRequestData('transaction_entity') == 'auth') { return; } + $parentTransactionId = $this->getRequestData('parent_txn_id'); $this->_importPaymentInformation(); $payment = $this->_order->getPayment(); $payment->setTransactionId( $this->getRequestData('txn_id') - )->setCurrencyCode( + ); + $payment->setCurrencyCode( $this->getRequestData('mc_currency') - )->setPreparedMessage( + ); + $payment->setPreparedMessage( $this->_createIpnComment('') - )->setParentTransactionId( - $this->getRequestData('parent_txn_id') - )->setShouldCloseParentTransaction( + ); + $payment->setParentTransactionId( + $parentTransactionId + ); + $payment->setShouldCloseParentTransaction( 'Completed' === $this->getRequestData('auth_status') - )->setIsTransactionClosed( + ); + $payment->setIsTransactionClosed( 0 - )->registerCaptureNotification( - $this->getRequestData('mc_gross') + ); + $payment->registerCaptureNotification( + $this->getRequestData('mc_gross'), + $skipFraudDetection && $parentTransactionId ); $this->_order->save(); @@ -360,7 +369,9 @@ class Ipn extends \Magento\Paypal\Model\AbstractIpn implements IpnInterface throw new Exception('The "order" authorizations are not implemented.'); } // case when was placed using PayPal standard - if (\Magento\Sales\Model\Order::STATE_PENDING_PAYMENT == $this->_order->getState()) { + if (\Magento\Sales\Model\Order::STATE_PENDING_PAYMENT == $this->_order->getState() + && !$this->getRequestData('transaction_entity') + ) { $this->_registerPaymentCapture(); return; } @@ -399,6 +410,8 @@ class Ipn extends \Magento\Paypal\Model\AbstractIpn implements IpnInterface $this->getRequestData('txn_id') )->setParentTransactionId( $this->getRequestData('parent_txn_id') + )->setCurrencyCode( + $this->getRequestData('mc_currency') )->setIsTransactionClosed( 0 )->registerAuthorizationNotification( diff --git a/app/code/Magento/Paypal/Model/Method/Agreement.php b/app/code/Magento/Paypal/Model/Method/Agreement.php index 2aa41c4c3ce140058fac69ccea19318e4863c1e8..cc2e0d474b06efe2e508f25d6949bf09478cab65 100644 --- a/app/code/Magento/Paypal/Model/Method/Agreement.php +++ b/app/code/Magento/Paypal/Model/Method/Agreement.php @@ -87,14 +87,14 @@ class Agreement extends \Magento\Paypal\Model\Payment\Method\Billing\AbstractAgr * * @var bool */ - protected $_canUseCheckout = false; + protected $_canUseCheckout = true; /** * Method instance setting * * @var bool */ - protected $_canUseInternal = false; + protected $_canUseInternal = true; /** * Method instance setting diff --git a/app/code/Magento/Paypal/Model/Method/Checks/SpecificationPlugin.php b/app/code/Magento/Paypal/Model/Method/Checks/SpecificationPlugin.php new file mode 100644 index 0000000000000000000000000000000000000000..7da69fe6c039f4c899981f311f9cc709bf6325b6 --- /dev/null +++ b/app/code/Magento/Paypal/Model/Method/Checks/SpecificationPlugin.php @@ -0,0 +1,73 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Paypal\Model\Method\Checks; + +use Magento\Payment\Model\Checks\PaymentMethodChecksInterface; +use Magento\Sales\Model\Quote; +use Magento\Payment\Model\Checks\SpecificationInterface; +use Magento\Paypal\Model\Billing\AgreementFactory; + +class SpecificationPlugin +{ + /** + * @var AgreementFactory + */ + protected $_agreementFactory; + + /** + * @param AgreementFactory $agreementFactory + */ + public function __construct(AgreementFactory $agreementFactory) + { + $this->_agreementFactory = $agreementFactory; + } + + /** + * Override check for Billing Agreements + * + * @param SpecificationInterface $specification + * @param \Closure $proceed + * @param PaymentMethodChecksInterface $paymentMethod + * @param Quote $quote + * @return bool + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function aroundIsApplicable( + SpecificationInterface $specification, + \Closure $proceed, + PaymentMethodChecksInterface $paymentMethod, + Quote $quote + ) { + $originallyIsApplicable = $proceed($paymentMethod, $quote); + if (!$originallyIsApplicable || $paymentMethod->getCode() != 'paypal_billing_agreement' + || !$quote->getCustomerId() + ) { + return $originallyIsApplicable; + } + $availableBA = $this->_agreementFactory->create()->getAvailableCustomerBillingAgreements( + $quote->getCustomerId() + ); + return count($availableBA) > 0; + } +} diff --git a/app/code/Magento/Paypal/Model/Payflowlink.php b/app/code/Magento/Paypal/Model/Payflowlink.php index 989980c6f452c76c1655d13ce5820a0881e581ec..31b9354b080bbd9bc09c633ff05afc4c32ceea78 100644 --- a/app/code/Magento/Paypal/Model/Payflowlink.php +++ b/app/code/Magento/Paypal/Model/Payflowlink.php @@ -156,6 +156,7 @@ class Payflowlink extends \Magento\Paypal\Model\Payflowpro * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Magento\Paypal\Model\ConfigFactory $configFactory * @param \Magento\Framework\Math\Random $mathRandom + * @param \Magento\Framework\HTTP\ZendClientFactory $httpClientFactory * @param \Magento\Paypal\Model\Payflow\RequestFactory $requestFactory * @param \Magento\Sales\Model\QuoteFactory $quoteFactory * @param \Magento\Sales\Model\OrderFactory $orderFactory @@ -177,6 +178,7 @@ class Payflowlink extends \Magento\Paypal\Model\Payflowpro \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Paypal\Model\ConfigFactory $configFactory, \Magento\Framework\Math\Random $mathRandom, + \Magento\Framework\HTTP\ZendClientFactory $httpClientFactory, \Magento\Paypal\Model\Payflow\RequestFactory $requestFactory, \Magento\Sales\Model\QuoteFactory $quoteFactory, \Magento\Sales\Model\OrderFactory $orderFactory, @@ -201,6 +203,7 @@ class Payflowlink extends \Magento\Paypal\Model\Payflowpro $storeManager, $configFactory, $mathRandom, + $httpClientFactory, $data ); } diff --git a/app/code/Magento/Paypal/Model/Payflowpro.php b/app/code/Magento/Paypal/Model/Payflowpro.php index 2a08c4e4c308f2bcb575b220d86b5de4a1048af8..9e4be498b697bac1691fc74aa829483a8ecac28d 100644 --- a/app/code/Magento/Paypal/Model/Payflowpro.php +++ b/app/code/Magento/Paypal/Model/Payflowpro.php @@ -47,6 +47,12 @@ class Payflowpro extends \Magento\Payment\Model\Method\Cc const TRXTYPE_DELAYED_INQUIRY = 'I'; + const TRXTYPE_ACCEPT_DENY = 'U'; + + const UPDATEACTION_APPROVED = 'APPROVE'; + + const UPDATEACTION_DECLINED_BY_MERCHANT = 'FPS_MERCHANT_DECLINE'; + /** * Tender type codes */ @@ -171,6 +177,13 @@ class Payflowpro extends \Magento\Payment\Model\Method\Cc */ protected $_canFetchTransactionInfo = true; + /** + * Payment Method feature + * + * @var bool + */ + protected $_canReviewPayment = true; + /** * Gateway request timeout * @@ -213,6 +226,11 @@ class Payflowpro extends \Magento\Payment\Model\Method\Cc */ protected $mathRandom; + /** + * @var \Magento\Framework\HTTP\ZendClientFactory + */ + protected $_httpClientFactory; + /** * @param \Magento\Framework\Event\ManagerInterface $eventManager * @param \Magento\Payment\Helper\Data $paymentData @@ -225,6 +243,7 @@ class Payflowpro extends \Magento\Payment\Model\Method\Cc * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Magento\Paypal\Model\ConfigFactory $configFactory * @param \Magento\Framework\Math\Random $mathRandom + * @param \Magento\Framework\HTTP\ZendClientFactory $httpClientFactory * @param array $data * * @SuppressWarnings(PHPMD.ExcessiveParameterList) @@ -241,11 +260,13 @@ class Payflowpro extends \Magento\Payment\Model\Method\Cc \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Paypal\Model\ConfigFactory $configFactory, \Magento\Framework\Math\Random $mathRandom, + \Magento\Framework\HTTP\ZendClientFactory $httpClientFactory, array $data = array() ) { $this->_storeManager = $storeManager; $this->_configFactory = $configFactory; $this->mathRandom = $mathRandom; + $this->_httpClientFactory = $httpClientFactory; parent::__construct( $eventManager, $paymentData, @@ -479,6 +500,7 @@ class Payflowpro extends \Magento\Payment\Model\Method\Cc { $request = $this->_buildBasicRequest($payment); $request->setTrxtype(self::TRXTYPE_DELAYED_INQUIRY); + $transactionId = $payment->getCcTransId() ? $payment->getCcTransId() : $transactionId; $request->setOrigid($transactionId); $response = $this->_postRequest($request); @@ -537,7 +559,8 @@ class Payflowpro extends \Magento\Payment\Model\Method\Cc { $debugData = array('request' => $request->getData()); - $client = new \Magento\Framework\HTTP\ZendClient(); + /** @var \Magento\Framework\HTTP\ZendClient $client */ + $client = $this->_httpClientFactory->create(); $result = new \Magento\Framework\Object(); $_config = array('maxredirects' => 5, 'timeout' => 30, 'verifypeer' => $this->getConfigData('verify_peer')); @@ -630,7 +653,15 @@ class Payflowpro extends \Magento\Payment\Model\Method\Cc $request->setCurrency($order->getBaseCurrencyCode()); $orderIncrementId = $order->getIncrementId(); - $request->setCustref($orderIncrementId)->setComment1($orderIncrementId); + + $request->setCurrency($order->getBaseCurrencyCode()) + ->setInvnum($orderIncrementId) + ->setPonum($order->getId()) + ->setComment1($orderIncrementId); + $customerId = $order->getCustomerId(); + if ($customerId) { + $request->setCustref($customerId); + } $billing = $order->getBillingAddress(); if (!empty($billing)) { @@ -731,6 +762,8 @@ class Payflowpro extends \Magento\Payment\Model\Method\Cc $response->getResultCode() != self::RESPONSE_CODE_FRAUDSERVICE_FILTER ) { throw new \Magento\Framework\Model\Exception($response->getRespmsg()); + } elseif ($response->getOrigresult() == self::RESPONSE_CODE_FRAUDSERVICE_FILTER) { + throw new \Magento\Framework\Model\Exception($response->getRespmsg()); } } @@ -745,4 +778,58 @@ class Payflowpro extends \Magento\Payment\Model\Method\Cc { return $this; } + + /** + * Attempt to accept a pending payment + * + * @param \Magento\Payment\Model\Info $payment + * @return bool + */ + public function acceptPayment(\Magento\Payment\Model\Info $payment) + { + return $this->reviewPayment($payment, self::UPDATEACTION_APPROVED); + } + + /** + * Attempt to deny a pending payment + * + * @param \Magento\Payment\Model\Info $payment + * @return bool + */ + public function denyPayment(\Magento\Payment\Model\Info $payment) + { + return $this->reviewPayment($payment, self::UPDATEACTION_DECLINED_BY_MERCHANT); + } + + + /** + * Perform the payment review + * + * @param \Magento\Payment\Model\Info $payment + * @param string $action + * @return bool + */ + public function reviewPayment(\Magento\Payment\Model\Info $payment, $action) + { + $request = $this->_buildBasicRequest($payment); + $transactionId = ($payment->getCcTransId()) ? $payment->getCcTransId() : $payment->getLastTransId(); + $request->setTrxtype(self::TRXTYPE_ACCEPT_DENY); + $request->setOrigid($transactionId); + $request->setUpdateaction($action); + + $response = $this->_postRequest($request); + $payment->setAdditionalInformation((array)$response->getData()); + $this->_processErrors($response); + + if (!$this->_isTransactionUnderReview($response->getOrigresult())) { + $payment->setTransactionId($response->getOrigpnref())->setIsTransactionClosed(0); + if ($response->getOrigresult() == self::RESPONSE_CODE_APPROVED) { + $payment->setIsTransactionApproved(true); + } else if ($response->getOrigresult() == self::RESPONSE_CODE_DECLINED_BY_MERCHANT) { + $payment->setIsTransactionDenied(true); + } + } + $rawData = $response->getData(); + return ($rawData) ? $rawData : array(); + } } diff --git a/app/code/Magento/Paypal/Model/Payment/Method/Billing/AbstractAgreement.php b/app/code/Magento/Paypal/Model/Payment/Method/Billing/AbstractAgreement.php index fa9970603fb453c1132eb0b7c7f0be90239552bb..312cff117bd5d4c495243cf3be2730340a449abf 100644 --- a/app/code/Magento/Paypal/Model/Payment/Method/Billing/AbstractAgreement.php +++ b/app/code/Magento/Paypal/Model/Payment/Method/Billing/AbstractAgreement.php @@ -86,13 +86,6 @@ abstract class AbstractAgreement extends \Magento\Payment\Model\Method\AbstractM public function isAvailable($quote = null) { if (is_null($this->_isAvailable)) { - if (is_object($quote) && $quote->getCustomerId()) { - $availableBA = $this->_agreementFactory->create()->getAvailableCustomerBillingAgreements( - $quote->getCustomerId() - ); - $isAvailableBA = count($availableBA) > 0; - $this->_canUseCheckout = $this->_canUseInternal = $isAvailableBA; - } $this->_isAvailable = parent::isAvailable($quote) && $this->_isAvailable($quote); $this->_canUseCheckout = $this->_isAvailable && $this->_canUseCheckout; $this->_canUseInternal = $this->_isAvailable && $this->_canUseInternal; diff --git a/app/code/Magento/Paypal/Model/Report/Settlement.php b/app/code/Magento/Paypal/Model/Report/Settlement.php index c5f84e716051569245c1d83ca3d22780c9d0c303..642ca200ae531c25b03c92473d9fa2e2a95c45fd 100644 --- a/app/code/Magento/Paypal/Model/Report/Settlement.php +++ b/app/code/Magento/Paypal/Model/Report/Settlement.php @@ -133,7 +133,8 @@ class Settlement extends \Magento\Framework\Model\AbstractModel 'Fee Currency' => 13, 'Custom Field' => 14, 'Consumer ID' => 15, - 'Payment Tracking ID' => 16 + 'Payment Tracking ID' => 16, + 'Store ID' => 17 ), 'rowmap' => array( 'Transaction ID' => 'transaction_id', @@ -151,7 +152,8 @@ class Settlement extends \Magento\Framework\Model\AbstractModel 'Fee Currency' => 'fee_currency', 'Custom Field' => 'custom_field', 'Consumer ID' => 'consumer_id', - 'Payment Tracking ID' => 'payment_tracking_id' + 'Payment Tracking ID' => 'payment_tracking_id', + 'Store ID' => 'store_id' ) ) ); @@ -246,8 +248,11 @@ class Settlement extends \Magento\Framework\Model\AbstractModel $encoded = $this->_tmpDirectory->readFile($localCsv); $csvFormat = 'new'; - if (self::FILES_OUT_CHARSET != mb_detect_encoding($encoded)) { - $decoded = @iconv(self::FILES_IN_CHARSET, self::FILES_OUT_CHARSET . '//IGNORE', $encoded); + + $fileEncoding = mb_detect_encoding($encoded); + + if (self::FILES_OUT_CHARSET != $fileEncoding) { + $decoded = @iconv($fileEncoding, self::FILES_OUT_CHARSET.'//IGNORE', $encoded); $this->_tmpDirectory->writeFile($localCsv, $decoded); $csvFormat = 'old'; } diff --git a/app/code/Magento/Paypal/UnavailableException.php b/app/code/Magento/Paypal/UnavailableException.php new file mode 100644 index 0000000000000000000000000000000000000000..6b4c9e9124eadfedc0f325236acb78b6843544fe --- /dev/null +++ b/app/code/Magento/Paypal/UnavailableException.php @@ -0,0 +1,34 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Paypal; + +/** + * Class UnavailableException for exceptions on Paypal side + * @package Magento\Paypal + */ +class UnavailableException extends \Magento\Framework\Model\Exception +{ + +} diff --git a/app/code/Magento/Paypal/etc/di.xml b/app/code/Magento/Paypal/etc/di.xml index 7acdb23682d0aae630d5ab4dcbf70808367503a4..4fc299e88f13d35c7069ae3605066acc18bd5c46 100644 --- a/app/code/Magento/Paypal/etc/di.xml +++ b/app/code/Magento/Paypal/etc/di.xml @@ -76,6 +76,9 @@ <argument name="alias" xsi:type="string">product.info.addtocart.paypalbml</argument> </arguments> </type> + <type name="Magento\Payment\Model\Checks\Composite"> + <plugin name="paypal_specification" type="Magento\Paypal\Model\Method\Checks\SpecificationPlugin"/> + </type> <virtualType name="Magento\Paypal\Block\Payflow\Bml\Shortcut" type="Magento\Paypal\Block\Bml\Shortcut"> <arguments> <argument name="paymentMethodCode" xsi:type="const">Magento\Paypal\Model\Config::METHOD_WPP_PE_EXPRESS</argument> diff --git a/app/code/Magento/Paypal/etc/frontend/di.xml b/app/code/Magento/Paypal/etc/frontend/di.xml index 5b7dbd8539dcd723b2ccbf000a7bb1d288e70926..7605fb374383c548cc7a72802ddc5332cf5bfe9c 100644 --- a/app/code/Magento/Paypal/etc/frontend/di.xml +++ b/app/code/Magento/Paypal/etc/frontend/di.xml @@ -58,6 +58,8 @@ <item name="paypal_payflowexpress" xsi:type="string">/paypal/payflowexpress</item> <item name="paypal_standard" xsi:type="string">/paypal/standard</item> <item name="paypal_express_callbackshippingoptions" xsi:type="string">paypal/express/callbackshippingoptions</item> + <item name="paypal_bml" xsi:type="string">/paypal/bml</item> + <item name="paypal_payflowbml" xsi:type="string">/paypal/payflowbml</item> </argument> </arguments> </type> diff --git a/app/code/Magento/Paypal/etc/module.xml b/app/code/Magento/Paypal/etc/module.xml index a15d87db0015667e74bcd738f18e960a618ac103..228996c72b5e40fb408ac462a85cdefeb903a19d 100644 --- a/app/code/Magento/Paypal/etc/module.xml +++ b/app/code/Magento/Paypal/etc/module.xml @@ -24,7 +24,7 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd"> - <module name="Magento_Paypal" schema_version="1.6.0.3" active="true"> + <module name="Magento_Paypal" schema_version="1.6.0.4" active="true"> <sequence> <module name="Magento_Checkout"/> <module name="Magento_Sales"/> diff --git a/app/code/Magento/Paypal/etc/payment.xml b/app/code/Magento/Paypal/etc/payment.xml index ca6074525cba356b17b5c293c9af777626d4244b..2302478cf066f1b01fe62f573c24e6a77253bdc1 100644 --- a/app/code/Magento/Paypal/etc/payment.xml +++ b/app/code/Magento/Paypal/etc/payment.xml @@ -41,8 +41,6 @@ <methods> <method name="paypal_express"> <support_recurring_payment>1</support_recurring_payment> - <allow_multiple_address>1</allow_multiple_address> - <allow_multiple_with_3dsecure>1</allow_multiple_with_3dsecure> </method> <method name="paypal_direct"> <allow_multiple_address>1</allow_multiple_address> @@ -50,15 +48,9 @@ </method> <method name="paypal_billing_agreement"> <allow_multiple_address>1</allow_multiple_address> - <allow_multiple_with_3dsecure>1</allow_multiple_with_3dsecure> </method> <method name="payflow_express"> - <allow_multiple_address>1</allow_multiple_address> - <allow_multiple_with_3dsecure>1</allow_multiple_with_3dsecure> - </method> - <method name="payflow_advanced"> - <allow_multiple_address>1</allow_multiple_address> - <allow_multiple_with_3dsecure>1</allow_multiple_with_3dsecure> + <support_recurring_payment>1</support_recurring_payment> </method> <method name="payflowpro"> <allow_multiple_address>1</allow_multiple_address> diff --git a/app/code/Magento/Paypal/sql/paypal_setup/upgrade-1.6.0.3-1.6.0.4.php b/app/code/Magento/Paypal/sql/paypal_setup/upgrade-1.6.0.3-1.6.0.4.php new file mode 100644 index 0000000000000000000000000000000000000000..2ab3222b039ddd83eb65a1b1d8580cdb59964ca2 --- /dev/null +++ b/app/code/Magento/Paypal/sql/paypal_setup/upgrade-1.6.0.3-1.6.0.4.php @@ -0,0 +1,37 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +/** @var $installer \Magento\Sales\Model\Resource\Setup */ +$installer = $this; + +$installer->getConnection() + ->addColumn( + $installer->getTable('paypal_settlement_report_row'), + 'store_id', + array( + 'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT, + 'comment' => 'Store ID', + 'length' => '50' + ) + ); diff --git a/app/code/Magento/Paypal/view/frontend/templates/billing/agreement/view.phtml b/app/code/Magento/Paypal/view/frontend/templates/billing/agreement/view.phtml index 8945271ff782230416ddf06d4906971352e6f7c7..85ffa6aa7d78131741fb5e5eaf5355933e561bfb 100644 --- a/app/code/Magento/Paypal/view/frontend/templates/billing/agreement/view.phtml +++ b/app/code/Magento/Paypal/view/frontend/templates/billing/agreement/view.phtml @@ -23,8 +23,8 @@ */ ?> <?php /* @var $this \Magento\Paypal\Block\Billing\Agreement\View */ ?> -<div class="block billing agreements"> - <div class="title"> +<div class="block block-billing-agreements-view"> + <div class="block-title"> <strong><?php echo __('Billing Agreement # %1', $this->escapeHtml($this->getReferenceId())) ?></strong> <?php if ($this->getCanCancel()): ?> <button type="button" title="<?php echo __('Cancel') ?>" class="secondary action cancel" onclick="if( confirm('<?php echo __('Are you sure you want to do this?') ?>') ) { window.location.href = '<?php echo $this->getCancelUrl() ?>'; } return false;"> @@ -32,31 +32,31 @@ </button> <?php endif; ?> </div> - <div class="content"> - <h2 class="subtitle caption"><?php echo __('Agreement Information') ?></h2> - <div class="wrapper table billing agreements"> - <table class="data table"> + <div class="block-title"><strong><?php echo __('Agreement Information') ?></strong></div> + <div class="block-content"> + <div class="table-wrapper billing-agreements-view"> + <table class="data table table-billing-agreements-view"> <caption class="table caption"><?php echo __('Agreement Information') ?></caption> <thead> <tr> - <th class="col id"><?php echo __('Reference ID:'); ?></th> - <th class="col status"><?php echo __('Status:'); ?></th> - <th class="col created"><?php echo __('Created:'); ?></th> + <th scope="col" class="col id"><?php echo __('Reference ID:'); ?></th> + <th scope="col" class="col status"><?php echo __('Status:'); ?></th> + <th scope="col" class="col created"><?php echo __('Created:'); ?></th> <?php if($this->getAgreementUpdatedAt()): ?> - <th class="col updated"><?php echo __('Updated:'); ?></th> + <th scope="col" class="col updated"><?php echo __('Updated:'); ?></th> <?php endif; ?> - <th class="col payment"><?php echo __('Payment Method:'); ?></th> + <th scope="col" class="col payment"><?php echo __('Payment Method:'); ?></th> </tr> </thead> <tbody> <tr> - <td class="col id"><?php echo $this->escapeHtml($this->getReferenceId()); ?></td> - <td class="col status"><?php echo $this->getAgreementStatus() ?></td> - <td class="col created"><?php echo $this->escapeHtml($this->getAgreementCreatedAt()) ?></td> + <td data-th="<?php echo $this->escapeHtml(__('Reference ID:')); ?>" class="col id"><?php echo $this->escapeHtml($this->getReferenceId()); ?></td> + <td data-th="<?php echo $this->escapeHtml(__('Status:')); ?>" class="col status"><?php echo $this->getAgreementStatus() ?></td> + <td data-th="<?php echo $this->escapeHtml(__('Created:')); ?>" class="col created"><?php echo $this->escapeHtml($this->getAgreementCreatedAt()) ?></td> <?php if($this->getAgreementUpdatedAt()): ?> - <td class="col updated"><?php echo $this->escapeHtml($this->getAgreementUpdatedAt()); ?></td> + <td data-th="<?php echo $this->escapeHtml(__('Updated:')); ?>" class="col updated"><?php echo $this->escapeHtml($this->getAgreementUpdatedAt()); ?></td> <?php endif; ?> - <td class="col payment"><?php echo $this->getPaymentMethodTitle() ?></td> + <td data-th="<?php echo $this->escapeHtml(__('Payment Method:')); ?>" class="col payment"><?php echo $this->getPaymentMethodTitle() ?></td> </tr> </tbody> </table> @@ -65,32 +65,35 @@ <?php if(count($relatedOrders) > 0): ?> <?php echo $this->getChildHtml('pager'); ?> <h2 class="subtitle caption"><?php echo __('Related Orders') ?></h2> - <table class="data table" id="related-orders-table"> - <thead> - <tr> - <th class="col id"><?php echo __('Order #') ?></th> - <th class="col date"><?php echo __('Date') ?></th> - <th class="col shipto"><?php echo __('Ship To') ?></th> - <th class="col total"><?php echo __('Order Total') ?></th> - <th class="col status"><?php echo __('Order Status') ?></th> - <th class="col actions"> </th> - </tr> - </thead> - <tbody> - <?php foreach ($relatedOrders as $order): ?> - <tr> - <th class="col id"><?php echo $this->getOrderItemValue($order, 'order_increment_id') ?></th> - <th class="col date"><?php echo $this->getOrderItemValue($order, 'created_at') ?></th> - <th class="col shipto"><?php echo $this->getOrderItemValue($order, 'shipping_address') ?></th> - <th class="col total"><?php echo $this->getOrderItemValue($order, 'order_total') ?></th> - <th class="col status"><?php echo $this->getOrderItemValue($order, 'status_label') ?></th> - <th class="col actions"> - <a href="<?php echo $this->getOrderItemValue($order, 'view_url') ?>"><?php echo __('View Order') ?></a> - </th> - </tr> - <?php endforeach; ?> - </tbody> - </table> + <div class="table-wrapper billing-agreements-related"> + <table class="data table table-billing-agreements-related" id="related-orders-table"> + <caption class="table caption"><?php echo __('Related Orders') ?></caption> + <thead> + <tr> + <th scope="col" class="col id"><?php echo __('Order #') ?></th> + <th scope="col" class="col date"><?php echo __('Date') ?></th> + <th scope="col" class="col shipto"><?php echo __('Ship To') ?></th> + <th scope="col" class="col total"><?php echo __('Order Total') ?></th> + <th scope="col" class="col status"><?php echo __('Order Status') ?></th> + <th scope="col" class="col actions"> </th> + </tr> + </thead> + <tbody> + <?php foreach ($relatedOrders as $order): ?> + <tr> + <th data-th="<?php echo $this->escapeHtml(__('Order #')); ?>" class="col id"><?php echo $this->getOrderItemValue($order, 'order_increment_id') ?></th> + <th data-th="<?php echo $this->escapeHtml(__('Date')); ?>" class="col date"><?php echo $this->getOrderItemValue($order, 'created_at') ?></th> + <th data-th="<?php echo $this->escapeHtml(__('Ship To')); ?>" class="col shipto"><?php echo $this->getOrderItemValue($order, 'shipping_address') ?></th> + <th data-th="<?php echo $this->escapeHtml(__('Order Total')); ?>" class="col total"><?php echo $this->getOrderItemValue($order, 'order_total') ?></th> + <th data-th="<?php echo $this->escapeHtml(__('Order Status')); ?>" class="col status"><?php echo $this->getOrderItemValue($order, 'status_label') ?></th> + <th data-th="" class="col actions"> + <a href="<?php echo $this->getOrderItemValue($order, 'view_url') ?>"><?php echo __('View Order') ?></a> + </th> + </tr> + <?php endforeach; ?> + </tbody> + </table> + </div> <?php endif; ?> <div class="actions-toolbar"> diff --git a/app/code/Magento/Paypal/view/frontend/templates/billing/agreements.phtml b/app/code/Magento/Paypal/view/frontend/templates/billing/agreements.phtml index 6420a0acc12f4f6b199fa7751f9719187e0a6542..84b1ff4917ac5abd03031de6775e0dce885f1909 100644 --- a/app/code/Magento/Paypal/view/frontend/templates/billing/agreements.phtml +++ b/app/code/Magento/Paypal/view/frontend/templates/billing/agreements.phtml @@ -23,32 +23,32 @@ */ ?> <?php /* @var $this \Magento\Paypal\Block\Billing\Agreements */ ?> -<div class="block billing agreements"> +<div class="account-billing-agreements"> <?php $billingAgreements = $this->getBillingAgreements(); ?> <?php if (count($billingAgreements) > 0): ?> <?php echo $this->getChildHtml('pager'); ?> - <div class="wrapper table billing agreements"> - <table id="billing-agreements" class="data table billing agreements"> + <div class="table-wrapper billing-agreements"> + <table id="billing-agreements" class="data table table-billing-agreements"> <caption class="table caption"><?php echo __('Billing Agreements') ?></caption> <thead> <tr> - <th class="col id"><?php echo __('Reference ID'); ?></th> - <th class="col status"><?php echo __('Status'); ?></th> - <th class="col created"><?php echo __('Created At'); ?></th> - <th class="col updated"><?php echo __('Updated At'); ?></th> - <th class="col payment"><?php echo __('Payment Method'); ?></th> - <th class="col actions"> </th> + <th scope="col" class="col id"><?php echo __('Reference ID'); ?></th> + <th scope="col" class="col status"><?php echo __('Status'); ?></th> + <th scope="col" class="col created"><?php echo __('Created At'); ?></th> + <th scope="col" class="col updated"><?php echo __('Updated At'); ?></th> + <th scope="col" class="col payment"><?php echo __('Payment Method'); ?></th> + <th scope="col" class="col actions"> </th> </tr> </thead> <tbody> <?php foreach ($billingAgreements as $item): ?> <tr> - <td class="col id"><?php echo $this->getItemValue($item, 'reference_id') ?></td> - <td class="col status"><?php echo $this->getItemValue($item, 'status') ?></td> - <td class="col created"><?php echo $this->getItemValue($item, 'created_at') ?></td> - <td class="col updated"><?php echo $this->getItemValue($item, 'updated_at') ?></td> - <td class="col payment"><?php echo $this->getItemValue($item, 'payment_method_label') ?></td> - <td class="col actions"> + <td data-th="<?php echo $this->escapeHtml(__('Reference ID')); ?>" class="col id"><?php echo $this->getItemValue($item, 'reference_id') ?></td> + <td data-th="<?php echo $this->escapeHtml(__('Status')); ?>" class="col status"><?php echo $this->getItemValue($item, 'status') ?></td> + <td data-th="<?php echo $this->escapeHtml(__('Created At')); ?>" class="col created"><?php echo $this->getItemValue($item, 'created_at') ?></td> + <td data-th="<?php echo $this->escapeHtml(__('Updated At')); ?>" class="col updated"><?php echo $this->getItemValue($item, 'updated_at') ?></td> + <td data-th="<?php echo $this->escapeHtml(__('Payment Method')); ?>" class="col payment"><?php echo $this->getItemValue($item, 'payment_method_label') ?></td> + <td data-th="" class="col actions"> <a href="<?php echo $this->getItemValue($item, 'edit_url') ?>"><?php echo __('View') ?></a> </td> </tr> @@ -62,10 +62,10 @@ <?php $paymentMethods = $this->getWizardPaymentMethodOptions() ?> <?php if ($paymentMethods): ?> - <h2 class="subtitle caption"><?php echo __('New Billing Agreement') ?></h2> - - <form action="<?php echo $this->getCreateUrl() ?>" method="post" class="form new agreement"> + <form action="<?php echo $this->getCreateUrl() ?>" method="post" class="form form-new-agreement"> <fieldset class="fieldset"> + <legend class="legend"><span><?php echo __('New Billing Agreement') ?></span></legend> + <br /> <p class="note"><?php echo __('You will be redirected to the payment system website.') ?></p> <div class="field payment method"> diff --git a/app/code/Magento/RecurringPayment/view/frontend/templates/recurring/grid.phtml b/app/code/Magento/RecurringPayment/view/frontend/templates/recurring/grid.phtml index 4a5774eaa063acbfb273583ae59ce9d6c8742c0d..34a92266f32108e4ed6a9b4acc86c5f173e302cf 100644 --- a/app/code/Magento/RecurringPayment/view/frontend/templates/recurring/grid.phtml +++ b/app/code/Magento/RecurringPayment/view/frontend/templates/recurring/grid.phtml @@ -32,45 +32,53 @@ <?php $gridElements = $this->getGridElements(); ?> <?php if ($gridElements): ?> - <div class="toolbar"><?php echo $this->getChildHtml('pager'); ?></div> - <table id="<?php echo $this->getGridHtmlId() ?>" class="data table"> - <thead> - <tr> - <?php foreach ($this->getGridColumns() as $column): - $nobr = $this->getObjectData($column, 'is_nobr') ? '<span class="nobr">%s</span>' : '%s'; - $title = $this->getObjectData($column, 'title'); - ?> - <th class="col title"><?php echo $title ? sprintf($nobr, $this->escapeHtml($title)) : ' ' ?></th> - <?php endforeach; ?> - </tr> - </thead> - <tbody> - <?php foreach ($gridElements as $row): ?> + <?php if ($this->getChildHtml('pager')): ?> + <div class="toolbar recurring-payments-toolbar top"><?php echo $this->getChildHtml('pager'); ?></div> + <?php endif; ?> + <div class="table-wrapper recurring-payments"> + <table id="<?php echo $this->getGridHtmlId() ?>" class="data table table-recurring-payments"> + <caption class="table caption"><?php echo __('Recurring Payments') ?></caption> + <thead> <tr> <?php foreach ($this->getGridColumns() as $column): - $nobr = $this->getObjectData($column, 'is_nobr') ? '<span class="nobr">%s</span>' : '%s'; - $index = $this->getObjectData($column, 'index'); - $value = $this->getObjectData($row, $index); - $linkUrl = $this->getObjectData($row, "{$index}_link_url"); - $linkAnchorText = $this->getObjectData($row, "{$index}_link_text"); - $linkText = $linkUrl ? ($linkAnchorText ? $linkAnchorText : $value) : ''; - $linkFormat = $linkUrl ? '<a href="%s">%s</a>' : ''; + $nobr = $this->getObjectData($column, 'is_nobr') ? '<span>%s</span>' : '%s'; + $title = $this->getObjectData($column, 'title'); ?> - <td<?php echo $this->getObjectData($row, 'is_amount') ? ' class="col qty"' : '' ?>> - <?php - if ($linkFormat) { - echo sprintf($nobr, sprintf($linkFormat, $this->escapeHtml($linkUrl), $this->escapeHtml($linkText))); - } else { - echo sprintf($nobr, $this->escapeHtml($value)); - } - ?> - </td> + <th scope="col" class="col title"><?php echo $title ? sprintf($nobr, $this->escapeHtml($title)) : ' ' ?></th> <?php endforeach; ?> </tr> - <?php endforeach; ?> - </tbody> - </table> - <div class="toolbar"><?php echo $this->getChildHtml('pager'); ?></div> + </thead> + <tbody> + <?php foreach ($gridElements as $row): ?> + <tr> + <?php foreach ($this->getGridColumns() as $column): + $nobr = $this->getObjectData($column, 'is_nobr') ? '<span>%s</span>' : '%s'; + $index = $this->getObjectData($column, 'index'); + $value = $this->getObjectData($row, $index); + $linkUrl = $this->getObjectData($row, "{$index}_link_url"); + $linkAnchorText = $this->getObjectData($row, "{$index}_link_text"); + $linkText = $linkUrl ? ($linkAnchorText ? $linkAnchorText : $value) : ''; + $linkFormat = $linkUrl ? '<a href="%s">%s</a>' : ''; + $title = $this->getObjectData($column, 'title'); + ?> + <td data-th="<?php echo $title ? $this->escapeHtml($title) : ' ' ?>" <?php echo $this->getObjectData($row, 'is_amount') ? ' class="col qty"' : '' ?>> + <?php + if ($linkFormat) { + echo sprintf($nobr, sprintf($linkFormat, $this->escapeHtml($linkUrl), $this->escapeHtml($linkText))); + } else { + echo sprintf($nobr, $this->escapeHtml($value)); + } + ?> + </td> + <?php endforeach; ?> + </tr> + <?php endforeach; ?> + </tbody> + </table> + </div> + <?php if ($this->getChildHtml('pager')): ?> + <div class="toolbar recurring-payments-toolbar bottom"><?php echo $this->getChildHtml('pager'); ?></div> + <?php endif;?> <?php else: ?> <div class="message info empty"><span><?php echo $this->escapeHtml($this->getEmptyGridMessage()); ?></span></div> <?php endif; ?> diff --git a/app/code/Magento/Reports/Model/Resource/Report/Collection/AbstractCollection.php b/app/code/Magento/Reports/Model/Resource/Report/Collection/AbstractCollection.php index bc7f79e9eea275f7fb7b83d42135b2d7919915d3..70c1a8954a0e5cfdf7ffeeaac48d79117a182de3 100644 --- a/app/code/Magento/Reports/Model/Resource/Report/Collection/AbstractCollection.php +++ b/app/code/Magento/Reports/Model/Resource/Report/Collection/AbstractCollection.php @@ -129,6 +129,16 @@ class AbstractCollection extends \Magento\Framework\Model\Resource\Db\Collection return $this; } + /** + * Apply needed aggregated table + * + * @return $this + */ + protected function _applyAggregatedTable() + { + return $this; + } + /** * Apply date range filter * @@ -257,6 +267,7 @@ class AbstractCollection extends \Magento\Framework\Model\Resource\Db\Collection { parent::_beforeLoad(); + $this->_applyAggregatedTable(); $this->_applyDateRangeFilter(); $this->_applyStoresFilter(); $this->_applyCustomFilter(); diff --git a/app/code/Magento/Review/Block/Adminhtml/Product/Grid.php b/app/code/Magento/Review/Block/Adminhtml/Product/Grid.php index b49f4457f359cc2bdf1eb2369e7d72f7d27a6bfe..a5d7d8990fe90a1af04359a4c847d6746147ee42 100644 --- a/app/code/Magento/Review/Block/Adminhtml/Product/Grid.php +++ b/app/code/Magento/Review/Block/Adminhtml/Product/Grid.php @@ -159,7 +159,7 @@ class Grid extends \Magento\Catalog\Block\Adminhtml\Product\Grid */ public function getGridUrl() { - return $this->getUrl('catalog/product/productGrid', array('_current' => true)); + return $this->getUrl('review/product/productGrid', array('_current' => true)); } /** diff --git a/app/code/Magento/Review/Block/Product/Review.php b/app/code/Magento/Review/Block/Product/Review.php new file mode 100644 index 0000000000000000000000000000000000000000..ed15320b73b5f80424b46aa427665d63912df5ca --- /dev/null +++ b/app/code/Magento/Review/Block/Product/Review.php @@ -0,0 +1,121 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Review\Block\Product; + +use Magento\Review\Model\Resource\Review\Collection as ReviewCollection; + +/** + * Product Review Tab + * + * @author Magento Core Team <core@magentocommerce.com> + */ +class Review extends \Magento\Framework\View\Element\Template +{ + /** + * Core registry + * + * @var \Magento\Framework\Registry + */ + protected $_coreRegistry; + + /** + * Review resource model + * + * @var \Magento\Review\Model\Resource\Review\CollectionFactory + */ + protected $_reviewsColFactory; + + /** + * @param \Magento\Backend\Block\Template\Context $context + * @param \Magento\Framework\Registry $registry + * @param \Magento\Review\Model\Resource\Review\CollectionFactory $collectionFactory + * @param array $data + */ + public function __construct( + \Magento\Backend\Block\Template\Context $context, + \Magento\Framework\Registry $registry, + \Magento\Review\Model\Resource\Review\CollectionFactory $collectionFactory, + array $data = array() + ) { + + $this->_coreRegistry = $registry; + $this->_reviewsColFactory = $collectionFactory; + parent::__construct($context, $data); + + $this->setTabTitle(); + } + + /** + * Get current product id + * + * @return null|int + */ + public function getProductId() + { + $product = $this->_coreRegistry->registry('product'); + return $product ? $product->getId() : null; + } + + /** + * Get URL for ajax call + * + * @return string + */ + public function getProductReviewUrl() + { + return $this->getUrl('review/product/listAjax', array('id' => $this->getProductId())); + } + + /** + * Set tab title + * + * @return void + */ + public function setTabTitle() + { + $title = $this->getCollectionSize() + ? __('Reviews %1', '<span class="counter">' . $this->getCollectionSize() . '</span>') + : __('Reviews'); + $this->setTitle($title); + } + + /** + * Get size of reviews collection + * + * @return int + */ + public function getCollectionSize() + { + $collection = $this->_reviewsColFactory->create()->addStoreFilter( + $this->_storeManager->getStore()->getId() + )->addStatusFilter( + \Magento\Review\Model\Review::STATUS_APPROVED + )->addEntityFilter( + 'product', + $this->getProductId() + ); + + return $collection->getSize(); + } +} diff --git a/app/code/Magento/Review/Block/Product/ReviewRenderer.php b/app/code/Magento/Review/Block/Product/ReviewRenderer.php index 822c017a3aa3eba0e16927bb70d24bcc403ec422..39010e82308e0b685fcc85dc8035dc610909c267 100644 --- a/app/code/Magento/Review/Block/Product/ReviewRenderer.php +++ b/app/code/Magento/Review/Block/Product/ReviewRenderer.php @@ -118,13 +118,18 @@ class ReviewRenderer extends \Magento\Framework\View\Element\Template implements /** * Get review product list url * + * @param bool $useDirectLink allows to use direct link for product reviews page * @return string */ - public function getReviewsUrl() + public function getReviewsUrl($useDirectLink = false) { - return $this->getUrl( - 'review/product/list', - array('id' => $this->getProduct()->getId(), 'category' => $this->getProduct()->getCategoryId()) - ); + $product = $this->getProduct(); + if ($useDirectLink) { + return $this->getUrl( + 'review/product/list', + array('id' => $product->getId(), 'category' => $product->getCategoryId()) + ); + } + return $product->getUrlModel()->getUrl($product, array('_ignore_category' => true)); } } diff --git a/app/code/Magento/Review/Block/Product/View.php b/app/code/Magento/Review/Block/Product/View.php index 5fc7f0e2bc93760a47e0fd8697f6cc84ad91c6c0..418c4a0ed41b0de8df6695fbee1f8b002e4b686e 100644 --- a/app/code/Magento/Review/Block/Product/View.php +++ b/app/code/Magento/Review/Block/Product/View.php @@ -52,7 +52,6 @@ class View extends \Magento\Catalog\Block\Product\View * @param \Magento\Core\Helper\Data $coreData * @param \Magento\Framework\Json\EncoderInterface $jsonEncoder * @param \Magento\Catalog\Model\ProductFactory $productFactory - * @param \Magento\Tax\Model\Calculation $taxCalculation * @param \Magento\Framework\Stdlib\String $string * @param \Magento\Catalog\Helper\Product $productHelper * @param \Magento\Catalog\Model\ProductTypes\ConfigInterface $productTypeConfig @@ -67,7 +66,6 @@ class View extends \Magento\Catalog\Block\Product\View \Magento\Core\Helper\Data $coreData, \Magento\Framework\Json\EncoderInterface $jsonEncoder, \Magento\Catalog\Model\ProductFactory $productFactory, - \Magento\Tax\Model\Calculation $taxCalculation, \Magento\Framework\Stdlib\String $string, \Magento\Catalog\Helper\Product $productHelper, \Magento\Catalog\Model\ProductTypes\ConfigInterface $productTypeConfig, @@ -83,7 +81,6 @@ class View extends \Magento\Catalog\Block\Product\View $coreData, $jsonEncoder, $productFactory, - $taxCalculation, $string, $productHelper, $productTypeConfig, diff --git a/app/code/Magento/Review/Controller/Product/ListAjax.php b/app/code/Magento/Review/Controller/Product/ListAjax.php new file mode 100644 index 0000000000000000000000000000000000000000..67095da81bbefa119f32ca1487c2dbda4ab9b2c8 --- /dev/null +++ b/app/code/Magento/Review/Controller/Product/ListAjax.php @@ -0,0 +1,40 @@ +<?php +/** + * + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Review\Controller\Product; + +class ListAjax extends \Magento\Review\Controller\Product +{ + /** + * Show list of product's reviews + * + * @return void + */ + public function execute() + { + $this->_initProduct(); + $this->_view->loadLayout(); + $this->_view->renderLayout(); + } +} diff --git a/app/code/Magento/Review/view/frontend/layout/catalog_product_view.xml b/app/code/Magento/Review/view/frontend/layout/catalog_product_view.xml index f9b4f8c6d5d4d24214bb73944ccf94cc3f4ee87a..263f6ff4274b02ee4479183b2ef4f53a2e1e2773 100644 --- a/app/code/Magento/Review/view/frontend/layout/catalog_product_view.xml +++ b/app/code/Magento/Review/view/frontend/layout/catalog_product_view.xml @@ -33,4 +33,11 @@ </arguments> </block> </referenceContainer> + <referenceBlock name="product.info.details"> + <block class="Magento\Review\Block\Product\Review" name="reviews.tab" as="reviews" template="Magento_Review::review.phtml" group="detailed_info"> + <block class="Magento\Review\Block\Form" name="product.review.form" as="review_form" cacheable="false"> + <container name="product.review.form.fields.before" as="form_fields_before" label="Review Form Fields Before"/> + </block> + </block> + </referenceBlock> </layout> diff --git a/app/code/Magento/Review/view/frontend/layout/review_product_listajax.xml b/app/code/Magento/Review/view/frontend/layout/review_product_listajax.xml new file mode 100644 index 0000000000000000000000000000000000000000..2c0d767ee8ebfd92104469e5d1831d08253bb25d --- /dev/null +++ b/app/code/Magento/Review/view/frontend/layout/review_product_listajax.xml @@ -0,0 +1,35 @@ +<?xml version="1.0"?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_single.xsd"> + <remove name="root"/> + <block class="Magento\Review\Block\Product\View\ListView" name="product.info.product_additional_data" as="product_additional_data" template="product/view/list.phtml" output="1"/> + <block class="Magento\Theme\Block\Html\Pager" name="product_review_list.toolbar" output="1"> + <arguments> + <argument name="show_per_page" xsi:type="boolean">false</argument> + <argument name="show_amounts" xsi:type="boolean">false</argument> + </arguments> + </block> +</layout> diff --git a/app/code/Magento/Review/view/frontend/templates/customer/list.phtml b/app/code/Magento/Review/view/frontend/templates/customer/list.phtml index e4c77558dd9404a431d601e6735c323a56745ebc..e7ec66e27540915a03bab7dfe8b0d50f57e7acf6 100644 --- a/app/code/Magento/Review/view/frontend/templates/customer/list.phtml +++ b/app/code/Magento/Review/view/frontend/templates/customer/list.phtml @@ -23,44 +23,46 @@ */ ?> <?php if( $this->getCollection() && $this->count()): ?> - <div class="products toolbar reviews"> - <?php echo $this->getToolbarHtml() ?> - </div> - <div class="wrapper table reviews"> - <table class="data table reviews" id="my-reviews-table"> + <?php if ($this->getToolbarHtml()): ?> + <div class="toolbar products-reviews-toolbar top"> + <?php echo $this->getToolbarHtml() ?> + </div> + <?php endif; ?> + <div class="table-wrapper reviews"> + <table class="data table table-reviews" id="my-reviews-table"> <caption class="table caption"><?php echo __('Product Reviews') ?></caption> <thead> <tr> - <th class="col date"><?php echo __('Created') ?></th> - <th class="col item"><?php echo __('Product Name') ?></th> - <th class="col summary"><?php echo __('Summary') ?></th> - <th class="col description"><?php echo __('Description') ?></th> - <th class="col actions"> </th> + <th scope="col" class="col date"><?php echo __('Created') ?></th> + <th scope="col" class="col item"><?php echo __('Product Name') ?></th> + <th scope="col" class="col summary"><?php echo __('Rating') ?></th> + <th scope="col" class="col description"><?php echo __('Review') ?></th> + <th scope="col" class="col actions"> </th> </tr> </thead> <tbody> <?php foreach ($this->getCollection() as $_review): ?> <tr> - <td class="col date"><?php echo $this->dateFormat($_review->getReviewCreatedAt()); ?></td> - <td class="col item"> - <strong class="product name"> + <td data-th="<?php echo $this->escapeHtml(__('Created')) ?>" class="col date"><?php echo $this->dateFormat($_review->getReviewCreatedAt()); ?></td> + <td data-th="<?php echo $this->escapeHtml(__('Product Name')) ?>" class="col item"> + <strong class="product-name"> <a href="<?php echo $this->getProductLink() ?>id/<?php echo $_review->getEntityPkValue() ?>"><?php echo $this->escapeHtml($_review->getName()) ?></a> </strong> </td> - <td class="col summary"> + <td data-th="<?php echo $this->escapeHtml(__('Rating')) ?>" class="col summary"> <?php if($_review->getSum()): ?> - <div class="rating summary"> + <div class="rating-summary"> <span class="label"><span><?php echo __('Rating') ?>:</span></span> - <div class="rating result" title="<?php echo ( $_review->getSum() / $_review->getCount() ) ?>%"> + <div class="rating-result" title="<?php echo ( $_review->getSum() / $_review->getCount() ) ?>%"> <span style="width:<?php echo ( $_review->getSum() / $_review->getCount() ) ?>%;"><span><?php echo ( $_review->getSum() / $_review->getCount() ) ?>%</span></span> </div> </div> <?php endif; ?> </td> - <td class="col description"> + <td data-th="<?php echo $this->escapeHtml(__('Review')) ?>" class="col description"> <?php echo $this->helper('Magento\Review\Helper\Data')->getDetailHtml($_review->getDetail()) ?> </td> - <td class="col actions"> + <td data-th="" class="col actions"> <a href="<?php echo $this->getReviewLink() ?>id/<?php echo $_review->getReviewId() ?>" class="action more"> <span><?php echo __('View Details') ?></span> </a> @@ -70,9 +72,11 @@ </tbody> </table> </div> - <div class="products toolbar reviews bottom"> - <?php echo $this->getToolbarHtml() ?> - </div> + <?php if ($this->getToolbarHtml()): ?> + <div class="toolbar products-reviews-toolbar bottom"> + <?php echo $this->getToolbarHtml() ?> + </div> + <?php endif; ?> <?php else: ?> <div class="message info empty"><span><?php echo __('You have submitted no reviews.') ?></span></div> <?php endif; ?> diff --git a/app/code/Magento/Review/view/frontend/templates/customer/recent.phtml b/app/code/Magento/Review/view/frontend/templates/customer/recent.phtml index 962210d341c6e38cc6d325d115b35bb3384fa0a9..f9b95885b07f7dbf9171e61d5992d62f552aa5dd 100644 --- a/app/code/Magento/Review/view/frontend/templates/customer/recent.phtml +++ b/app/code/Magento/Review/view/frontend/templates/customer/recent.phtml @@ -28,21 +28,21 @@ ?> <?php if( $this->getCollection() && $this->count()): ?> -<div class="block reviews dashboard"> - <div class="title"> +<div class="block block-reviews-dashboard"> + <div class="block-title"> <strong><?php echo __('My Recent Reviews') ?></strong> - <a class="action view" href="<?php echo $this->getAllReviewsUrl() ?>"><span><?php echo __('View All Reviews') ?></span></a> + <a class="action view" href="<?php echo $this->getAllReviewsUrl() ?>"><span><?php echo __('View All') ?></span></a> </div> - <div class="content"> + <div class="block-content"> <ol class="items"> <?php foreach ($this->getCollection() as $_review): ?> <li class="item"> - <strong class="product name"><a href="<?php echo $this->getReviewUrl($_review->getReviewId()) ?>"><?php echo $this->escapeHtml($_review->getName()) ?></a></strong> + <strong class="product-name"><a href="<?php echo $this->getReviewUrl($_review->getReviewId()) ?>"><?php echo $this->escapeHtml($_review->getName()) ?></a></strong> <?php if($_review->getSum()): ?> <?php $rating = $_review->getSum() / $_review->getCount() ?> - <div class="rating summary"> + <div class="rating-summary"> <span class="label"><span><?php echo __('Rating') ?>:</span></span> - <div class="rating result" title="<?php echo $rating; ?>%"> + <div class="rating-result" title="<?php echo $rating; ?>%"> <span style="width:<?php echo $rating; ?>%"><span><?php echo $rating; ?>%</span></span> </div> </div> diff --git a/app/code/Magento/Review/view/frontend/templates/customer/view.phtml b/app/code/Magento/Review/view/frontend/templates/customer/view.phtml index 79f513333492d595b153470769a20603df230250..9914b5407b72f3d3cb5a7d90713b8dff48581c15 100644 --- a/app/code/Magento/Review/view/frontend/templates/customer/view.phtml +++ b/app/code/Magento/Review/view/frontend/templates/customer/view.phtml @@ -24,49 +24,50 @@ ?> <?php if($this->getProductData()->getId()): ?> <?php $imageBlock = $this->getLayout()->createBlock('Magento\Catalog\Block\Product\Image'); ?> -<div class="customer review view"> - <h2 class="product name"><?php echo $this->escapeHtml($this->getProductData()->getName()) ?></h2> - <div class="product details"> - <a class="product photo" href="<?php echo $this->getProductData()->getProductUrl() ?>"> - <?php /* customer_account_product_review_page */ ?> - <?php echo $imageBlock->init($this->getProductData(), 'customer_account_product_review_page')->toHtml() ?> - </a> - <?php if( $this->getRating() && $this->getRating()->getSize()): ?> - <p><?php echo __('Average Customer Rating:') ?></p> - <?php echo $this->getReviewsSummaryHtml($this->getProductData()) ?> - <?php endif; ?> +<div class="customer-review view"> + <div class="product-details"> + <div class="product-media"> + <a class="product-photo" href="<?php echo $this->getProductData()->getProductUrl() ?>"> + <?php /* customer_account_product_review_page */ ?> + <?php echo $imageBlock->init($this->getProductData(), 'customer_account_product_review_page')->toHtml() ?> + </a> + </div> + <div class="product-info"> + <h2 class="product-name"><?php echo $this->escapeHtml($this->getProductData()->getName()) ?></h2> + <?php if( $this->getRating() && $this->getRating()->getSize()): ?> + <span class="rating-average-label"><?php echo __('Average Customer Rating:') ?></span> + <?php echo $this->getReviewsSummaryHtml($this->getProductData()) ?> + <?php endif; ?> + </div> </div> - <div class="review details"> + <div class="review-details"> <?php if( $this->getRating() && $this->getRating()->getSize()): ?> - <div class="ratings summary items"> - <strong><?php echo ($this->isReviewOwner()) ? __('Your Rating:') : __('Rating:'); ?></strong> - - <?php foreach ($this->getRating() as $_rating): ?> - <?php if($_rating->getPercent()): ?> - <?php $rating = ceil($_rating->getPercent()) ?> - <div class="rating summary item"> - <span class="label"><span><?php echo $this->escapeHtml($_rating->getRatingCode()) ?>:</span></span> - <div class="rating result" title="<?php echo $rating; ?>%"> - <span style="width:<?php echo $rating; ?>%"> - <span><?php echo $rating; ?>%</span> - </span> + <div class="title"> + <strong><?php echo ($this->isReviewOwner()) ? __('Your Review') : __('Review'); ?></strong> + </div> + <div class="customer-review-rating"> + <?php foreach ($this->getRating() as $_rating): ?> + <?php if($_rating->getPercent()): ?> + <?php $rating = ceil($_rating->getPercent()) ?> + <div class="rating-summary item"> + <span class="rating-label"><span><?php echo $this->escapeHtml($_rating->getRatingCode()) ?></span></span> + <div class="rating-result" title="<?php echo $rating; ?>%"> + <span style="width:<?php echo $rating; ?>%"> + <span><?php echo $rating; ?>%</span> + </span> + </div> </div> - </div> - <?php endif; ?> - <?php endforeach; ?> - </div> + <?php endif; ?> + <?php endforeach; ?> + </div> <?php endif; ?> - <div class="review title"><?php echo $this->escapeHtml($this->getReviewData()->getTitle()) ?></div> - <p class="review date"> - <?php if ($this->isReviewOwner()): ?> - <?php echo __('Your Review (submitted on %1):', '<time class="date">' . $this->dateFormat($this->getReviewData()->getCreatedAt()) . '</time>') ?> - <?php else :?> - <?php echo __('Review (submitted on %1):', '<time class="date">' . $this->dateFormat($this->getReviewData()->getCreatedAt()) . '</time>') ?> - <?php endif;?> - </p> - <div class="review content"><?php echo nl2br($this->escapeHtml($this->getReviewData()->getDetail())) ?></div> + <div class="review-title"><?php echo $this->escapeHtml($this->getReviewData()->getTitle()) ?></div> + <div class="review-content"><?php echo nl2br($this->escapeHtml($this->getReviewData()->getDetail())) ?></div> + <div class="review-date"> + <?php echo __('Submitted on %1', '<time class="date">' . $this->dateFormat($this->getReviewData()->getCreatedAt()) . '</time>') ?> + </div> </div> </div> <div class="actions-toolbar"> diff --git a/app/code/Magento/Review/view/frontend/templates/form.phtml b/app/code/Magento/Review/view/frontend/templates/form.phtml index 5a9b51ecd1dd141b58753f626ec2c2838ba2c23c..0eb61fb9b498812412b4dbcf51a98d34b67a381e 100644 --- a/app/code/Magento/Review/view/frontend/templates/form.phtml +++ b/app/code/Magento/Review/view/frontend/templates/form.phtml @@ -22,38 +22,38 @@ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) */ ?> -<div class="block add review"> - <div class="title"><strong><?php echo __('Write Your Own Review') ?></strong></div> -<div class="content"> +<div class="block review-add"> + <div class="block-title"><strong><?php echo __('Write Your Own Review') ?></strong></div> +<div class="block-content"> <?php if ($this->getAllowWriteReviewFlag()): ?> -<form action="<?php echo $this->getAction() ?>" method="post" id="review-form"> +<form action="<?php echo $this->getAction() ?>" class="review-form" method="post" id="review-form"> <?php echo $this->getBlockHtml('formkey'); ?> <?php echo $this->getChildHtml('form_fields_before')?> - <fieldset class="fieldset" data-hasrequired="<?php __('* Required Fields'); ?>"> - <legend class="legend"><span><?php echo __("You're reviewing:"); ?></span><strong><?php echo $this->escapeHtml($this->getProductInfo()->getName()) ?></strong></legend><br /> + <fieldset class="fieldset review-fieldset" data-hasrequired="<?php __('* Required Fields'); ?>"> + <legend class="legend review-legend"><span><?php echo __("You're reviewing:"); ?></span><strong><?php echo $this->escapeHtml($this->getProductInfo()->getName()) ?></strong></legend><br /> <?php if ($this->getRatings() && $this->getRatings()->getSize()): ?> <span id="input-message-box"></span> - <fieldset class="field ratings vote required"> - <legend class="label"><span><?php echo __('How do you rate this product?') ?><span></legend> + <fieldset class="field required review-field-ratings"> + <legend class="label"><span><?php echo __('How do you rate this product?') ?><span></legend><br/> <div class="control"> <div class="nested" id="product-review-table"> <?php foreach ($this->getRatings() as $_rating): ?> - <div class="field choice rating"> - <label class="label" id="<?php echo $this->escapeHtml($_rating->getRatingCode()) ?>_rating_label"><span><?php echo $this->escapeHtml($_rating->getRatingCode()) ?>:</span></label> - <div class="control rating vote"> + <div class="field choice review-field-rating"> + <label class="label" id="<?php echo $this->escapeHtml($_rating->getRatingCode()) ?>_rating_label"><span><?php echo $this->escapeHtml($_rating->getRatingCode()) ?></span></label> + <div class="control review-control-vote"> <?php $options = $_rating->getOptions();?> <?php $iterator = 1; foreach ($options as $_option): ?> - <input - type="radio" - name="ratings[<?php echo $_rating->getId() ?>]" - id="<?php echo $this->escapeHtml($_rating->getRatingCode()) ?>_<?php echo $_option->getValue() ?>" - value="<?php echo $_option->getId() ?>" - class="radio" + <input + type="radio" + name="ratings[<?php echo $_rating->getId() ?>]" + id="<?php echo $this->escapeHtml($_rating->getRatingCode()) ?>_<?php echo $_option->getValue() ?>" + value="<?php echo $_option->getId() ?>" + class="radio" data-validate="{required:true, messages:{required:'Please select one of each of the ratings above.'}}" aria-labelledby="<?php echo $this->escapeHtml($_rating->getRatingCode()) ?>_rating_label <?php echo $this->escapeHtml($_rating->getRatingCode()) ?>_<?php echo $_option->getValue() ?>_label" /> - <label - class="rating-<?php echo $iterator; ?>" - for="<?php echo $this->escapeHtml($_rating->getRatingCode()) ?>_<?php echo $_option->getValue() ?>" + <label + class="rating-<?php echo $iterator; ?>" + for="<?php echo $this->escapeHtml($_rating->getRatingCode()) ?>_<?php echo $_option->getValue() ?>" title="<?php echo __('%1 %2', $iterator, $iterator > 1 ? 'stars' : 'star') ?>" id="<?php echo $this->escapeHtml($_rating->getRatingCode()) ?>_<?php echo $_option->getValue() ?>_label"> <span><?php echo __('%1 %2', $iterator, $iterator > 1 ? 'stars' : 'star') ?></span> @@ -68,27 +68,27 @@ </div> </fieldset> <?php endif ?> - <div class="field nickname required"> + <div class="field review-field-nickname required"> <label for="nickname_field" class="label"><span><?php echo __('Nickname') ?></span></label> <div class="control"> <input type="text" name="nickname" id="nickname_field" class="input-text" data-validate="{required:true}" value="<?php echo $this->escapeHtml($data->getNickname()) ?>" /> </div> </div> - <div class="field summary required"> + <div class="field review-field-summary required"> <label for="summary_field" class="label"><span><?php echo __('Summary of Your Review') ?></span></label> <div class="control"> <input type="text" name="title" id="summary_field" class="input-text" data-validate="{required:true}" value="<?php echo $this->escapeHtml($data->getTitle()) ?>" /> </div> </div> - <div class="field text required"> + <div class="field review-field-text required"> <label for="review_field" class="label"><span><?php echo __('Review') ?></span></label> <div class="control"> <textarea name="detail" id="review_field" cols="5" rows="3" data-validate="{required:true}"><?php echo $this->escapeHtml($data->getDetail()) ?></textarea> </div> </div> </fieldset> - <div class="actions-toolbar"> - <div class="primary"> + <div class="actions-toolbar review-form-actions"> + <div class="primary actions-primary"> <button type="submit" class="action submit primary"><span><?php echo __('Submit Review') ?></span></button> </div> <!-- <button type="button" class="action cancel"><span><?php echo __('Cancel') ?></span></button> --> @@ -109,9 +109,11 @@ })(jQuery); </script> <?php else: ?> - <p class="review notlogged" id="review-form"> - <?php echo __('Only registered users can write reviews. Please, <a href="%1">log in</a> or <a href="%2">register</a>', $this->getLoginLink(), $this->helper('Magento\Customer\Helper\Data')->getRegisterUrl()) ?> - </p> + <div class="message info notlogged" id="review-form"> + <div> + <?php echo __('Only registered users can write reviews. Please, <a href="%1">log in</a> or <a href="%2">register</a>', $this->getLoginLink(), $this->helper('Magento\Customer\Helper\Data')->getRegisterUrl()) ?> + </div> + </div> <?php endif ?> </div> </div> diff --git a/app/code/Magento/Review/view/frontend/templates/helper/summary.phtml b/app/code/Magento/Review/view/frontend/templates/helper/summary.phtml index 5cdc0be511e64fbc68d17530611eede55f7040d5..11b60ed74379c17fdce1f5a75657af7f43c8b5ef 100644 --- a/app/code/Magento/Review/view/frontend/templates/helper/summary.phtml +++ b/app/code/Magento/Review/view/frontend/templates/helper/summary.phtml @@ -22,44 +22,30 @@ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) */ ?> -<?php $url = $this->getReviewsUrl(); ?> +<?php $url = $this->getReviewsUrl() . '#reviews'; ?> <?php $urlForm = $this->getReviewsUrl() . '#review-form'; ?> -<?php //$url = $this->getProduct()->getProductUrl() . '#info-product_reviews' ?> -<?php //$urlForm = $this->getProduct()->getProductUrl() . '#info-product_reviews' ?> <?php if ($this->getReviewsCount()): ?> <?php $rating = $this->getRatingSummary(); ?> -<div class="product reviews summary<?php echo !$rating ? ' no-rating' :''?>"> +<div class="product-reviews-summary<?php echo !$rating ? ' no-rating' :''?>"> <?php if ($rating):?> - <div class="rating summary"> + <div class="rating-summary"> <span class="label"><span><?php echo __('Rating') ?>:</span></span> - <div class="rating result" title="<?php echo $rating; ?>%"> + <div class="rating-result" title="<?php echo $rating; ?>%"> <span style="width:<?php echo $rating; ?>%"><span><?php echo $rating; ?>%</span></span> </div> </div> <?php endif;?> - <div class="reviews actions"> + <div class="reviews-actions"> <a class="action view" href="<?php echo $url ?>"><?php echo $this->getReviewsCount() ?> <span><?php echo ($this->getReviewsCount() == 1) ? __('Review') : __('Reviews') ?></span></a> <a class="action add" href="<?php echo $urlForm ?>"><?php echo __('Add Your Review') ?></a> </div> </div> <?php elseif ($this->getDisplayIfEmpty()): ?> -<div class="product reviews summary empty"> - <a class="action add" href="<?php echo $urlForm; ?>"> - <?php echo __('Be the first to review this product') ?> - </a> +<div class="product-reviews-summary empty"> + <div class="reviews-actions"> + <a class="action add" href="<?php echo $urlForm; ?>"> + <?php echo __('Be the first to review this product') ?> + </a> + </div> </div> <?php endif; ?> -<script type="text/javascript"> - (function($) { - $(document).ready(function() { - $('.reviews.summary .action').click(function(evt){ - if($('#product_reviews').length > 0) { - evt.preventDefault(); - $('[data-sections]').terms({start:'product_reviews'}); - } else { - return - } - }) - }); - })(jQuery); -</script> \ No newline at end of file diff --git a/app/code/Magento/Review/view/frontend/templates/helper/summary_short.phtml b/app/code/Magento/Review/view/frontend/templates/helper/summary_short.phtml index 804494a3bae3fe34e5f5b1ff1b4b406103ddd70c..edb4ff0f052d70e3f229cf42dbd8ce3899d7e78e 100644 --- a/app/code/Magento/Review/view/frontend/templates/helper/summary_short.phtml +++ b/app/code/Magento/Review/view/frontend/templates/helper/summary_short.phtml @@ -22,45 +22,29 @@ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) */ ?> -<?php $url = $this->getReviewsUrl(); ?> +<?php $url = $this->getReviewsUrl() . '#reviews'; ?> <?php $urlForm = $this->getReviewsUrl() . '#review-form'; ?> -<?php //$url = $this->getProduct()->getProductUrl() . '#info-product_reviews' ?> -<?php //$urlForm = $this->getProduct()->getProductUrl() . '#info-product_reviews' ?> <?php if ($this->getReviewsCount()): ?> <?php $rating = $this->getRatingSummary(); ?> -<div class="product reviews summary short<?php echo !$rating ? ' no-rating' :''?>"> +<div class="product-reviews-summary short<?php echo !$rating ? ' no-rating' :''?>"> <?php if ($rating):?> - <div class="rating summary"> + <div class="rating-summary"> <span class="label"><span><?php echo __('Rating') ?>:</span></span> - <div class="rating result" title="<?php echo $rating; ?>%"> - <span style="width:<?php echo $rating; ?>%"> - <span><?php echo $rating; ?>%</span> - </span> + <div class="rating-result" title="<?php echo $rating; ?>%"> + <span style="width:<?php echo $rating; ?>%"><span><?php echo $rating; ?>%</span></span> </div> </div> <?php endif;?> - <div class="reviews actions"> - <a class="action view" href="<?php echo $urlForm ?>"><?php echo $this->getReviewsCount() ?> <span><?php echo ($this->getReviewsCount() == 1) ? __('Review') : __('Reviews') ?></span></a> + <div class="reviews-actions"> + <a class="action view" href="<?php echo $url ?>"><?php echo $this->getReviewsCount() ?> <span><?php echo ($this->getReviewsCount() == 1) ? __('Review') : __('Reviews') ?></span></a> </div> </div> <?php elseif ($this->getDisplayIfEmpty()): ?> -<div class="product reviews summary short empty"> - <a class="action add" href="<?php echo $urlForm; ?>"> - <?php echo __('Be the first to review this product') ?> - </a> +<div class="product-reviews-summary short empty"> + <div class="reviews-actions"> + <a class="action add" href="<?php echo $urlForm; ?>"> + <?php echo __('Be the first to review this product') ?> + </a> + </div> </div> <?php endif; ?> -<script type="text/javascript"> - (function($) { - $(document).ready(function() { - $('.reviews.summary .action').click(function(evt){ - if($('#product_reviews').length > 0) { - evt.preventDefault(); - $('[data-sections]').terms({start:'product_reviews'}); - } else { - return - } - }) - }); - })(jQuery); -</script> diff --git a/app/code/Magento/Review/view/frontend/templates/product/view/list.phtml b/app/code/Magento/Review/view/frontend/templates/product/view/list.phtml index 9104cd535b17f76c9eef44ab18a1f94899487ba0..8ab88ed9e1f26b9b9dd167a3ecd7b03863848d5a 100644 --- a/app/code/Magento/Review/view/frontend/templates/product/view/list.phtml +++ b/app/code/Magento/Review/view/frontend/templates/product/view/list.phtml @@ -22,51 +22,60 @@ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) */ ?> - -<?php +<?php +/** + * @description: + * + */ +?> +<?php $_items = $this->getReviewsCollection()->getItems(); $format = $this->getDateFormat() ?: 'short'; ?> <?php if (count($_items)):?> -<div class="block reviews list" id="customer-reviews"> - <div class="title"> +<div class="block review-list" id="customer-reviews"> + <div class="block-title"> <strong><?php echo __('Customer Reviews') ?></strong> </div> - <div class="content"> - <div class="toolbar products"> + <div class="block-content"> + <div class="toolbar review-toolbar"> <?php echo $this->getChildHtml('toolbar') ?> </div> - <ol class="reviews items"> - <?php foreach ($_items as $_review):?> - <li class="item review"> - <?php foreach ($_review->getRatingVotes() as $_vote): ?> - <div class="rating summary item"> - <span class="label"><span><?php echo $this->escapeHtml($_vote->getRatingCode()) ?>:</span></span> - <div class="rating result" title="<?php echo $_vote->getPercent() ?>%"> - <span style="width:<?php echo $_vote->getPercent() ?>%"> - <span><?php echo $_vote->getPercent() ?>%</span> - </span> + <ol class="items review-items"> + <?php foreach ($_items as $_review):?> + <li class="item review-item"> + <div class="review-title"><?php echo $this->escapeHtml($_review->getTitle()) ?></div> + <?php if (count($_review->getRatingVotes())): ?> + <div class="review-ratings"> + <?php foreach ($_review->getRatingVotes() as $_vote): ?> + <div class="rating-summary item"> + <span class="label rating-label"><span><?php echo $this->escapeHtml($_vote->getRatingCode()) ?></span></span> + <div class="rating-result" title="<?php echo $_vote->getPercent() ?>%"> + <span style="width:<?php echo $_vote->getPercent() ?>%"> + <span><?php echo $_vote->getPercent() ?>%</span> + </span> + </div> + </div> + <?php endforeach; ?> + </div> + <?php endif; ?> + <div class="review-content"> + <?php echo nl2br($this->escapeHtml($_review->getDetail())) ?> + </div> + <div class="review-details"> + <p class="review-author"> + <span class="review-details-label"><?php echo __('Review by')?></span> + <strong class="review-details-value"><?php echo $this->escapeHtml($_review->getNickname()) ?></strong> + </p> + <p class="review-date"> + <span class="review-details-label"><?php echo __('Posted on') ?></span> + <time class="review-details-value"><?php echo $this->formatDate($_review->getCreatedAt(), $format) ?></time> + </p> </div> - </div> - <?php endforeach; ?> - <div class="review details"> - <p class="author"> - <span><?php echo __('Review by')?></span> - <strong class="nickname"><?php echo $this->escapeHtml($_review->getNickname()) ?></strong> - </p> - <p class="review date"> - <span><?php echo __('Posted on') ?></span> - <time class="date"><?php echo $this->formatDate($_review->getCreatedAt(), $format) ?></time> - </p> - </div> - <div class="review title"><?php echo $this->escapeHtml($_review->getTitle()) ?></div> - <div class="review content"> - <?php echo nl2br($this->escapeHtml($_review->getDetail())) ?> - </div> - </li> - <?php endforeach; ?> - </ol> - <div class="toolbar products"> + </li> + <?php endforeach; ?> + </ol> + <div class="toolbar review-toolbar"> <?php echo $this->getChildHtml('toolbar') ?> </div> </div> diff --git a/app/code/Magento/Review/view/frontend/templates/review.phtml b/app/code/Magento/Review/view/frontend/templates/review.phtml new file mode 100644 index 0000000000000000000000000000000000000000..eb2ff606ce27a4f465824ff050c4bdf1dbda8dd4 --- /dev/null +++ b/app/code/Magento/Review/view/frontend/templates/review.phtml @@ -0,0 +1,71 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +?> + +<div id="product-review-container"></div> +<?php echo $this->getChildHtml(); ?> + +<script type="text/javascript"> +//<![CDATA[ +function processReviews(url,fromPages) { +(function($) { + $.ajax({ + url: url, + dataType: 'html' + }).done(function(data) { + $('#product-review-container').html(data); + $('.pages a').each(function(index, element) { + $(element).click(function(event) { + processReviews($(element).attr('href'), true); + event.preventDefault(); + }); + }); + }).complete(function(){ + if (fromPages == true) { + $('html, body').animate({ + scrollTop: $('#reviews').offset().top - 50 + }, 300); + } + }); +})(jQuery); +} +processReviews('<?php echo $this->getProductReviewUrl();?>'); + +jQuery(function() { + jQuery('.product-info-main .reviews-actions a').click(function(event) { + event.preventDefault(); + var acnchor = jQuery(this).attr('href').replace(/^.*?(#|$)/,''); + jQuery(".product.data.items [data-role='content']").each(function(index){ + if(this.id == "reviews") { + jQuery(".product.data.items").tabs('activate',index); + jQuery('html, body').animate({ + scrollTop: jQuery('#' + acnchor).offset().top - 50 + }, 300); + } + }) + }) +}); + +//]]> +</script> diff --git a/app/code/Magento/Sales/Model/Order.php b/app/code/Magento/Sales/Model/Order.php index c9b48275f79028df25c4b752dc90db9d8271d6bc..b5c0720cae93d2b37296e3529ee77dc877c60269 100644 --- a/app/code/Magento/Sales/Model/Order.php +++ b/app/code/Magento/Sales/Model/Order.php @@ -1521,6 +1521,7 @@ class Order extends \Magento\Sales\Model\AbstractModel if (!$this->_salesData->canSendNewOrderEmail($storeId)) { return $this; } + // Get the destination email addresses to send copies to $copyTo = $this->_getEmails(self::XML_PATH_EMAIL_COPY_TO); $copyMethod = $this->_scopeConfig->getValue( diff --git a/app/code/Magento/Sales/Model/Order/Payment.php b/app/code/Magento/Sales/Model/Order/Payment.php index e34716cca608d585183ebb1ae4bea4e09ae652d7..8e0cf75fd9c4978dc8088866d1debaf6de81844e 100644 --- a/app/code/Magento/Sales/Model/Order/Payment.php +++ b/app/code/Magento/Sales/Model/Order/Payment.php @@ -355,6 +355,8 @@ class Payment extends \Magento\Payment\Model\Info } else { $orderState = \Magento\Sales\Model\Order::STATE_PROCESSING; $this->processAction($action, $order); + $orderState = $order->getState() ? $order->getState() : $orderState; + $orderStatus = $order->getStatus() ? $order->getStatus() : $orderStatus; } } @@ -537,9 +539,10 @@ class Payment extends \Magento\Payment\Model\Info * TODO: eliminate logic duplication with capture() * * @param float $amount + * @param bool $skipFraudDetection * @return $this */ - public function registerCaptureNotification($amount) + public function registerCaptureNotification($amount, $skipFraudDetection = false) { $this->_generateTransactionId( \Magento\Sales\Model\Order\Payment\Transaction::TYPE_CAPTURE, @@ -557,7 +560,7 @@ class Payment extends \Magento\Payment\Model\Info $order->addRelatedObject($invoice); $this->setCreatedInvoice($invoice); } else { - $this->setIsFraudDetected(true); + $this->setIsFraudDetected(!$skipFraudDetection); $this->_updateTotals(array('base_amount_paid_online' => $amount)); } } @@ -857,10 +860,10 @@ class Payment extends \Magento\Payment\Model\Info $amount = $amountRefundLeft; } - if ($amount <= 0) { + if ($amount != $baseGrandTotal) { $order->addStatusHistoryComment( __( - 'IPN "Refunded". Refund issued by merchant. Registered notification about refunded amount of %1. Transaction ID: "%2"', + 'IPN "Refunded". Refund issued by merchant. Registered notification about refunded amount of %1. Transaction ID: "%2". Credit Memo has not been created. Please create offline Credit Memo.', $this->_formatPrice($notificationAmount), $this->getTransactionId() ), @@ -1067,7 +1070,6 @@ class Payment extends \Magento\Payment\Model\Info $this, $transactionId ); - } else { } if ($this->getIsTransactionApproved()) { $result = true; @@ -1089,9 +1091,16 @@ class Payment extends \Magento\Payment\Model\Info } // process payment in case of positive or negative result, or add a comment - if (-1 === $result) { - // switch won't work with such $result! - $order->addStatusHistoryComment($message); + if (-1 === $result) { // switch won't work with such $result! + if ($order->getState() != \Magento\Sales\Model\Order::STATE_PAYMENT_REVIEW) { + $status = $this->getIsFraudDetected() ? \Magento\Sales\Model\Order::STATUS_FRAUD : false; + $order->setState(\Magento\Sales\Model\Order::STATE_PAYMENT_REVIEW, $status, $message); + if ($transactionId) { + $this->setLastTransId($transactionId); + } + } else { + $order->addStatusHistoryComment($message); + } } elseif (true === $result) { if ($invoice) { $invoice->pay(); @@ -1167,6 +1176,13 @@ class Payment extends \Magento\Payment\Model\Info */ protected function _authorize($isOnline, $amount) { + // check for authorization amount to be equal to grand total + $this->setShouldCloseParentTransaction(false); + $isSameCurrency = $this->_isSameCurrency(); + if (!$isSameCurrency || !$this->_isCaptureFinal($amount)) { + $this->setIsFraudDetected(true); + } + // update totals $amount = $this->_formatAmount($amount, true); $this->setBaseAmountAuthorized($amount); @@ -1187,11 +1203,19 @@ class Payment extends \Magento\Payment\Model\Info $this->_formatPrice($amount) ); $state = \Magento\Sales\Model\Order::STATE_PAYMENT_REVIEW; + } else { if ($this->getIsFraudDetected()) { - $status = \Magento\Sales\Model\Order::STATUS_FRAUD; + $message = __( + 'Order is suspended as its authorizing amount %1 is suspected to be fraudulent.', + $this->_formatPrice($amount, $this->getCurrencyCode()) + ); + } else { + $message = __('Authorized amount of %1', $this->_formatPrice($amount)); } - } else { - $message = __('Authorized amount of %1', $this->_formatPrice($amount)); + } + if ($this->getIsFraudDetected()) { + $state = \Magento\Sales\Model\Order::STATE_PAYMENT_REVIEW; + $status = \Magento\Sales\Model\Order::STATUS_FRAUD; } // update transactions, order state and add comments diff --git a/app/code/Magento/Sales/Model/Resource/Report/Bestsellers/Collection.php b/app/code/Magento/Sales/Model/Resource/Report/Bestsellers/Collection.php index d079180c09e35f43050b17a0061847334e2f4faa..abae4d21b0e8933dd442c494ae681f7f420611cb 100644 --- a/app/code/Magento/Sales/Model/Resource/Report/Bestsellers/Collection.php +++ b/app/code/Magento/Sales/Model/Resource/Report/Bestsellers/Collection.php @@ -133,7 +133,7 @@ class Collection extends \Magento\Sales\Model\Resource\Report\Collection\Abstrac * * @return $this */ - protected function _initSelect() + protected function _applyAggregatedTable() { $select = $this->getSelect(); diff --git a/app/code/Magento/Sales/view/frontend/layout/sales_order_creditmemo.xml b/app/code/Magento/Sales/view/frontend/layout/sales_order_creditmemo.xml index 99b5cebd27edf8abfcdc411a537264c70394501c..bcb05b783805c2bdbcd633844f9b2147320d4af4 100644 --- a/app/code/Magento/Sales/view/frontend/layout/sales_order_creditmemo.xml +++ b/app/code/Magento/Sales/view/frontend/layout/sales_order_creditmemo.xml @@ -26,11 +26,16 @@ <layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_single.xsd"> <update handle="sales_order_creditmemo_renderers" /> <update handle="customer_account"/> - <referenceContainer name="content"> - <block class="Magento\Sales\Block\Order\Info" as="info" name="sales.order.info"> + <referenceContainer name="page.main.title"> + <block class="Magento\Sales\Block\Order\Info" name="order.status" template="order/order_status.phtml" /> + <block class="Magento\Sales\Block\Order\Info" name="order.date" template="order/order_date.phtml" /> + <container name="order.actions.container" htmlTag="div" htmlClass="actions-toolbar order-actions-toolbar"> <block class="Magento\Sales\Block\Order\Info\Buttons" as="buttons" name="sales.order.info.buttons" cacheable="false"/> - </block> - <block class="Magento\Sales\Block\Order\Creditmemo" name="sales.order.creditmemo" after="sales.order.info" cacheable="false"> + <block class="Magento\Sales\Block\Order\Info" name="order.rss" template="order/order_rss.phtml" /> + </container> + </referenceContainer> + <referenceContainer name="content"> + <block class="Magento\Sales\Block\Order\Creditmemo" name="sales.order.creditmemo" cacheable="false"> <block class="Magento\Sales\Block\Order\Creditmemo\Items" name="creditmemo_items" template="order/creditmemo/items.phtml"> <block class="Magento\Framework\View\Element\RendererList" name="sales.order.creditmemo.renderers" as="renderer.list" /> <block class="Magento\Sales\Block\Order\Creditmemo\Totals" name="creditmemo_totals" template="order/totals.phtml"> diff --git a/app/code/Magento/Sales/view/frontend/layout/sales_order_info_links.xml b/app/code/Magento/Sales/view/frontend/layout/sales_order_info_links.xml index fba533f2bd6e35b9525a58a3a940e2fade593556..aabd36d18af947e31b837fbb2aedef32976af5a4 100644 --- a/app/code/Magento/Sales/view/frontend/layout/sales_order_info_links.xml +++ b/app/code/Magento/Sales/view/frontend/layout/sales_order_info_links.xml @@ -24,15 +24,15 @@ */ --> <layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_single.xsd"> - <referenceBlock name="sales.order.info"> - <block class="Magento\Framework\View\Element\Html\Links" as="links" name="sales.order.info.links"> + <referenceContainer name="content"> + <block class="Magento\Framework\View\Element\Html\Links" as="links" name="sales.order.info.links" before="-"> <arguments> - <argument name="css_class" xsi:type="string">items</argument> + <argument name="css_class" xsi:type="string">items order-links</argument> </arguments> <block class="Magento\Sales\Block\Order\Link" name="sales.order.info.links.information"> <arguments> <argument name="path" xsi:type="string">sales/order/view</argument> - <argument name="label" xsi:type="string">Order Information</argument> + <argument name="label" xsi:type="string">Items Ordered</argument> </arguments> </block> <block class="Magento\Sales\Block\Order\Link" name="sales.order.info.links.invoice"> @@ -57,5 +57,5 @@ </arguments> </block> </block> - </referenceBlock> + </referenceContainer> </layout> diff --git a/app/code/Magento/Sales/view/frontend/layout/sales_order_invoice.xml b/app/code/Magento/Sales/view/frontend/layout/sales_order_invoice.xml index 999471a570737e6ce316e4dc3629d35e899d1a06..13934744f2c830b3a377867449e8003236f33559 100644 --- a/app/code/Magento/Sales/view/frontend/layout/sales_order_invoice.xml +++ b/app/code/Magento/Sales/view/frontend/layout/sales_order_invoice.xml @@ -26,11 +26,16 @@ <layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_single.xsd"> <update handle="customer_account"/> <update handle="sales_order_invoice_renderers" /> - <referenceContainer name="content"> - <block class="Magento\Sales\Block\Order\Info" as="info" name="sales.order.info"> + <referenceContainer name="page.main.title"> + <block class="Magento\Sales\Block\Order\Info" name="order.status" template="order/order_status.phtml" /> + <block class="Magento\Sales\Block\Order\Info" name="order.date" template="order/order_date.phtml" /> + <container name="order.actions.container" htmlTag="div" htmlClass="actions-toolbar order-actions-toolbar"> <block class="Magento\Sales\Block\Order\Info\Buttons" as="buttons" name="sales.order.info.buttons" cacheable="false"/> - </block> - <block class="Magento\Sales\Block\Order\Invoice" name="sales.order.invoice" after="sales.order.info" cacheable="false"> + <block class="Magento\Sales\Block\Order\Info" name="order.rss" template="order/order_rss.phtml" /> + </container> + </referenceContainer> + <referenceContainer name="content"> + <block class="Magento\Sales\Block\Order\Invoice" name="sales.order.invoice" cacheable="false"> <block class="Magento\Sales\Block\Order\Invoice\Items" name="invoice_items" template="order/invoice/items.phtml"> <block class="Magento\Framework\View\Element\RendererList" name="sales.order.invoice.renderers" as="renderer.list"/> <block class="Magento\Sales\Block\Order\Invoice\Totals" name="invoice_totals" template="order/totals.phtml"> @@ -43,6 +48,7 @@ <block class="Magento\Sales\Block\Order\Comments" name="invoice_comments" template="order/comments.phtml"/> </block> </block> + <block class="Magento\Sales\Block\Order\Info" as="info" name="sales.order.info" after="-" /> </referenceContainer> <update handle="sales_order_info_links"/> <block class="Magento\Framework\View\Element\Template" name="additional.product.info" template="Magento_Core::template.phtml"/> diff --git a/app/code/Magento/Sales/view/frontend/layout/sales_order_shipment.xml b/app/code/Magento/Sales/view/frontend/layout/sales_order_shipment.xml index 606039127986620b849a29feaccf01b83ede25fd..45a152d0dd0cdb87a423fa7c3a103c72753d2eb3 100644 --- a/app/code/Magento/Sales/view/frontend/layout/sales_order_shipment.xml +++ b/app/code/Magento/Sales/view/frontend/layout/sales_order_shipment.xml @@ -25,10 +25,16 @@ --> <layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_single.xsd"> <update handle="customer_account"/> - <referenceContainer name="content"> - <block class="Magento\Sales\Block\Order\Info" as="info" name="sales.order.info"> + <referenceContainer name="page.main.title"> + <block class="Magento\Sales\Block\Order\Info" name="order.status" template="order/order_status.phtml" /> + <block class="Magento\Sales\Block\Order\Info" name="order.date" template="order/order_date.phtml" /> + <container name="order.actions.container" htmlTag="div" htmlClass="actions-toolbar order-actions-toolbar"> <block class="Magento\Sales\Block\Order\Info\Buttons" as="buttons" name="sales.order.info.buttons" cacheable="false"/> - </block> + <block class="Magento\Sales\Block\Order\Info" name="order.rss" template="order/order_rss.phtml" /> + </container> + </referenceContainer> + <referenceContainer name="content"> + <block class="Magento\Sales\Block\Order\Info" as="info" name="sales.order.info" after="sales.order.shipment" /> </referenceContainer> <update handle="sales_order_info_links"/> <block class="Magento\Framework\View\Element\Template" name="additional.product.info" template="Magento_Core::template.phtml"/> diff --git a/app/code/Magento/Sales/view/frontend/layout/sales_order_view.xml b/app/code/Magento/Sales/view/frontend/layout/sales_order_view.xml index 44686104961afe15082d70c6276f4e912287c8d1..bd4dce6776bb173a31b0105249b377fbde85e29b 100644 --- a/app/code/Magento/Sales/view/frontend/layout/sales_order_view.xml +++ b/app/code/Magento/Sales/view/frontend/layout/sales_order_view.xml @@ -26,11 +26,17 @@ <layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_single.xsd"> <update handle="customer_account"/> <update handle="sales_order_item_renderers"/> - <referenceContainer name="content"> - <block class="Magento\Sales\Block\Order\Info" as="info" name="sales.order.info"> + <referenceContainer name="page.main.title"> + <block class="Magento\Sales\Block\Order\Info" name="order.status" template="order/order_status.phtml" /> + <block class="Magento\Sales\Block\Order\Info" name="order.date" template="order/order_date.phtml" /> + <container name="order.actions.container" htmlTag="div" htmlClass="actions-toolbar order-actions-toolbar"> <block class="Magento\Sales\Block\Order\Info\Buttons" as="buttons" name="sales.order.info.buttons" cacheable="false"/> - </block> - <block class="Magento\Sales\Block\Order\View" name="sales.order.view" after="sales.order.info" cacheable="false"> + <block class="Magento\Sales\Block\Order\Info" name="order.rss" template="order/order_rss.phtml" /> + </container> + </referenceContainer> + <referenceContainer name="content"> + <block class="Magento\Sales\Block\Order\View" name="order.comments" template="order/order_comments.phtml" before="sales.order.info.links" /> + <block class="Magento\Sales\Block\Order\View" name="sales.order.view" cacheable="false"> <block class="Magento\Sales\Block\Order\Items" name="order_items" template="order/items.phtml"> <block class="Magento\Framework\View\Element\RendererList" name="sales.order.items.renderers" as="renderer.list" /> <block class="Magento\Sales\Block\Order\Totals" name="order_totals" template="order/totals.phtml"> @@ -42,6 +48,7 @@ </block> </block> </block> + <block class="Magento\Sales\Block\Order\Info" as="info" name="sales.order.info" after="sales.order.view" /> </referenceContainer> <update handle="sales_order_info_links"/> <block class="Magento\Framework\View\Element\Template" name="additional.product.info" template="Magento_Core::template.phtml"/> diff --git a/app/code/Magento/Sales/view/frontend/templates/order/creditmemo.phtml b/app/code/Magento/Sales/view/frontend/templates/order/creditmemo.phtml index ded58aa14fe8991b5f814b6d6dd69aa68d17812f..ea441b5f441f05e42c2e223a5772b373465ab0bd 100644 --- a/app/code/Magento/Sales/view/frontend/templates/order/creditmemo.phtml +++ b/app/code/Magento/Sales/view/frontend/templates/order/creditmemo.phtml @@ -22,7 +22,7 @@ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) */ ?> -<div class="order details items creditmemo"> +<div class="order-details-items creditmemo"> <?php echo $this->getChildHtml('creditmemo_items') ?> <div class="actions-toolbar"> <div class="secondary"> diff --git a/app/code/Magento/Sales/view/frontend/templates/order/creditmemo/items.phtml b/app/code/Magento/Sales/view/frontend/templates/order/creditmemo/items.phtml index 31c8f81b66bceece4f256a5c4d7a2c21f30c3ee9..d12df7489333e86cbf30bfd6294e1a2f3f8a7975 100644 --- a/app/code/Magento/Sales/view/frontend/templates/order/creditmemo/items.phtml +++ b/app/code/Magento/Sales/view/frontend/templates/order/creditmemo/items.phtml @@ -23,17 +23,15 @@ */ ?> <?php $_order = $this->getOrder() ?> -<div class="order toolbar"> - <div class="actions"> - <a href="<?php echo $this->getPrintAllCreditmemosUrl($_order) ?>" - onclick="this.target='_blank'" - class="action print"> - <span><?php echo __('Print All Refunds') ?></span> - </a> - </div> +<div class="actions-toolbar"> + <a href="<?php echo $this->getPrintAllCreditmemosUrl($_order) ?>" + onclick="this.target='_blank'" + class="action print"> + <span><?php echo __('Print All Refunds') ?></span> + </a> </div> <?php foreach ($_order->getCreditmemosCollection() as $_creditmemo): ?> -<div class="order title"> +<div class="order-title"> <strong><?php echo __('Refund #') ?><?php echo $_creditmemo->getIncrementId(); ?> </strong> <a href="<?php echo $this->getPrintCreditmemoUrl($_creditmemo) ?>" onclick="this.target='_blank'" @@ -42,9 +40,8 @@ </a> </div> -<div class="order subtitle caption"><strong><?php echo __('Items Refunded') ?></strong></div> -<div class="wrapper table order items creditmemo"> - <table class="data table order items creditmemo" id="my-refund-table-<?php echo $_creditmemo->getId(); ?>"> +<div class="table-wrapper order-items-creditmemo"> + <table class="data table table-order-items creditmemo" id="my-refund-table-<?php echo $_creditmemo->getId(); ?>"> <caption class="table caption"><?php echo __('Items Refunded') ?></caption> <thead> <tr> diff --git a/app/code/Magento/Sales/view/frontend/templates/order/creditmemo/items/renderer/default.phtml b/app/code/Magento/Sales/view/frontend/templates/order/creditmemo/items/renderer/default.phtml index 1424311f7e6c4c966b249e9353db9e20a3e2e40e..2728e71d8e523bdd40a606c57ae5913d1429a49b 100644 --- a/app/code/Magento/Sales/view/frontend/templates/order/creditmemo/items/renderer/default.phtml +++ b/app/code/Magento/Sales/view/frontend/templates/order/creditmemo/items/renderer/default.phtml @@ -25,8 +25,8 @@ <?php $_item = $this->getItem() ?> <?php $_order = $this->getItem()->getOrderItem()->getOrder() ?> <tr id="order-item-row-<?php echo $_item->getId() ?>"> - <td class="col name"> - <strong class="product name"><?php echo $this->escapeHtml($_item->getName()) ?></strong> + <td class="col name" data-th="<?php echo $this->escapeHtml(__('Product Name')); ?>"> + <strong class="product name product-item-name"><?php echo $this->escapeHtml($_item->getName()) ?></strong> <?php if($_options = $this->getItemOptions()): ?> <dl class="item options"> <?php foreach ($_options as $_option) : ?> @@ -73,187 +73,94 @@ data-item-id="<?php echo $_item->getId() ?>"><?php echo __('Gift Message') ?></a> <?php endif; ?> </td> - <td class="col sku"><?php echo $this->prepareSku($this->getSku()) ?></td> - <td class="col price"> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceExclTax()): ?> - <span class="price-excl-tax"> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices()): ?> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart-price"> - <?php endif; ?> - <span class="label"><?php echo __('Excl. Tax'); ?>:</span> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - </span> - <?php endif; ?> - <?php endif; ?> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}' - <?php else: ?> - <span class="cart-price"> - <?php endif; ?> - - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()+$this->getItem()->getWeeeTaxAppliedAmount()+$this->getItem()->getWeeeTaxDisposition()); ?> - <?php else: ?> - <?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()) ?> - <?php endif; ?> - </span> - - <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> - - <span class="cart-tax-info" id="eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display:none;"> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <span class="nobr"><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount']); ?></span> - <?php endforeach; ?> - </small> - <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <span class="nobr"><small><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></small></span> - <?php endforeach; ?> - <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <span class="nobr"><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></span> - <?php endforeach; ?> - </small> - <?php endif; ?> - </span> - - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}' - <span class="nobr"><?php echo __('Total'); ?>:<br /> <?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()+$this->getItem()->getWeeeTaxAppliedAmount()+$this->getItem()->getWeeeTaxDisposition()); ?></span> - </span> - <?php endif; ?> - <?php endif; ?> - </span> - <br /> - <?php endif; ?> + <td class="col sku" data-th="<?php echo $this->escapeHtml(__('SKU')); ?>"><?php echo $this->prepareSku($this->getSku()) ?></td> + <td class="col price" data-th="<?php echo $this->escapeHtml(__('Price')); ?>"> <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceInclTax()): ?> - <span class="price-incl-tax"> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices()): ?> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart-price"> - <?php endif; ?> - <span class="label"><?php echo __('Incl. Tax'); ?>:</span> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - </span> - <?php endif; ?> - <?php endif; ?> + <span class="incl tax" data-th="<?php echo $this->escapeHtml(__('Incl. Tax')); ?>"> <?php $_incl = $this->helper('Magento\Checkout\Helper\Data')->getPriceInclTax($this->getItem()); ?> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#unit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}' + <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#unit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> <?php else: ?> <span class="cart-price"> <?php endif; ?> - - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedAmount()); ?> - <?php else: ?> - <?php echo $this->getOrder()->formatPrice($_incl-$this->getItem()->getWeeeTaxDisposition()) ?> - <?php endif; ?> - </span> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedAmount()); ?> + <?php else: ?> + <?php echo $this->getOrder()->formatPrice($_incl-$this->getItem()->getWeeeTaxDisposition()) ?> + <?php endif; ?> + </span> <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> - - <span class="cart-tax-info" id="unit-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display:none;"> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <span class="nobr"><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount']); ?></span> - <?php endforeach; ?> - </small> - <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <span class="nobr"><small><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></small></span> - <?php endforeach; ?> - <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <span class="nobr"><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></span> - <?php endforeach; ?> - </small> - <?php endif; ?> + <span class="cart-tax-info" id="unit-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display: none;"> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount']); ?></span> + <?php endforeach; ?> + <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></span> + <?php endforeach; ?> + <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></span> + <?php endforeach; ?> + <?php endif; ?> </span> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#unit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}' - <span class="nobr"><?php echo __('Total incl. tax'); ?>:<br /> <?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedAmount()); ?></span> + <span class="weee" data-th="<?php echo __('Total incl. tax'); ?>"><?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedAmount()); ?></span> </span> <?php endif; ?> <?php endif; ?> </span> <?php endif; ?> - </td> - <td class="col qty"><?php echo $_item->getQty()*1 ?></td> - <td class="col subtotal"> + <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceExclTax()): ?> - <span class="price-excl-tax"> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices()): ?> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart-price"> - <?php endif; ?> - <span class="label"><?php echo __('Excl. Tax'); ?>:</span> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - </span> - <?php endif; ?> - <?php endif; ?> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <span class="excl tax" data-th="<?php echo $this->escapeHtml(__('Excl. Tax')); ?>"> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> <?php else: ?> - <span class="cart-price"> - <?php endif; ?> + <span class="cart-price"> + <?php endif; ?> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()+$this->getItem()->getWeeeTaxAppliedRowAmount()+$this->getItem()->getWeeeTaxRowDisposition()); ?> - <?php else: ?> - <?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()) ?> - <?php endif; ?> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()+$this->getItem()->getWeeeTaxAppliedAmount()+$this->getItem()->getWeeeTaxDisposition()); ?> + <?php else: ?> + <?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()) ?> + <?php endif; ?> </span> - <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> + <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> + <span class="cart-tax-info" id="eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display: none;"> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount']); ?></span> + <?php endforeach; ?> + <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></span> + <?php endforeach; ?> + <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></span> + <?php endforeach; ?> + <?php endif; ?> + </span> - <span class="cart-tax-info" id="esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display:none;"> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <span class="nobr"><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount']); ?></span> - <?php endforeach; ?> - </small> - <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <span class="nobr"><small><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></small></span> - <?php endforeach; ?> - <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <span class="nobr"><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></span> - <?php endforeach; ?> - </small> - <?php endif; ?> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <span class="weee" data-th="<?php echo $this->escapeHtml(__('Total')); ?>"><?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()+$this->getItem()->getWeeeTaxAppliedAmount()+$this->getItem()->getWeeeTaxDisposition()); ?></span> </span> - - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> - <span class="nobr"><?php echo __('Total'); ?>:<br /> <?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()+$this->getItem()->getWeeeTaxAppliedRowAmount()+$this->getItem()->getWeeeTaxRowDisposition()); ?></span> - </span> - <?php endif; ?> <?php endif; ?> + <?php endif; ?> </span> - <br /> <?php endif; ?> + </td> + <td class="col qty" data-th="<?php echo $this->escapeHtml(__('Qty')); ?>"><?php echo $_item->getQty()*1 ?></td> + <td class="col subtotal" data-th="<?php echo $this->escapeHtml(__('Subtotal')); ?>"> <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceInclTax()): ?> - <span class="price-incl-tax"> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices()): ?> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart-price"> - <?php endif; ?> - <span class="label"><?php echo __('Incl. Tax'); ?>:</span> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - </span> - <?php endif; ?> - <?php endif; ?> + <span class="incl tax" data-th="<?php echo $this->escapeHtml(__('Incl. Tax')); ?>"> <?php $_incl = $this->helper('Magento\Checkout\Helper\Data')->getSubtotalInclTax($this->getItem()); ?> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#subtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> @@ -265,41 +172,77 @@ <?php else: ?> <?php echo $this->getOrder()->formatPrice($_incl-$this->getItem()->getWeeeTaxRowDisposition()) ?> <?php endif; ?> - </span> + </span> <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> - - <span class="cart-tax-info" id="subtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display:none;"> + <span class="cart-tax-info" id="subtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display: none;"> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <span class="nobr"><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount']); ?></span> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount']); ?></span> <?php endforeach; ?> - </small> <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <span class="nobr"><small><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></small></span> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></span> <?php endforeach; ?> <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <span class="nobr"><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></span> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></span> <?php endforeach; ?> - </small> <?php endif; ?> </span> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#subtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> - <span class="nobr"><?php echo __('Total incl. tax'); ?>:<br /> <?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedRowAmount()); ?></span> + <span class="weee" data-th="<?php echo $this->escapeHtml(__('Total incl. tax')); ?>"><?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedRowAmount()); ?></span> </span> <?php endif; ?> <?php endif; ?> </span> <?php endif; ?> + + <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceExclTax()): ?> + <span class="excl tax" data-th="<?php echo $this->escapeHtml(__('Excl. Tax')); ?>"> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <?php else: ?> + <span class="cart-price"> + <?php endif; ?> + + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()+$this->getItem()->getWeeeTaxAppliedRowAmount()+$this->getItem()->getWeeeTaxRowDisposition()); ?> + <?php else: ?> + <?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()) ?> + <?php endif; ?> + </span> + + <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> + <span class="cart-tax-info" id="esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display: none;"> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount']); ?></span> + <?php endforeach; ?> + <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></span> + <?php endforeach; ?> + <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></span> + <?php endforeach; ?> + <?php endif; ?> + </span> + + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <span class="weee" data-th="<?php echo $this->escapeHtml(__('Total')); ?>"><?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()+$this->getItem()->getWeeeTaxAppliedRowAmount()+$this->getItem()->getWeeeTaxRowDisposition()); ?></span> + </span> + <?php endif; ?> + <?php endif; ?> + </span> + <?php endif; ?> </td> - <td class="col discount"><?php echo $_order->formatPrice(-$_item->getDiscountAmount()) ?></td> - <td class="cot total"> + <td class="col discount" data-th="<?php echo $this->escapeHtml(__('Discount Amount')); ?>"><?php echo $_order->formatPrice(-$_item->getDiscountAmount()) ?></td> + <td class="cot total" data-th="<?php echo $this->escapeHtml(__('Row Total')); ?>"> <?php echo $_order->formatPrice($_item->getRowTotal()-$_item->getDiscountAmount()+$_item->getTaxAmount()+$_item->getWeeeTaxAppliedRowAmount()) ?> </td> </tr> diff --git a/app/code/Magento/Sales/view/frontend/templates/order/history.phtml b/app/code/Magento/Sales/view/frontend/templates/order/history.phtml index 6acad7a99cd668c3401843b6268fd0723705cd54..ef58807040549d84921dc066549c89096f7e4df0 100644 --- a/app/code/Magento/Sales/view/frontend/templates/order/history.phtml +++ b/app/code/Magento/Sales/view/frontend/templates/order/history.phtml @@ -25,29 +25,31 @@ <?php $_orders = $this->getOrders(); ?> <?php echo $this->getChildHtml('info');?> <?php if($_orders->getSize()): ?> - <div class="order products toolbar"><?php echo $this->getPagerHtml(); ?></div> - <div class="wrapper table orders history"> - <table class="data table orders history" id="my-orders-table"> + <?php if ($this->getPagerHtml()): ?> + <div class="order-products-toolbar toolbar top"><?php echo $this->getPagerHtml(); ?></div> + <?php endif ?> + <div class="table-wrapper orders-history"> + <table class="data table table-order-items history" id="my-orders-table"> <caption class="table caption"><?php echo __('Orders') ?></caption> <thead> <tr> - <th class="col id"><?php echo __('Order #') ?></th> - <th class="col date"><?php echo __('Date') ?></th> - <th class="col shipping"><?php echo __('Ship To') ?></th> - <th class="col total"><?php echo __('Order Total') ?></th> - <th class="col status"><?php echo __('Status') ?></th> - <th class="col actions"> </th> + <th scope="col" class="col id"><?php echo __('Order #') ?></th> + <th scope="col" class="col date"><?php echo __('Date') ?></th> + <th scope="col" class="col shipping"><?php echo __('Ship To') ?></th> + <th scope="col" class="col total"><?php echo __('Order Total') ?></th> + <th scope="col" class="col status"><?php echo __('Status') ?></th> + <th scope="col" class="col actions"> </th> </tr> </thead> <tbody> <?php foreach ($_orders as $_order): ?> <tr> - <td class="col id"><?php echo $_order->getRealOrderId() ?></td> - <td class="col date"><?php echo $this->formatDate($_order->getCreatedAtStoreDate()) ?></td> - <td class="col shipping"><?php echo $_order->getShippingAddress() ? $this->escapeHtml($_order->getShippingAddress()->getName()) : ' ' ?></td> - <td class="col total"><?php echo $_order->formatPrice($_order->getGrandTotal()) ?></td> - <td class="col status"><em><?php echo $_order->getStatusLabel() ?></em></td> - <td class="col actions"> + <td data-th="<?php echo $this->escapeHtml(__('Order #')) ?>" class="col id"><?php echo $_order->getRealOrderId() ?></td> + <td data-th="<?php echo $this->escapeHtml(__('Date')) ?>" class="col date"><?php echo $this->formatDate($_order->getCreatedAtStoreDate()) ?></td> + <td data-th="<?php echo $this->escapeHtml(__('Ship To')) ?>" class="col shipping"><?php echo $_order->getShippingAddress() ? $this->escapeHtml($_order->getShippingAddress()->getName()) : ' ' ?></td> + <td data-th="<?php echo $this->escapeHtml(__('Order Total')) ?>" class="col total"><?php echo $_order->formatPrice($_order->getGrandTotal()) ?></td> + <td data-th="<?php echo $this->escapeHtml(__('Status')) ?>" class="col status"><?php echo $_order->getStatusLabel() ?></td> + <td data-th="" class="col actions"> <a href="<?php echo $this->getViewUrl($_order) ?>" class="action view"> <span><?php echo __('View Order') ?></span> </a> @@ -62,7 +64,9 @@ </tbody> </table> </div> - <div class="order products toolbar bottom"><?php echo $this->getPagerHtml(); ?></div> + <?php if ($this->getPagerHtml()): ?> + <div class="order-products-toolbar toolbar bottom"><?php echo $this->getPagerHtml(); ?></div> + <?php endif ?> <?php else: ?> <div class="message info empty"><span><?php echo __('You have placed no orders.'); ?></span></div> <?php endif ?> diff --git a/app/code/Magento/Sales/view/frontend/templates/order/info.phtml b/app/code/Magento/Sales/view/frontend/templates/order/info.phtml index e21fa9f70938e05b252aaed612d9e1becf176d58..cc5ebaf8ef6f04559c16655822076d2bca7b9a9f 100644 --- a/app/code/Magento/Sales/view/frontend/templates/order/info.phtml +++ b/app/code/Magento/Sales/view/frontend/templates/order/info.phtml @@ -24,50 +24,48 @@ ?> <?php /** @var $this \Magento\Sales\Block\Order\Info */ ?> <?php $_order = $this->getOrder() ?> -<div class="order details view"> - <strong class="order status"><?php echo $_order->getStatusLabel() ?></strong> - <div class="order toolbar"> - <?php echo $this->getChildHtml('buttons') ?> - <?php echo $this->getStatusHistoryRssUrl($_order) ?> +<div class="block block-order-details-view"> + <div class="block-title"> + <strong><?php echo __('Order Information') ?></strong> </div> - - <div class="order info links"><?php echo $this->getChildHtml('links') ?></div> - - <p class="order date"><?php echo __('<span class="label">Order Date:</span> %1', '<date>' . $this->formatDate($_order->getCreatedAtStoreDate(), 'long') . '</date>' ) ?></p> -<?php if (!$_order->getIsVirtual()): ?> - <div class="block order shipping address"> - <div class="title"><strong><?php echo __('Shipping Address') ?></strong></div> - <div class="content"> - <address><?php echo $_order->getShippingAddress()->format('html') ?></address> + <div class="block-content"> + <?php if (!$_order->getIsVirtual()): ?> + <div class="box box-order-shipping-address"> + <strong class="box-title"><span><?php echo __('Shipping Address') ?></span></strong> + <div class="box-content"> + <address><?php echo $_order->getShippingAddress()->format('html') ?></address> + </div> </div> - </div> - <div class="block order shipping method"> - <div class="title"><strong><?php echo __('Shipping Method') ?></strong></div> - <div class="content"> - <?php if ($_order->getShippingDescription()): ?> - <?php echo $this->escapeHtml($_order->getShippingDescription()) ?> - <?php else: ?> - <?php echo __('No shipping information available'); ?> - <?php endif; ?> + <div class="box box-order-shipping-method"> + <strong class="box-title"> + <span><?php echo __('Shipping Method') ?></span> + </strong> + <div class="box-content"> + <?php if ($_order->getShippingDescription()): ?> + <?php echo $this->escapeHtml($_order->getShippingDescription()) ?> + <?php else: ?> + <?php echo __('No shipping information available'); ?> + <?php endif; ?> + </div> </div> - </div> + <?php endif; ?> -<?php endif; ?> - <div class="block order billing address"> - <div class="title"> - <strong><?php echo __('Billing Address') ?></strong> - </div> - <div class="content"> - <address><?php echo $_order->getBillingAddress()->format('html') ?></address> - </div> - </div> - <div class="block order billing method"> - <div class="title"> - <strong><?php echo __('Payment Method') ?></strong> + <div class="box box-order-billing-address"> + <strong class="box-title"> + <span><?php echo __('Billing Address') ?></span> + </strong> + <div class="box-content"> + <address><?php echo $_order->getBillingAddress()->format('html') ?></address> + </div> </div> - <div class="content"> - <?php echo $this->getPaymentInfoHtml() ?> + <div class="box box-order-billing-method"> + <strong class="box-title"> + <span><?php echo __('Payment Method') ?></span> + </strong> + <div class="box-content"> + <?php echo $this->getPaymentInfoHtml() ?> + </div> </div> </div> </div> \ No newline at end of file diff --git a/app/code/Magento/Sales/view/frontend/templates/order/invoice.phtml b/app/code/Magento/Sales/view/frontend/templates/order/invoice.phtml index 1d4039efdff3904817b4a3962b80f321d44a60c0..9a0cefcc544256b31784e0709d6451a1324e39e3 100644 --- a/app/code/Magento/Sales/view/frontend/templates/order/invoice.phtml +++ b/app/code/Magento/Sales/view/frontend/templates/order/invoice.phtml @@ -22,7 +22,7 @@ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) */ ?> -<div class="order details items invoice"> +<div class="order-details-items invoice"> <?php echo $this->getChildHtml('invoice_items') ?> <div class="actions-toolbar"> <div class="secondary"> diff --git a/app/code/Magento/Sales/view/frontend/templates/order/invoice/items.phtml b/app/code/Magento/Sales/view/frontend/templates/order/invoice/items.phtml index e688936000b92620d01916537b51e9e06b02d73b..fa70c0b03dc433c1353897af149a41f2718ac614 100644 --- a/app/code/Magento/Sales/view/frontend/templates/order/invoice/items.phtml +++ b/app/code/Magento/Sales/view/frontend/templates/order/invoice/items.phtml @@ -23,17 +23,15 @@ */ ?> <?php $_order = $this->getOrder() ?> -<div class="order toolbar"> - <div class="actions"> - <a href="<?php echo $this->getPrintAllInvoicesUrl($_order) ?>" - target="_blank" - class="action print"> - <span><?php echo __('Print All Invoices') ?></span> - </a> - </div> +<div class="actions-toolbar"> + <a href="<?php echo $this->getPrintAllInvoicesUrl($_order) ?>" + target="_blank" + class="action print"> + <span><?php echo __('Print All Invoices') ?></span> + </a> </div> <?php foreach ($_order->getInvoiceCollection() as $_invoice): ?> -<div class="order title"> +<div class="order-title"> <strong><?php echo __('Invoice #') ?><?php echo $_invoice->getIncrementId(); ?></strong> <a href="<?php echo $this->getPrintInvoiceUrl($_invoice) ?>" onclick="this.target='_blank'" @@ -41,9 +39,8 @@ <span><?php echo __('Print Invoice') ?></span> </a> </div> -<div class="order subtitle caption"><strong><?php echo __('Items Invoiced') ?></strong></div> -<div class="wrapper table order items invoice"> - <table class="data table order items invoice" id="my-invoice-table-<?php echo $_invoice->getId(); ?>"> +<div class="table-wrapper table-order-items invoice"> + <table class="data table table-order-items invoice" id="my-invoice-table-<?php echo $_invoice->getId(); ?>"> <caption class="table caption"><?php echo __('Items Invoiced') ?></caption> <thead> <tr> diff --git a/app/code/Magento/Sales/view/frontend/templates/order/invoice/items/renderer/default.phtml b/app/code/Magento/Sales/view/frontend/templates/order/invoice/items/renderer/default.phtml index 1f3f3da9bf3b8564b5c97defde0082efa774d3bf..d303068af260e321312b19ae0bf27819b66b04f5 100644 --- a/app/code/Magento/Sales/view/frontend/templates/order/invoice/items/renderer/default.phtml +++ b/app/code/Magento/Sales/view/frontend/templates/order/invoice/items/renderer/default.phtml @@ -25,8 +25,8 @@ <?php $_item = $this->getItem() ?> <?php $_order = $this->getItem()->getOrderItem()->getOrder() ?> <tr id="order-item-row-<?php echo $_item->getId() ?>"> - <td class="col name"> - <strong class="product name"><?php echo $this->escapeHtml($_item->getName()) ?></strong> + <td class="col name" data-th="<?php echo $this->escapeHtml(__('Product Name')); ?>"> + <strong class="product name product-item-name"><?php echo $this->escapeHtml($_item->getName()) ?></strong> <?php if($_options = $this->getItemOptions()): ?> <dl class="item options"> <?php foreach ($_options as $_option) : ?> @@ -64,236 +64,177 @@ </a> <?php endif; ?> </td> - <td class="col sku"><?php echo $this->prepareSku($this->getSku()) ?></td> - <td class="col price"> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceExclTax()): ?> - <span class="price-excl-tax"> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices()): ?> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart-price"> - <?php endif; ?> - <span class="label"><?php echo __('Excl. Tax'); ?>:</span> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - </span> - <?php endif; ?> - <?php endif; ?> + <td class="col sku" data-th="<?php echo $this->escapeHtml(__('SKU')); ?>"><?php echo $this->prepareSku($this->getSku()) ?></td> + <td class="col price" data-th="<?php echo $this->escapeHtml(__('Price')); ?>"> + <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceInclTax()): ?> + <span class="incl tax" data-th="<?php echo $this->escapeHtml(__('Incl. Tax')); ?>"> + <?php $_incl = $this->helper('Magento\Checkout\Helper\Data')->getPriceInclTax($this->getItem()); ?> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}' + <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#unit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> <?php else: ?> <span class="cart-price"> <?php endif; ?> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()+$this->getItem()->getWeeeTaxAppliedAmount()+$this->getItem()->getWeeeTaxDisposition()); ?> - <?php else: ?> - <?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()) ?> - <?php endif; ?> - - </span> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedAmount()); ?> + <?php else: ?> + <?php echo $this->getOrder()->formatPrice($_incl-$this->getItem()->getWeeeTaxDisposition()) ?> + <?php endif; ?> + </span> <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> - - <span class="cart-tax-info" id="eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display:none;"> + <span class="cart-tax-info" id="unit-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display: none;"> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <span class="nobr"><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount']); ?></span> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount']); ?></span> <?php endforeach; ?> - </small> <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <span class="nobr"><small><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></small></span> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></span> <?php endforeach; ?> <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <span class="nobr"><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></span> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></span> <?php endforeach; ?> - </small> <?php endif; ?> </span> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}' - <span class="nobr"><?php echo __('Total'); ?>:<br /> <?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()+$this->getItem()->getWeeeTaxAppliedAmount()+$this->getItem()->getWeeeTaxDisposition()); ?></span> + <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#unit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}' + <span class="weee" data-th="<?php echo $this->escapeHtml(__('Total incl. tax')); ?>"><?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedAmount()); ?></span> </span> <?php endif; ?> <?php endif; ?> </span> - <br /> <?php endif; ?> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceInclTax()): ?> - <span class="price-incl-tax"> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices()): ?> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart-price"> - <?php endif; ?> - <span class="label"><?php echo __('Incl. Tax'); ?>:</span> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - </span> - <?php endif; ?> - <?php endif; ?> - <?php $_incl = $this->helper('Magento\Checkout\Helper\Data')->getPriceInclTax($this->getItem()); ?> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#unit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}' - <?php else: ?> - <span class="cart-price"> - <?php endif; ?> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedAmount()); ?> - <?php else: ?> - <?php echo $this->getOrder()->formatPrice($_incl-$this->getItem()->getWeeeTaxDisposition()) ?> - <?php endif; ?> + <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceExclTax()): ?> + <span class="excl tax" data-th="<?php echo $this->escapeHtml(__('Excl. Tax')); ?>"> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <?php else: ?> + <span class="cart-price"> + <?php endif; ?> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()+$this->getItem()->getWeeeTaxAppliedAmount()+$this->getItem()->getWeeeTaxDisposition()); ?> + <?php else: ?> + <?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()) ?> + <?php endif; ?> </span> - <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> + <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> + <span class="cart-tax-info" id="eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display: none;"> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount']); ?></span> + <?php endforeach; ?> + <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></span> + <?php endforeach; ?> + <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></span> + <?php endforeach; ?> + <?php endif; ?> + </span> - <span class="cart-tax-info" id="unit-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display:none;"> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <span class="nobr"><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount']); ?></span> - <?php endforeach; ?> - </small> - <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <span class="nobr"><small><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></small></span> - <?php endforeach; ?> - <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <span class="nobr"><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></span> - <?php endforeach; ?> - </small> - <?php endif; ?> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}' + <span class="weee" data-th="<?php echo $this->escapeHtml(__('Total')); ?>"><?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()+$this->getItem()->getWeeeTaxAppliedAmount()+$this->getItem()->getWeeeTaxDisposition()); ?></span> </span> - - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#unit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}' - <span class="nobr"><?php echo __('Total incl. tax'); ?>:<br /> <?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedAmount()); ?></span> - </span> - <?php endif; ?> <?php endif; ?> + <?php endif; ?> </span> <?php endif; ?> </td> - <td class="col qty"> + <td class="col qty" data-th="<?php echo $this->escapeHtml(__('Qty Invoiced')); ?>"> <span class="qty summary"><?php echo $_item->getQty()*1 ?></span> </td> - <td class="col subtotal"> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceExclTax()): ?> - <span class="price-excl-tax"> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices()): ?> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart-price"> - <?php endif; ?> - <span class="label"><?php echo __('Excl. Tax'); ?>:</span> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - </span> - <?php endif; ?> - <?php endif; ?> + <td class="col subtotal" data-th="<?php echo $this->escapeHtml(__('Subtotal')); ?>"> + <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceInclTax()): ?> + <span class="incl tax" data-th="<?php echo $this->escapeHtml(__('Incl. Tax')); ?>"> + <?php $_incl = $this->helper('Magento\Checkout\Helper\Data')->getSubtotalInclTax($this->getItem()); ?> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#subtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> <?php else: ?> <span class="cart-price"> <?php endif; ?> - - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()+$this->getItem()->getWeeeTaxAppliedRowAmount()+$this->getItem()->getWeeeTaxRowDisposition()); ?> - <?php else: ?> - <?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()) ?> - <?php endif; ?> - - </span> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedRowAmount()); ?> + <?php else: ?> + <?php echo $this->getOrder()->formatPrice($_incl-$this->getItem()->getWeeeTaxRowDisposition()) ?> + <?php endif; ?> + </span> <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> - - <span class="cart-tax-info" id="esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display:none;"> + <span class="cart-tax-info" id="subtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display: none;"> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <span class="nobr"><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount']); ?></span> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount']); ?></span> <?php endforeach; ?> - </small> <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <span class="nobr"><small><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></small></span> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></span> <?php endforeach; ?> <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> <small> <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <span class="nobr"><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></span> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></span> <?php endforeach; ?> </small> <?php endif; ?> </span> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> - <span class="nobr"><?php echo __('Total'); ?>:<br /> <?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()+$this->getItem()->getWeeeTaxAppliedRowAmount()+$this->getItem()->getWeeeTaxRowDisposition()); ?></span> + <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#subtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <span class="weee" data-th="<?php echo $this->escapeHtml(__('Total incl. tax')); ?>"><?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedRowAmount()); ?></span> </span> <?php endif; ?> <?php endif; ?> </span> - <br /> <?php endif; ?> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceInclTax()): ?> - <span class="price-incl-tax"> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices()): ?> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart-price"> - <?php endif; ?> - <span class="label"><?php echo __('Incl. Tax'); ?>:</span> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - </span> - <?php endif; ?> - <?php endif; ?> - <?php $_incl = $this->helper('Magento\Checkout\Helper\Data')->getSubtotalInclTax($this->getItem()); ?> + + <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceExclTax()): ?> + <span class="excl tax" data-th="<?php echo $this->escapeHtml(__('Excl. Tax')); ?>"> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#subtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> <?php else: ?> <span class="cart-price"> <?php endif; ?> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedRowAmount()); ?> - <?php else: ?> - <?php echo $this->getOrder()->formatPrice($_incl-$this->getItem()->getWeeeTaxRowDisposition()) ?> - <?php endif; ?> - </span> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()+$this->getItem()->getWeeeTaxAppliedRowAmount()+$this->getItem()->getWeeeTaxRowDisposition()); ?> + <?php else: ?> + <?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()) ?> + <?php endif; ?> + </span> <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> - - <span class="cart-tax-info" id="subtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display:none;"> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <span class="nobr"><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount']); ?></span> - <?php endforeach; ?> - </small> - <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <span class="nobr"><small><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></small></span> - <?php endforeach; ?> - <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <span class="nobr"><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></span> - <?php endforeach; ?> - </small> - <?php endif; ?> + <span class="cart-tax-info" id="esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display: none;"> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount']); ?></span> + <?php endforeach; ?> + <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></span> + <?php endforeach; ?> + <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></span> + <?php endforeach; ?> + <?php endif; ?> </span> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#subtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> - <span class="nobr"><?php echo __('Total incl. tax'); ?>:<br /> <?php echo $this->getOrder()->formatPrice($_incl+$this->getItem()->getWeeeTaxAppliedRowAmount()); ?></span> + <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <span class="weee" data-th="<?php echo $this->escapeHtml(__('Total')); ?>"><<?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()+$this->getItem()->getWeeeTaxAppliedRowAmount()+$this->getItem()->getWeeeTaxRowDisposition()); ?></span> </span> <?php endif; ?> <?php endif; ?> - </span> - <?php endif; ?> + <?php endif; ?> </td> </tr> diff --git a/app/code/Magento/Sales/view/frontend/templates/order/items.phtml b/app/code/Magento/Sales/view/frontend/templates/order/items.phtml index e71956e9ec85d8b02189c8f1b1974cac0a76e88f..8bab5f6305a1c0fefc14c4044a331dca1e188374 100644 --- a/app/code/Magento/Sales/view/frontend/templates/order/items.phtml +++ b/app/code/Magento/Sales/view/frontend/templates/order/items.phtml @@ -24,8 +24,8 @@ ?> <?php $_order = $this->getOrder() ?> <?php $_giftMessage; ?> -<div class="wrapper table order items"> - <table class="data table order items" id="my-orders-table" summary="<?php echo __('Items Ordered') ?>"> +<div class="table-wrapper order-items"> + <table class="data table table-order-items" id="my-orders-table" summary="<?php echo __('Items Ordered') ?>"> <caption class="table caption"><?php echo __('Items Ordered') ?></caption> <thead> <tr> @@ -48,7 +48,7 @@ <tbody> <?php echo $this->getItemHtml($_item) ?> <?php if ($this->helper('Magento\GiftMessage\Helper\Message')->getIsMessagesAvailable('order_item', $_item) && $_item->getGiftMessageId()): ?> - <tr id="order-item-gift-message-<?php echo $_item->getId() ?>" role="region" aria-expanded="false" tabindex="-1" style="display:none;"> + <tr id="order-item-gift-message-<?php echo $_item->getId() ?>" role="region" aria-expanded="false" tabindex="-1" style="display: none;"> <?php $_giftMessage = $this->helper('Magento\GiftMessage\Helper\Message')->getGiftMessageForEntity($_item); ?> <td class="col message" colspan="7"> <div class="gift message details"> diff --git a/app/code/Magento/Sales/view/frontend/templates/order/items/renderer/default.phtml b/app/code/Magento/Sales/view/frontend/templates/order/items/renderer/default.phtml index 08cf3d7ad5645b0ab2de671ee722ccc673b8f03a..f4e97fb4766c862eea365e7112d00ce8ee2935be 100644 --- a/app/code/Magento/Sales/view/frontend/templates/order/items/renderer/default.phtml +++ b/app/code/Magento/Sales/view/frontend/templates/order/items/renderer/default.phtml @@ -27,8 +27,8 @@ $_item = $this->getItem(); $_weeeHelper = $this->helper('Magento\Weee\Helper\Data'); ?> <tr id="order-item-row-<?php echo $_item->getId() ?>"> - <td class="col name"> - <strong class="product name"><?php echo $this->escapeHtml($_item->getName()) ?></strong> + <td class="col name" data-th="<?php echo $this->escapeHtml(__('Product Name')); ?>"> + <strong class="product name product-item-name"><?php echo $this->escapeHtml($_item->getName()) ?></strong> <?php if($_options = $this->getItemOptions()): ?> <dl class="item options"> <?php foreach ($_options as $_option) : ?> @@ -69,240 +69,196 @@ $_weeeHelper = $this->helper('Magento\Weee\Helper\Data'); </a> <?php endif; ?> </td> - <td class="col sku"><?php echo $this->prepareSku($this->getSku()) ?></td> - <td class="col price"> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceExclTax()): ?> - <span class="price-excl-tax"> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices()): ?> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart-price"> - <?php endif; ?> - <span class="label"><?php echo __('Excl. Tax'); ?>:</span> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - </span> - <?php endif; ?> - <?php endif; ?> + <td class="col sku" data-th="<?php echo $this->escapeHtml(__('SKU')); ?>"><?php echo $this->prepareSku($this->getSku()) ?></td> + <td class="col price" data-th="<?php echo $this->escapeHtml(__('Price')); ?>"> + <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceInclTax()): ?> + <span class="incl tax" data-th="<?php echo $this->escapeHtml(__('Incl. Tax')); ?>"> + <?php $_incl = $this->helper('Magento\Checkout\Helper\Data')->getPriceInclTax($this->getItem()); ?> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}' + <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#unit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> <?php else: ?> <span class="cart-price"> <?php endif; ?> - - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()+$this->getItem()->getWeeeTaxAppliedAmount()+$this->getItem()->getWeeeTaxDisposition()); ?> - <?php else: ?> - <?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()) ?> - <?php endif; ?> - </span> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php echo $this->getOrder()->formatPrice($_incl+$_weeeHelper->getWeeeTaxInclTax($this->getItem())); ?> + <?php else: ?> + <?php echo $this->getOrder()->formatPrice($_incl-$this->getItem()->getWeeeTaxDisposition()) ?> + <?php endif; ?> + </span> <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> - - <span class="cart-tax-info" id="eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display:none;"> + <span class="cart-tax-info" id="unit-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display: none;"> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <span class="nobr"><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount']); ?></span> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></span> <?php endforeach; ?> - </small> <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <span class="nobr"><small><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount']); ?></small></span> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></span> <?php endforeach; ?> <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <span class="nobr"><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount']); ?></span> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></span> <?php endforeach; ?> - </small> <?php endif; ?> </span> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}' - <span class="nobr"><?php echo __('Total'); ?>:<br /> <?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()+$this->getItem()->getWeeeTaxAppliedAmount()+$this->getItem()->getWeeeTaxDisposition()); ?></span> + <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#unit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}' + <span class="weee" data-th="<?php echo $this->escapeHtml(__('Total incl. tax')); ?>"><?php echo $this->getOrder()->formatPrice($_incl+$_weeeHelper->getWeeeTaxInclTax($this->getItem())); ?></span> </span> <?php endif; ?> <?php endif; ?> </span> <?php endif; ?> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceInclTax()): ?> - <span class="price-incl-tax"> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices()): ?> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart-price"> - <?php endif; ?> - <span class="label"><?php echo __('Incl. Tax'); ?>:</span> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - </span> - <?php endif; ?> - <?php endif; ?> - <?php $_incl = $this->helper('Magento\Checkout\Helper\Data')->getPriceInclTax($this->getItem()); ?> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#unit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}' - <?php else: ?> - <span class="cart-price"> - <?php endif; ?> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <?php echo $this->getOrder()->formatPrice($_incl+$_weeeHelper->getWeeeTaxInclTax($this->getItem())); ?> - <?php else: ?> - <?php echo $this->getOrder()->formatPrice($_incl-$this->getItem()->getWeeeTaxDisposition()) ?> - <?php endif; ?> - </span> - <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> + <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceExclTax()): ?> + <span class="excl tax" data-th="<?php echo $this->escapeHtml(__('Excl. Tax')); ?>"> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <?php else: ?> + <span class="cart-price"> + <?php endif; ?> - <span class="cart-tax-info" id="unit-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display:none;"> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <span class="nobr"><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></span> - <?php endforeach; ?> - </small> - <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <span class="nobr"><small><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></small></span> - <?php endforeach; ?> - <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <span class="nobr"><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['amount_incl_tax']); ?></span> - <?php endforeach; ?> - </small> - <?php endif; ?> - </span> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()+$this->getItem()->getWeeeTaxAppliedAmount()+$this->getItem()->getWeeeTaxDisposition()); ?> + <?php else: ?> + <?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()) ?> + <?php endif; ?> + </span> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#unit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}' - <span class="nobr"><?php echo __('Total incl. tax'); ?>:<br /> <?php echo $this->getOrder()->formatPrice($_incl+$_weeeHelper->getWeeeTaxInclTax($this->getItem())); ?></span> - </span> - <?php endif; ?> - <?php endif; ?> - </span> + <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> + <span class="cart-tax-info" id="eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display: none;"> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount']); ?></span> + <?php endforeach; ?> + <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount']); ?></span> + <?php endforeach; ?> + <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['amount']); ?></span> + <?php endforeach; ?> + <?php endif; ?> + </span> + + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $this->getItem()->getId(); ?>"}' + <span class="weee" data-th="<?php echo $this->escapeHtml(__('Total')); ?>"><?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()+$this->getItem()->getWeeeTaxAppliedAmount()+$this->getItem()->getWeeeTaxDisposition()); ?></span> + </span> + <?php endif; ?> + <?php endif; ?> + </span> <?php endif; ?> </td> - <td class="col qty"> - <ul class="qty summary items"> + <td class="col qty" data-th="<?php echo $this->escapeHtml(__('Qty')); ?>"> + <ul class="items-qty"> <?php if ($this->getItem()->getQtyOrdered() > 0): ?> - <li class="item"><span class="label"><?php echo __('Ordered'); ?></span><strong><?php echo $this->getItem()->getQtyOrdered()*1 ?></strong></li> + <li class="item"> + <span class="title"><?php echo __('Ordered'); ?></span> + <span class="content"><?php echo $this->getItem()->getQtyOrdered()*1 ?></span> + </li> <?php endif; ?> <?php if ($this->getItem()->getQtyShipped() > 0): ?> - <li class="item"><span class="label"><?php echo __('Shipped'); ?></span><strong><?php echo $this->getItem()->getQtyShipped()*1 ?></strong></li> + <li class="item"> + <span class="title"><?php echo __('Shipped'); ?></span> + <span class="content"><?php echo $this->getItem()->getQtyShipped()*1 ?></span> + </li> <?php endif; ?> <?php if ($this->getItem()->getQtyCanceled() > 0): ?> - <li class="item"><span class="label"><?php echo __('Canceled'); ?></span><strong><?php echo $this->getItem()->getQtyCanceled()*1 ?></strong></li> + <li class="item"> + <span class="title"><?php echo __('Canceled'); ?></span> + <span class="content"><?php echo $this->getItem()->getQtyCanceled()*1 ?></span> + </li> <?php endif; ?> <?php if ($this->getItem()->getQtyRefunded() > 0): ?> - <li class="item"><span class="label"><?php echo __('Refunded'); ?></span><strong><?php echo $this->getItem()->getQtyRefunded()*1 ?></strong></li> + <li class="item"> + <span class="title"><?php echo __('Refunded'); ?></span> + <span class="content"><?php echo $this->getItem()->getQtyRefunded()*1 ?></span> + </li> <?php endif; ?> </ul> </td> - <td class="col subtotal"> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceExclTax()): ?> - <span class="price-excl-tax"> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices()): ?> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart-price"> - <?php endif; ?> - <span class="label"><?php echo __('Excl. Tax'); ?>:</span> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - </span> - <?php endif; ?> - <?php endif; ?> + <td class="col subtotal" data-th="<?php echo $this->escapeHtml(__('Subtotal')); ?>"> + <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceInclTax()): ?> + <span class="incl tax" data-th="<?php echo $this->escapeHtml(__('Incl. Tax')); ?>"> + <?php $_incl = $this->helper('Magento\Checkout\Helper\Data')->getSubtotalInclTax($this->getItem()); ?> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#subtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> <?php else: ?> <span class="cart-price"> <?php endif; ?> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()+$this->getItem()->getWeeeTaxAppliedRowAmount()+$this->getItem()->getWeeeTaxRowDisposition()); ?> + <?php echo $this->getOrder()->formatPrice($_incl+$_weeeHelper->getRowWeeeTaxInclTax($this->getItem())); ?> <?php else: ?> - <?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()) ?> + <?php echo $this->getOrder()->formatPrice($_incl-$this->getItem()->getWeeeTaxRowDisposition()) ?> <?php endif; ?> - </span> - + </span> <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> - - <span class="cart-tax-info" id="esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display:none;"> + <span class="cart-tax-info" id="subtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display: none;"> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <span class="nobr"><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount']); ?></span> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></span> <?php endforeach; ?> - </small> <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <span class="nobr"><small><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount']); ?></small></span> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></span> <?php endforeach; ?> <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <span class="nobr"><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount']); ?></span> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></span> <?php endforeach; ?> - </small> <?php endif; ?> </span> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> - <span class="nobr"><?php echo __('Total'); ?>:<br /> <?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()+$this->getItem()->getWeeeTaxAppliedRowAmount()+$this->getItem()->getWeeeTaxRowDisposition()); ?></span> + <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#subtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <span class="weee" data-th="<?php echo $this->escapeHtml(__('Total incl. tax')); ?>"><?php echo $this->getOrder()->formatPrice($_incl+$_weeeHelper->getRowWeeeTaxInclTax($this->getItem())); ?></span> </span> <?php endif; ?> <?php endif; ?> </span> - <br /> <?php endif; ?> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceInclTax()): ?> - <span class="price-incl-tax"> - <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices()): ?> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart-price"> - <?php endif; ?> - <span class="label"><?php echo __('Incl. Tax'); ?>:</span> - <?php if (!$this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - </span> - <?php endif; ?> - <?php endif; ?> - <?php $_incl = $this->helper('Magento\Checkout\Helper\Data')->getSubtotalInclTax($this->getItem()); ?> + + <?php if ($this->helper('Magento\Tax\Helper\Data')->displaySalesBothPrices() || $this->helper('Magento\Tax\Helper\Data')->displaySalesPriceExclTax()): ?> + <span class="excl tax" data-th="<?php echo $this->escapeHtml(__('Excl. Tax')); ?>"> <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#subtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <?php else: ?> + <span class="cart-price"> + <?php endif; ?> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()+$this->getItem()->getWeeeTaxAppliedRowAmount()+$this->getItem()->getWeeeTaxRowDisposition()); ?> <?php else: ?> - <span class="cart-price"> + <?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()) ?> <?php endif; ?> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(0, 1, 4), 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <?php echo $this->getOrder()->formatPrice($_incl+$_weeeHelper->getRowWeeeTaxInclTax($this->getItem())); ?> - <?php else: ?> - <?php echo $this->getOrder()->formatPrice($_incl-$this->getItem()->getWeeeTaxRowDisposition()) ?> - <?php endif; ?> </span> - <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> + <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem())): ?> + <span class="cart-tax-info" id="esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display: none;"> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount']); ?></span> + <?php endforeach; ?> + <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount']); ?></span> + <?php endforeach; ?> + <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> + <span class="weee" data-th="<?php echo $tax['title']; ?>"><?php echo $this->getOrder()->formatPrice($tax['row_amount']); ?></span> + <?php endforeach; ?> + <?php endif; ?> + </span> - <span class="cart-tax-info" id="subtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>" style="display:none;"> - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(1, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <span class="nobr"><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></span> - <?php endforeach; ?> - </small> - <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <span class="nobr"><small><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></small></span> - <?php endforeach; ?> - <?php elseif ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(4, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <small> - <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($this->getItem()) as $tax): ?> - <span class="nobr"><?php echo $tax['title']; ?>: <?php echo $this->getOrder()->formatPrice($tax['row_amount_incl_tax']); ?></span> - <?php endforeach; ?> - </small> - <?php endif; ?> + <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> + <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> + <span class="weee" data-th="<?php echo $this->escapeHtml(__('Total')); ?>"><?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()+$this->getItem()->getWeeeTaxAppliedRowAmount()+$this->getItem()->getWeeeTaxRowDisposition()); ?></span> </span> - - <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(2, 'sales') && (float)$this->getItem()->getWeeeTaxAppliedAmount()): ?> - <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#subtotal-item-tax-details<?php echo $this->getItem()->getId(); ?>"}'> - <span class="nobr"><?php echo __('Total incl. tax'); ?>:<br /> <?php echo $this->getOrder()->formatPrice($_incl+$_weeeHelper->getRowWeeeTaxInclTax($this->getItem())); ?></span> - </span> - <?php endif; ?> <?php endif; ?> + <?php endif; ?> </span> <?php endif; ?> </td> diff --git a/app/code/Magento/Sales/view/frontend/templates/order/order_comments.phtml b/app/code/Magento/Sales/view/frontend/templates/order/order_comments.phtml new file mode 100644 index 0000000000000000000000000000000000000000..d09f03d81bba6df6655a09fc6094f6d72aa75c43 --- /dev/null +++ b/app/code/Magento/Sales/view/frontend/templates/order/order_comments.phtml @@ -0,0 +1,41 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +?> +<?php /** @var $this \Magento\Sales\Block\Order\View*/?> + +<?php $_history = $this->getOrder()->getVisibleStatusHistory() ?> +<?php if (count($_history)): ?> + <div class="block block-order-details-comments"> + <div class="block-title"><strong><?php echo __('About Your Order') ?></strong></div> + <div class="block-content"> + <dl class="order-comments"> + <?php foreach ($_history as $_historyItem): ?> + <dt class="comment-date"><?php echo $this->formatDate($_historyItem->getCreatedAtStoreDate(), 'medium', true) ?></dt> + <dd class="comment-content"><?php echo $this->escapeHtml($_historyItem->getComment()) ?></dd> + <?php endforeach; ?> + </dl> + + </div> + </div> +<?php endif; ?> diff --git a/app/code/Magento/Sales/view/frontend/templates/order/order_date.phtml b/app/code/Magento/Sales/view/frontend/templates/order/order_date.phtml new file mode 100644 index 0000000000000000000000000000000000000000..02e9b2f83a195e6f0efac1119c3afd113308d646 --- /dev/null +++ b/app/code/Magento/Sales/view/frontend/templates/order/order_date.phtml @@ -0,0 +1,26 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +?> + +<div class="order-date"><?php echo __('<span class="label">Order Date:</span> %1', '<date>' . $this->formatDate($this->getOrder()->getCreatedAtStoreDate(), 'long') . '</date>' ) ?></div> diff --git a/app/code/Magento/Sales/view/frontend/templates/order/order_rss.phtml b/app/code/Magento/Sales/view/frontend/templates/order/order_rss.phtml new file mode 100644 index 0000000000000000000000000000000000000000..705fb178493c633f6e216cb5255cd89965e2641e --- /dev/null +++ b/app/code/Magento/Sales/view/frontend/templates/order/order_rss.phtml @@ -0,0 +1,26 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +?> +<?php /** @var $this \Magento\Sales\Block\Order\Info */ ?> +<?php echo $this->getStatusHistoryRssUrl($this->getOrder()) ?> diff --git a/app/code/Magento/Sales/view/frontend/templates/order/order_status.phtml b/app/code/Magento/Sales/view/frontend/templates/order/order_status.phtml new file mode 100644 index 0000000000000000000000000000000000000000..585071c2fa6a6816b55d23b4fdae178603a4e1cb --- /dev/null +++ b/app/code/Magento/Sales/view/frontend/templates/order/order_status.phtml @@ -0,0 +1,27 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +?> +<?php /** @var $this \Magento\Sales\Block\Order\Info */ ?> + +<span class="order-status"><?php echo $this->getOrder()->getStatusLabel() ?></span> diff --git a/app/code/Magento/Sales/view/frontend/templates/order/print.phtml b/app/code/Magento/Sales/view/frontend/templates/order/print.phtml index 0f6e73322d5981254eebfa9732a4aeb63721edb4..00da52142659f06e46d7bce24b269b6586ec2a67 100644 --- a/app/code/Magento/Sales/view/frontend/templates/order/print.phtml +++ b/app/code/Magento/Sales/view/frontend/templates/order/print.phtml @@ -65,8 +65,8 @@ </div> </div> -<div class="order details items"> - <div class="order subtitle caption"> +<div class="order-details-items"> + <div class="order-title"> <strong><?php echo __('Items Ordered') ?></strong> </div> <table class="data table order items" id="my-orders-table"> diff --git a/app/code/Magento/Sales/view/frontend/templates/order/print/creditmemo.phtml b/app/code/Magento/Sales/view/frontend/templates/order/print/creditmemo.phtml index dd81437c0a2b26942d214229d451cb8f125f1a70..5dc5c30828f6228d62e3253b0a8fe8863313c498 100644 --- a/app/code/Magento/Sales/view/frontend/templates/order/print/creditmemo.phtml +++ b/app/code/Magento/Sales/view/frontend/templates/order/print/creditmemo.phtml @@ -71,7 +71,7 @@ </div> </div> <?php endif; ?> - <div class="block order payment method"> + <div class="block order payment-method"> <div class="title"> <strong><?php echo __('Payment Method') ?></strong> </div> @@ -79,10 +79,9 @@ <?php echo $this->getPaymentInfoHtml() ?> </div> </div> - </div> - <div class="order details items"> - <div class="order subtitle caption"> + <div class="order-details-items"> + <div class="order-title"> <strong><?php echo __('Items Refunded') ?></strong> </div> <table class="data table order items" id="my-refund-table-<?php echo $_creditmemo->getId(); ?>"> diff --git a/app/code/Magento/Sales/view/frontend/templates/order/print/invoice.phtml b/app/code/Magento/Sales/view/frontend/templates/order/print/invoice.phtml index d56dcc43c6da5f8c181664b4b6b079b4ed1e3930..7a5813f5a0a0dfe68812efc12370a8063ca68190 100644 --- a/app/code/Magento/Sales/view/frontend/templates/order/print/invoice.phtml +++ b/app/code/Magento/Sales/view/frontend/templates/order/print/invoice.phtml @@ -70,7 +70,7 @@ </div> </div> <?php endif; ?> - <div class="block order payment method"> + <div class="block order payment-method"> <div class="title"> <strong><?php echo __('Payment Method') ?></strong> </div> @@ -79,8 +79,8 @@ </div> </div> </div> -<div class="order details items"> - <div class="order subtitle caption"> +<div class="order-details-items"> + <div class="order-title"> <strong><?php echo __('Items Invoiced') ?></strong> </div> <table class="data table order items" id="my-invoice-table-<?php echo $_invoice->getId(); ?>"> diff --git a/app/code/Magento/Sales/view/frontend/templates/order/print/shipment.phtml b/app/code/Magento/Sales/view/frontend/templates/order/print/shipment.phtml index 051a90c2324d1fd86ab79ef7c74fd8d00a353076..bf2db55c1287fc4280e0bdd955cd9e1118955d7d 100644 --- a/app/code/Magento/Sales/view/frontend/templates/order/print/shipment.phtml +++ b/app/code/Magento/Sales/view/frontend/templates/order/print/shipment.phtml @@ -81,7 +81,7 @@ <?php endif; ?> </div> - <div class="block order payment method"> + <div class="block order payment-method"> <div class="title"> <strong><?php echo __('Payment Method') ?></strong> </div> @@ -91,8 +91,8 @@ </div> </div> - <div class="order details items"> - <div class="order subtitle caption"> + <div class="order-details-items"> + <div class="order-title"> <strong><?php echo __('Items Shipped') ?></strong> </div> <table class="data table order items" id="my-shipment-table-<?php echo $this->getObjectData($shipment, 'id') ?>"> diff --git a/app/code/Magento/Sales/view/frontend/templates/order/recent.phtml b/app/code/Magento/Sales/view/frontend/templates/order/recent.phtml index 0e59cad70e4bfc0b779731331fb4e7e2862f8780..caf54b3b9b3326f6eebc17c8a979ecedb738c1b8 100644 --- a/app/code/Magento/Sales/view/frontend/templates/order/recent.phtml +++ b/app/code/Magento/Sales/view/frontend/templates/order/recent.phtml @@ -22,9 +22,9 @@ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) */ ?> -<div class="block dashboard orders"> +<div class="block block-dashboard-orders"> <?php $_orders = $this->getOrders(); ?> - <div class="order title"> + <div class="block-title order"> <strong><?php echo __('Recent Orders') ?></strong> <?php if( sizeof($_orders->getItems()) > 0 ): ?> <a class="action view" href="<?php echo $this->getUrl('sales/order/history') ?>"> @@ -32,31 +32,31 @@ </a> <?php endif; ?> </div> - <div class="content"> + <div class="block-content"> <?php echo $this->getChildHtml()?> <?php if( sizeof($_orders->getItems()) > 0 ): ?> - <div class="wrapper table orders recent"> - <table class="data table orders recent" id="my-orders-table"> + <div class="table-wrapper orders-recent"> + <table class="data table table-order-items recent" id="my-orders-table"> <caption class="table caption"><?php echo __('Recent Orders') ?></caption> <thead> <tr> - <th class="col id"><?php echo __('Order #') ?></th> - <th class="col date"><?php echo __('Date') ?></th> - <th class="col shipping"><?php echo __('Ship To') ?></th> - <th class="col total"><?php echo __('Order Total') ?></th> - <th class="col status"><?php echo __('Status') ?></th> - <th class="col actions"> </th> + <th scope="col" class="col id"><?php echo __('Order #') ?></th> + <th scope="col" class="col date"><?php echo __('Date') ?></th> + <th scope="col" class="col shipping"><?php echo __('Ship To') ?></th> + <th scope="col" class="col total"><?php echo __('Order Total') ?></th> + <th scope="col" class="col status"><?php echo __('Status') ?></th> + <th scope="col" class="col actions"> </th> </tr> </thead> <tbody> <?php foreach ($_orders as $_order): ?> <tr> - <td class="col id"><?php echo $_order->getRealOrderId() ?></td> - <td class="col date"><?php echo $this->formatDate($_order->getCreatedAtStoreDate()) ?></td> - <td class="col shipping"><?php echo $_order->getShippingAddress() ? $this->escapeHtml($_order->getShippingAddress()->getName()) : ' ' ?></td> - <td class="col total"><?php echo $_order->formatPrice($_order->getGrandTotal()) ?></td> - <td class="col status"><em><?php echo $_order->getStatusLabel() ?></em></td> - <td class="col actions"> + <td data-th="<?php echo $this->escapeHtml(__('Order #')) ?>" class="col id"><?php echo $_order->getRealOrderId() ?></td> + <td data-th="<?php echo $this->escapeHtml(__('Date')) ?>" class="col date"><?php echo $this->formatDate($_order->getCreatedAtStoreDate()) ?></td> + <td data-th="<?php echo $this->escapeHtml(__('Ship To')) ?>" class="col shipping"><?php echo $_order->getShippingAddress() ? $this->escapeHtml($_order->getShippingAddress()->getName()) : ' ' ?></td> + <td data-th="<?php echo $this->escapeHtml(__('Order Total')) ?>" class="col total"><?php echo $_order->formatPrice($_order->getGrandTotal()) ?></td> + <td data-th="<?php echo $this->escapeHtml(__('Status')) ?>" class="col status"><?php echo $_order->getStatusLabel() ?></td> + <td data-th="<?php echo $this->escapeHtml(__('Actions')) ?>" class="col actions"> <a href="<?php echo $this->getViewUrl($_order) ?>" class="action view"> <span><?php echo __('View Order') ?></span> </a> diff --git a/app/code/Magento/Sales/view/frontend/templates/order/shipment/items/renderer/default.phtml b/app/code/Magento/Sales/view/frontend/templates/order/shipment/items/renderer/default.phtml index f82b1f01d2f0451b1237a5668270c6c22efd4505..a5f1ceecc0ca140a883b1d8d0b10a63efa167edf 100644 --- a/app/code/Magento/Sales/view/frontend/templates/order/shipment/items/renderer/default.phtml +++ b/app/code/Magento/Sales/view/frontend/templates/order/shipment/items/renderer/default.phtml @@ -25,8 +25,8 @@ <?php $_item = $this->getItem() ?> <?php $_order = $this->getItem()->getOrderItem()->getOrder() ?> <tr id="order-item-row-<?php echo $_item->getId() ?>"> - <td class="col name"> - <strong class="product name"><?php echo $this->escapeHtml($_item->getName()) ?></strong> + <td class="col name" data-th="<?php echo $this->escapeHtml(__('Product Name')); ?>"> + <strong class="product name product-item-name"><?php echo $this->escapeHtml($_item->getName()) ?></strong> <?php if($_options = $this->getItemOptions()): ?> <dl class="item options"> <?php foreach ($_options as $_option) : ?> @@ -65,6 +65,6 @@ </a> <?php endif; ?> </td> - <td class="col sku"><?php echo $this->prepareSku($this->getSku()) ?></td> - <td class="col qty"><?php echo $_item->getQty()*1 ?></td> + <td class="col sku" data-th="<?php echo $this->escapeHtml(__('SKU')); ?>"><?php echo $this->prepareSku($this->getSku()) ?></td> + <td class="col qty" data-th="<?php echo $this->escapeHtml(__('Qty Shipped')); ?>"><?php echo $_item->getQty()*1 ?></td> </tr> diff --git a/app/code/Magento/Sales/view/frontend/templates/order/view.phtml b/app/code/Magento/Sales/view/frontend/templates/order/view.phtml index 885e151dd5b7d2d068f9bb0e6e37244e49735031..096ef21e0f70d1175d5c063917740eaf20a1c99b 100644 --- a/app/code/Magento/Sales/view/frontend/templates/order/view.phtml +++ b/app/code/Magento/Sales/view/frontend/templates/order/view.phtml @@ -23,10 +23,10 @@ */ ?> <?php /** @var $this \Magento\Sales\Block\Order\View*/?> -<div class="order details items"> +<div class="order-details-items ordered"> <?php $_order = $this->getOrder() ?> - <div class="order subtitle caption"> + <div class="order-title"> <strong><?php echo __('Items Ordered') ?></strong> <?php if ($_order->getTracksCollection()->count()) : ?> <?php echo $this->getChildHtml('tracking-info-link') ?> @@ -36,28 +36,19 @@ <?php echo $this->getChildHtml('order_items') ?> <?php if($this->helper('Magento\GiftMessage\Helper\Message')->getIsMessagesAvailable('order', $_order) && $_order->getGiftMessageId()): ?> - <div class="order additional details gift"> - <div class="order subtitle caption"><strong><?php echo __('Gift Message for This Order') ?></strong></div> + <div class="block block-order-details-additional"> + <div class="block-title"><strong><?php echo __('Gift Message for This Order') ?></strong></div> <?php $_giftMessage=$this->helper('Magento\GiftMessage\Helper\Message')->getGiftMessageForEntity($_order); ?> - <dl class="gift message"> - <dt class="gift sender"><strong class="label"><?php echo __('From:') ?></strong> <?php echo $this->escapeHtml($_giftMessage->getSender()) ?></dt> - <dt class="gift recipient"><strong class="label"><?php echo __('To:') ?></strong> <?php echo $this->escapeHtml($_giftMessage->getRecipient()) ?></dt> - <dd class="message text"><?php echo $this->helper('Magento\GiftMessage\Helper\Message')->getEscapedGiftMessage($_order) ?></dd> - </dl> - </div> - <?php endif; ?> - <?php $_history = $this->getOrder()->getVisibleStatusHistory() ?> - <?php if (count($_history)): ?> - <div class="order additional details comments"> - <div class="order subtitle caption"><strong><?php echo __('About Your Order') ?></strong></div> - <dl class="order comments"> - <?php foreach ($_history as $_historyItem): ?> - <dt class="comment date"><?php echo $this->formatDate($_historyItem->getCreatedAtStoreDate(), 'medium', true) ?></dt> - <dd class="comment text"><?php echo $this->escapeHtml($_historyItem->getComment()) ?></dd> - <?php endforeach; ?> - </dl> + <div class="block-content"> + <dl class="gift-message"> + <dt class="gift-sender"><strong class="label"><?php echo __('From:') ?></strong> <?php echo $this->escapeHtml($_giftMessage->getSender()) ?></dt> + <dt class="gift-recipient"><strong class="label"><?php echo __('To:') ?></strong> <?php echo $this->escapeHtml($_giftMessage->getRecipient()) ?></dt> + <dd class="gift-message-text"><?php echo $this->helper('Magento\GiftMessage\Helper\Message')->getEscapedGiftMessage($_order) ?></dd> + </dl> + </div> </div> <?php endif; ?> + <div class="actions-toolbar"> <div class="secondary"> <a class="action back" href="<?php echo $this->getBackUrl() ?>"> diff --git a/app/code/Magento/SalesRule/Model/RulesApplier.php b/app/code/Magento/SalesRule/Model/RulesApplier.php new file mode 100644 index 0000000000000000000000000000000000000000..a1138962db5ee3842f9da79bad0f18709b25aa78 --- /dev/null +++ b/app/code/Magento/SalesRule/Model/RulesApplier.php @@ -0,0 +1,253 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\SalesRule\Model; + +use Magento\Sales\Model\Quote\Address; + +/** + * Class RulesApplier + * @package Magento\SalesRule\Model\Validator + */ +class RulesApplier +{ + /** + * Application Event Dispatcher + * + * @var \Magento\Framework\Event\ManagerInterface + */ + protected $_eventManager; + + /** + * @var \Magento\SalesRule\Model\Utility + */ + protected $validatorUtility; + + /** + * @param \Magento\SalesRule\Model\Rule\Action\Discount\CalculatorFactory $calculatorFactory + * @param \Magento\Framework\Event\ManagerInterface $eventManager + * @param \Magento\SalesRule\Model\Utility $utility + */ + public function __construct( + \Magento\SalesRule\Model\Rule\Action\Discount\CalculatorFactory $calculatorFactory, + \Magento\Framework\Event\ManagerInterface $eventManager, + \Magento\SalesRule\Model\Utility $utility + ) { + $this->calculatorFactory = $calculatorFactory; + $this->validatorUtility = $utility; + $this->_eventManager = $eventManager; + } + + /** + * Apply rules to current order item + * + * @param \Magento\Sales\Model\Quote\Item\AbstractItem $item + * @param \Magento\SalesRule\Model\Resource\Rule\Collection $rules + * @param bool $skipValidation + * @param mixed $couponCode + * @return array + */ + public function applyRules($item, $rules, $skipValidation, $couponCode) + { + $address = $item->getAddress(); + $appliedRuleIds = array(); + /* @var $rule \Magento\SalesRule\Model\Rule */ + foreach ($rules as $rule) { + if (!$this->validatorUtility->canProcessRule($rule, $address)) { + continue; + } + + if (!$skipValidation && !$rule->getActions()->validate($item)) { + continue; + } + + $this->applyRule($item, $rule, $address, $couponCode); + $appliedRuleIds[$rule->getRuleId()] = $rule->getRuleId(); + + if ($rule->getStopRulesProcessing()) { + break; + } + } + + return $appliedRuleIds; + } + + /** + * Add rule discount description label to address object + * + * @param Address $address + * @param \Magento\SalesRule\Model\Rule $rule + * @return $this + */ + public function addDiscountDescription($address, $rule) + { + $description = $address->getDiscountDescriptionArray(); + $ruleLabel = $rule->getStoreLabel($address->getQuote()->getStore()); + $label = ''; + if ($ruleLabel) { + $label = $ruleLabel; + } else { + if (strlen($address->getCouponCode())) { + $label = $address->getCouponCode(); + } + } + + if (strlen($label)) { + $description[$rule->getId()] = $label; + } + + $address->setDiscountDescriptionArray($description); + + return $this; + } + + /** + * @param \Magento\Sales\Model\Quote\Item\AbstractItem $item + * @param \Magento\SalesRule\Model\Rule $rule + * @param \Magento\Sales\Model\Quote\Address $address + * @param mixed $couponCode + * @return $this + */ + protected function applyRule($item, $rule, $address, $couponCode) + { + $discountData = $this->getDiscountData($item, $rule); + $this->setDiscountData($discountData, $item); + + $this->maintainAddressCouponCode($address, $rule, $couponCode); + $this->addDiscountDescription($address, $rule); + + return $this; + } + + /** + * @param \Magento\Sales\Model\Quote\Item\AbstractItem $item + * @param \Magento\SalesRule\Model\Rule $rule + * @return \Magento\SalesRule\Model\Rule\Action\Discount\Data + */ + protected function getDiscountData($item, $rule) + { + $qty = $this->validatorUtility->getItemQty($item, $rule); + + $discountCalculator = $this->calculatorFactory->create($rule->getSimpleAction()); + $qty = $discountCalculator->fixQuantity($qty, $rule); + $discountData = $discountCalculator->calculate($rule, $item, $qty); + + $this->eventFix($discountData, $item, $rule, $qty); + $this->validatorUtility->deltaRoundingFix($discountData, $item); + + /** + * We can't use row total here because row total not include tax + * Discount can be applied on price included tax + */ + + $this->validatorUtility->minFix($discountData, $item, $qty); + + return $discountData; + } + + /** + * @param \Magento\SalesRule\Model\Rule\Action\Discount\Data $discountData + * @param \Magento\Sales\Model\Quote\Item\AbstractItem $item + * @return $this + */ + protected function setDiscountData($discountData, $item) + { + $item->setDiscountAmount($discountData->getAmount()); + $item->setBaseDiscountAmount($discountData->getBaseAmount()); + $item->setOriginalDiscountAmount($discountData->getOriginalAmount()); + $item->setBaseOriginalDiscountAmount($discountData->getBaseOriginalAmount()); + + return $this; + } + + /** + * Set coupon code to address if $rule contains validated coupon + * + * @param Address $address + * @param \Magento\SalesRule\Model\Rule $rule + * @param mixed $couponCode + * @return $this + */ + public function maintainAddressCouponCode($address, $rule, $couponCode) + { + /* + Rule is a part of rules collection, which includes only rules with 'No Coupon' type or with validated coupon. + As a result, if rule uses coupon code(s) ('Specific' or 'Auto' Coupon Type), it always contains validated coupon + */ + if ($rule->getCouponType() != \Magento\SalesRule\Model\Rule::COUPON_TYPE_NO_COUPON) { + $address->setCouponCode($couponCode); + } + + return $this; + } + + /** + * Fire event to allow overwriting of discount amounts + * + * @param \Magento\SalesRule\Model\Rule\Action\Discount\Data $discountData + * @param \Magento\Sales\Model\Quote\Item\AbstractItem $item + * @param \Magento\SalesRule\Model\Rule $rule + * @param float $qty + * @return $this + */ + protected function eventFix( + \Magento\SalesRule\Model\Rule\Action\Discount\Data $discountData, + \Magento\Sales\Model\Quote\Item\AbstractItem $item, + \Magento\SalesRule\Model\Rule $rule, + $qty + ) { + $quote = $item->getQuote(); + $address = $item->getAddress(); + + $this->_eventManager->dispatch( + 'salesrule_validator_process', + array( + 'rule' => $rule, + 'item' => $item, + 'address' => $address, + 'quote' => $quote, + 'qty' => $qty, + 'result' => $discountData + ) + ); + + return $this; + } + + /** + * @param \Magento\Sales\Model\Quote\Item\AbstractItem $item + * @param int[] $appliedRuleIds + * @return $this + */ + public function setAppliedRuleIds(\Magento\Sales\Model\Quote\Item\AbstractItem $item, array $appliedRuleIds) + { + $address = $item->getAddress(); + $quote = $item->getQuote(); + + $item->setAppliedRuleIds(join(',', $appliedRuleIds)); + $address->setAppliedRuleIds($this->validatorUtility->mergeIds($address->getAppliedRuleIds(), $appliedRuleIds)); + $quote->setAppliedRuleIds($this->validatorUtility->mergeIds($quote->getAppliedRuleIds(), $appliedRuleIds)); + + return $this; + } +} diff --git a/app/code/Magento/SalesRule/Model/Utility.php b/app/code/Magento/SalesRule/Model/Utility.php new file mode 100644 index 0000000000000000000000000000000000000000..a3c0e1a8a62b06e7b1b8b031451725cd93cb5535 --- /dev/null +++ b/app/code/Magento/SalesRule/Model/Utility.php @@ -0,0 +1,268 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\SalesRule\Model; + + +class Utility +{ + /** + * @var array + */ + protected $_roundingDeltas = array(); + + /** + * @var array + */ + protected $_baseRoundingDeltas = array(); + + /** + * @var \Magento\SalesRule\Model\Resource\Coupon\UsageFactory + */ + protected $usageFactory; + + /** + * @var \Magento\SalesRule\Model\CouponFactory + */ + protected $couponFactory; + + /** + * @var \Magento\SalesRule\Model\Rule\CustomerFactory + */ + protected $customerFactory; + + /** + * @param \Magento\SalesRule\Model\Resource\Coupon\UsageFactory $usageFactory + * @param \Magento\SalesRule\Model\CouponFactory $couponFactory + * @param \Magento\SalesRule\Model\Rule\CustomerFactory $customerFactory + */ + public function __construct ( + \Magento\SalesRule\Model\Resource\Coupon\UsageFactory $usageFactory, + \Magento\SalesRule\Model\CouponFactory $couponFactory, + \Magento\SalesRule\Model\Rule\CustomerFactory $customerFactory + ) { + $this->couponFactory = $couponFactory; + $this->customerFactory = $customerFactory; + $this->usageFactory = $usageFactory; + } + + /** + * Check if rule can be applied for specific address/quote/customer + * + * @param \Magento\SalesRule\Model\Rule $rule + * @param \Magento\Sales\Model\Quote\Address $address + * @return bool + */ + public function canProcessRule($rule, $address) + { + if ($rule->hasIsValidForAddress($address) && !$address->isObjectNew()) { + return $rule->getIsValidForAddress($address); + } + + /** + * check per coupon usage limit + */ + if ($rule->getCouponType() != \Magento\SalesRule\Model\Rule::COUPON_TYPE_NO_COUPON) { + $couponCode = $address->getQuote()->getCouponCode(); + if (strlen($couponCode)) { + /** @var \Magento\SalesRule\Model\Coupon $coupon */ + $coupon = $this->couponFactory->create(); + $coupon->load($couponCode, 'code'); + if ($coupon->getId()) { + // check entire usage limit + if ($coupon->getUsageLimit() && $coupon->getTimesUsed() >= $coupon->getUsageLimit()) { + $rule->setIsValidForAddress($address, false); + return false; + } + // check per customer usage limit + $customerId = $address->getQuote()->getCustomerId(); + if ($customerId && $coupon->getUsagePerCustomer()) { + $couponUsage = new \Magento\Framework\Object(); + $this->usageFactory->create()->loadByCustomerCoupon( + $couponUsage, + $customerId, + $coupon->getId() + ); + if ($couponUsage->getCouponId() && + $couponUsage->getTimesUsed() >= $coupon->getUsagePerCustomer() + ) { + $rule->setIsValidForAddress($address, false); + return false; + } + } + } + } + } + + /** + * check per rule usage limit + */ + $ruleId = $rule->getId(); + if ($ruleId && $rule->getUsesPerCustomer()) { + $customerId = $address->getQuote()->getCustomerId(); + $ruleCustomer = $this->customerFactory->create(); + $ruleCustomer->loadByCustomerRule($customerId, $ruleId); + if ($ruleCustomer->getId()) { + if ($ruleCustomer->getTimesUsed() >= $rule->getUsesPerCustomer()) { + $rule->setIsValidForAddress($address, false); + return false; + } + } + } + $rule->afterLoad(); + /** + * quote does not meet rule's conditions + */ + if (!$rule->validate($address)) { + $rule->setIsValidForAddress($address, false); + return false; + } + /** + * passed all validations, remember to be valid + */ + $rule->setIsValidForAddress($address, true); + return true; + } + + /** + * @param \Magento\SalesRule\Model\Rule\Action\Discount\Data $discountData + * @param \Magento\Sales\Model\Quote\Item\AbstractItem $item + * @param float $qty + * @return void + */ + public function minFix( + \Magento\SalesRule\Model\Rule\Action\Discount\Data $discountData, + \Magento\Sales\Model\Quote\Item\AbstractItem $item, + $qty + ) { + $itemPrice = $this->getItemPrice($item); + $baseItemPrice = $this->getItemBasePrice($item); + + $itemDiscountAmount = $item->getDiscountAmount(); + $itemBaseDiscountAmount = $item->getBaseDiscountAmount(); + + $discountAmount = min($itemDiscountAmount + $discountData->getAmount(), $itemPrice * $qty); + $baseDiscountAmount = min($itemBaseDiscountAmount + $discountData->getBaseAmount(), $baseItemPrice * $qty); + + $discountData->setAmount($discountAmount); + $discountData->setBaseAmount($baseDiscountAmount); + } + + /** + * Process "delta" rounding + * + * @param \Magento\SalesRule\Model\Rule\Action\Discount\Data $discountData + * @param \Magento\Sales\Model\Quote\Item\AbstractItem $item + * @return $this + */ + public function deltaRoundingFix( + \Magento\SalesRule\Model\Rule\Action\Discount\Data $discountData, + \Magento\Sales\Model\Quote\Item\AbstractItem $item + ) { + $store = $item->getQuote()->getStore(); + $discountAmount = $discountData->getAmount(); + $baseDiscountAmount = $discountData->getBaseAmount(); + + //TODO Seems \Magento\Sales\Model\Quote\Item\AbstractItem::getDiscountPercent() returns float value + //that can not be used as array index + $percentKey = $item->getDiscountPercent(); + if ($percentKey) { + $delta = isset($this->_roundingDeltas[$percentKey]) ? $this->_roundingDeltas[$percentKey] : 0; + $baseDelta = isset($this->_baseRoundingDeltas[$percentKey]) ? $this->_baseRoundingDeltas[$percentKey] : 0; + + $discountAmount += $delta; + $baseDiscountAmount += $baseDelta; + + $this->_roundingDeltas[$percentKey] = $discountAmount - $store->roundPrice($discountAmount); + $this->_baseRoundingDeltas[$percentKey] = $baseDiscountAmount - $store->roundPrice($baseDiscountAmount); + } + + $discountData->setAmount($store->roundPrice($discountAmount)); + $discountData->setBaseAmount($store->roundPrice($baseDiscountAmount)); + + return $this; + } + + /** + * Return item price + * + * @param \Magento\Sales\Model\Quote\Item\AbstractItem $item + * @return float + */ + public function getItemPrice($item) + { + $price = $item->getDiscountCalculationPrice(); + $calcPrice = $item->getCalculationPrice(); + return $price === null ? $calcPrice : $price; + } + + /** + * Return item base price + * + * @param \Magento\Sales\Model\Quote\Item\AbstractItem $item + * @return float + */ + public function getItemBasePrice($item) + { + $price = $item->getDiscountCalculationPrice(); + return $price !== null ? $item->getBaseDiscountCalculationPrice() : $item->getBaseCalculationPrice(); + } + + /** + * Return discount item qty + * + * @param \Magento\Sales\Model\Quote\Item\AbstractItem $item + * @param \Magento\SalesRule\Model\Rule $rule + * @return int + */ + public function getItemQty($item, $rule) + { + $qty = $item->getTotalQty(); + $discountQty = $rule->getDiscountQty(); + return $discountQty ? min($qty, $discountQty) : $qty; + } + + /** + * Merge two sets of ids + * + * @param array|string $a1 + * @param array|string $a2 + * @param bool $asString + * @return array + */ + public function mergeIds($a1, $a2, $asString = true) + { + if (!is_array($a1)) { + $a1 = empty($a1) ? array() : explode(',', $a1); + } + if (!is_array($a2)) { + $a2 = empty($a2) ? array() : explode(',', $a2); + } + $a = array_unique(array_merge($a1, $a2)); + if ($asString) { + $a = implode(',', $a); + } + return $a; + } +} diff --git a/app/code/Magento/SalesRule/Model/Validator.php b/app/code/Magento/SalesRule/Model/Validator.php index 12367e76dc23821de6355fcc8529f5b84a91d0b2..c89304ffb3fe92f281e2cbf85d9d9c5a131de4d9 100644 --- a/app/code/Magento/SalesRule/Model/Validator.php +++ b/app/code/Magento/SalesRule/Model/Validator.php @@ -47,16 +47,6 @@ class Validator extends \Magento\Framework\Model\AbstractModel */ protected $_rules; - /** - * @var array - */ - protected $_roundingDeltas = array(); - - /** - * @var array - */ - protected $_baseRoundingDeltas = array(); - /** * Defines if method \Magento\SalesRule\Model\Validator::reset() wasn't called * Used for clearing applied rule ids in Quote and in Address @@ -92,41 +82,22 @@ class Validator extends \Magento\Framework\Model\AbstractModel protected $_collectionFactory; /** - * @var \Magento\SalesRule\Model\Resource\Coupon\UsageFactory - */ - protected $_usageFactory; - - /** - * @var \Magento\SalesRule\Model\CouponFactory + * @var \Magento\SalesRule\Model\Utility */ - protected $_couponFactory; + protected $validatorUtility; /** - * @var \Magento\SalesRule\Model\Rule\CustomerFactory + * @var \Magento\SalesRule\Model\RulesApplier */ - protected $_customerFactory; - - /** - * @var \Magento\SalesRule\Model\Rule\Action\Discount\CalculatorFactory - */ - protected $calculatorFactory; - - /** - * Defines if rule with stop further rules is already applied - * - * @var bool - */ - protected $_stopFurtherRules = false; + protected $rulesApplier; /** * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry - * @param \Magento\SalesRule\Model\Resource\Coupon\UsageFactory $usageFactory - * @param \Magento\SalesRule\Model\Resource\Rule\CollectionFactory $collectionFactory + * @param Resource\Rule\CollectionFactory $collectionFactory * @param \Magento\Tax\Helper\Data $taxData - * @param \Magento\SalesRule\Model\CouponFactory $couponFactory - * @param \Magento\SalesRule\Model\Rule\CustomerFactory $customerFactory - * @param \Magento\SalesRule\Model\Rule\Action\Discount\CalculatorFactory $calculatorFactory + * @param Utility $utility + * @param RulesApplier $rulesApplier * @param \Magento\Framework\Model\Resource\AbstractResource $resource * @param \Magento\Framework\Data\Collection\Db $resourceCollection * @param array $data @@ -134,22 +105,18 @@ class Validator extends \Magento\Framework\Model\AbstractModel public function __construct( \Magento\Framework\Model\Context $context, \Magento\Framework\Registry $registry, - \Magento\SalesRule\Model\Resource\Coupon\UsageFactory $usageFactory, \Magento\SalesRule\Model\Resource\Rule\CollectionFactory $collectionFactory, \Magento\Tax\Helper\Data $taxData, - \Magento\SalesRule\Model\CouponFactory $couponFactory, - \Magento\SalesRule\Model\Rule\CustomerFactory $customerFactory, - \Magento\SalesRule\Model\Rule\Action\Discount\CalculatorFactory $calculatorFactory, + \Magento\SalesRule\Model\Utility $utility, + \Magento\SalesRule\Model\RulesApplier $rulesApplier, \Magento\Framework\Model\Resource\AbstractResource $resource = null, \Magento\Framework\Data\Collection\Db $resourceCollection = null, array $data = array() ) { - $this->_usageFactory = $usageFactory; $this->_collectionFactory = $collectionFactory; $this->_taxData = $taxData; - $this->_couponFactory = $couponFactory; - $this->_customerFactory = $customerFactory; - $this->calculatorFactory = $calculatorFactory; + $this->validatorUtility = $utility; + $this->rulesApplier = $rulesApplier; parent::__construct($context, $registry, $resource, $resourceCollection, $data); } @@ -169,12 +136,14 @@ class Validator extends \Magento\Framework\Model\AbstractModel $key = $websiteId . '_' . $customerGroupId . '_' . $couponCode; if (!isset($this->_rules[$key])) { - $this->_rules[$key] = $this->_collectionFactory->create()->setValidationFilter( - $websiteId, - $customerGroupId, - $couponCode - )->addFieldToFilter('is_active', 1) - ->load(); + $this->_rules[$key] = $this->_collectionFactory->create() + ->setValidationFilter( + $websiteId, + $customerGroupId, + $couponCode + ) + ->addFieldToFilter('is_active', 1) + ->load(); } return $this; } @@ -190,84 +159,6 @@ class Validator extends \Magento\Framework\Model\AbstractModel return $this->_rules[$key]; } - /** - * Check if rule can be applied for specific address/quote/customer - * - * @param \Magento\SalesRule\Model\Rule $rule - * @param Address $address - * @return bool - */ - protected function _canProcessRule($rule, $address) - { - if ($rule->hasIsValidForAddress($address) && !$address->isObjectNew()) { - return $rule->getIsValidForAddress($address); - } - - /** - * check per coupon usage limit - */ - if ($rule->getCouponType() != \Magento\SalesRule\Model\Rule::COUPON_TYPE_NO_COUPON) { - $couponCode = $address->getQuote()->getCouponCode(); - if (strlen($couponCode)) { - /** @var \Magento\SalesRule\Model\Coupon $coupon */ - $coupon = $this->_couponFactory->create(); - $coupon->load($couponCode, 'code'); - if ($coupon->getId()) { - // check entire usage limit - if ($coupon->getUsageLimit() && $coupon->getTimesUsed() >= $coupon->getUsageLimit()) { - $rule->setIsValidForAddress($address, false); - return false; - } - // check per customer usage limit - $customerId = $address->getQuote()->getCustomerId(); - if ($customerId && $coupon->getUsagePerCustomer()) { - $couponUsage = new \Magento\Framework\Object(); - $this->_usageFactory->create()->loadByCustomerCoupon( - $couponUsage, - $customerId, - $coupon->getId() - ); - if ($couponUsage->getCouponId() && - $couponUsage->getTimesUsed() >= $coupon->getUsagePerCustomer() - ) { - $rule->setIsValidForAddress($address, false); - return false; - } - } - } - } - } - - /** - * check per rule usage limit - */ - $ruleId = $rule->getId(); - if ($ruleId && $rule->getUsesPerCustomer()) { - $customerId = $address->getQuote()->getCustomerId(); - $ruleCustomer = $this->_customerFactory->create(); - $ruleCustomer->loadByCustomerRule($customerId, $ruleId); - if ($ruleCustomer->getId()) { - if ($ruleCustomer->getTimesUsed() >= $rule->getUsesPerCustomer()) { - $rule->setIsValidForAddress($address, false); - return false; - } - } - } - $rule->afterLoad(); - /** - * quote does not meet rule's conditions - */ - if (!$rule->validate($address)) { - $rule->setIsValidForAddress($address, false); - return false; - } - /** - * passed all validations, remember to be valid - */ - $rule->setIsValidForAddress($address, true); - return true; - } - /** * Set skip actions validation flag * @@ -290,7 +181,7 @@ class Validator extends \Magento\Framework\Model\AbstractModel { $address = $item->getAddress(); foreach ($this->_getRules() as $rule) { - if (!$this->_canProcessRule($rule, $address) || !$rule->getActions()->validate($item)) { + if (!$this->validatorUtility->canProcessRule($rule, $address) || !$rule->getActions()->validate($item)) { return false; } } @@ -332,8 +223,13 @@ class Validator extends \Magento\Framework\Model\AbstractModel return $this; } - $appliedRuleIds = $this->applyRules($item); - $this->setAppliedRuleIds($item, $appliedRuleIds); + $appliedRuleIds = $this->rulesApplier->applyRules( + $item, + $this->_getRules(), + $this->_skipActionsValidation, + $this->getCouponCode() + ); + $this->rulesApplier->setAppliedRuleIds($item, $appliedRuleIds); return $this; } @@ -367,11 +263,11 @@ class Validator extends \Magento\Framework\Model\AbstractModel switch ($rule->getSimpleAction()) { case \Magento\SalesRule\Model\Rule::TO_PERCENT_ACTION: $rulePercent = max(0, 100 - $rule->getDiscountAmount()); - // break is intentionally omitted + // break is intentionally omitted case \Magento\SalesRule\Model\Rule::BY_PERCENT_ACTION: $discountAmount = ($shippingAmount - $address->getShippingDiscountAmount()) * $rulePercent / 100; $baseDiscountAmount = ($baseShippingAmount - - $address->getBaseShippingDiscountAmount()) * $rulePercent / 100; + $address->getBaseShippingDiscountAmount()) * $rulePercent / 100; $discountPercent = min(100, $address->getShippingDiscountPercent() + $rulePercent); $address->setShippingDiscountPercent($discountPercent); break; @@ -413,42 +309,19 @@ class Validator extends \Magento\Framework\Model\AbstractModel $address->setBaseShippingDiscountAmount($baseDiscountAmount); $appliedRuleIds[$rule->getRuleId()] = $rule->getRuleId(); - $this->_maintainAddressCouponCode($address, $rule); - $this->_addDiscountDescription($address, $rule); + $this->rulesApplier->maintainAddressCouponCode($address, $rule, $this->getCouponCode()); + $this->rulesApplier->addDiscountDescription($address, $rule); if ($rule->getStopRulesProcessing()) { break; } } - $address->setAppliedRuleIds($this->mergeIds($address->getAppliedRuleIds(), $appliedRuleIds)); - $quote->setAppliedRuleIds($this->mergeIds($quote->getAppliedRuleIds(), $appliedRuleIds)); + $address->setAppliedRuleIds($this->validatorUtility->mergeIds($address->getAppliedRuleIds(), $appliedRuleIds)); + $quote->setAppliedRuleIds($this->validatorUtility->mergeIds($quote->getAppliedRuleIds(), $appliedRuleIds)); return $this; } - /** - * Merge two sets of ids - * - * @param array|string $a1 - * @param array|string $a2 - * @param bool $asString - * @return array - */ - public function mergeIds($a1, $a2, $asString = true) - { - if (!is_array($a1)) { - $a1 = empty($a1) ? array() : explode(',', $a1); - } - if (!is_array($a2)) { - $a2 = empty($a2) ? array() : explode(',', $a2); - } - $a = array_unique(array_merge($a1, $a2)); - if ($asString) { - $a = implode(',', $a); - } - return $a; - } - /** * Calculate quote totals for each rule and save results * @@ -465,12 +338,9 @@ class Validator extends \Magento\Framework\Model\AbstractModel } foreach ($this->_getRules() as $rule) { - if (\Magento\SalesRule\Model\Rule::CART_FIXED_ACTION == $rule->getSimpleAction() && $this->_canProcessRule( - $rule, - $address - ) + if (\Magento\SalesRule\Model\Rule::CART_FIXED_ACTION == $rule->getSimpleAction() + && $this->validatorUtility->canProcessRule($rule, $address) ) { - $ruleTotalItemsPrice = 0; $ruleTotalBaseItemsPrice = 0; $validItemsCount = 0; @@ -483,7 +353,7 @@ class Validator extends \Magento\Framework\Model\AbstractModel if (!$rule->getActions()->validate($item)) { continue; } - $qty = $this->_getItemQty($item, $rule); + $qty = $this->validatorUtility->getItemQty($item, $rule); $ruleTotalItemsPrice += $this->getItemPrice($item) * $qty; $ruleTotalBaseItemsPrice += $this->getItemBasePrice($item) * $qty; $validItemsCount++; @@ -497,54 +367,6 @@ class Validator extends \Magento\Framework\Model\AbstractModel } } - $this->_stopFurtherRules = false; - return $this; - } - - /** - * Set coupon code to address if $rule contains validated coupon - * - * @param Address $address - * @param \Magento\SalesRule\Model\Rule $rule - * @return $this - */ - protected function _maintainAddressCouponCode($address, $rule) - { - /* - Rule is a part of rules collection, which includes only rules with 'No Coupon' type or with validated coupon. - As a result, if rule uses coupon code(s) ('Specific' or 'Auto' Coupon Type), it always contains validated coupon - */ - if ($rule->getCouponType() != \Magento\SalesRule\Model\Rule::COUPON_TYPE_NO_COUPON) { - $address->setCouponCode($this->getCouponCode()); - } - - return $this; - } - - /** - * Add rule discount description label to address object - * - * @param Address $address - * @param \Magento\SalesRule\Model\Rule $rule - * @return $this - */ - protected function _addDiscountDescription($address, $rule) - { - $description = $address->getDiscountDescriptionArray(); - $ruleLabel = $rule->getStoreLabel($address->getQuote()->getStore()); - $label = ''; - if ($ruleLabel) { - $label = $ruleLabel; - } else if (strlen($address->getCouponCode())) { - $label = $address->getCouponCode(); - } - - if (strlen($label)) { - $description[$rule->getId()] = $label; - } - - $address->setDiscountDescriptionArray($description); - return $this; } @@ -595,20 +417,6 @@ class Validator extends \Magento\Framework\Model\AbstractModel return $this->_taxData->getPrice($item, $item->getBaseOriginalPrice(), true); } - /** - * Return discount item qty - * - * @param AbstractItem $item - * @param \Magento\SalesRule\Model\Rule $rule - * @return int - */ - protected function _getItemQty($item, $rule) - { - $qty = $item->getTotalQty(); - $discountQty = $rule->getDiscountQty(); - return $discountQty ? min($qty, $discountQty) : $qty; - } - /** * Convert address discount description array to string * @@ -660,115 +468,6 @@ class Validator extends \Magento\Framework\Model\AbstractModel return $items; } - /** - * @param \Magento\Sales\Model\Quote\Item\AbstractItem $item - * @param int[] $appliedRuleIds - * @return $this - */ - protected function setAppliedRuleIds(\Magento\Sales\Model\Quote\Item\AbstractItem $item, array $appliedRuleIds) - { - $address = $item->getAddress(); - $quote = $item->getQuote(); - - $item->setAppliedRuleIds(join(',', $appliedRuleIds)); - $address->setAppliedRuleIds($this->mergeIds($address->getAppliedRuleIds(), $appliedRuleIds)); - $quote->setAppliedRuleIds($this->mergeIds($quote->getAppliedRuleIds(), $appliedRuleIds)); - - return $this; - } - - /** - * Fire event to allow overwriting of discount amounts - * - * @param \Magento\SalesRule\Model\Rule\Action\Discount\Data $discountData - * @param \Magento\Sales\Model\Quote\Item\AbstractItem $item - * @param \Magento\SalesRule\Model\Rule $rule - * @param float $qty - * @return $this - */ - protected function eventFix( - \Magento\SalesRule\Model\Rule\Action\Discount\Data $discountData, - \Magento\Sales\Model\Quote\Item\AbstractItem $item, - \Magento\SalesRule\Model\Rule $rule, - $qty - ) { - $quote = $item->getQuote(); - $address = $item->getAddress(); - - $this->_eventManager->dispatch( - 'salesrule_validator_process', - array( - 'rule' => $rule, - 'item' => $item, - 'address' => $address, - 'quote' => $quote, - 'qty' => $qty, - 'result' => $discountData - ) - ); - - return $this; - } - - /** - * Process "delta" rounding - * - * @param \Magento\SalesRule\Model\Rule\Action\Discount\Data $discountData - * @param \Magento\Sales\Model\Quote\Item\AbstractItem $item - * @return $this - */ - protected function deltaRoundingFix( - \Magento\SalesRule\Model\Rule\Action\Discount\Data $discountData, - \Magento\Sales\Model\Quote\Item\AbstractItem $item - ) { - $store = $item->getQuote()->getStore(); - $discountAmount = $discountData->getAmount(); - $baseDiscountAmount = $discountData->getBaseAmount(); - - //TODO Seems \Magento\Sales\Model\Quote\Item\AbstractItem::getDiscountPercent() returns float value - //that can not be used as array index - $percentKey = $item->getDiscountPercent(); - if ($percentKey) { - $delta = isset($this->_roundingDeltas[$percentKey]) ? $this->_roundingDeltas[$percentKey] : 0; - $baseDelta = isset($this->_baseRoundingDeltas[$percentKey]) ? $this->_baseRoundingDeltas[$percentKey] : 0; - - $discountAmount += $delta; - $baseDiscountAmount += $baseDelta; - - $this->_roundingDeltas[$percentKey] = $discountAmount - $store->roundPrice($discountAmount); - $this->_baseRoundingDeltas[$percentKey] = $baseDiscountAmount - $store->roundPrice($baseDiscountAmount); - } - - $discountData->setAmount($store->roundPrice($discountAmount)); - $discountData->setBaseAmount($store->roundPrice($baseDiscountAmount)); - - return $this; - } - - /** - * @param Rule\Action\Discount\Data $discountData - * @param \Magento\Sales\Model\Quote\Item\AbstractItem $item - * @param float $qty - * @return void - */ - protected function minFix( - \Magento\SalesRule\Model\Rule\Action\Discount\Data $discountData, - \Magento\Sales\Model\Quote\Item\AbstractItem $item, - $qty - ) { - $itemPrice = $this->getItemPrice($item); - $baseItemPrice = $this->getItemBasePrice($item); - - $itemDiscountAmount = $item->getDiscountAmount(); - $itemBaseDiscountAmount = $item->getBaseDiscountAmount(); - - $discountAmount = min($itemDiscountAmount + $discountData->getAmount(), $itemPrice * $qty); - $baseDiscountAmount = min($itemBaseDiscountAmount + $discountData->getBaseAmount(), $baseItemPrice * $qty); - - $discountData->setAmount($discountAmount); - $discountData->setBaseAmount($baseDiscountAmount); - } - /** * @param int $key * @return array @@ -793,97 +492,4 @@ class Validator extends \Magento\Framework\Model\AbstractModel return $this; } - - /** - * @param \Magento\Sales\Model\Quote\Item\AbstractItem $item - * @return array - */ - protected function applyRules($item) - { - $address = $item->getAddress(); - - $appliedRuleIds = array(); - /* @var $rule \Magento\SalesRule\Model\Rule */ - foreach ($this->_getRules() as $rule) { - if ($this->_stopFurtherRules) { - break; - } - - if (!$this->_canProcessRule($rule, $address)) { - continue; - } - - if (!$this->_skipActionsValidation && !$rule->getActions()->validate($item)) { - continue; - } - - $this->applyRule($item, $rule, $address); - $appliedRuleIds[$rule->getRuleId()] = $rule->getRuleId(); - - if ($rule->getStopRulesProcessing()) { - $this->_stopFurtherRules = true; - break; - } - } - - return $appliedRuleIds; - } - - /** - * @param \Magento\Sales\Model\Quote\Item\AbstractItem $item - * @param \Magento\SalesRule\Model\Rule $rule - * @param \Magento\Sales\Model\Quote\Address $address - * @return $this - */ - protected function applyRule($item, $rule, $address) - { - $discountData = $this->getDiscountData($item, $rule); - $this->setDiscountData($discountData, $item); - - $this->_maintainAddressCouponCode($address, $rule); - $this->_addDiscountDescription($address, $rule); - - return $this; - } - - /** - * @param \Magento\Sales\Model\Quote\Item\AbstractItem $item - * @param \Magento\SalesRule\Model\Rule $rule - * @return Rule\Action\Discount\Data - */ - protected function getDiscountData($item, $rule) - { - $qty = $this->_getItemQty($item, $rule); - - $discountCalculator = $this->calculatorFactory->create($rule->getSimpleAction()); - $qty = $discountCalculator->fixQuantity($qty, $rule); - $discountData = $discountCalculator->calculate($rule, $item, $qty); - - $this->eventFix($discountData, $item, $rule, $qty); - $this->deltaRoundingFix($discountData, $item); - - /** - * We can't use row total here because row total not include tax - * Discount can be applied on price included tax - */ - - $this->minFix($discountData, $item, $qty); - - return $discountData; - } - - /** - * @param Rule\Action\Discount\Data $discountData - * @param \Magento\Sales\Model\Quote\Item\AbstractItem $item - * @return $this - */ - protected function setDiscountData($discountData, $item) - { - $item->setDiscountAmount($discountData->getAmount()); - $item->setBaseDiscountAmount($discountData->getBaseAmount()); - $item->setOriginalDiscountAmount($discountData->getOriginalAmount()); - $item->setBaseOriginalDiscountAmount($discountData->getBaseOriginalAmount()); - - return $this; - } } diff --git a/app/code/Magento/Sendfriend/view/frontend/templates/send.phtml b/app/code/Magento/Sendfriend/view/frontend/templates/send.phtml index 275153630f44c2640d404923ace593da5f747c68..911cf5fe89d2005e59621d1276baf038e6cd37b6 100644 --- a/app/code/Magento/Sendfriend/view/frontend/templates/send.phtml +++ b/app/code/Magento/Sendfriend/view/frontend/templates/send.phtml @@ -31,7 +31,7 @@ <div class="actions-toolbar"> <div class="secondary"> <button type="button" id="btn-remove${_index_}" class="action remove" - title="<?php echo $this->escapeJsQuote(__('Remove Email')) ?>"><span><?php echo $this->escapeJsQuote(__('Remove Email')) ?></span></button> + title="<?php echo $this->escapeJsQuote(__('Remove')) ?>"><span><?php echo $this->escapeJsQuote(__('Remove')) ?></span></button> </div> </div> <fieldset class="fieldset"> diff --git a/app/code/Magento/Shipping/view/frontend/layout/sales_order_shipment.xml b/app/code/Magento/Shipping/view/frontend/layout/sales_order_shipment.xml index 753d3a45406a1a1c60480cca8a06454217c143f7..93e203f6427964dba79f246ec4d414c1099499d6 100644 --- a/app/code/Magento/Shipping/view/frontend/layout/sales_order_shipment.xml +++ b/app/code/Magento/Shipping/view/frontend/layout/sales_order_shipment.xml @@ -26,7 +26,7 @@ <layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_single.xsd"> <update handle="sales_order_shipment_renderers" /> <referenceContainer name="content"> - <block class="Magento\Shipping\Block\Order\Shipment" name="sales.order.shipment" after="sales.order.info" cacheable="false"> + <block class="Magento\Shipping\Block\Order\Shipment" name="sales.order.shipment" cacheable="false"> <block class="Magento\Shipping\Block\Items" name="shipment_items" template="items.phtml"> <block class="Magento\Framework\View\Element\RendererList" name="sales.order.shipment.renderers" as="renderer.list" /> <block class="Magento\Shipping\Block\Tracking\Link" name="track-all-link" template="tracking/link.phtml"> diff --git a/app/code/Magento/Shipping/view/frontend/templates/items.phtml b/app/code/Magento/Shipping/view/frontend/templates/items.phtml index ce25944c50aa294e54fa7e27794078ba81f4b87b..55f3d5187a9d55a7ff5ed6eef85e5500b3c9ba50 100644 --- a/app/code/Magento/Shipping/view/frontend/templates/items.phtml +++ b/app/code/Magento/Shipping/view/frontend/templates/items.phtml @@ -24,20 +24,18 @@ ?> <?php /** @var $this \Magento\Shipping\Block\Items */ ?> <?php $_order = $this->getOrder() ?> -<div class="order toolbar"> - <div class="actions"> - <?php if ($_order->getTracksCollection()->count()) : ?> - <?php echo $this->getChildHtml('track-all-link') ?> - <?php endif; ?> - <a href="<?php echo $this->getPrintAllShipmentsUrl($_order) ?>" - onclick="this.target='_blank'" - class="action print"> - <span><?php echo __('Print All Shipments') ?></span> - </a> - </div> +<div class="actions-toolbar"> + <?php if ($_order->getTracksCollection()->count()) : ?> + <?php echo $this->getChildHtml('track-all-link') ?> + <?php endif; ?> + <a href="<?php echo $this->getPrintAllShipmentsUrl($_order) ?>" + onclick="this.target='_blank'" + class="action print"> + <span><?php echo __('Print All Shipments') ?></span> + </a> </div> <?php foreach ($_order->getShipmentsCollection() as $_shipment): ?> -<div class="order title"> +<div class="order-title"> <strong><?php echo __('Shipment #') ?><?php echo $_shipment->getIncrementId(); ?></strong> <a href="<?php echo $this->getPrintShipmentUrl($_shipment) ?>" onclick="this.target='_blank'" @@ -53,35 +51,27 @@ </div> <?php $tracks = $_shipment->getTracksCollection(); ?> <?php if ($tracks->count()): ?> - <table class="data table order tracking" id="my-tracking-table-<?php echo $_shipment->getId(); ?>"> - <tbody> - <tr> - <th class="col label"><?php echo __('Tracking Number(s):') ?></th> - <td class="col number"> - <?php - $i = 1; - $_size = $tracks->count(); - foreach($tracks as $track): ?> - <?php if($track->isCustom()): ?> - <?php echo $this->escapeHtml($track->getNumber()) ?> - <?php else: ?> - <a href="#" - data-mage-init='{"popupWindow": {"windowURL":"<?php echo $this->helper('Magento\Shipping\Helper\Data')->getTrackingPopupUrlBySalesModel($track) ?>","windowName":"trackorder","width":800,"height":600,"left":0,"top":0,"resizable":1,"scrollbars":1}}' - class="action track"> - <span><?php echo $this->escapeHtml($track->getNumber()) ?></span> - </a> - <?php endif; ?> - <?php if($i!=$_size): ?>, <?php endif; ?> + <dl class="order-tracking" id="my-tracking-table-<?php echo $_shipment->getId(); ?>"> + <dt class="tracking-title"> + <?php echo __('Tracking Number(s):') ?> + </dt> + <dd class="tracking-content"> + <?php + $i = 1; + $_size = $tracks->count(); + foreach ($tracks as $track): ?> + <?php if ($track->isCustom()): ?><?php echo $this->escapeHtml($track->getNumber()) ?><?php else: ?><a + href="#" + data-mage-init='{"popupWindow": {"windowURL":"<?php echo $this->helper('Magento\Shipping\Helper\Data')->getTrackingPopupUrlBySalesModel($track) ?>","windowName":"trackorder","width":800,"height":600,"left":0,"top":0,"resizable":1,"scrollbars":1}}' + class="action track"><span><?php echo $this->escapeHtml($track->getNumber()) ?></span> + </a><?php endif; ?><?php if ($i != $_size): ?>, <?php endif; ?> <?php $i++; - endforeach; ?> - </td> - </tr> - </tbody> - </table> + endforeach; ?> + </dd> + </dl> <?php endif; ?> -<div class="order subtitle caption"><strong><?php echo __('Items Shipped') ?></strong></div> -<div class="wrapper table order items shipment"> - <table class="data table order items shipment" id="my-shipment-table-<?php echo $_shipment->getId(); ?>"> +<div class="table-wrapper order-items-shipment"> + <table class="data table table-order-items shipment" id="my-shipment-table-<?php echo $_shipment->getId(); ?>"> <caption class="table caption"><?php echo __('Items Shipped') ?></caption> <thead> <tr> diff --git a/app/code/Magento/Shipping/view/frontend/templates/order/shipment.phtml b/app/code/Magento/Shipping/view/frontend/templates/order/shipment.phtml index 89362b4377019522faedf4617ae0c63d4dbca208..e019f5067eab3f3bde1473bab8efd5ef6545a20e 100644 --- a/app/code/Magento/Shipping/view/frontend/templates/order/shipment.phtml +++ b/app/code/Magento/Shipping/view/frontend/templates/order/shipment.phtml @@ -22,7 +22,7 @@ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) */ ?> -<div class="order items details shipments"> +<div class="order-details-items shipments"> <?php echo $this->getChildHtml('shipment_items') ?> <div class="actions-toolbar"> <div class="secondary"> diff --git a/app/code/Magento/Tax/Helper/Data.php b/app/code/Magento/Tax/Helper/Data.php index 76569e00913619cdead2f0b6dc4cdf3521d57ddb..c87caae9d81af6efb9de5a7100e8b88d71eb16cc 100644 --- a/app/code/Magento/Tax/Helper/Data.php +++ b/app/code/Magento/Tax/Helper/Data.php @@ -28,6 +28,8 @@ use Magento\Customer\Model\Address; use Magento\Tax\Model\Config; use Magento\Tax\Service\V1\Data\QuoteDetailsBuilder; use Magento\Tax\Service\V1\Data\QuoteDetails\ItemBuilder as QuoteDetailsItemBuilder; +use Magento\Tax\Service\V1\Data\TaxClassKey; +use Magento\Tax\Service\V1\Data\TaxClassKeyBuilder; use Magento\Tax\Service\V1\TaxCalculationServiceInterface; use Magento\Customer\Model\Address\Converter as AddressConverter; @@ -149,6 +151,13 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper */ protected $addressConverter; + /** + * TaxClassKey builder + * + * @var TaxClassKeyBuilder + */ + protected $taxClassKeyBuilder; + /** * @param \Magento\Framework\App\Helper\Context $context * @param \Magento\Core\Helper\Data $coreData @@ -163,6 +172,7 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper * @param \Magento\Framework\Locale\ResolverInterface $localeResolver * @param QuoteDetailsBuilder $quoteDetailsBuilder * @param QuoteDetailsItemBuilder $quoteDetailsItemBuilder + * @param TaxClassKeyBuilder $taxClassKeyBuilder * @param TaxCalculationServiceInterface $taxCalculationService * @param AddressConverter $addressConverter */ @@ -180,6 +190,7 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper \Magento\Framework\Locale\ResolverInterface $localeResolver, QuoteDetailsBuilder $quoteDetailsBuilder, QuoteDetailsItemBuilder $quoteDetailsItemBuilder, + TaxClassKeyBuilder $taxClassKeyBuilder, TaxCalculationServiceInterface $taxCalculationService, AddressConverter $addressConverter ) { @@ -196,6 +207,7 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper $this->_localeResolver = $localeResolver; $this->quoteDetailsBuilder = $quoteDetailsBuilder; $this->quoteDetailsItemBuilder = $quoteDetailsItemBuilder; + $this->taxClassKeyBuilder = $taxClassKeyBuilder; $this->taxCalculationService = $taxCalculationService; $this->addressConverter = $addressConverter; } @@ -570,16 +582,20 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper $item = $this->quoteDetailsItemBuilder->setQuantity(1) ->setCode($product->getSku()) ->setShortDescription($product->getShortDescription()) - ->setTaxClassId($product->getTaxClassId()) - ->setTaxIncluded($priceIncludesTax) + ->setTaxClassKey( + $this->taxClassKeyBuilder->setType(TaxClassKey::TYPE_ID) + ->setValue($product->getTaxClassId())->create() + )->setTaxIncluded($priceIncludesTax) ->setType('product') ->setUnitPrice($price) ->create(); $quoteDetails = $this->quoteDetailsBuilder ->setShippingAddress($shippingAddressDataObject) ->setBillingAddress($billingAddressDataObject) - ->setCustomerTaxClassId($ctc) - ->setItems([$item]) + ->setCustomerTaxClassKey( + $this->taxClassKeyBuilder->setType(TaxClassKey::TYPE_ID) + ->setValue($ctc)->create() + )->setItems([$item]) ->create(); $storeId = null; diff --git a/app/code/Magento/Tax/Model/Calculation.php b/app/code/Magento/Tax/Model/Calculation.php index ab4fddc830125d79760597c6d8da93d13f248835..52e592ec26f74072539edd2c89d9138236151605 100644 --- a/app/code/Magento/Tax/Model/Calculation.php +++ b/app/code/Magento/Tax/Model/Calculation.php @@ -552,13 +552,15 @@ class Calculation extends \Magento\Framework\Model\AbstractModel break; } - if (is_null($customerTaxClass) && $customerId) { - $customerData = $this->customerAccountService->getCustomer($customerId); - $customerTaxClass = $this->_groupService->getGroup($customerData->getGroupId())->getTaxClassId(); - } elseif ($customerTaxClass === false && !$customerId) { - $customerTaxClass = $this->_groupService - ->getGroup(GroupServiceInterface::NOT_LOGGED_IN_ID) - ->getTaxClassId(); + if (is_null($customerTaxClass) || $customerTaxClass === false) { + if ($customerId) { + $customerData = $this->customerAccountService->getCustomer($customerId); + $customerTaxClass = $this->_groupService->getGroup($customerData->getGroupId())->getTaxClassId(); + } else { + $customerTaxClass = $this->_groupService->getGroup( + GroupServiceInterface::NOT_LOGGED_IN_ID + )->getTaxClassId(); + } } $request = new \Magento\Framework\Object(); @@ -639,49 +641,6 @@ class Calculation extends \Magento\Framework\Model\AbstractModel return $identical; } - /** - * Gets the tax rates by type - * - * @param \Magento\Framework\Object $request - * @param string|array $fieldName - * @param string|array $type - * @return array - */ - protected function _getRates($request, $fieldName, $type) - { - $result = array(); - /** @var $classes \Magento\Tax\Model\Resource\TaxClass\Collection */ - $classes = $this->_classesFactory->create(); - $classes->addFieldToFilter('class_type', $type)->load(); - foreach ($classes as $class) { - $request->setData($fieldName, $class->getId()); - $result[$class->getId()] = $this->getRate($request); - } - return $result; - } - - /** - * Gets rates for all the product tax classes - * - * @param \Magento\Framework\Object $request - * @return array - */ - public function getRatesForAllProductTaxClasses($request) - { - return $this->_getRates($request, 'product_class_id', \Magento\Tax\Model\ClassModel::TAX_CLASS_TYPE_PRODUCT); - } - - /** - * Gets rates for all the customer tax classes - * - * @param \Magento\Framework\Object $request - * @return array - */ - public function getRatesForAllCustomerTaxClasses($request) - { - return $this->_getRates($request, 'customer_class_id', \Magento\Tax\Model\ClassModel::TAX_CLASS_TYPE_CUSTOMER); - } - /** * Get information about tax rates applied to request * diff --git a/app/code/Magento/Tax/Model/Calculation/AbstractAggregateCalculator.php b/app/code/Magento/Tax/Model/Calculation/AbstractAggregateCalculator.php new file mode 100644 index 0000000000000000000000000000000000000000..ecfbc2ef49f03161672373391ed7475c0b824f23 --- /dev/null +++ b/app/code/Magento/Tax/Model/Calculation/AbstractAggregateCalculator.php @@ -0,0 +1,187 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Tax\Model\Calculation; + +use Magento\Tax\Model\Calculation; +use Magento\Customer\Service\V1\Data\Address; +use Magento\Tax\Service\V1\Data\QuoteDetails\Item as QuoteDetailsItem; + +abstract class AbstractAggregateCalculator extends AbstractCalculator +{ + /** + * {@inheritdoc} + */ + protected function calculateWithTaxInPrice(QuoteDetailsItem $item, $quantity) + { + $taxRateRequest = $this->getAddressRateRequest()->setProductClassId( + $this->taxClassService->getTaxClassId($item->getTaxClassKey()) + ); + $rate = $this->calculationTool->getRate($taxRateRequest); + $storeRate = $storeRate = $this->calculationTool->getStoreRate($taxRateRequest, $this->storeId); + + // Calculate $rowTotalInclTax + $priceInclTax = $this->calculationTool->round($item->getUnitPrice()); + $rowTotalInclTax = $priceInclTax * $quantity; + if (!$this->isSameRateAsStore($rate, $storeRate)) { + $priceInclTax = $this->calculatePriceInclTax($priceInclTax, $storeRate, $rate); + $rowTotalInclTax = $priceInclTax * $quantity; + } + $rowTaxExact = $this->calculationTool->calcTaxAmount($rowTotalInclTax, $rate, true, false); + $rowTax = $this->roundAmount($rowTaxExact, $rate, true); + $rowTotal = $rowTotalInclTax - $rowTax; + $price = $this->calculationTool->round($rowTotal / $quantity); + + //Handle discount + $discountTaxCompensationAmount = 0; + $applyTaxAfterDiscount = $this->config->applyTaxAfterDiscount($this->storeId); + $discountAmount = $item->getDiscountAmount(); + if ($discountAmount && $applyTaxAfterDiscount) { + //TODO: handle originalDiscountAmount + $taxableAmount = max($rowTotalInclTax - $discountAmount, 0); + $rowTaxAfterDiscount = $this->calculationTool->calcTaxAmount( + $taxableAmount, + $rate, + true, + false + ); + $rowTaxAfterDiscount = $this->roundAmount( + $rowTaxAfterDiscount, + $rate, + true, + self::KEY_TAX_AFTER_DISCOUNT_DELTA_ROUNDING + ); + // Set discount tax compensation + $discountTaxCompensationAmount = $rowTax - $rowTaxAfterDiscount; + $rowTax = $rowTaxAfterDiscount; + } + + // Calculate applied taxes + /** @var \Magento\Tax\Service\V1\Data\TaxDetails\AppliedTax[] $appliedTaxes */ + $appliedTaxes = []; + $appliedRates = $this->calculationTool->getAppliedRates($taxRateRequest); + $appliedTaxes = $this->getAppliedTaxes($rowTax, $rate, $appliedRates); + + $this->taxDetailsItemBuilder->setCode($item->getCode()); + $this->taxDetailsItemBuilder->setType($item->getType()); + $this->taxDetailsItemBuilder->setRowTax($rowTax); + $this->taxDetailsItemBuilder->setPrice($price); + $this->taxDetailsItemBuilder->setPriceInclTax($priceInclTax); + $this->taxDetailsItemBuilder->setRowTotal($rowTotal); + $this->taxDetailsItemBuilder->setRowTotalInclTax($rowTotalInclTax); + $this->taxDetailsItemBuilder->setDiscountTaxCompensationAmount($discountTaxCompensationAmount); + $this->taxDetailsItemBuilder->setAssociatedItemCode($item->getAssociatedItemCode()); + $this->taxDetailsItemBuilder->setTaxPercent($rate); + $this->taxDetailsItemBuilder->setAppliedTaxes($appliedTaxes); + return $this->taxDetailsItemBuilder->create(); + } + + /** + * {@inheritdoc} + */ + protected function calculateWithTaxNotInPrice(QuoteDetailsItem $item, $quantity) + { + $taxRateRequest = $this->getAddressRateRequest()->setProductClassId( + $this->taxClassService->getTaxClassId($item->getTaxClassKey()) + ); + $rate = $this->calculationTool->getRate($taxRateRequest); + $appliedRates = $this->calculationTool->getAppliedRates($taxRateRequest); + + $applyTaxAfterDiscount = $this->config->applyTaxAfterDiscount($this->storeId); + $discountAmount = $item->getDiscountAmount(); + $discountTaxCompensationAmount = 0; + + // Calculate $rowTotal + $price = $this->calculationTool->round($item->getUnitPrice()); + $rowTotal = $price * $quantity; + $rowTaxes = []; + $rowTaxesBeforeDiscount = []; + $appliedTaxes = []; + //Apply each tax rate separately + foreach ($appliedRates as $appliedRate) { + $taxId = $appliedRate['id']; + $taxRate = $appliedRate['percent']; + $rowTaxPerRate = $this->calculationTool->calcTaxAmount($rowTotal, $taxRate, false, false); + $rowTaxPerRate = $this->roundAmount($rowTaxPerRate, $taxRate, false); + $rowTaxAfterDiscount = $rowTaxPerRate; + + //Handle discount + if ($discountAmount && $applyTaxAfterDiscount) { + //TODO: handle originalDiscountAmount + $taxableAmount = max($rowTotal - $discountAmount, 0); + $rowTaxAfterDiscount = $this->calculationTool->calcTaxAmount( + $taxableAmount, + $taxRate, + false, + false + ); + $rowTaxAfterDiscount = $this->roundAmount( + $rowTaxAfterDiscount, + $taxRate, + false, + self::KEY_TAX_AFTER_DISCOUNT_DELTA_ROUNDING + ); + } + $appliedTaxes[$taxId] = $this->getAppliedTax( + $rowTaxAfterDiscount, + $appliedRate + ); + + $rowTaxes[] = $rowTaxAfterDiscount; + $rowTaxesBeforeDiscount[] = $rowTaxPerRate; + } + $rowTax = array_sum($rowTaxes); + $rowTaxBeforeDiscount = array_sum($rowTaxesBeforeDiscount); + $rowTotalInclTax = $rowTotal + $rowTaxBeforeDiscount; + $priceInclTax = $this->calculationTool->round($rowTotalInclTax / $quantity); + + $this->taxDetailsItemBuilder->setCode($item->getCode()); + $this->taxDetailsItemBuilder->setType($item->getType()); + $this->taxDetailsItemBuilder->setRowTax($rowTax); + $this->taxDetailsItemBuilder->setPrice($price); + $this->taxDetailsItemBuilder->setPriceInclTax($priceInclTax); + $this->taxDetailsItemBuilder->setRowTotal($rowTotal); + $this->taxDetailsItemBuilder->setRowTotalInclTax($rowTotalInclTax); + $this->taxDetailsItemBuilder->setDiscountTaxCompensationAmount($discountTaxCompensationAmount); + $this->taxDetailsItemBuilder->setAssociatedItemCode($item->getAssociatedItemCode()); + $this->taxDetailsItemBuilder->setTaxPercent($rate); + $this->taxDetailsItemBuilder->setAppliedTaxes($appliedTaxes); + return $this->taxDetailsItemBuilder->create(); + } + + /** + * Round amount + * + * @param float $amount + * @param null|float $rate + * @param null|bool $direction + * @param string $type + * @return float + */ + abstract protected function roundAmount( + $amount, + $rate = null, + $direction = null, + $type = self::KEY_REGULAR_DELTA_ROUNDING + ); +} diff --git a/app/code/Magento/Tax/Model/Calculation/AbstractCalculator.php b/app/code/Magento/Tax/Model/Calculation/AbstractCalculator.php new file mode 100644 index 0000000000000000000000000000000000000000..922bdd04cee45c47dce9e9913b455cfb20ec43fd --- /dev/null +++ b/app/code/Magento/Tax/Model/Calculation/AbstractCalculator.php @@ -0,0 +1,441 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Tax\Model\Calculation; + +use Magento\Tax\Model\Calculation; +use Magento\Customer\Service\V1\Data\Address; +use Magento\Tax\Service\V1\Data\QuoteDetails\Item as QuoteDetailsItem; +use Magento\Tax\Service\V1\Data\QuoteDetails; +use Magento\Tax\Service\V1\Data\TaxDetails\ItemBuilder as TaxDetailsItemBuilder; +use Magento\Tax\Service\V1\Data\TaxDetails\Item as TaxDetailsItem; +use Magento\Tax\Service\V1\Data\TaxClassKey; +use \Magento\Tax\Service\V1\Data\TaxClass; +use Magento\Tax\Service\V1\TaxClassService; + +abstract class AbstractCalculator +{ + /**#@+ + * Constants for delta rounding key + */ + const KEY_REGULAR_DELTA_ROUNDING = 'regular'; + + const KEY_APPLIED_TAX_DELTA_ROUNDING = 'applied_tax_amount'; + + const KEY_TAX_AFTER_DISCOUNT_DELTA_ROUNDING = 'tax_after_discount'; + /**#@-*/ + + /** + * Tax details item builder + * + * @var TaxDetailsItemBuilder + */ + protected $taxDetailsItemBuilder; + + /** + * Tax calculation tool + * + * @var Calculation + */ + protected $calculationTool; + + /** + * Store id + * + * @var int + */ + protected $storeId; + + /** + * Customer tax class id + * + * @var int + */ + protected $customerTaxClassId; + + /** + * Customer id + * + * @var int + */ + protected $customerId; + + /** + * Shipping Address + * + * @var Address + */ + protected $shippingAddress; + + /** + * Billing Address + * + * @var Address + */ + protected $billingAddress; + + /** + * Tax configuration object + * + * @var \Magento\Tax\Model\Config + */ + protected $config; + + /** + * Address rate request + * + * Request object contain: + * country_id (->getCountryId()) + * region_id (->getRegionId()) + * postcode (->getPostcode()) + * customer_class_id (->getCustomerClassId()) + * store (->getStore()) + * + * @var \Magento\Framework\Object + */ + private $addressRateRequest = null; + + /** + * Rounding deltas for prices + * + * @var string[] + * example: + * [ + * 'type' => [ + * 'rate' => 'rounding delta', + * ], + * ] + */ + protected $roundingDeltas; + + /** + * Tax Class Service + * + * @var TaxClassService + */ + protected $taxClassService; + + /** + * Constructor + * + * @param TaxClassService $taxClassService + * @param TaxDetailsItemBuilder $taxDetailsItemBuilder + * @param Calculation $calculationTool + * @param \Magento\Tax\Model\Config $config + * @param int $storeId + * @param \Magento\Framework\Object $addressRateRequest + */ + public function __construct( + TaxClassService $taxClassService, + TaxDetailsItemBuilder $taxDetailsItemBuilder, + Calculation $calculationTool, + \Magento\Tax\Model\Config $config, + $storeId, + \Magento\Framework\Object $addressRateRequest = null + ) { + $this->taxClassService = $taxClassService; + $this->taxDetailsItemBuilder = $taxDetailsItemBuilder; + $this->calculationTool = $calculationTool; + $this->config = $config; + $this->storeId = $storeId; + $this->addressRateRequest = $addressRateRequest; + } + + /** + * Set billing address + * + * @param Address $billingAddress + * @return void + */ + public function setBillingAddress(Address $billingAddress) + { + $this->billingAddress = $billingAddress; + } + + /** + * Set shipping address + * + * @param Address $shippingAddress + * @return void + */ + public function setShippingAddress(Address $shippingAddress) + { + $this->shippingAddress = $shippingAddress; + } + + /** + * Set customer tax class id + * + * @param int $customerTaxClassId + * @return void + */ + public function setCustomerTaxClassId($customerTaxClassId) + { + $this->customerTaxClassId = $customerTaxClassId; + } + + /** + * Set customer id + * + * @param int $customerId + * @return void + */ + public function setCustomerId($customerId) + { + $this->customerId = $customerId; + } + + /** + * Calculate tax details for quote item with given quantity + * + * @param QuoteDetailsItem $item + * @param int $quantity + * @return TaxDetailsItem + */ + public function calculate(QuoteDetailsItem $item, $quantity) + { + if ($item->getTaxIncluded()) { + return $this->calculateWithTaxInPrice($item, $quantity); + } else { + return $this->calculateWithTaxNotInPrice($item, $quantity); + } + } + + /** + * Calculate tax details for quote item with tax in price with given quantity + * + * @param QuoteDetailsItem $item + * @param int $quantity + * @return TaxDetailsItem + */ + abstract protected function calculateWithTaxInPrice(QuoteDetailsItem $item, $quantity); + + /** + * Calculate tax details for quote item with tax not in price with given quantity + * + * @param QuoteDetailsItem $item + * @param int $quantity + * @return TaxDetailsItem + */ + abstract protected function calculateWithTaxNotInPrice(QuoteDetailsItem $item, $quantity); + + /** + * Get address rate request + * + * Request object contain: + * country_id (->getCountryId()) + * region_id (->getRegionId()) + * postcode (->getPostcode()) + * customer_class_id (->getCustomerClassId()) + * store (->getStore()) + * + * @return \Magento\Framework\Object + */ + protected function getAddressRateRequest() + { + if (null == $this->addressRateRequest) { + $this->addressRateRequest = $this->calculationTool->getRateRequest( + $this->shippingAddress, + $this->billingAddress, + $this->customerTaxClassId, + $this->storeId, + $this->customerId + ); + } + return $this->addressRateRequest; + } + + /** + * Check if tax rate is same as store tax rate + * + * @param float $rate + * @param float $storeRate + * @return bool + */ + protected function isSameRateAsStore($rate, $storeRate) + { + if ((bool)$this->config->crossBorderTradeEnabled($this->storeId)) { + return true; + } else { + return (abs($rate - $storeRate) < 0.00001); + } + } + + /** + * Create AppliedTax data object based applied tax rates and tax amount + * + * @param float $rowTax + * @param array $appliedRate + * example: + * [ + * 'id' => 'id', + * 'percent' => 7.5, + * 'rates' => [ + * 'code' => 'code', + * 'title' => 'title', + * 'percent' => 5.3, + * ], + * ] + * @return \Magento\Tax\Service\V1\Data\TaxDetails\AppliedTax + */ + protected function getAppliedTax($rowTax, $appliedRate) + { + $appliedTaxBuilder = $this->taxDetailsItemBuilder->getAppliedTaxBuilder(); + $appliedTaxRateBuilder = $appliedTaxBuilder->getAppliedTaxRateBuilder(); + $appliedTaxBuilder->setAmount($rowTax); + $appliedTaxBuilder->setPercent($appliedRate['percent']); + $appliedTaxBuilder->setTaxRateKey($appliedRate['id']); + + /** @var AppliedTaxRate[] $rateDataObjects */ + $rateDataObjects = []; + foreach ($appliedRate['rates'] as $rate) { + $appliedTaxRateBuilder->setPercent($rate['percent']); + $appliedTaxRateBuilder->setCode($rate['code']); + $appliedTaxRateBuilder->setTitle($rate['title']); + //Skipped position, priority and rule_id + $rateDataObjects[$rate['code']] = $appliedTaxRateBuilder->create(); + } + $appliedTaxBuilder->setRates($rateDataObjects); + $appliedTax = $appliedTaxBuilder->create(); + return $appliedTax; + } + + /** + * Create AppliedTax data object based on applied tax rates and tax amount + * + * @param float $rowTax + * @param float $totalTaxRate + * @param array $appliedRates May contain multiple tax rates when catalog price includes tax + * example: + * [ + * [ + * 'id' => 'id1', + * 'percent' => 7.5, + * 'rates' => [ + * 'code' => 'code1', + * 'title' => 'title1', + * 'percent' => 5.3, + * ], + * ], + * [ + * 'id' => 'id2', + * 'percent' => 8.5, + * 'rates' => [ + * 'code' => 'code2', + * 'title' => 'title2', + * 'percent' => 7.3, + * ], + * ], + * ] + * @return \Magento\Tax\Service\V1\Data\TaxDetails\AppliedTax[] + */ + protected function getAppliedTaxes($rowTax, $totalTaxRate, $appliedRates) + { + $appliedTaxBuilder = $this->taxDetailsItemBuilder->getAppliedTaxBuilder(); + $appliedTaxRateBuilder = $appliedTaxBuilder->getAppliedTaxRateBuilder(); + /** @var \Magento\Tax\Service\V1\Data\TaxDetails\AppliedTax[] $appliedTaxes */ + $appliedTaxes = []; + $totalAppliedAmount = 0; + foreach ($appliedRates as $appliedRate) { + if ($appliedRate['percent'] == 0) { + continue; + } + + $appliedAmount = $rowTax / $totalTaxRate * $appliedRate['percent']; + //Use delta rounding to split tax amounts for each tax rates between items + $appliedAmount = $this->deltaRound( + $appliedAmount, + $appliedRate['id'], + true, + self::KEY_APPLIED_TAX_DELTA_ROUNDING + ); + if ($totalAppliedAmount + $appliedAmount > $rowTax) { + $appliedAmount = $rowTax - $totalAppliedAmount; + } + $totalAppliedAmount += $appliedAmount; + + $appliedTaxBuilder->setAmount($appliedAmount); + $appliedTaxBuilder->setPercent($appliedRate['percent']); + $appliedTaxBuilder->setTaxRateKey($appliedRate['id']); + + /** @var AppliedTaxRate[] $rateDataObjects */ + $rateDataObjects = []; + foreach ($appliedRate['rates'] as $rate) { + $appliedTaxRateBuilder->setPercent($rate['percent']); + $appliedTaxRateBuilder->setCode($rate['code']); + $appliedTaxRateBuilder->setTitle($rate['title']); + //Skipped position, priority and rule_id + $rateDataObjects[$rate['code']] = $appliedTaxRateBuilder->create(); + } + $appliedTaxBuilder->setRates($rateDataObjects); + $appliedTax = $appliedTaxBuilder->create(); + $appliedTaxes[$appliedTax->getTaxRateKey()] = $appliedTax; + } + + return $appliedTaxes; + } + + /** + * Round price based on previous rounding operation delta + * + * @param float $price + * @param string $rate + * @param bool $direction + * @param string $type + * @return float + */ + protected function deltaRound($price, $rate, $direction, $type = self::KEY_REGULAR_DELTA_ROUNDING) + { + if ($price) { + $rate = (string)$rate; + $type = $type . $direction; + // initialize the delta to a small number to avoid non-deterministic behavior with rounding of 0.5 + $delta = isset($this->roundingDeltas[$type][$rate]) ? + $this->roundingDeltas[$type][$rate] : + 0.000001; + $price += $delta; + $roundPrice = $this->calculationTool->round($price); + $this->roundingDeltas[$type][$rate] = $price - $roundPrice; + $price = $roundPrice; + } + return $price; + } + + /** + * Given a store price that includes tax at the store rate, this function will back out the store's tax, and add in + * the customer's tax. Returns this new price which is the customer's price including tax. + * + * @param float $storePriceInclTax + * @param float $storeRate + * @param float $customerRate + * @return float + */ + protected function calculatePriceInclTax($storePriceInclTax, $storeRate, $customerRate) + { + $storeTax = $this->calculationTool->calcTaxAmount($storePriceInclTax, $storeRate, true, false); + $priceExclTax = $storePriceInclTax - $storeTax; + $customerTax = $this->calculationTool->calcTaxAmount($priceExclTax, $customerRate, false, false); + $customerPriceInclTax = $this->calculationTool->round($priceExclTax + $customerTax); + return $customerPriceInclTax; + } +} diff --git a/app/code/Magento/Tax/Model/Calculation/CalculatorFactory.php b/app/code/Magento/Tax/Model/Calculation/CalculatorFactory.php new file mode 100644 index 0000000000000000000000000000000000000000..b042d865a8b111aa03cd15a1f2bf14c43d6d0c6a --- /dev/null +++ b/app/code/Magento/Tax/Model/Calculation/CalculatorFactory.php @@ -0,0 +1,110 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Tax\Model\Calculation; + +use \Magento\Customer\Service\V1\Data\Address; + +class CalculatorFactory +{ + /** + * Identifier constant for unit based calculation + */ + const CALC_UNIT_BASE = 'UNIT_BASE_CALCULATION'; + + /** + * Identifier constant for row based calculation + */ + const CALC_ROW_BASE = 'ROW_BASE_CALCULATION'; + + /** + * Identifier constant for total based calculation + */ + const CALC_TOTAL_BASE = 'TOTAL_BASE_CALCULATION'; + + /** + * @var \Magento\Framework\ObjectManager + */ + protected $objectManager; + + /** + * Constructor + * + * @param \Magento\Framework\ObjectManager $objectManager + */ + public function __construct(\Magento\Framework\ObjectManager $objectManager) + { + $this->objectManager = $objectManager; + } + + /** + * Create new calculator + * + * @param string $type Type of calculator + * @param int $storeId + * @param Address $billingAddress + * @param Address $shippingAddress + * @param null|int $customerTaxClassId + * @param null|int $customerId + * @return \Magento\Tax\Model\Calculation\AbstractCalculator + * @throws \InvalidArgumentException + */ + public function create( + $type, + $storeId, + Address $billingAddress = null, + Address $shippingAddress = null, + $customerTaxClassId = null, + $customerId = null + ) { + switch ($type) { + case self::CALC_UNIT_BASE: + $className = 'Magento\Tax\Model\Calculation\UnitBaseCalculator'; + break; + case self::CALC_ROW_BASE: + $className = 'Magento\Tax\Model\Calculation\RowBaseCalculator'; + break; + case self::CALC_TOTAL_BASE: + $className = 'Magento\Tax\Model\Calculation\TotalBaseCalculator'; + break; + default: + throw new \InvalidArgumentException('Unknown calculation type: ' . $type); + } + /** @var \Magento\Tax\Model\Calculation\AbstractCalculator $calculator */ + $calculator = $this->objectManager->create($className, ['storeId' => $storeId]); + if (null != $shippingAddress) { + $calculator->setShippingAddress($shippingAddress); + } + if (null != $billingAddress) { + $calculator->setBillingAddress($billingAddress); + } + if (null != $customerTaxClassId) { + $calculator->setCustomerTaxClassId($customerTaxClassId); + } + if (null != $customerId) { + $calculator->setCustomerId($customerTaxClassId); + } + return $calculator; + } +} diff --git a/app/code/Magento/Tax/Model/Calculation/RowBaseCalculator.php b/app/code/Magento/Tax/Model/Calculation/RowBaseCalculator.php new file mode 100644 index 0000000000000000000000000000000000000000..a727a2de6552ff1a279dea852c0ccf280c8a31d4 --- /dev/null +++ b/app/code/Magento/Tax/Model/Calculation/RowBaseCalculator.php @@ -0,0 +1,39 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Tax\Model\Calculation; + +use Magento\Tax\Model\Calculation; +use Magento\Customer\Service\V1\Data\Address; +use Magento\Tax\Service\V1\Data\QuoteDetails\Item as QuoteDetailsItem; + +class RowBaseCalculator extends AbstractAggregateCalculator +{ + /** + * {@inheritdoc} + */ + protected function roundAmount($amount, $rate = null, $direction = null, $type = self::KEY_REGULAR_DELTA_ROUNDING) + { + return $this->calculationTool->round($amount); + } +} diff --git a/app/code/Magento/Tax/Model/Calculation/TotalBaseCalculator.php b/app/code/Magento/Tax/Model/Calculation/TotalBaseCalculator.php new file mode 100644 index 0000000000000000000000000000000000000000..f018a2f17f94f0e5c2d3e12688c6aa64b4237830 --- /dev/null +++ b/app/code/Magento/Tax/Model/Calculation/TotalBaseCalculator.php @@ -0,0 +1,39 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Tax\Model\Calculation; + +use Magento\Tax\Model\Calculation; +use Magento\Customer\Service\V1\Data\Address; +use Magento\Tax\Service\V1\Data\QuoteDetails\Item as QuoteDetailsItem; + +class TotalBaseCalculator extends AbstractAggregateCalculator +{ + /** + * {@inheritdoc} + */ + protected function roundAmount($amount, $rate = null, $direction = null, $type = self::KEY_REGULAR_DELTA_ROUNDING) + { + return $this->deltaRound($amount, $rate, $direction, $type); + } +} diff --git a/app/code/Magento/Tax/Model/Calculation/UnitBaseCalculator.php b/app/code/Magento/Tax/Model/Calculation/UnitBaseCalculator.php new file mode 100644 index 0000000000000000000000000000000000000000..f28de1c132647e5d8465aea2c4fdd24c19c27f8b --- /dev/null +++ b/app/code/Magento/Tax/Model/Calculation/UnitBaseCalculator.php @@ -0,0 +1,159 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Tax\Model\Calculation; + +use Magento\Tax\Model\Calculation; +use Magento\Customer\Service\V1\Data\Address; +use Magento\Tax\Service\V1\Data\QuoteDetails\Item as QuoteDetailsItem; + +class UnitBaseCalculator extends AbstractCalculator +{ + /** + * {@inheritdoc} + */ + protected function calculateWithTaxInPrice(QuoteDetailsItem $item, $quantity) + { + $taxRateRequest = $this->getAddressRateRequest()->setProductClassId( + $this->taxClassService->getTaxClassId($item->getTaxClassKey()) + ); + $rate = $this->calculationTool->getRate($taxRateRequest); + $storeRate = $storeRate = $this->calculationTool->getStoreRate($taxRateRequest, $this->storeId); + + // Calculate $priceInclTax + $priceInclTax = $this->calculationTool->round($item->getUnitPrice()); + if (!$this->isSameRateAsStore($rate, $storeRate)) { + $priceInclTax = $this->calculatePriceInclTax($priceInclTax, $storeRate, $rate); + } + $uniTax = $this->calculationTool->calcTaxAmount($priceInclTax, $rate, true, true); + $price = $priceInclTax - $uniTax; + + //Handle discount + $discountTaxCompensationAmount = 0; + $applyTaxAfterDiscount = $this->config->applyTaxAfterDiscount($this->storeId); + $discountAmount = $item->getDiscountAmount(); + if ($discountAmount && $applyTaxAfterDiscount) { + //TODO: handle originalDiscountAmount + $unitDiscountAmount = $discountAmount / $quantity; + $taxableAmount = max($priceInclTax - $unitDiscountAmount, 0); + $unitTaxAfterDiscount = $this->calculationTool->calcTaxAmount( + $taxableAmount, + $rate, + true, + true + ); + + // Set discount tax compensation + $unitDiscountTaxCompensationAmount = $uniTax - $unitTaxAfterDiscount; + $discountTaxCompensationAmount = $unitDiscountTaxCompensationAmount * $quantity; + $uniTax = $unitTaxAfterDiscount; + } + $rowTax = $uniTax * $quantity; + + // Calculate applied taxes + /** @var \Magento\Tax\Service\V1\Data\TaxDetails\AppliedTax[] $appliedTaxes */ + $appliedTaxes = []; + $appliedRates = $this->calculationTool->getAppliedRates($taxRateRequest); + $appliedTaxes = $this->getAppliedTaxes($rowTax, $rate, $appliedRates); + + $this->taxDetailsItemBuilder->setCode($item->getCode()); + $this->taxDetailsItemBuilder->setType($item->getType()); + $this->taxDetailsItemBuilder->setRowTax($rowTax); + $this->taxDetailsItemBuilder->setPrice($price); + $this->taxDetailsItemBuilder->setPriceInclTax($priceInclTax); + $this->taxDetailsItemBuilder->setRowTotal($price * $quantity); + $this->taxDetailsItemBuilder->setRowTotalInclTax($priceInclTax * $quantity); + $this->taxDetailsItemBuilder->setDiscountTaxCompensationAmount($discountTaxCompensationAmount); + $this->taxDetailsItemBuilder->setAssociatedItemCode($item->getAssociatedItemCode()); + $this->taxDetailsItemBuilder->setTaxPercent($rate); + $this->taxDetailsItemBuilder->setAppliedTaxes($appliedTaxes); + return $this->taxDetailsItemBuilder->create(); + } + + /** + * {@inheritdoc} + */ + protected function calculateWithTaxNotInPrice(QuoteDetailsItem $item, $quantity) + { + $taxRateRequest = $this->getAddressRateRequest()->setProductClassId( + $this->taxClassService->getTaxClassId($item->getTaxClassKey()) + ); + $rate = $this->calculationTool->getRate($taxRateRequest); + $appliedRates = $this->calculationTool->getAppliedRates($taxRateRequest); + + $applyTaxAfterDiscount = $this->config->applyTaxAfterDiscount($this->storeId); + $discountAmount = $item->getDiscountAmount(); + $discountTaxCompensationAmount = 0; + + // Calculate $price + $price = $this->calculationTool->round($item->getUnitPrice()); + $unitTaxes = []; + $unitTaxesBeforeDiscount = []; + $appliedTaxes = []; + //Apply each tax rate separately + foreach ($appliedRates as $appliedRate) { + $taxId = $appliedRate['id']; + $taxRate = $appliedRate['percent']; + $unitTaxPerRate = $this->calculationTool->calcTaxAmount($price, $taxRate, false); + $unitTaxAfterDiscount = $unitTaxPerRate; + + //Handle discount + if ($discountAmount && $applyTaxAfterDiscount) { + //TODO: handle originalDiscountAmount + $unitDiscountAmount = $discountAmount / $quantity; + $taxableAmount = max($price - $unitDiscountAmount, 0); + $unitTaxAfterDiscount = $this->calculationTool->calcTaxAmount( + $taxableAmount, + $taxRate, + false, + true + ); + } + $appliedTaxes[$taxId] = $this->getAppliedTax( + $unitTaxAfterDiscount * $quantity, + $appliedRate + ); + + $unitTaxes[] = $unitTaxAfterDiscount; + $unitTaxesBeforeDiscount[] = $unitTaxPerRate; + } + $unitTax = array_sum($unitTaxes); + $unitTaxBeforeDiscount = array_sum($unitTaxesBeforeDiscount); + + $rowTax = $unitTax * $quantity; + $priceInclTax = $price + $unitTaxBeforeDiscount; + + $this->taxDetailsItemBuilder->setCode($item->getCode()); + $this->taxDetailsItemBuilder->setType($item->getType()); + $this->taxDetailsItemBuilder->setRowTax($rowTax); + $this->taxDetailsItemBuilder->setPrice($price); + $this->taxDetailsItemBuilder->setPriceInclTax($priceInclTax); + $this->taxDetailsItemBuilder->setRowTotal($price * $quantity); + $this->taxDetailsItemBuilder->setRowTotalInclTax($priceInclTax * $quantity); + $this->taxDetailsItemBuilder->setDiscountTaxCompensationAmount($discountTaxCompensationAmount); + $this->taxDetailsItemBuilder->setAssociatedItemCode($item->getAssociatedItemCode()); + $this->taxDetailsItemBuilder->setTaxPercent($rate); + $this->taxDetailsItemBuilder->setAppliedTaxes($appliedTaxes); + return $this->taxDetailsItemBuilder->create(); + } +} diff --git a/app/code/Magento/Tax/Model/Observer.php b/app/code/Magento/Tax/Model/Observer.php index 494460f693dd9bbbd5a4c701c2c738367775d753..571b44e441e3cecaf1295d8d9c8691d60a64e34b 100644 --- a/app/code/Magento/Tax/Model/Observer.php +++ b/app/code/Magento/Tax/Model/Observer.php @@ -112,6 +112,14 @@ class Observer $order->setAppliedTaxes($taxes); $order->setConvertingFromQuote(true); } + + $itemAppliedTaxes = $address->getItemsAppliedTaxes(); + if (is_array($itemAppliedTaxes)) { + if (is_array($order->getItemAppliedTaxes())) { + $itemAppliedTaxes = array_merge($order->getItemAppliedTaxes(), $itemAppliedTaxes); + } + $order->setItemAppliedTaxes($itemAppliedTaxes); + } } /** @@ -128,7 +136,7 @@ class Observer return; } - $getTaxesForItems = $order->getQuote()->getTaxesForItems(); + $getTaxesForItems = $order->getItemAppliedTaxes(); $taxes = $order->getAppliedTaxes(); $ratesIdQuoteItemId = array(); @@ -139,18 +147,32 @@ class Observer foreach ($taxesArray as $rates) { if (count($rates['rates']) == 1) { $ratesIdQuoteItemId[$rates['id']][] = array( - 'id' => $quoteItemId, + 'id' => $rates['item_id'], 'percent' => $rates['percent'], - 'code' => $rates['rates'][0]['code'] + 'code' => $rates['rates'][0]['code'], + 'associated_item_id' => $rates['associated_item_id'], + 'item_type' => $rates['item_type'], + 'amount' => $rates['amount'], + 'base_amount' => $rates['base_amount'], + 'real_amount' => $rates['amount'], + 'real_base_amount' => $rates['base_amount'], ); } else { $percentDelta = $rates['percent']; $percentSum = 0; foreach ($rates['rates'] as $rate) { + $real_amount = $rates['amount'] * $rate['percent'] / $rates['percent']; + $real_base_amount = $rates['base_amount'] * $rate['percent'] / $rates['percent']; $ratesIdQuoteItemId[$rates['id']][] = array( - 'id' => $quoteItemId, + 'id' => $rates['item_id'], 'percent' => $rate['percent'], - 'code' => $rate['code'] + 'code' => $rate['code'], + 'associated_item_id' => $rates['associated_item_id'], + 'item_type' => $rates['item_type'], + 'amount' => $rates['amount'], + 'base_amount' => $rates['base_amount'], + 'real_amount' => $real_amount, + 'real_base_amount' => $real_base_amount, ); $percentSum += $rate['percent']; } @@ -202,17 +224,32 @@ class Observer if (isset($ratesIdQuoteItemId[$id])) { foreach ($ratesIdQuoteItemId[$id] as $quoteItemId) { if ($quoteItemId['code'] == $tax['code']) { - $item = $order->getItemByQuoteItemId($quoteItemId['id']); - if ($item) { - $data = array( - 'item_id' => $item->getId(), - 'tax_id' => $result->getTaxId(), - 'tax_percent' => $quoteItemId['percent'] - ); - /** @var $taxItem \Magento\Tax\Model\Sales\Order\Tax\Item */ - $taxItem = $this->_taxItemFactory->create(); - $taxItem->setData($data)->save(); + $itemId = null; + $associatedItemId = null; + if (isset($quoteItemId['id'])) { + //This is a product item + $item = $order->getItemByQuoteItemId($quoteItemId['id']); + $itemId = $item->getId(); + } elseif (isset($quoteItemId['associated_item_id'])) { + //This item is associated with a product item + $item = $order->getItemByQuoteItemId($quoteItemId['associated_item_id']); + $associatedItemId = $item->getId(); } + + $data = array( + 'item_id' => $itemId, + 'tax_id' => $result->getTaxId(), + 'tax_percent' => $quoteItemId['percent'], + 'associated_item_id' => $associatedItemId, + 'amount' => $quoteItemId['amount'], + 'base_amount' => $quoteItemId['base_amount'], + 'real_amount' => $quoteItemId['real_amount'], + 'real_base_amount' => $quoteItemId['real_base_amount'], + 'taxable_item_type' => $quoteItemId['item_type'], + ); + /** @var $taxItem \Magento\Tax\Model\Sales\Order\Tax\Item */ + $taxItem = $this->_taxItemFactory->create(); + $taxItem->setData($data)->save(); } } } diff --git a/app/code/Magento/Tax/Model/Sales/Total/Quote/CommonTaxCollector.php b/app/code/Magento/Tax/Model/Sales/Total/Quote/CommonTaxCollector.php new file mode 100644 index 0000000000000000000000000000000000000000..a888602de26d3f67901f0e7f52b4334053332f70 --- /dev/null +++ b/app/code/Magento/Tax/Model/Sales/Total/Quote/CommonTaxCollector.php @@ -0,0 +1,819 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Tax\Model\Sales\Total\Quote; + +use Magento\Store\Model\Store; +use Magento\Sales\Model\Quote\Address; +use Magento\Sales\Model\Quote\Address\Total\AbstractTotal; +use Magento\Tax\Model\Calculation; +use Magento\Sales\Model\Quote\Item\AbstractItem; +use Magento\Customer\Service\V1\Data\AddressBuilder; +use Magento\Tax\Service\V1\Data\QuoteDetailsBuilder; +use Magento\Tax\Service\V1\Data\QuoteDetails\ItemBuilder; +use Magento\Tax\Service\V1\Data\QuoteDetails\Item as ItemDataObject; +use Magento\Tax\Service\V1\Data\TaxClassKey; +use Magento\Tax\Service\V1\Data\TaxDetails; +use Magento\Tax\Service\V1\Data\QuoteDetails; +use Magento\Tax\Service\V1\Data\TaxDetails\Item as ItemTaxDetails; +use Magento\Framework\Object; + +/** + * Tax totals calculation model + */ +class CommonTaxCollector extends AbstractTotal +{ + /**#@+ + * Constants defined for type of items + */ + const ITEM_TYPE_SHIPPING = 'shipping'; + const ITEM_TYPE_PRODUCT = 'product'; + /**#@-*/ + + /** + * Constant for shipping item code + */ + const ITEM_CODE_SHIPPING = 'shipping'; + + /**#@+ + * Constants for array keys + */ + const KEY_ITEM = 'item'; + const KEY_BASE_ITEM = 'base_item'; + /**#@-*/ + + /**#@+ + * Constants for fields in associated taxables array + */ + const KEY_ASSOCIATED_TAXABLE_TYPE = 'type'; + const KEY_ASSOCIATED_TAXABLE_CODE = 'code'; + const KEY_ASSOCIATED_TAXABLE_UNIT_PRICE = 'unit_price'; + const KEY_ASSOCIATED_TAXABLE_BASE_UNIT_PRICE = 'base_unit_price'; + const KEY_ASSOCIATED_TAXABLE_QUANTITY = 'quantity'; + const KEY_ASSOCIATED_TAXABLE_TAX_CLASS_ID = 'tax_class_id'; + const KEY_ASSOCIATED_TAXABLE_PRICE_INCLUDES_TAX = 'price_includes_tax'; + const KEY_ASSOCIATED_TAXABLE_ASSOCIATION_ITEM_CODE = 'associated_item_code'; + /**#@-*/ + + /** + * When an extra taxable item is associated with quote and not with an item, this value + * is used as associated item code + */ + const ASSOCIATION_ITEM_CODE_FOR_QUOTE = 'quote'; + + /**#@+ + * Constants for fields in tax details for associated taxable items + */ + const KEY_TAX_DETAILS_TYPE = 'type'; + const KEY_TAX_DETAILS_CODE = 'code'; + const KEY_TAX_DETAILS_PRICE_EXCL_TAX = 'price_excl_tax'; + const KEY_TAX_DETAILS_BASE_PRICE_EXCL_TAX = 'base_price_excl_tax'; + const KEY_TAX_DETAILS_PRICE_INCL_TAX = 'price_incl_tax'; + const KEY_TAX_DETAILS_BASE_PRICE_INCL_TAX = 'base_price_incl_tax'; + const KEY_TAX_DETAILS_ROW_TOTAL = 'row_total_excl_tax'; + const KEY_TAX_DETAILS_BASE_ROW_TOTAL = 'base_row_total_excl_tax'; + const KEY_TAX_DETAILS_ROW_TOTAL_INCL_TAX = 'row_total_incl_tax'; + const KEY_TAX_DETAILS_BASE_ROW_TOTAL_INCL_TAX = 'base_row_total_incl_tax'; + const KEY_TAX_DETAILS_TAX_PERCENT = 'tax_percent'; + const KEY_TAX_DETAILS_ROW_TAX = 'row_tax'; + const KEY_TAX_DETAILS_BASE_ROW_TAX = 'base_row_tax'; + const KEY_TAX_DETAILS_APPLIED_TAXES = 'applied_taxes'; + /**#@-*/ + + /** + * Static counter + * + * @var int + */ + protected static $counter = 0; + + /** + * Tax configuration object + * + * @var \Magento\Tax\Model\Config + */ + protected $_config; + + /** + * @var Store + */ + protected $_store; + + /** + * Tax calculation service, the collector will call the service which performs the actual calculation + * + * @var \Magento\Tax\Service\V1\TaxCalculationService + */ + protected $taxCalculationService; + + /** + * Builder to create QuoteDetails as input to tax calculation service + * + * @var \Magento\Tax\Service\V1\Data\QuoteDetailsBuilder + */ + protected $quoteDetailsBuilder; + + /** + * Class constructor + * + * @param \Magento\Tax\Model\Config $taxConfig + * @param \Magento\Tax\Service\V1\TaxCalculationService $taxCalculationService + * @param \Magento\Tax\Service\V1\Data\QuoteDetailsBuilder $quoteDetailsBuilder + */ + public function __construct( + \Magento\Tax\Model\Config $taxConfig, + \Magento\Tax\Service\V1\TaxCalculationService $taxCalculationService, + \Magento\Tax\Service\V1\Data\QuoteDetailsBuilder $quoteDetailsBuilder + ) { + $this->taxCalculationService = $taxCalculationService; + $this->quoteDetailsBuilder = $quoteDetailsBuilder; + $this->_config = $taxConfig; + } + + /** + * Map Address to Address data object + * + * @param AddressBuilder $addressBuilder + * @param Address $address + * @return \Magento\Customer\Service\V1\Data\Address + */ + public function mapAddress(AddressBuilder $addressBuilder, Address $address) + { + $addressBuilder->setCountryId($address->getCountryId()); + $addressBuilder->setRegion( + $addressBuilder->getRegionBuilder() + ->setRegionId($address->getRegionId()) + ->create() + ); + $addressBuilder->setPostcode($address->getPostcode()); + $addressBuilder->setCity($address->getCity()); + $addressBuilder->setStreet($address->getStreet()); + + return $addressBuilder->create(); + } + + /** + * Increment and return static counter. This function is intended to be used to generate temporary + * id for an item. + * + * @return int + */ + protected function getNextIncrement() + { + return ++self::$counter; + } + + /** + * Map an item to item data object + * + * @param ItemBuilder $itemBuilder + * @param AbstractItem $item + * @param bool $priceIncludesTax + * @param bool $useBaseCurrency + * @param string $parentCode + * @return ItemDataObject + */ + public function mapItem( + ItemBuilder $itemBuilder, + AbstractItem $item, + $priceIncludesTax, + $useBaseCurrency, + $parentCode = null + ) { + if (!$item->getTaxCalculationItemId()) { + $sequence = 'sequence-' . $this->getNextIncrement(); + $item->setTaxCalculationItemId($sequence); + } + $itemBuilder->setCode($item->getTaxCalculationItemId()); + $itemBuilder->setQuantity($item->getQty()); + $itemBuilder->setTaxClassKey( + $itemBuilder->getTaxClassKeyBuilder() + ->setType(TaxClassKey::TYPE_ID) + ->setValue($item->getProduct()->getTaxClassId()) + ->create() + ); + + $itemBuilder->setTaxIncluded($priceIncludesTax); + $itemBuilder->setType(self::ITEM_TYPE_PRODUCT); + + if ($useBaseCurrency) { + if (!$item->getBaseTaxCalculationPrice()) { + $item->setBaseTaxCalculationPrice($item->getBaseCalculationPriceOriginal()); + } + $itemBuilder->setUnitPrice($item->getBaseTaxCalculationPrice()); + $itemBuilder->setDiscountAmount($item->getBaseDiscountAmount()); + } else { + if (!$item->getTaxCalculationPrice()) { + $item->setTaxCalculationPrice($item->getCalculationPriceOriginal()); + } + $itemBuilder->setUnitPrice($item->getTaxCalculationPrice()); + $itemBuilder->setDiscountAmount($item->getDiscountAmount()); + } + + $itemBuilder->setParentCode($parentCode); + + return $itemBuilder->create(); + } + + /** + * Map item extra taxables + * + * @param ItemBuilder $itemBuilder + * @param AbstractItem $item + * @param bool $priceIncludesTax + * @param bool $useBaseCurrency + * @return ItemDataObject[] + */ + public function mapItemExtraTaxables( + ItemBuilder $itemBuilder, + AbstractItem $item, + $priceIncludesTax, + $useBaseCurrency + ) { + $itemDataObjects = []; + $extraTaxables = $item->getAssociatedTaxables(); + if (!$extraTaxables) { + return []; + } + + foreach ($extraTaxables as $extraTaxable) { + $extraTaxableIncludesTax = + isset($extraTaxable['price_includes_tax']) ? $extraTaxable['price_includes_tax'] : $priceIncludesTax; + + $itemBuilder->setCode($extraTaxable[self::KEY_ASSOCIATED_TAXABLE_CODE]); + $itemBuilder->setType($extraTaxable[self::KEY_ASSOCIATED_TAXABLE_TYPE]); + $itemBuilder->setQuantity($extraTaxable[self::KEY_ASSOCIATED_TAXABLE_QUANTITY]); + $itemBuilder->setTaxClassKey( + $itemBuilder->getTaxClassKeyBuilder() + ->setType(TaxClassKey::TYPE_ID) + ->setValue($extraTaxable[self::KEY_ASSOCIATED_TAXABLE_TAX_CLASS_ID]) + ->create() + ); + if ($useBaseCurrency) { + $unitPrice = $extraTaxable[self::KEY_ASSOCIATED_TAXABLE_BASE_UNIT_PRICE]; + } else { + $unitPrice = $extraTaxable[self::KEY_ASSOCIATED_TAXABLE_UNIT_PRICE]; + } + $itemBuilder->setUnitPrice($unitPrice); + $itemBuilder->setTaxIncluded($extraTaxableIncludesTax); + $itemBuilder->setAssociatedItemCode($item->getTaxCalculationItemId()); + $itemDataObjects[] = $itemBuilder->create(); + } + + return $itemDataObjects; + } + + /** + * Add quote items to quoteDetailsBuilder + * + * @param Address $address + * @param bool $useBaseCurrency + * @param bool $priceIncludesTax + * @return ItemDataObject[] + */ + public function mapItems( + Address $address, + $priceIncludesTax, + $useBaseCurrency + ) { + $items = $this->_getAddressItems($address); + if (!count($items)) { + return []; + } + + //Populate with items + $itemBuilder = $this->quoteDetailsBuilder->getItemBuilder(); + $itemDataObjects = []; + foreach ($items as $item) { + if ($item->getParentItem()) { + continue; + } + + if ($item->getHasChildren() && $item->isChildrenCalculated()) { + $parentItemDataObject = $this->mapItem($itemBuilder, $item, $priceIncludesTax, $useBaseCurrency); + $itemDataObjects[] = $parentItemDataObject; + foreach ($item->getChildren() as $child) { + $childItemDataObject = $this->mapItem( + $itemBuilder, + $child, + $priceIncludesTax, + $useBaseCurrency, + $parentItemDataObject->getCode() + ); + $itemDataObjects[] = $childItemDataObject; + $extraTaxableItems = $this->mapItemExtraTaxables( + $itemBuilder, + $item, + $priceIncludesTax, + $useBaseCurrency + ); + $itemDataObjects = array_merge($itemDataObjects, $extraTaxableItems); + } + } else { + $itemDataObject = $this->mapItem($itemBuilder, $item, $priceIncludesTax, $useBaseCurrency); + $itemDataObjects[] = $itemDataObject; + $extraTaxableItems = $this->mapItemExtraTaxables( + $itemBuilder, + $item, + $priceIncludesTax, + $useBaseCurrency + ); + $itemDataObjects = array_merge($itemDataObjects, $extraTaxableItems); + } + } + + return $itemDataObjects; + } + + /** + * Populate the quote details builder with address information + * + * @param QuoteDetailsBuilder $quoteDetailsBuilder + * @param Address $address + * @return QuoteDetailsBuilder + */ + public function populateAddressData(QuoteDetailsBuilder $quoteDetailsBuilder, Address $address) + { + $addressBuilder = $this->quoteDetailsBuilder->getAddressBuilder(); + + //Set billing address + $this->quoteDetailsBuilder->setBillingAddress( + $this->mapAddress($addressBuilder, $address->getQuote()->getBillingAddress()) + ); + //Set shipping address + $this->quoteDetailsBuilder->setShippingAddress( + $this->mapAddress($addressBuilder, $address) + ); + + return $quoteDetailsBuilder; + } + + /** + * @param Address $address + * @param bool $useBaseCurrency + * @return \Magento\Tax\Service\V1\Data\QuoteDetails\Item + */ + public function getShippingDataObject(Address $address, $useBaseCurrency) + { + if (!$address->getShippingTaxCalculationAmount() || $address->getShippingTaxCalculationAmount() <= 0) { + //Save the original shipping amount because shipping amount will be overridden + //with shipping amount excluding tax + $address->setShippingTaxCalculationAmount($address->getShippingAmount()); + $address->setBaseShippingTaxCalculationAmount($address->getBaseShippingAmount()); + } + if ($address->getShippingTaxCalculationAmount() > 0) { + $itemBuilder = $this->quoteDetailsBuilder->getItemBuilder(); + $itemBuilder->setType(self::ITEM_TYPE_SHIPPING); + $itemBuilder->setCode(self::ITEM_CODE_SHIPPING); + $itemBuilder->setQuantity(1); + if ($useBaseCurrency) { + $itemBuilder->setUnitPrice($address->getBaseShippingTaxCalculationAmount()); + } else { + $itemBuilder->setUnitPrice($address->getShippingTaxCalculationAmount()); + } + if ($address->getShippingDiscountAmount()) { + if ($useBaseCurrency) { + $itemBuilder->setDiscountAmount($address->getBaseShippingDiscountAmount()); + } else { + $itemBuilder->setDiscountAmount($address->getShippingDiscountAmount()); + } + } + $itemBuilder->setTaxClassKey( + $itemBuilder->getTaxClassKeyBuilder() + ->setType(TaxClassKey::TYPE_ID) + ->setValue($this->_config->getShippingTaxClass($this->_store)) + ->create() + ); + $itemBuilder->setTaxIncluded($this->_config->shippingPriceIncludesTax($this->_store)); + return $itemBuilder->create(); + } + return null; + } + + /** + * Populate QuoteDetails object from Address object + * + * @param Address $address + * @param ItemDataObject[] $itemDataObjects + * @return \Magento\Tax\Service\V1\Data\QuoteDetails + */ + protected function prepareQuoteDetails(Address $address, $itemDataObjects) + { + $items = $this->_getAddressItems($address); + if (!count($items)) { + return $this->quoteDetailsBuilder->create(); + } + + $this->populateAddressData($this->quoteDetailsBuilder, $address); + + //Set customer tax class + $this->quoteDetailsBuilder->setCustomerTaxClassKey( + $this->quoteDetailsBuilder->getTaxClassKeyBuilder() + ->setType(TaxClassKey::TYPE_ID) + ->setValue($address->getQuote()->getCustomerTaxClassId()) + ->create() + ); + $this->quoteDetailsBuilder->setItems($itemDataObjects); + + $quoteDetails = $this->quoteDetailsBuilder->create(); + return $quoteDetails; + } + + /** + * Organize tax details by type and by item code + * + * @param TaxDetails $taxDetails + * @param TaxDetails $baseTaxDetails + * @return array + */ + protected function organizeItemTaxDetailsByType(TaxDetails $taxDetails, TaxDetails $baseTaxDetails) + { + /** @var \Magento\Tax\Service\V1\Data\TaxDetails\Item[] $keyedItems */ + $keyedItems = []; + foreach ($taxDetails->getItems() as $item) { + $keyedItems[$item->getCode()] = $item; + } + /** @var \Magento\Tax\Service\V1\Data\TaxDetails\Item[] $baseKeyedItems */ + $baseKeyedItems = []; + foreach ($baseTaxDetails->getItems() as $item) { + $baseKeyedItems[$item->getCode()] = $item; + } + + $itemsByType = []; + foreach ($keyedItems as $code => $item) { + $baseItem = $baseKeyedItems[$code]; + $itemType = $item->getType(); + $itemsByType[$itemType][$code] = [self::KEY_ITEM => $item, self::KEY_BASE_ITEM => $baseItem]; + } + + return $itemsByType; + } + + /** + * Process product items in the quote. + * Set the following aggregated values in the quote object: + * subtotal, subtotalInclTax, tax, hidden_tax, + * + * @param Address $address + * @param array $itemTaxDetails + * @return $this + */ + protected function processProductItems(Address $address, array $itemTaxDetails) + { + /** @var AbstractItem[] $keyedAddressItems */ + $keyedAddressItems = []; + foreach ($this->_getAddressItems($address) as $addressItem) { + $keyedAddressItems[$addressItem->getTaxCalculationItemId()] = $addressItem; + } + + $subtotal = $baseSubtotal = 0; + $hiddenTax = $baseHiddenTax = 0; + $tax = $baseTax = 0; + $subtotalInclTax = $baseSubtotalInclTax = 0; + + foreach ($itemTaxDetails as $code => $itemTaxDetail) { + /** @var ItemTaxDetails $taxDetail */ + $taxDetail = $itemTaxDetail[self::KEY_ITEM]; + /** @var ItemTaxDetails $baseTaxDetail */ + $baseTaxDetail = $itemTaxDetail[self::KEY_BASE_ITEM]; + $quoteItem = $keyedAddressItems[$code]; + $this->updateItemTaxInfo($quoteItem, $taxDetail, $baseTaxDetail); + + //Update aggregated values + if ($quoteItem->getHasChildren() && $quoteItem->isChildrenCalculated()) { + //avoid double counting + continue; + } + $subtotal += $taxDetail->getRowTotal(); + $baseSubtotal += $baseTaxDetail->getRowTotal(); + $hiddenTax += $taxDetail->getDiscountTaxCompensationAmount(); + $baseHiddenTax += $baseTaxDetail->getDiscountTaxCompensationAmount(); + $tax += $taxDetail->getRowTax(); + $baseTax += $baseTaxDetail->getRowTax(); + $subtotalInclTax += $taxDetail->getRowTotalInclTax(); + $baseSubtotalInclTax += $baseTaxDetail->getRowTotalInclTax(); + } + + //Set aggregated values + $address->setTotalAmount('subtotal', $subtotal); + $address->setBaseTotalAmount('subtotal', $baseSubtotal); + $address->setTotalAmount('tax', $tax); + $address->setBaseTotalAmount('tax', $baseTax); + $address->setTotalAmount('hidden_tax', $hiddenTax); + $address->setBaseTotalAmount('hidden_tax', $baseHiddenTax); + + $address->setSubtotalInclTax($subtotalInclTax); + $address->setBaseSubtotalInclTax($baseSubtotalInclTax); + + return $this; + } + + /** + * Process applied taxes for items and quote + * + * @param Address $address + * @param array $itemsByType + * @return $this + */ + protected function processAppliedTaxes(Address $address, Array $itemsByType) + { + $address->setAppliedTaxes([]); + $allAppliedTaxesArray = []; + + /** @var AbstractItem[] $keyedAddressItems */ + $keyedAddressItems = []; + foreach ($this->_getAddressItems($address) as $addressItem) { + $keyedAddressItems[$addressItem->getTaxCalculationItemId()] = $addressItem; + } + + foreach ($itemsByType as $itemType => $items) { + foreach ($items as $itemTaxCalculationId => $itemTaxDetails) { + /** @var ItemTaxDetails $taxDetails */ + $taxDetails = $itemTaxDetails[self::KEY_ITEM]; + $baseTaxDetails = $itemTaxDetails[self::KEY_BASE_ITEM]; + + $appliedTaxes = $taxDetails->getAppliedTaxes(); + $baseAppliedTaxes = $baseTaxDetails->getAppliedTaxes(); + + $itemType = $taxDetails->getType(); + $itemId = null; + $associatedItemId = null; + if ($itemType == self::ITEM_TYPE_PRODUCT) { + //Use item id instead of tax calculation id + $itemId = $keyedAddressItems[$itemTaxCalculationId]->getId(); + } else { + if ($taxDetails->getAssociatedItemCode() + && $taxDetails->getAssociatedItemCode() != self::ASSOCIATION_ITEM_CODE_FOR_QUOTE) { + //This item is associated with a product item + $associatedItemId = $keyedAddressItems[$taxDetails->getAssociatedItemCode()]->getId(); + } else { + //This item is associated with an order, e.g., shipping, etc. + $itemId = null; + } + } + $extraInfo = [ + 'item_id' => $itemId, + 'item_type' => $itemType, + 'associated_item_id' => $associatedItemId, + ]; + + $appliedTaxesArray = $this->convertAppliedTaxes($appliedTaxes, $baseAppliedTaxes, $extraInfo); + + if ($itemType == self::ITEM_TYPE_PRODUCT) { + $quoteItem = $keyedAddressItems[$itemTaxCalculationId]; + $quoteItem->setAppliedTaxes($appliedTaxesArray); + } + + $allAppliedTaxesArray[$itemTaxCalculationId] = $appliedTaxesArray; + + foreach ($appliedTaxesArray as $appliedTaxArray) { + $this->_saveAppliedTaxes( + $address, + [$appliedTaxArray], + $appliedTaxArray['amount'], + $appliedTaxArray['base_amount'], + $appliedTaxArray['percent'] + ); + } + } + } + + $address->setItemsAppliedTaxes($allAppliedTaxesArray); + + return $this; + } + + /** + * Update tax related fields for quote item + * + * @param AbstractItem $quoteItem + * @param ItemTaxDetails $itemTaxDetails + * @param ItemTaxDetails $baseItemTaxDetails + * @return $this + */ + public function updateItemTaxInfo($quoteItem, $itemTaxDetails, $baseItemTaxDetails) + { + //The price should be base price + $quoteItem->setPrice($baseItemTaxDetails->getPrice()); + $quoteItem->setConvertedPrice($itemTaxDetails->getPrice()); + $quoteItem->setPriceInclTax($itemTaxDetails->getPriceInclTax()); + $quoteItem->setRowTotal($itemTaxDetails->getRowTotal()); + $quoteItem->setRowTotalInclTax($itemTaxDetails->getRowTotalInclTax()); + $quoteItem->setTaxAmount($itemTaxDetails->getRowTax()); + $quoteItem->setTaxPercent($itemTaxDetails->getTaxPercent()); + $quoteItem->setHiddenTaxAmount($itemTaxDetails->getDiscountTaxCompensationAmount()); + + $quoteItem->setBasePrice($baseItemTaxDetails->getPrice()); + $quoteItem->setBasePriceInclTax($baseItemTaxDetails->getPriceInclTax()); + $quoteItem->setBaseRowTotal($baseItemTaxDetails->getRowTotal()); + $quoteItem->setBaseRowTotalInclTax($baseItemTaxDetails->getRowTotalInclTax()); + $quoteItem->setBaseTaxAmount($baseItemTaxDetails->getRowTax()); + $quoteItem->setTaxPercent($baseItemTaxDetails->getTaxPercent()); + $quoteItem->setBaseHiddenTaxAmount($baseItemTaxDetails->getDiscountTaxCompensationAmount()); + + //Set discount calculation price, this may be needed by discount collector + if ($this->_config->discountTax($this->_store)) { + $quoteItem->setDiscountCalculationPrice($itemTaxDetails->getPriceInclTax()); + $quoteItem->setBaseDiscountCalculationPrice($baseItemTaxDetails->getPriceInclTax()); + } else { + $quoteItem->setDiscountCalculationPrice($itemTaxDetails->getPrice()); + $quoteItem->setBaseDiscountCalculationPrice($baseItemTaxDetails->getPrice()); + } + + return $this; + } + + /** + * Update tax related fields for shipping + * + * @param Address $address + * @param \Magento\Tax\Service\V1\Data\TaxDetails\Item $shippingTaxDetails + * @param \Magento\Tax\Service\V1\Data\TaxDetails\Item $baseShippingTaxDetails + * @return $this + */ + protected function processShippingTaxInfo(Address $address, $shippingTaxDetails, $baseShippingTaxDetails) + { + $address->setTotalAmount('shipping', $shippingTaxDetails->getRowTotal()); + $address->setBaseTotalAmount('shipping', $baseShippingTaxDetails->getRowTotal()); + $address->setTotalAmount('shipping_hidden_tax', $shippingTaxDetails->getDiscountTaxCompensationAmount()); + $address->setBaseTotalAmount('shipping_hidden_tax', $baseShippingTaxDetails->getDiscountTaxCompensationAmount()); + + $address->setShippingInclTax($shippingTaxDetails->getRowTotalInclTax()); + $address->setBaseShippingInclTax($baseShippingTaxDetails->getRowTotalInclTax()); + $address->setShippingTaxAmount($shippingTaxDetails->getRowTax()); + $address->setBaseShippingTaxAmount($baseShippingTaxDetails->getRowTax()); + + //Add the shipping tax to total tax amount + $address->addTotalAmount('tax', $shippingTaxDetails->getRowTax()); + $address->addBaseTotalAmount('tax', $baseShippingTaxDetails->getRowTax()); + + if ($this->_config->discountTax($this->_store)) { + $address->setShippingAmountForDiscount($shippingTaxDetails->getRowTotalInclTax()); + $address->setBaseShippingAmountForDiscount($baseShippingTaxDetails->getRowTotalInclTax()); + } + + return $this; + } + + /** + * Convert appliedTax data object from tax calculation service to internal array format + * + * @param \Magento\Tax\Service\V1\Data\TaxDetails\AppliedTax[] $appliedTaxes + * @param \Magento\Tax\Service\V1\Data\TaxDetails\AppliedTax[] $baseAppliedTaxes + * @param array $extraInfo + * @return array + */ + public function convertAppliedTaxes($appliedTaxes, $baseAppliedTaxes, $extraInfo = []) + { + $appliedTaxesArray = []; + + if (!$appliedTaxes || !$baseAppliedTaxes) { + return $appliedTaxesArray; + } + + foreach ($appliedTaxes as $taxId => $appliedTax) { + $baseAppliedTax = $baseAppliedTaxes[$taxId]; + $rateDataObjects = $appliedTax->getRates(); + + $rates = []; + foreach ($rateDataObjects as $rateDataObject) { + $rates[] = [ + 'percent' => $rateDataObject->getPercent(), + 'code' => $rateDataObject->getCode(), + 'title' => $rateDataObject->getTitle(), + ]; + } + + $appliedTaxArray = [ + 'amount' => $appliedTax->getAmount(), + 'base_amount' => $baseAppliedTax->getAmount(), + 'percent' => $appliedTax->getPercent(), + 'id' => $appliedTax->getTaxRateKey(), + 'rates' => $rates, + ]; + if (!empty($extraInfo)) { + $appliedTaxArray = array_merge($appliedTaxArray, $extraInfo); + } + + $appliedTaxesArray[] = $appliedTaxArray; + } + + return $appliedTaxesArray; + } + + /** + * Collect applied tax rates information on address level + * + * @param Address $address + * @param array $applied + * @param float $amount + * @param float $baseAmount + * @param float $rate + * @return void + */ + protected function _saveAppliedTaxes( + Address $address, + $applied, + $amount, + $baseAmount, + $rate + ) { + $previouslyAppliedTaxes = $address->getAppliedTaxes(); + $process = count($previouslyAppliedTaxes); + + foreach ($applied as $row) { + if ($row['percent'] == 0) { + continue; + } + if (!isset($previouslyAppliedTaxes[$row['id']])) { + $row['process'] = $process; + $row['amount'] = 0; + $row['base_amount'] = 0; + $previouslyAppliedTaxes[$row['id']] = $row; + } + + if (!is_null($row['percent'])) { + $row['percent'] = $row['percent'] ? $row['percent'] : 1; + $rate = $rate ? $rate : 1; + + $appliedAmount = $amount / $rate * $row['percent']; + $baseAppliedAmount = $baseAmount / $rate * $row['percent']; + } else { + $appliedAmount = 0; + $baseAppliedAmount = 0; + foreach ($row['rates'] as $rate) { + $appliedAmount += $rate['amount']; + $baseAppliedAmount += $rate['base_amount']; + } + } + + if ($appliedAmount || $previouslyAppliedTaxes[$row['id']]['amount']) { + $previouslyAppliedTaxes[$row['id']]['amount'] += $appliedAmount; + $previouslyAppliedTaxes[$row['id']]['base_amount'] += $baseAppliedAmount; + } else { + unset($previouslyAppliedTaxes[$row['id']]); + } + } + $address->setAppliedTaxes($previouslyAppliedTaxes); + } + + /** + * Determine whether to include shipping in tax calculation + * + * @return bool + */ + protected function includeShipping() + { + return false; + } + + /** + * Determine whether to include item in tax calculation + * + * @return bool + */ + protected function includeItems() + { + return false; + } + + /** + * Determine whether to include item in tax calculation + * + * @return bool + */ + protected function includeExtraTax() + { + return false; + } + + /** + * Determine whether to save applied tax in address + * + * @return bool + */ + protected function saveAppliedTaxes() + { + return false; + } +} diff --git a/app/code/Magento/Tax/Model/Sales/Total/Quote/Shipping.php b/app/code/Magento/Tax/Model/Sales/Total/Quote/Shipping.php index cba13d0a9f95d5d3d7736dfa4c90fcc8f7f25e6b..ee8a2639c3c3377a92f8ffc1e4d6ee860ee9a083 100644 --- a/app/code/Magento/Tax/Model/Sales/Total/Quote/Shipping.php +++ b/app/code/Magento/Tax/Model/Sales/Total/Quote/Shipping.php @@ -26,33 +26,43 @@ namespace Magento\Tax\Model\Sales\Total\Quote; use Magento\Sales\Model\Quote\Address; use Magento\Tax\Model\Calculation; -class Shipping extends Tax +class Shipping extends CommonTaxCollector { /** - * {@inheritdoc} - */ - protected function includeShipping() - { - return true; - } - /** - * Override the behavior in Tax collector to not process extra subtotal amount to avoid double counting + * Collect tax totals for shipping. The result can be used to calculate discount on shipping * - * @return bool + * @param Address $address + * @return $this */ - protected function processExtraSubtotalAmount() + public function collect(Address $address) { - return false; - } + parent::collect($address); + $items = $this->_getAddressItems($address); + if (!$items) { + return $this; + } - /** - * Override the behavior in Tax collector to return empty array - * - * @param Address $address - * @return array - */ - public function fetch(Address $address) - { - return []; + //Add shipping + $shippingDataObject = $this->getShippingDataObject($address, false); + $baseShippingDataObject = $this->getShippingDataObject($address, true); + if ($shippingDataObject == null || $baseShippingDataObject == null) { + return $this; + } + + $quoteDetails = $this->prepareQuoteDetails($address, [$shippingDataObject]); + $taxDetails = $this->taxCalculationService + ->calculateTax($quoteDetails, $address->getQuote()->getStore()->getStoreId()); + + $baseQuoteDetails = $this->prepareQuoteDetails($address, [$baseShippingDataObject]); + $baseTaxDetails = $this->taxCalculationService + ->calculateTax($baseQuoteDetails, $address->getQuote()->getStore()->getStoreId()); + + $this->processShippingTaxInfo( + $address, + $taxDetails->getItems()[self::ITEM_CODE_SHIPPING], + $baseTaxDetails->getItems()[self::ITEM_CODE_SHIPPING] + ); + + return $this; } } diff --git a/app/code/Magento/Tax/Model/Sales/Total/Quote/Subtotal.php b/app/code/Magento/Tax/Model/Sales/Total/Quote/Subtotal.php index 80eae0d9f88964c02d7a363a9b312efbc90f19a9..b8398e81bbcea70a2e6c2be1632bba1a2a6d0f0f 100644 --- a/app/code/Magento/Tax/Model/Sales/Total/Quote/Subtotal.php +++ b/app/code/Magento/Tax/Model/Sales/Total/Quote/Subtotal.php @@ -31,37 +31,42 @@ use Magento\Sales\Model\Quote\Address; use Magento\Sales\Model\Quote\Item\AbstractItem; use Magento\Tax\Model\Calculation; -class Subtotal extends Tax +class Subtotal extends CommonTaxCollector { /** - * {@inheritdoc} + * Calculate tax on product items. The result will be used to determine shipping + * and discount later. + * + * @param Address $address + * @return $this */ - protected function includeShipping() + public function collect(Address $address) { - return false; - } + parent::collect($address); + $items = $this->_getAddressItems($address); + if (!$items) { + return $this; + } + $priceIncludesTax = $this->_config->priceIncludesTax($this->_store); - /** - * Override the behavior in Tax collector to not process extra subtotal amount to avoid double counting - * - * @return bool - */ - protected function processExtraSubtotalAmount() - { - $result = false; - return $result; - } + //Setup taxable items + $itemDataObjects = $this->mapItems($address, $priceIncludesTax, false); + $quoteDetails = $this->prepareQuoteDetails($address, $itemDataObjects); + $taxDetails = $this->taxCalculationService + ->calculateTax($quoteDetails, $address->getQuote()->getStore()->getStoreId()); - /** - * Override the behavior in Tax collector to return empty array - * - * @param Address $address - * @return array - */ - public function fetch(Address $address) - { - $result = []; - return $result; + $itemDataObjects = $this->mapItems($address, $priceIncludesTax, true); + $baseQuoteDetails = $this->prepareQuoteDetails($address, $itemDataObjects); + $baseTaxDetails = $this->taxCalculationService + ->calculateTax($baseQuoteDetails, $address->getQuote()->getStore()->getStoreId()); + + $itemsByType = $this->organizeItemTaxDetailsByType($taxDetails, $baseTaxDetails); + + if (isset($itemsByType[self::ITEM_TYPE_PRODUCT])) { + $this->processProductItems($address, $itemsByType[self::ITEM_TYPE_PRODUCT]); + } + + return $this; } } diff --git a/app/code/Magento/Tax/Model/Sales/Total/Quote/Tax.php b/app/code/Magento/Tax/Model/Sales/Total/Quote/Tax.php index 776f3d03952ecb3264d8fa28b262d9e19fbd3a25..25a3529507b9c12bbdc8704ef802e13f2c751b9a 100644 --- a/app/code/Magento/Tax/Model/Sales/Total/Quote/Tax.php +++ b/app/code/Magento/Tax/Model/Sales/Total/Quote/Tax.php @@ -32,25 +32,14 @@ use Magento\Customer\Service\V1\Data\AddressBuilder; use Magento\Tax\Service\V1\Data\QuoteDetailsBuilder; use Magento\Tax\Service\V1\Data\QuoteDetails\ItemBuilder; use Magento\Tax\Service\V1\Data\QuoteDetails\Item as ItemDataObject; +use Magento\Tax\Service\V1\Data\TaxClassKey; use Magento\Tax\Service\V1\Data\TaxDetails; /** * Tax totals calculation model */ -class Tax extends AbstractTotal +class Tax extends CommonTaxCollector { - /**#@+ - * Constants defined for type of items - */ - const SHIPPING_ITEM_TYPE = 'shipping'; - const PRODUCT_ITEM_TYPE = 'product'; - /**#@-*/ - - /** - * Constant for shipping item code - */ - const SHIPPING_ITEM_CODE = 'shipping'; - /** * Static counter * @@ -132,489 +121,171 @@ class Tax extends AbstractTotal if (!$items) { return $this; } - //Preparation for calling taxCalculationService with base currency - $quoteDetails = $this->prepareQuoteDetails($address, true); - $baseTaxDetailsBase = $this->taxCalculationService - ->calculateTax($quoteDetails, $address->getQuote()->getStore()->getStoreId()); + $baseTaxDetails = $this->getQuoteTaxDetails($address, true); + $taxDetails = $this->getQuoteTaxDetails($address, false); - //Preparation for calling taxCalculationService with display currency - $quoteDetails = $this->prepareQuoteDetails($address, false); + //Populate address and items with tax calculation results + $itemsByType = $this->organizeItemTaxDetailsByType($taxDetails, $baseTaxDetails); + if (isset($itemsByType[self::ITEM_TYPE_PRODUCT])) { + $this->processProductItems($address, $itemsByType[self::ITEM_TYPE_PRODUCT]); + } - $taxDetails = $this->taxCalculationService - ->calculateTax($quoteDetails, $address->getQuote()->getStore()->getStoreId()); + if (isset($itemsByType[self::ITEM_TYPE_SHIPPING])) { + $shippingTaxDetails = $itemsByType[self::ITEM_TYPE_SHIPPING][self::ITEM_CODE_SHIPPING][self::KEY_ITEM]; + $baseShippingTaxDetails = + $itemsByType[self::ITEM_TYPE_SHIPPING][self::ITEM_CODE_SHIPPING][self::KEY_BASE_ITEM]; + $this->processShippingTaxInfo($address, $shippingTaxDetails, $baseShippingTaxDetails); + } + //Process taxable items that are not product or shipping + $this->processExtraTaxables($address, $itemsByType); - //Populate address and items with tax calculation results - $this->updateTaxInfo($address, $taxDetails, $baseTaxDetailsBase); - - if ($this->processExtraSubtotalAmount()) { - $address->addTotalAmount('tax', $address->getExtraTaxAmount()); - $address->addBaseTotalAmount('tax', $address->getBaseExtraTaxAmount()); - $address->addTotalAmount('subtotal', $address->getExtraSubtotalAmount()); - $address->addBaseTotalAmount('subtotal', $address->getBaseExtraSubtotalAmount()); - $address->setSubtotalInclTax( - $address->getSubtotalInclTax() + $address->getExtraSubtotalAmount() + $address->getExtraTaxAmount() - ); - $address->setBaseSubtotalInclTax( - $address->getBaseSubtotalInclTax() + - $address->getBaseExtraSubtotalAmount() + - $address->getBaseExtraTaxAmount() - ); + //Save applied taxes for each item and the quote in aggregation + $this->processAppliedTaxes($address, $itemsByType); + + if ($this->includeExtraTax()) { + $this->_addAmount($address->getExtraTaxAmount()); + $this->_addBaseAmount($address->getBaseExtraTaxAmount()); } + return $this; } /** - * Populate QuoteDetails object from Address object + * Call tax calculation service to get tax details on the quote and items * * @param Address $address * @param bool $useBaseCurrency - * @return \Magento\Tax\Service\V1\Data\QuoteDetails + * @return TaxDetails */ - protected function prepareQuoteDetails(Address $address, $useBaseCurrency) + protected function getQuoteTaxDetails($address, $useBaseCurrency) { - $items = $this->_getAddressItems($address); - if (!count($items)) { - return $this->quoteDetailsBuilder->create(); - } - - $addressBuilder = $this->quoteDetailsBuilder->getAddressBuilder(); - - //Set billing address - $this->quoteDetailsBuilder->setBillingAddress( - $this->mapAddress($addressBuilder, $address->getQuote()->getBillingAddress()) - ); - //Set shipping address - $this->quoteDetailsBuilder->setShippingAddress( - $this->mapAddress($addressBuilder, $address) - ); - //Set customer tax class - $this->quoteDetailsBuilder->setCustomerTaxClassId($address->getQuote()->getCustomerTaxClassId()); - //Populate with items + //Setup taxable items $priceIncludesTax = $this->_config->priceIncludesTax($this->_store); - $itemBuilder = $this->quoteDetailsBuilder->getItemBuilder(); - $itemDataObjects = []; - foreach ($items as $item) { - if ($item->getParentItem()) { - continue; - } + $itemDataObjects = $this->mapItems($address, $priceIncludesTax, $useBaseCurrency); - if ($item->getHasChildren() && $item->isChildrenCalculated()) { - $parentItemDataObject = $this->mapItem($itemBuilder, $item, $priceIncludesTax, $useBaseCurrency); - $itemDataObjects[] = $parentItemDataObject; - foreach ($item->getChildren() as $child) { - $childItemDataObject = $this->mapItem( - $itemBuilder, - $child, - $priceIncludesTax, - $useBaseCurrency, - $parentItemDataObject->getCode() - ); - $itemDataObjects[] = $childItemDataObject; - } - } else { - $itemDataObject = $this->mapItem($itemBuilder, $item, $priceIncludesTax, $useBaseCurrency); - $itemDataObjects[] = $itemDataObject; - } + //Add shipping + $shippingDataObject = $this->getShippingDataObject($address, $useBaseCurrency); + if ($shippingDataObject != null) { + $itemDataObjects[] = $shippingDataObject; } - if ($this->includeShipping()) { - //Add shipping as an item - if (!$address->getShippingTaxCalculationAmount() || $address->getShippingTaxCalculationAmount() <= 0) { - //Save the original shipping amount because shipping amount will be overridden - //with shipping amount excluding tax - $address->setShippingTaxCalculationAmount($address->getShippingAmount()); - $address->setBaseShippingTaxCalculationAmount($address->getBaseShippingAmount()); - } - if ($address->getShippingTaxCalculationAmount() > 0) { - $itemBuilder->setType(self::SHIPPING_ITEM_TYPE); - $itemBuilder->setCode(self::SHIPPING_ITEM_CODE); - $itemBuilder->setQuantity(1); - if ($useBaseCurrency) { - $itemBuilder->setUnitPrice($address->getBaseShippingTaxCalculationAmount()); - } else { - $itemBuilder->setUnitPrice($address->getShippingTaxCalculationAmount()); - } - if ($address->getShippingDiscountAmount()) { - if ($useBaseCurrency) { - $itemBuilder->setDiscountAmount($address->getBaseShippingDiscountAmount()); - } else { - $itemBuilder->setDiscountAmount($address->getShippingDiscountAmount()); - } - } - $itemBuilder->setTaxClassId($this->_config->getShippingTaxClass($this->_store)); - $itemBuilder->setTaxIncluded($this->_config->shippingPriceIncludesTax($this->_store)); - $itemDataObjects[] = $itemBuilder->create(); - } + //process extra taxable items associated only with quote + $quoteExtraTaxables = $this->mapQuoteExtraTaxables( + $this->quoteDetailsBuilder->getItemBuilder(), + $address, + $useBaseCurrency + ); + if (!empty($quoteExtraTaxables)) { + $itemDataObjects = array_merge($itemDataObjects, $quoteExtraTaxables); } - $this->quoteDetailsBuilder->setItems($itemDataObjects); - $quoteDetails = $this->quoteDetailsBuilder->create(); - return $quoteDetails; - } + //Preparation for calling taxCalculationService + $quoteDetails = $this->prepareQuoteDetails($address, $itemDataObjects); - /** - * Map Address to Address data object - * - * @param AddressBuilder $addressBuilder - * @param Address $address - * @return \Magento\Customer\Service\V1\Data\Address - */ - protected function mapAddress(AddressBuilder $addressBuilder, Address $address) - { - $addressBuilder->setCountryId($address->getCountryId()); - $addressBuilder->setRegion( - $addressBuilder->getRegionBuilder() - ->setRegionId($address->getRegionId()) - ->create() - ); - $addressBuilder->setPostcode($address->getPostcode()); - $addressBuilder->setCity($address->getCity()); - $addressBuilder->setStreet($address->getStreet()); + $taxDetails = $this->taxCalculationService + ->calculateTax($quoteDetails, $address->getQuote()->getStore()->getStoreId()); - return $addressBuilder->create(); + return $taxDetails; } + /** - * Map an item to item data object + * Map extra taxables associated with quote * * @param ItemBuilder $itemBuilder - * @param AbstractItem $item - * @param bool $priceIncludesTax + * @param Address $address * @param bool $useBaseCurrency - * @param string $parentCode - * @return ItemDataObject + * @return ItemDataObject[] */ - protected function mapItem( + public function mapQuoteExtraTaxables( ItemBuilder $itemBuilder, - AbstractItem $item, - $priceIncludesTax, - $useBaseCurrency, - $parentCode = null + Address $address, + $useBaseCurrency ) { - if (!$item->getSequence()) { - $sequence = 'sequence-' . $this->getNextIncrement(); - $item->setSequence($sequence); - } - $itemBuilder->setCode($item->getSequence()); - $itemBuilder->setQuantity($item->getQty()); - $itemBuilder->setTaxClassId($item->getProduct()->getTaxClassId()); - - $itemBuilder->setTaxIncluded($priceIncludesTax); - $itemBuilder->setType('product'); //TODO: find a place to define constants - - if ($item->getParentItem()) { - $itemBuilder->setParentCode($item->getParentItem()->getId()); + $itemDataObjects = []; + $extraTaxables = $address->getAssociatedTaxables(); + if (!$extraTaxables) { + return []; } - if ($useBaseCurrency) { - if (!$item->getBaseTaxCalculationPrice()) { - $item->setBaseTaxCalculationPrice($item->getBaseCalculationPriceOriginal()); - } - $itemBuilder->setUnitPrice($item->getBaseTaxCalculationPrice()); - $itemBuilder->setDiscountAmount($item->getBaseDiscountAmount()); - } else { - if (!$item->getTaxCalculationPrice()) { - $item->setTaxCalculationPrice($item->getCalculationPriceOriginal()); + foreach ($extraTaxables as $extraTaxable) { + $itemBuilder->setCode($extraTaxable[self::KEY_ASSOCIATED_TAXABLE_CODE]); + $itemBuilder->setType($extraTaxable[self::KEY_ASSOCIATED_TAXABLE_TYPE]); + $itemBuilder->setQuantity($extraTaxable[self::KEY_ASSOCIATED_TAXABLE_QUANTITY]); + $itemBuilder->setTaxClassKey( + $itemBuilder->getTaxClassKeyBuilder() + ->setType(TaxClassKey::TYPE_ID) + ->setValue($extraTaxable[self::KEY_ASSOCIATED_TAXABLE_TAX_CLASS_ID]) + ->create() + ); + if ($useBaseCurrency) { + $unitPrice = $extraTaxable[self::KEY_ASSOCIATED_TAXABLE_BASE_UNIT_PRICE]; + } else { + $unitPrice = $extraTaxable[self::KEY_ASSOCIATED_TAXABLE_UNIT_PRICE]; } - $itemBuilder->setUnitPrice($item->getTaxCalculationPrice()); - $itemBuilder->setDiscountAmount($item->getDiscountAmount()); + $itemBuilder->setUnitPrice($unitPrice); + $itemBuilder->setTaxIncluded($extraTaxable[self::KEY_ASSOCIATED_TAXABLE_PRICE_INCLUDES_TAX]); + $itemBuilder->setAssociatedItemCode($extraTaxable[self::KEY_ASSOCIATED_TAXABLE_ASSOCIATION_ITEM_CODE]); + $itemDataObjects[] = $itemBuilder->create(); } - $itemBuilder->setParentCode($parentCode); - - return $itemBuilder->create(); + return $itemDataObjects; } /** - * Increment and return static counter - * - * @return int - */ - protected function getNextIncrement() - { - return ++self::$counter; - } - - /** - * Update item tax and prices from item tax details object from tax calculation service + * Process everything other than product or shipping, save the result in quote * * @param Address $address - * @param TaxDetails $taxDetails - * @param TaxDetails $baseTaxDetails + * @param array $itemsByType * @return $this */ - protected function updateTaxInfo(Address $address, TaxDetails $taxDetails, TaxDetails $baseTaxDetails) + protected function processExtraTaxables(Address $address, Array $itemsByType) { - $address->setAppliedTaxes([]); - /** @var \Magento\Tax\Service\V1\Data\TaxDetails\Item[] $keyedItems */ - $keyedItems = []; - foreach ($taxDetails->getItems() as $item) { - $keyedItems[$item->getCode()] = $item; - } - /** @var \Magento\Tax\Service\V1\Data\TaxDetails\Item[] $baseKeyedItems */ - $baseKeyedItems = []; - foreach ($baseTaxDetails->getItems() as $item) { - $baseKeyedItems[$item->getCode()] = $item; - } - - $appliedTaxesByItem = []; - - /** @var AbstractItem[] $keyedAddressItems */ - $keyedAddressItems = []; - foreach ($this->_getAddressItems($address) as $addressItem) { - $keyedAddressItems[$addressItem->getSequence()] = $addressItem; - } - - $subtotal = $baseSubtotal = 0; - $hiddenTax = $baseHiddenTax = 0; - $tax = $baseTax = 0; - $subtotalInclTax = $baseSubtotalInclTax = 0; - - foreach ($keyedItems as $code => $itemTaxDetails) { - $baseItemTaxDetails = $baseKeyedItems[$code]; - $type = $itemTaxDetails->getType(); - if ($type == self::PRODUCT_ITEM_TYPE) { - $quoteItem = $keyedAddressItems[$code]; - $this->updateItemTaxInfo($quoteItem, $itemTaxDetails, $baseItemTaxDetails); - - if ($quoteItem->getHasChildren() && $quoteItem->isChildrenCalculated()) { - //avoid double counting - continue; + $extraTaxableDetails = []; + foreach ($itemsByType as $itemType => $itemTaxDetails) { + if ($itemType != self::ITEM_TYPE_PRODUCT and $itemType != self::ITEM_TYPE_SHIPPING) { + foreach ($itemTaxDetails as $itemCode => $itemTaxDetail) { + /** @var ItemTaxDetails $taxDetails */ + $taxDetails = $itemTaxDetail[self::KEY_ITEM]; + /** @var ItemTaxDetails $baseTaxDetails */ + $baseTaxDetails = $itemTaxDetail[self::KEY_BASE_ITEM]; + + $appliedTaxes = $taxDetails->getAppliedTaxes(); + $baseAppliedTaxes = $baseTaxDetails->getAppliedTaxes(); + + $associatedItemCode = $taxDetails->getAssociatedItemCode(); + + $appliedTaxesArray = $this->convertAppliedTaxes($appliedTaxes, $baseAppliedTaxes); + $extraTaxableDetails[$itemType][$associatedItemCode][] = [ + self::KEY_TAX_DETAILS_TYPE => $taxDetails->getType(), + self::KEY_TAX_DETAILS_CODE => $taxDetails->getCode(), + self::KEY_TAX_DETAILS_PRICE_EXCL_TAX => $taxDetails->getPrice(), + self::KEY_TAX_DETAILS_PRICE_INCL_TAX => $taxDetails->getPriceInclTax(), + self::KEY_TAX_DETAILS_BASE_PRICE_EXCL_TAX => $baseTaxDetails->getPrice(), + self::KEY_TAX_DETAILS_BASE_PRICE_INCL_TAX => $baseTaxDetails->getPriceInclTax(), + self::KEY_TAX_DETAILS_ROW_TOTAL => $taxDetails->getRowTotal(), + self::KEY_TAX_DETAILS_ROW_TOTAL_INCL_TAX => $taxDetails->getRowTotalInclTax(), + self::KEY_TAX_DETAILS_BASE_ROW_TOTAL => $baseTaxDetails->getRowTotal(), + self::KEY_TAX_DETAILS_BASE_ROW_TOTAL_INCL_TAX => $baseTaxDetails->getRowTotalInclTax(), + self::KEY_TAX_DETAILS_TAX_PERCENT => $taxDetails->getTaxPercent(), + self::KEY_TAX_DETAILS_ROW_TAX => $taxDetails->getRowTax(), + self::KEY_TAX_DETAILS_BASE_ROW_TAX => $baseTaxDetails->getRowTax(), + self::KEY_TAX_DETAILS_APPLIED_TAXES => $appliedTaxesArray, + ]; + + $address->addTotalAmount('tax', $taxDetails->getRowTax()); + $address->addBaseTotalAmount('tax', $baseTaxDetails->getRowTax()); + //TODO: save applied taxes for the item } - $subtotal += $itemTaxDetails->getRowTotal(); - $baseSubtotal += $baseItemTaxDetails->getRowTotal(); - $hiddenTax += $itemTaxDetails->getDiscountTaxCompensationAmount(); - $baseHiddenTax += $baseItemTaxDetails->getDiscountTaxCompensationAmount(); - $tax += $itemTaxDetails->getRowTax(); - $baseTax += $baseItemTaxDetails->getRowTax(); - $subtotalInclTax += $itemTaxDetails->getRowTotalInclTax(); - $baseSubtotalInclTax += $baseItemTaxDetails->getRowTotalInclTax(); - - $appliedTaxes = $itemTaxDetails->getAppliedTaxes(); - $baseAppliedTaxes = $baseItemTaxDetails->getAppliedTaxes(); - $appliedTaxesArray = $this->convertAppliedTaxes($appliedTaxes, $baseAppliedTaxes); - - foreach ($appliedTaxesArray as $appliedTaxArray) { - $this->_saveAppliedTaxes( - $address, - [$appliedTaxArray], - $appliedTaxArray['amount'], - $appliedTaxArray['base_amount'], - $appliedTaxArray['percent'] - ); - } - - $appliedTaxesByItem[$quoteItem->getId()] = $appliedTaxesArray; - //Set applied tax for item - $quoteItem->setAppliedTaxes($appliedTaxesArray); } - $address->getQuote()->setTaxesForItems($appliedTaxesByItem); - } - - // Set item subtotals - $address->setTotalAmount('subtotal', $subtotal); - $address->setBaseTotalAmount('subtotal', $baseSubtotal); - - $address->setSubtotalInclTax($subtotalInclTax); - $address->setBaseSubtotalInclTax($baseSubtotalInclTax); - $address->setTotalAmount('hidden_tax', $hiddenTax); - $address->setBaseTotalAmount('hidden_tax', $baseHiddenTax); - - //Set shipping tax - if (isset($keyedItems[self::SHIPPING_ITEM_CODE]) && isset($baseKeyedItems[self::SHIPPING_ITEM_CODE])) { - $shippingItem = $keyedItems[self::SHIPPING_ITEM_CODE]; - $baseShippingItem = $baseKeyedItems[self::SHIPPING_ITEM_CODE]; - - $this->updateShippingTaxInfo($address, $shippingItem, $baseShippingItem); - - $tax += $shippingItem->getRowTax(); - $baseTax += $baseShippingItem->getRowTax(); - } - - $address->setTotalAmount('tax', $tax); - $address->setBaseTotalAmount('tax', $baseTax); - - return $this; - } - - /** - * Update tax related fields for quote item - * - * @param AbstractItem $quoteItem - * @param \Magento\Tax\Service\V1\Data\TaxDetails\Item $itemTaxDetails - * @param \Magento\Tax\Service\V1\Data\TaxDetails\Item $baseItemTaxDetails - * @return $this - */ - protected function updateItemTaxInfo($quoteItem, $itemTaxDetails, $baseItemTaxDetails) - { - //The price should be base price - $quoteItem->setPrice($baseItemTaxDetails->getPrice()); - $quoteItem->setConvertedPrice($itemTaxDetails->getPrice()); - $quoteItem->setPriceInclTax($itemTaxDetails->getPriceInclTax()); - $quoteItem->setRowTotal($itemTaxDetails->getRowTotal()); - $quoteItem->setRowTotalInclTax($itemTaxDetails->getRowTotalInclTax()); - $quoteItem->setTaxAmount($itemTaxDetails->getRowTax()); - $quoteItem->setTaxPercent($itemTaxDetails->getTaxPercent()); - $quoteItem->setHiddenTaxAmount($itemTaxDetails->getDiscountTaxCompensationAmount()); - - $quoteItem->setBasePrice($baseItemTaxDetails->getPrice()); - $quoteItem->setBasePriceInclTax($baseItemTaxDetails->getPriceInclTax()); - $quoteItem->setBaseRowTotal($baseItemTaxDetails->getRowTotal()); - $quoteItem->setBaseRowTotalInclTax($baseItemTaxDetails->getRowTotalInclTax()); - $quoteItem->setBaseTaxAmount($baseItemTaxDetails->getRowTax()); - $quoteItem->setTaxPercent($baseItemTaxDetails->getTaxPercent()); - $quoteItem->setBaseHiddenTaxAmount($baseItemTaxDetails->getDiscountTaxCompensationAmount()); - - //Set discount calculation price, this may be needed by discount collector - if ($this->_config->discountTax($this->_store)) { - $quoteItem->setDiscountCalculationPrice($itemTaxDetails->getPriceInclTax()); - $quoteItem->setBaseDiscountCalculationPrice($baseItemTaxDetails->getPriceInclTax()); - } else { - $quoteItem->setDiscountCalculationPrice($itemTaxDetails->getPrice()); - $quoteItem->setBaseDiscountCalculationPrice($baseItemTaxDetails->getPrice()); - - } - return $this; - } - - /** - * Update tax related fields for shipping - * - * @param Address $address - * @param \Magento\Tax\Service\V1\Data\TaxDetails\Item $shippingTaxDetails - * @param \Magento\Tax\Service\V1\Data\TaxDetails\Item $baseShippingTaxDetails - * @return $this - */ - protected function updateShippingTaxInfo(Address $address, $shippingTaxDetails, $baseShippingTaxDetails) - { - $address->setTotalAmount('shipping', $shippingTaxDetails->getRowTotal()); - $address->setBaseTotalAmount('shipping', $baseShippingTaxDetails->getRowTotal()); - $address->setShippingTaxAmount($shippingTaxDetails->getRowTax()); - $address->setBaseShippingTaxAmount($baseShippingTaxDetails->getRowTax()); - $address->setTotalAmount('shipping_hidden_tax', $shippingTaxDetails->getDiscountTaxCompensationAmount()); - $address->setBaseTotalAmount('shipping_hidden_tax', $baseShippingTaxDetails->getDiscountTaxCompensationAmount()); - - $address->setShippingInclTax($shippingTaxDetails->getRowTotalInclTax()); - $address->setBaseShippingInclTax($baseShippingTaxDetails->getRowTotalInclTax()); - - if ($this->_config->discountTax($this->_store)) { - $address->setShippingAmountForDiscount($shippingTaxDetails->getRowTotalInclTax()); - $address->setBaseShippingAmountForDiscount($baseShippingTaxDetails->getRowTotalInclTax()); } - //Add taxes applied to shipping to applied taxes - $appliedTaxes = $shippingTaxDetails->getAppliedTaxes(); - $baseAppliedTaxes = $baseShippingTaxDetails->getAppliedTaxes(); - $appliedTaxesArray = $this->convertAppliedTaxes($appliedTaxes, $baseAppliedTaxes); - $this->_saveAppliedTaxes( - $address, - $appliedTaxesArray, - $shippingTaxDetails->getRowTax(), - $baseShippingTaxDetails->getRowTax(), - $shippingTaxDetails->getTaxPercent() - ); - + $address->setExtraTaxableDetails($extraTaxableDetails); return $this; } - /** - * Convert appliedTax data object from tax calculation service to internal array format - * - * @param \Magento\Tax\Service\V1\Data\TaxDetails\AppliedTax[] $appliedTaxes - * @param \Magento\Tax\Service\V1\Data\TaxDetails\AppliedTax[] $baseAppliedTaxes - * @return array - */ - protected function convertAppliedTaxes($appliedTaxes, $baseAppliedTaxes) - { - $appliedTaxesArray = []; - - if (!$appliedTaxes || !$baseAppliedTaxes) { - return $appliedTaxesArray; - } - - foreach ($appliedTaxes as $taxId => $appliedTax) { - $baseAppliedTax = $baseAppliedTaxes[$taxId]; - $rateDataObjects = $appliedTax->getRates(); - - $rates = []; - foreach ($rateDataObjects as $rateDataObject) { - $rates[] = [ - 'percent' => $rateDataObject->getPercent(), - 'code' => $rateDataObject->getCode(), - 'title' => $rateDataObject->getTitle(), - ]; - } - - $appliedTaxesArray[] = [ - 'amount' => $appliedTax->getAmount(), - 'base_amount' => $baseAppliedTax->getAmount(), - 'percent' => $appliedTax->getPercent(), - 'id' => $appliedTax->getTaxRateKey(), - 'rates' => $rates, - ]; - } - - return $appliedTaxesArray; - } - - /** - * Collect applied tax rates information on address level - * - * @param Address $address - * @param array $applied - * @param float $amount - * @param float $baseAmount - * @param float $rate - * @return void - */ - protected function _saveAppliedTaxes( - Address $address, - $applied, - $amount, - $baseAmount, - $rate - ) { - $previouslyAppliedTaxes = $address->getAppliedTaxes(); - $process = count($previouslyAppliedTaxes); - - foreach ($applied as $row) { - if ($row['percent'] == 0) { - continue; - } - if (!isset($previouslyAppliedTaxes[$row['id']])) { - $row['process'] = $process; - $row['amount'] = 0; - $row['base_amount'] = 0; - $previouslyAppliedTaxes[$row['id']] = $row; - } - - if (!is_null($row['percent'])) { - $row['percent'] = $row['percent'] ? $row['percent'] : 1; - $rate = $rate ? $rate : 1; - - $appliedAmount = $amount / $rate * $row['percent']; - $baseAppliedAmount = $baseAmount / $rate * $row['percent']; - } else { - $appliedAmount = 0; - $baseAppliedAmount = 0; - foreach ($row['rates'] as $rate) { - $appliedAmount += $rate['amount']; - $baseAppliedAmount += $rate['base_amount']; - } - } - - if ($appliedAmount || $previouslyAppliedTaxes[$row['id']]['amount']) { - $previouslyAppliedTaxes[$row['id']]['amount'] += $appliedAmount; - $previouslyAppliedTaxes[$row['id']]['base_amount'] += $baseAppliedAmount; - } else { - unset($previouslyAppliedTaxes[$row['id']]); - } - } - $address->setAppliedTaxes($previouslyAppliedTaxes); - } - /** * Add tax totals information to address object * @@ -707,24 +378,4 @@ class Tax extends AbstractTotal { return __('Tax'); } - - /** - * Determine whether to include shipping in tax calculation - * - * @return bool - */ - protected function includeShipping() - { - return true; - } - - /** - * Return a flag to indicate whether to process extra subtotal field in the quote - * - * @return bool - */ - protected function processExtraSubtotalAmount() - { - return true; - } } diff --git a/app/code/Magento/Tax/Model/TaxClass/Source/Product.php b/app/code/Magento/Tax/Model/TaxClass/Source/Product.php index d4d7c9ff1e871e051587bccd9d607d4a590ae6d3..c102950e4a0d4bb5137b35434c2a37cfb49c723f 100644 --- a/app/code/Magento/Tax/Model/TaxClass/Source/Product.php +++ b/app/code/Magento/Tax/Model/TaxClass/Source/Product.php @@ -24,6 +24,7 @@ namespace Magento\Tax\Model\TaxClass\Source; +use Magento\Framework\DB\Ddl\Table; use Magento\Tax\Service\V1\Data\TaxClass; /** @@ -135,16 +136,20 @@ class Product extends \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource * * @return array */ - public function getFlatColums() + public function getFlatColumns() { $attributeCode = $this->getAttribute()->getAttributeCode(); - $column = array('unsigned' => true, 'default' => null, 'extra' => null); - $column['type'] = \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER; - $column['nullable'] = true; - $column['comment'] = $attributeCode . ' tax column'; - - return array($attributeCode => $column); + return [ + $attributeCode => [ + 'unsigned' => true, + 'default' => null, + 'extra' => null, + 'type' => Table::TYPE_INTEGER, + 'nullable' => true, + 'comment' => $attributeCode . ' tax column', + ], + ]; } /** diff --git a/app/code/Magento/Tax/Pricing/Price/Plugin/AttributePrice.php b/app/code/Magento/Tax/Pricing/Price/Plugin/AttributePrice.php index d5f511d5a4207cec1db555fd88e96ec55b4f7e96..6a9a0677a47a65424604a7507a998714a9cd5a14 100644 --- a/app/code/Magento/Tax/Pricing/Price/Plugin/AttributePrice.php +++ b/app/code/Magento/Tax/Pricing/Price/Plugin/AttributePrice.php @@ -34,20 +34,20 @@ class AttributePrice protected $taxHelper; /** - * @var \Magento\Tax\Model\Calculation + * @var \Magento\Tax\Service\V1\TaxCalculationServiceInterface */ - protected $calculation; + protected $taxCalculationService; /** * @param \Magento\Tax\Helper\Data $helper - * @param \Magento\Tax\Model\Calculation $calculation + * @param \Magento\Tax\Service\V1\TaxCalculationServiceInterface $taxCalculationService */ public function __construct( \Magento\Tax\Helper\Data $helper, - \Magento\Tax\Model\Calculation $calculation + \Magento\Tax\Service\V1\TaxCalculationServiceInterface $taxCalculationService ) { $this->taxHelper = $helper; - $this->calculation = $calculation; + $this->taxCalculationService = $taxCalculationService; } /** @@ -65,10 +65,16 @@ class AttributePrice $productClassId = $product->getTaxClassId(); - $defaultValue = $this->applyRate($productClassId, false, false, false, $result['customerId']); + $defaultValue = $this->taxCalculationService->getDefaultCalculatedRate( + $productClassId, + $result['customerId'] + ); $result['defaultTax'] = $defaultValue + $result['defaultTax']; - $currentTax = $this->applyRate($productClassId, null, null, null, $result['customerId']); + $currentTax = $this->taxCalculationService->getCalculatedRate( + $productClassId, + $result['customerId'] + ); $result['currentTax'] = $currentTax + $result['currentTax']; $adjustment = $product->getPriceInfo()->getAdjustment(\Magento\Tax\Pricing\Adjustment::ADJUSTMENT_CODE); @@ -78,32 +84,4 @@ class AttributePrice $result['showBothPrices'] = $this->taxHelper->displayBothPrices(); return $result; } - - /** - * Apply Tax Rate - * - * @param int $classId - * @param null $shippingAddress - * @param null $billingAddress - * @param null $customerTaxClass - * @param int|null $customerId - * @return float - */ - protected function applyRate( - $classId, - $shippingAddress = null, - $billingAddress = null, - $customerTaxClass = null, - $customerId = null - ) { - $rateRequest = $this->calculation->getRateRequest( - $shippingAddress, - $billingAddress, - $customerTaxClass, - null, - $customerId - ); - $rateRequest->setProductClassId($classId); - return $this->calculation->getRate($rateRequest); - } } diff --git a/app/code/Magento/Tax/Service/V1/Collection/TaxRuleCollection.php b/app/code/Magento/Tax/Service/V1/Collection/TaxRuleCollection.php index 384b30432f8388bf588bf33877aa0a7e03fe3160..46aa4d16183cc2e1e56a50a81b81b5baaf627758 100644 --- a/app/code/Magento/Tax/Service/V1/Collection/TaxRuleCollection.php +++ b/app/code/Magento/Tax/Service/V1/Collection/TaxRuleCollection.php @@ -99,7 +99,7 @@ class TaxRuleCollection extends AbstractServiceCollection /* should cast to string so that some optional fields won't be null on the collection grid pages */ $collectionItem->setPriority((string)$taxRule->getPriority()); $collectionItem->setPosition((string)$taxRule->getSortOrder()); - $collectionItem->setCalculateSubtotal((string)$taxRule->getCalculateSubtotal()); + $collectionItem->setCalculateSubtotal($taxRule->getCalculateSubtotal() ? '1' : '0'); $collectionItem->setCustomerTaxClasses($taxRule->getCustomerTaxClassIds()); $collectionItem->setProductTaxClasses($taxRule->getProductTaxClassIds()); $collectionItem->setTaxRates($taxRule->getTaxRateIds()); diff --git a/app/code/Magento/Tax/Service/V1/Data/QuoteDetails.php b/app/code/Magento/Tax/Service/V1/Data/QuoteDetails.php index 1411a71a06cd09626ae800b434e680741a849aea..4a928878af1f3328c1e6fdfcd848f6759c93b42e 100644 --- a/app/code/Magento/Tax/Service/V1/Data/QuoteDetails.php +++ b/app/code/Magento/Tax/Service/V1/Data/QuoteDetails.php @@ -33,7 +33,7 @@ class QuoteDetails extends \Magento\Framework\Service\Data\AbstractObject const KEY_SHIPPING_ADDRESS = 'shipping_address'; - const KEY_CUSTOMER_TAX_CLASS_ID = 'customer_tax_class_id'; + const KEY_CUSTOMER_TAX_CLASS_KEY = 'customer_tax_class_key'; const KEY_ITEMS = 'items'; @@ -61,19 +61,19 @@ class QuoteDetails extends \Magento\Framework\Service\Data\AbstractObject } /** - * Get customer tax class id + * Get customer tax class key * - * @return int|null + * @return \Magento\Tax\Service\V1\Data\TaxClassKey|null */ - public function getCustomerTaxClassId() + public function getCustomerTaxClassKey() { - return $this->_get(self::KEY_CUSTOMER_TAX_CLASS_ID); + return $this->_get(self::KEY_CUSTOMER_TAX_CLASS_KEY); } /** * Get customer id * - * @return id|null + * @return int|null */ public function getCustomerId() { diff --git a/app/code/Magento/Tax/Service/V1/Data/QuoteDetails/Item.php b/app/code/Magento/Tax/Service/V1/Data/QuoteDetails/Item.php index 7be400b173873f59b8129f738d67571d6f93010c..b8c507161af9a81b4bf95284948fbec02c12bddf 100644 --- a/app/code/Magento/Tax/Service/V1/Data/QuoteDetails/Item.php +++ b/app/code/Magento/Tax/Service/V1/Data/QuoteDetails/Item.php @@ -32,7 +32,7 @@ class Item extends \Magento\Framework\Service\Data\AbstractObject const KEY_TYPE = 'type'; - const KEY_TAX_CLASS_ID = 'tax_class_id'; + const KEY_TAX_CLASS_KEY = 'tax_class_key'; const KEY_UNIT_PRICE = 'unit_price'; @@ -45,6 +45,8 @@ class Item extends \Magento\Framework\Service\Data\AbstractObject const KEY_DISCOUNT_AMOUNT = 'discount_amount'; const KEY_PARENT_CODE = 'parent_code'; + + const KEY_ASSOCIATED_ITEM_CODE = 'association_code'; /**#@-*/ /** @@ -68,13 +70,13 @@ class Item extends \Magento\Framework\Service\Data\AbstractObject } /** - * Get tax class id + * Get tax class key * - * @return int + * @return \Magento\Tax\Service\V1\Data\TaxClassKey */ - public function getTaxClassId() + public function getTaxClassKey() { - return $this->_get(self::KEY_TAX_CLASS_ID); + return $this->_get(self::KEY_TAX_CLASS_KEY); } /** @@ -136,4 +138,14 @@ class Item extends \Magento\Framework\Service\Data\AbstractObject { return $this->_get(self::KEY_PARENT_CODE); } + + /** + * Get associated item code if this item is associated with another item, null otherwise + * + * @return mixed|null + */ + public function getAssociatedItemCode() + { + return $this->_get(self::KEY_ASSOCIATED_ITEM_CODE); + } } diff --git a/app/code/Magento/Tax/Service/V1/Data/QuoteDetails/ItemBuilder.php b/app/code/Magento/Tax/Service/V1/Data/QuoteDetails/ItemBuilder.php index 0b94e9246afe5b43053cc6e8e3e6254aadc83187..44bb07e2157716a9f61aac18ccc9af6e416257b0 100644 --- a/app/code/Magento/Tax/Service/V1/Data/QuoteDetails/ItemBuilder.php +++ b/app/code/Magento/Tax/Service/V1/Data/QuoteDetails/ItemBuilder.php @@ -30,6 +30,37 @@ namespace Magento\Tax\Service\V1\Data\QuoteDetails; */ class ItemBuilder extends \Magento\Framework\Service\Data\AbstractObjectBuilder { + /** + * TaxClassKey data object builder + * + * @var \Magento\Tax\Service\V1\Data\TaxClassKeyBuilder + */ + protected $taxClassKeyBuilder; + + /** + * Initialize dependencies + * + * @param \Magento\Framework\Service\Data\ObjectFactory $objectFactory + * @param \Magento\Tax\Service\V1\Data\TaxClassKeyBuilder $taxClassKeyBuilder + */ + public function __construct( + \Magento\Framework\Service\Data\ObjectFactory $objectFactory, + \Magento\Tax\Service\V1\Data\TaxClassKeyBuilder $taxClassKeyBuilder + ) { + parent::__construct($objectFactory); + $this->taxClassKeyBuilder = $taxClassKeyBuilder; + } + + /** + * Get tax class key builder + * + * @return \Magento\Tax\Service\V1\Data\TaxClassKeyBuilder + */ + public function getTaxClassKeyBuilder() + { + return $this->taxClassKeyBuilder; + } + /** * Set code (sku or shipping code) * @@ -53,14 +84,14 @@ class ItemBuilder extends \Magento\Framework\Service\Data\AbstractObjectBuilder } /** - * Set tax class id + * Set tax class key * - * @param int $taxClassId + * @param \Magento\Tax\Service\V1\Data\TaxClassKey $taxClassKey * @return $this */ - public function setTaxClassId($taxClassId) + public function setTaxClassKey($taxClassKey) { - return $this->_set(Item::KEY_TAX_CLASS_ID, $taxClassId); + return $this->_set(Item::KEY_TAX_CLASS_KEY, $taxClassKey); } /** @@ -128,4 +159,29 @@ class ItemBuilder extends \Magento\Framework\Service\Data\AbstractObjectBuilder { return $this->_set(Item::KEY_PARENT_CODE, $code); } + + /** + * Set associated item code + * + * @param string $code + * @return $this + */ + public function setAssociatedItemCode($code) + { + return $this->_set(Item::KEY_ASSOCIATED_ITEM_CODE, $code); + } + + /** + * {@inheritdoc} + */ + protected function _setDataValues(array $data) + { + if (array_key_exists(Item::KEY_TAX_CLASS_KEY, $data)) { + $data[Item::KEY_TAX_CLASS_KEY] = $this->taxClassKeyBuilder->populateWithArray( + $data[Item::KEY_TAX_CLASS_KEY] + )->create(); + } + + return parent::_setDataValues($data); + } } diff --git a/app/code/Magento/Tax/Service/V1/Data/QuoteDetailsBuilder.php b/app/code/Magento/Tax/Service/V1/Data/QuoteDetailsBuilder.php index 08382bba602c029f2951abf5176f99d808f4d730..dddfa6f4f666e630879abb152ac38c7527c3f6c5 100644 --- a/app/code/Magento/Tax/Service/V1/Data/QuoteDetailsBuilder.php +++ b/app/code/Magento/Tax/Service/V1/Data/QuoteDetailsBuilder.php @@ -37,20 +37,37 @@ class QuoteDetailsBuilder extends \Magento\Framework\Service\Data\AbstractObject */ protected $itemBuilder; + /** + * Address builder + * + * @var \Magento\Customer\Service\V1\Data\AddressBuilder + */ + protected $addressBuilder; + + /** + * TaxClassKey builder + * + * @var \Magento\Tax\Service\V1\Data\TaxClassKeyBuilder + */ + protected $taxClassKeyBuilder; + /** * Initialize dependencies. * * @param \Magento\Framework\Service\Data\ObjectFactory $objectFactory * @param \Magento\Tax\Service\V1\Data\QuoteDetails\ItemBuilder $itemBuilder + * @param \Magento\Tax\Service\V1\Data\TaxClassKeyBuilder $taxClassKeyBuilder * @param \Magento\Customer\Service\V1\Data\AddressBuilder $addressBuilder */ public function __construct( \Magento\Framework\Service\Data\ObjectFactory $objectFactory, \Magento\Tax\Service\V1\Data\QuoteDetails\ItemBuilder $itemBuilder, + \Magento\Tax\Service\V1\Data\TaxClassKeyBuilder $taxClassKeyBuilder, \Magento\Customer\Service\V1\Data\AddressBuilder $addressBuilder ) { parent::__construct($objectFactory); $this->itemBuilder = $itemBuilder; + $this->taxClassKeyBuilder = $taxClassKeyBuilder; $this->addressBuilder = $addressBuilder; } @@ -74,6 +91,16 @@ class QuoteDetailsBuilder extends \Magento\Framework\Service\Data\AbstractObject return $this->addressBuilder; } + /** + * Get tax class key builder + * + * @return TaxClassKeyBuilder + */ + public function getTaxClassKeyBuilder() + { + return $this->taxClassKeyBuilder; + } + /** * Set customer billing address * @@ -97,14 +124,14 @@ class QuoteDetailsBuilder extends \Magento\Framework\Service\Data\AbstractObject } /** - * Set customer tax class id + * Set customer tax class key * - * @param int $taxClassId + * @param \Magento\Tax\Service\V1\Data\TaxClassKey $taxClassKey * @return $this */ - public function setCustomerTaxClassId($taxClassId) + public function setCustomerTaxClassKey($taxClassKey) { - return $this->_set(QuoteDetails::KEY_CUSTOMER_TAX_CLASS_ID, $taxClassId); + return $this->_set(QuoteDetails::KEY_CUSTOMER_TAX_CLASS_KEY, $taxClassKey); } /** @@ -151,6 +178,11 @@ class QuoteDetailsBuilder extends \Magento\Framework\Service\Data\AbstractObject } $data[QuoteDetails::KEY_ITEMS] = $items; } + if (array_key_exists(QuoteDetails::KEY_CUSTOMER_TAX_CLASS_KEY, $data)) { + $data[QuoteDetails::KEY_CUSTOMER_TAX_CLASS_KEY] = $this->taxClassKeyBuilder->populateWithArray( + $data[QuoteDetails::KEY_CUSTOMER_TAX_CLASS_KEY] + )->create(); + } return parent::_setDataValues($data); } } diff --git a/app/code/Magento/Tax/Service/V1/Data/TaxClassKey.php b/app/code/Magento/Tax/Service/V1/Data/TaxClassKey.php new file mode 100644 index 0000000000000000000000000000000000000000..ef9585faf8313d2f236294992a1ea464feda6ca7 --- /dev/null +++ b/app/code/Magento/Tax/Service/V1/Data/TaxClassKey.php @@ -0,0 +1,69 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Tax\Service\V1\Data; + +use Magento\Framework\Service\Data\AbstractObject; + +/** + * Class TaxClassKey + */ +class TaxClassKey extends AbstractObject +{ + /**#@+ + * Constants defined for keys of array, makes typos less likely + */ + const KEY_TYPE = 'type'; + + const KEY_VALUE = 'value'; + /**#@-*/ + + /**#@+ + * Constants defined for type of tax class key + */ + const TYPE_ID = 'id'; + + const TYPE_NAME = 'name'; + /**#@-*/ + + /** + * Get type of tax class key + * + * @return string + */ + public function getType() + { + return $this->_get(self::KEY_TYPE); + } + + /** + * Get value of tax class key + * + * @return string + */ + public function getValue() + { + return $this->_get(self::KEY_VALUE); + } +} diff --git a/app/code/Magento/Tax/Service/V1/Data/TaxClassKeyBuilder.php b/app/code/Magento/Tax/Service/V1/Data/TaxClassKeyBuilder.php new file mode 100644 index 0000000000000000000000000000000000000000..ed6b6e2b1f0df64ed89ba2a7eb2c4702d50ed179 --- /dev/null +++ b/app/code/Magento/Tax/Service/V1/Data/TaxClassKeyBuilder.php @@ -0,0 +1,56 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Tax\Service\V1\Data; + +use Magento\Framework\Service\Data\AbstractObjectBuilder; + +/** + * Builder for the TaxClassKey Service Data Object + * + * @method TaxClassKey create() + */ +class TaxClassKeyBuilder extends AbstractObjectBuilder +{ + /** + * Set type of tax class key + * + * @param string $type + * @return $this + */ + public function setType($type) + { + return $this->_set(TaxClassKey::KEY_TYPE, $type); + } + + /** + * Set value of tax class key + * + * @param String $value + * @return $this + */ + public function setValue($value) + { + return $this->_set(TaxClassKey::KEY_VALUE, $value); + } +} diff --git a/app/code/Magento/Tax/Service/V1/Data/TaxDetails/Item.php b/app/code/Magento/Tax/Service/V1/Data/TaxDetails/Item.php index 8146c35a02858ffdad5f56fb181425d2bc4fcdc7..dbec30a30e9d96f31081cfe5d269e1293e98e095 100644 --- a/app/code/Magento/Tax/Service/V1/Data/TaxDetails/Item.php +++ b/app/code/Magento/Tax/Service/V1/Data/TaxDetails/Item.php @@ -52,6 +52,8 @@ class Item extends \Magento\Framework\Service\Data\AbstractObject const KEY_DISCOUNT_TAX_COMPENSATION_AMOUNT = 'discount_tax_compensation_amount'; const KEY_APPLIED_TAXES = 'applied_taxes'; + + const KEY_ASSOCIATED_ITEM_CODE = 'associated_item_code'; /**#@-*/ /** @@ -173,4 +175,14 @@ class Item extends \Magento\Framework\Service\Data\AbstractObject { return $this->_get(self::KEY_APPLIED_TAXES); } + + /** + * Return associated item code if this item is associated with another item, null otherwise + * + * @return mixed|null + */ + public function getAssociatedItemCode() + { + return $this->_get(self::KEY_ASSOCIATED_ITEM_CODE); + } } diff --git a/app/code/Magento/Tax/Service/V1/Data/TaxDetails/ItemBuilder.php b/app/code/Magento/Tax/Service/V1/Data/TaxDetails/ItemBuilder.php index f10479c1fc686b8fade45467273e8d60eb8c4500..4bca388e1a4054219f21a6073e07b9c17c0159d7 100644 --- a/app/code/Magento/Tax/Service/V1/Data/TaxDetails/ItemBuilder.php +++ b/app/code/Magento/Tax/Service/V1/Data/TaxDetails/ItemBuilder.php @@ -208,22 +208,32 @@ class ItemBuilder extends \Magento\Framework\Service\Data\AbstractObjectBuilder return $this; } + /** + * Set the associated item code + * + * @param string $code + * @return $this + */ + public function setAssociatedItemCode($code) + { + $this->_set(Item::KEY_ASSOCIATED_ITEM_CODE, $code); + return $this; + } + /** * {@inheritdoc} */ protected function _setDataValues(array $data) { - $appliedTaxDataObjects = []; - if (isset($data[Item::KEY_APPLIED_TAXES])) { + $appliedTaxDataObjects = []; $appliedTaxes = $data[Item::KEY_APPLIED_TAXES]; foreach ($appliedTaxes as $appliedTax) { $appliedTaxDataObjects[] = $this->appliedTaxBuilder->populateWithArray($appliedTax)->create(); } + $data[Item::KEY_APPLIED_TAXES] = $appliedTaxDataObjects; } - $data[Item::KEY_APPLIED_TAXES] = $appliedTaxDataObjects; - return parent::_setDataValues($data); } } diff --git a/app/code/Magento/Tax/Service/V1/Data/TaxRate.php b/app/code/Magento/Tax/Service/V1/Data/TaxRate.php index 7f16788a0e9ecece10d787da1c9a2a3d6ebe81d4..d3203bc8bace624cf32f571eaa89ce1296d123fa 100644 --- a/app/code/Magento/Tax/Service/V1/Data/TaxRate.php +++ b/app/code/Magento/Tax/Service/V1/Data/TaxRate.php @@ -66,7 +66,7 @@ class TaxRate extends \Magento\Framework\Service\Data\AbstractObject /** * Get region id * - * @return int + * @return int|null */ public function getRegionId() { diff --git a/app/code/Magento/Tax/Service/V1/Data/TaxRule.php b/app/code/Magento/Tax/Service/V1/Data/TaxRule.php index 60a9897a05bc777d10475510bbbae4bc8492a874..120b006fe1574a3e551e9f98d9aa8964fb322c3c 100644 --- a/app/code/Magento/Tax/Service/V1/Data/TaxRule.php +++ b/app/code/Magento/Tax/Service/V1/Data/TaxRule.php @@ -74,7 +74,7 @@ class TaxRule extends AbstractObject /** * Get customer tax class id * - * @return int[]|null + * @return int[] */ public function getCustomerTaxClassIds() { @@ -84,7 +84,7 @@ class TaxRule extends AbstractObject /** * Get product tax class id * - * @return int[]|null + * @return int[] */ public function getProductTaxClassIds() { @@ -94,7 +94,7 @@ class TaxRule extends AbstractObject /** * Get tax rate ids * - * @return string[]|null + * @return int[] */ public function getTaxRateIds() { @@ -124,7 +124,7 @@ class TaxRule extends AbstractObject /** * Get calculate subtotal. * - * @return int|null + * @return bool|null */ public function getCalculateSubtotal() { diff --git a/app/code/Magento/Tax/Service/V1/Data/TaxRuleBuilder.php b/app/code/Magento/Tax/Service/V1/Data/TaxRuleBuilder.php index 82bbb0d517a557495fc9e982345ca1f304f2660e..3c420fa1ff7ceee182beb047554895dfa7ca4a22 100644 --- a/app/code/Magento/Tax/Service/V1/Data/TaxRuleBuilder.php +++ b/app/code/Magento/Tax/Service/V1/Data/TaxRuleBuilder.php @@ -133,11 +133,11 @@ class TaxRuleBuilder extends AbstractObjectBuilder /** * Set calculate subtotal. * - * @param int $calculateSubtotal + * @param bool $calculateSubtotal * @return $this */ public function setCalculateSubtotal($calculateSubtotal) { - return $this->_set(TaxRule::CALCULATE_SUBTOTAL, (int)$calculateSubtotal); + return $this->_set(TaxRule::CALCULATE_SUBTOTAL, (bool)$calculateSubtotal); } } diff --git a/app/code/Magento/Tax/Service/V1/TaxCalculationService.php b/app/code/Magento/Tax/Service/V1/TaxCalculationService.php index 928779b7911480aa82f37e67609a1cfac6c41365..6ba8e66711a52bdbb97f3bf616f8b8287f4fe6bf 100644 --- a/app/code/Magento/Tax/Service/V1/TaxCalculationService.php +++ b/app/code/Magento/Tax/Service/V1/TaxCalculationService.php @@ -30,12 +30,15 @@ use Magento\Tax\Model\Calculation; use Magento\Tax\Model\Resource\Sales\Order\Tax; use Magento\Tax\Service\V1\Data\QuoteDetails; use Magento\Tax\Service\V1\Data\QuoteDetails\Item as QuoteDetailsItem; +use Magento\Tax\Service\V1\Data\TaxClass; +use Magento\Tax\Service\V1\Data\TaxClassKey; use Magento\Tax\Service\V1\Data\TaxDetails; use Magento\Tax\Service\V1\Data\TaxDetails\AppliedTax; use Magento\Tax\Service\V1\Data\TaxDetails\AppliedTaxRate; use Magento\Tax\Service\V1\Data\TaxDetails\Item as TaxDetailsItem; use Magento\Tax\Service\V1\Data\TaxDetails\ItemBuilder as TaxDetailsItemBuilder; use Magento\Tax\Service\V1\Data\TaxDetailsBuilder; +use Magento\Tax\Model\Calculation\CalculatorFactory; /** * Tax Calculation Service @@ -43,22 +46,12 @@ use Magento\Tax\Service\V1\Data\TaxDetailsBuilder; */ class TaxCalculationService implements TaxCalculationServiceInterface { - /**#@+ - * Constants for delta rounding key - */ - const KEY_REGULAR_DELTA_ROUNDING = 'regular'; - - const KEY_APPLIED_TAX_DELTA_ROUNDING = 'applied_tax_amount'; - - const KEY_TAX_AFTER_DISCOUNT_DELTA_ROUNDING = 'tax_after_discount'; - /**#@-*/ - /** * Tax calculation model * * @var Calculation */ - protected $calculator; + protected $calculationTool; /** * Tax configuration object @@ -74,19 +67,6 @@ class TaxCalculationService implements TaxCalculationServiceInterface */ protected $taxDetailsBuilder; - /** - * Rounding deltas for prices - * - * @var array - * example: - * [ - * 'type' => [ - * 'rate' => 'rounding delta', - * ], - * ] - */ - protected $roundingDeltas; - /** * Array to hold discount compensations for items * @@ -125,30 +105,50 @@ class TaxCalculationService implements TaxCalculationServiceInterface */ protected $customerAccountService; + /** + * Tax Class Service + * + * @var TaxClassService + */ + protected $taxClassService; + + /** + * Calculator Factory + * + * @var CalculatorFactory + */ + protected $calculatorFactory; + /** * Constructor * * @param Calculation $calculation + * @param CalculatorFactory $calculatorFactory * @param \Magento\Tax\Model\Config $config * @param TaxDetailsBuilder $taxDetailsBuilder * @param TaxDetailsItemBuilder $taxDetailsItemBuilder * @param StoreManagerInterface $storeManager * @param CustomerAccountServiceInterface $customerAccountService + * @param TaxClassService $taxClassService */ public function __construct( Calculation $calculation, + CalculatorFactory $calculatorFactory, \Magento\Tax\Model\Config $config, TaxDetailsBuilder $taxDetailsBuilder, TaxDetailsItemBuilder $taxDetailsItemBuilder, StoreManagerInterface $storeManager, - CustomerAccountServiceInterface $customerAccountService + CustomerAccountServiceInterface $customerAccountService, + TaxClassService $taxClassService ) { - $this->calculator = $calculation; + $this->calculationTool = $calculation; + $this->calculatorFactory = $calculatorFactory; $this->config = $config; $this->taxDetailsBuilder = $taxDetailsBuilder; $this->taxDetailsItemBuilder = $taxDetailsItemBuilder; $this->storeManager = $storeManager; $this->customerAccountService = $customerAccountService; + $this->taxClassService = $taxClassService; } /** @@ -175,38 +175,22 @@ class TaxCalculationService implements TaxCalculationServiceInterface } $this->computeRelationships($items); - $addressRequest = $this->getAddressTaxRequest($quoteDetails, $storeId, $quoteDetails->getCustomerId()); - if ($this->config->priceIncludesTax($storeId)) { - $storeRequest = $this->getStoreTaxRequest($storeId); - $classIds = []; - foreach ($items as $item) { - if ($item->getTaxClassId()) { - $classIds[] = $item->getTaxClassId(); - } - } - $classIds = array_unique($classIds); - $addressRequest->setProductClassId($classIds); - $storeRequest->setProductClassId($classIds); - if ((bool)$this->config->crossBorderTradeEnabled($storeId)) { - $addressRequest->setSameRateAsStore(true); - } else { - $addressRequest->setSameRateAsStore( - $this->calculator->compareRequests($storeRequest, $addressRequest) - ); - } - } + $calculator = $this->calculatorFactory->create( + $this->config->getAlgorithm($storeId), + $storeId, + $quoteDetails->getBillingAddress(), + $quoteDetails->getShippingAddress(), + $this->taxClassService->getTaxClassId($quoteDetails->getCustomerTaxClassKey(), 'customer'), + $quoteDetails->getCustomerId() + ); - // init rounding deltas for this quote - $this->roundingDeltas = []; - // init discount tax compensations array - $this->discountTaxCompensations = []; $processedItems = []; /** @var QuoteDetailsItem $item */ foreach ($this->keyedItems as $item) { if (isset($this->parentToChildren[$item->getCode()])) { $processedChildren = []; foreach ($this->parentToChildren[$item->getCode()] as $child) { - $processedItem = $this->processItem($child, $addressRequest, $storeId); + $processedItem = $this->processItem($child, $calculator); $taxDetailsData = $this->aggregateItemData($taxDetailsData, $processedItem); $processedItems[$processedItem->getCode()] = $processedItem; $processedChildren[] = $processedItem; @@ -216,7 +200,7 @@ class TaxCalculationService implements TaxCalculationServiceInterface $processedItemBuilder->setType($item->getType()); $processedItem = $processedItemBuilder->create(); } else { - $processedItem = $this->processItem($item, $addressRequest, $storeId); + $processedItem = $this->processItem($item, $calculator); $taxDetailsData = $this->aggregateItemData($taxDetailsData, $processedItem); } $processedItems[$processedItem->getCode()] = $processedItem; @@ -266,12 +250,12 @@ class TaxCalculationService implements TaxCalculationServiceInterface $storeId = $this->storeManager->getStore()->getStoreId(); } if (!$isDefault) { - $addressRequestObject = $this->calculator->getRateRequest(null, null, null, $storeId, $customerId); + $addressRequestObject = $this->calculationTool->getRateRequest(null, null, null, $storeId, $customerId); } else { - $addressRequestObject = $this->calculator->getDefaultRateRequest($storeId, $customerId); + $addressRequestObject = $this->calculationTool->getDefaultRateRequest($storeId, $customerId); } $addressRequestObject->setProductClassId($productTaxClassID); - return $this->calculator->getRate($addressRequestObject); + return $this->calculationTool->getRate($addressRequestObject); } /** @@ -293,453 +277,19 @@ class TaxCalculationService implements TaxCalculationServiceInterface } } - /** - * Get request for fetching address tax rate - * - * @param QuoteDetails $quoteDetails - * @param int $storeId - * @param int $customerId - * @return \Magento\Framework\Object - */ - protected function getAddressTaxRequest(QuoteDetails $quoteDetails, $storeId, $customerId) - { - return $this->calculator->getRateRequest( - $quoteDetails->getShippingAddress(), - $quoteDetails->getBillingAddress(), - $quoteDetails->getCustomerTaxClassId(), - $storeId, - $customerId - ); - } - - /** - * Get request for fetching store tax rate - * - * @param int $storeId - * @return \Magento\Framework\Object - */ - protected function getStoreTaxRequest($storeId) - { - return $this->calculator->getRateOriginRequest($storeId); - } - /** * Calculate item tax with customized rounding level * * @param QuoteDetailsItem $item - * @param \Magento\Framework\Object $taxRequest - * @param int $storeId - * @return TaxDetailsItem|null - */ - protected function processItem( - QuoteDetailsItem $item, - \Magento\Framework\Object $taxRequest, - $storeId - ) { - switch ($this->config->getAlgorithm($storeId)) { - case Calculation::CALC_UNIT_BASE: - return $this->unitBaseCalculation($item, $taxRequest, $storeId); - case Calculation::CALC_ROW_BASE: - case Calculation::CALC_TOTAL_BASE: - return $this->totalBaseCalculation($item, $taxRequest, $storeId); - default: - return null; - } - } - - /** - * Calculate item price and row total including/excluding tax based on unit price rounding level - * This function also saves applied tax per tax rate for the item - * - * @param QuoteDetailsItem $item - * @param \Magento\Framework\Object $taxRateRequest - * @param int $storeId + * @param Calculation\AbstractCalculator $calculator * @return TaxDetailsItem */ - protected function unitBaseCalculation( - QuoteDetailsItem $item, - \Magento\Framework\Object $taxRateRequest, - $storeId - ) { - /** @var \Magento\Tax\Service\V1\Data\TaxDetails\AppliedTax[] $appliedTaxes */ - $appliedTaxes = []; - $appliedTaxBuilder = $this->taxDetailsItemBuilder->getAppliedTaxBuilder(); - $appliedTaxRateBuilder = $appliedTaxBuilder->getAppliedTaxRateBuilder(); - - $taxRateRequest->setProductClassId($item->getTaxClassId()); - $appliedRates = $this->calculator->getAppliedRates($taxRateRequest); - $rate = $this->calculator->getRate($taxRateRequest); - - $quantity = $this->getTotalQuantity($item); - $price = $priceInclTax = $this->calculator->round($item->getUnitPrice()); - $rowTotal = $rowTotalInclTax = $this->calcRowTotal($item); - - $discountAmount = $item->getDiscountAmount(); - $applyTaxAfterDiscount = $this->config->applyTaxAfterDiscount($storeId); - - $discountTaxCompensationAmount = 0; - - if ($item->getTaxIncluded()) { - if ($taxRateRequest->getSameRateAsStore()) { - $uniTax = $this->calculator->calcTaxAmount($priceInclTax, $rate, true); - $price = $priceInclTax - $uniTax; - $rowTax = $uniTax * $quantity; - $rowTotal = $price * $quantity; - } else { - $storeRate = $this->calculator->getStoreRate($taxRateRequest, $storeId); - $priceInclTax = $this->calculatePriceInclTax($price, $storeRate, $rate); - $uniTax = $this->calculator->calcTaxAmount($priceInclTax, $rate, true, true); - $rowTax = $uniTax * $quantity; - $price = $priceInclTax - $uniTax; - $rowTotalInclTax = $priceInclTax * $quantity; - $rowTotal = $price * $quantity; - } - - //Handle discount - if ($discountAmount && $applyTaxAfterDiscount) { - //TODO: handle originalDiscountAmount - $unitDiscountAmount = $discountAmount / $quantity; - $taxableAmount = max($priceInclTax - $unitDiscountAmount, 0); - $unitTaxAfterDiscount = $this->calculator->calcTaxAmount( - $taxableAmount, - $rate, - true, - true - ); - - // Set discount tax compensation - $unitDiscountTaxCompensationAmount = $uniTax - $unitTaxAfterDiscount; - $discountTaxCompensationAmount = $unitDiscountTaxCompensationAmount * $quantity; - $rowTax = $unitTaxAfterDiscount * $quantity; - } - - //save applied taxes - $appliedTaxes = $this->getAppliedTaxes($appliedTaxBuilder, $rowTax, $rate, $appliedRates); - } else { //catalog price does not include tax - $taxable = $price; - $appliedRates = $this->calculator->getAppliedRates($taxRateRequest); - $unitTaxes = []; - $unitTaxesBeforeDiscount = []; - //Apply each tax rate separately - foreach ($appliedRates as $appliedRate) { - $taxId = $appliedRate['id']; - $taxRate = $appliedRate['percent']; - $unitTaxPerRate = $this->calculator->calcTaxAmount($taxable, $taxRate, false); - $unitTaxAfterDiscount = $unitTaxPerRate; - - //Handle discount - if ($discountAmount && $applyTaxAfterDiscount) { - //TODO: handle originalDiscountAmount - $unitDiscountAmount = $discountAmount / $quantity; - $taxableAmount = max($priceInclTax - $unitDiscountAmount, 0); - $unitTaxAfterDiscount = $this->calculator->calcTaxAmount( - $taxableAmount, - $taxRate, - false, - true - ); - } - $appliedTaxes[$taxId] = $this->getAppliedTax( - $appliedTaxBuilder, - $unitTaxAfterDiscount * $quantity, - $appliedRate - ); - - $unitTaxes[] = $unitTaxAfterDiscount; - $unitTaxesBeforeDiscount[] = $unitTaxPerRate; - } - $unitTax = array_sum($unitTaxes); - $unitTaxBeforeDiscount = array_sum($unitTaxesBeforeDiscount); - $rowTax = $unitTax * $quantity; - $priceInclTax = $price + $unitTaxBeforeDiscount; - $rowTotalInclTax = $priceInclTax * $quantity; - } - - $this->taxDetailsItemBuilder->setCode($item->getCode()); - $this->taxDetailsItemBuilder->setRowTax($rowTax); - $this->taxDetailsItemBuilder->setPrice($price); - $this->taxDetailsItemBuilder->setPriceInclTax($priceInclTax); - $this->taxDetailsItemBuilder->setRowTotal($rowTotal); - $this->taxDetailsItemBuilder->setRowTotalInclTax($rowTotalInclTax); - $this->taxDetailsItemBuilder->setCode($item->getCode()); - $this->taxDetailsItemBuilder->setType($item->getType()); - $this->taxDetailsItemBuilder->setTaxPercent($rate); - $this->taxDetailsItemBuilder->setDiscountTaxCompensationAmount($discountTaxCompensationAmount); - - $this->taxDetailsItemBuilder->setAppliedTaxes($appliedTaxes); - return $this->taxDetailsItemBuilder->create(); - } - - /** - * Create AppliedTax data object based applied tax rates and tax amount - * - * @param \Magento\Tax\Service\V1\Data\TaxDetails\AppliedTaxBuilder $appliedTaxBuilder - * @param float $rowTax - * @param array $appliedRate - * @return \Magento\Tax\Service\V1\Data\TaxDetails\AppliedTax - */ - protected function getAppliedTax($appliedTaxBuilder, $rowTax, $appliedRate) - { - $appliedTaxRateBuilder = $appliedTaxBuilder->getAppliedTaxRateBuilder(); - $appliedTaxBuilder->setAmount($rowTax); - $appliedTaxBuilder->setPercent($appliedRate['percent']); - $appliedTaxBuilder->setTaxRateKey($appliedRate['id']); - - /** @var AppliedTaxRate[] $rateDataObjects */ - $rateDataObjects = []; - foreach ($appliedRate['rates'] as $rate) { - $appliedTaxRateBuilder->setPercent($rate['percent']); - $appliedTaxRateBuilder->setCode($rate['code']); - $appliedTaxRateBuilder->setTitle($rate['title']); - //Skipped position, priority and rule_id - $rateDataObjects[$rate['code']] = $appliedTaxRateBuilder->create(); - } - $appliedTaxBuilder->setRates($rateDataObjects); - $appliedTax = $appliedTaxBuilder->create(); - return $appliedTax; - } - - /** - * Create AppliedTax data object based on applied tax rates and tax amount - * - * @param \Magento\Tax\Service\V1\Data\TaxDetails\AppliedTaxBuilder $appliedTaxBuilder - * @param float $rowTax - * @param float $totalTaxRate - * @param array $appliedRates May contain multiple tax rates when catalog price includes tax - * @return \Magento\Tax\Service\V1\Data\TaxDetails\AppliedTax[] - */ - protected function getAppliedTaxes($appliedTaxBuilder, $rowTax, $totalTaxRate, $appliedRates) - { - /** @var \Magento\Tax\Service\V1\Data\TaxDetails\AppliedTax[] $appliedTaxes */ - $appliedTaxes = []; - $appliedTaxRateBuilder = $appliedTaxBuilder->getAppliedTaxRateBuilder(); - $totalAppliedAmount = 0; - foreach ($appliedRates as $appliedRate) { - if ($appliedRate['percent'] == 0) { - continue; - } - - $appliedAmount = $rowTax / $totalTaxRate * $appliedRate['percent']; - //Use delta rounding to split tax amounts for each tax rates between items - $appliedAmount = $this->deltaRound( - $appliedAmount, - $appliedRate['id'], - true, - self::KEY_APPLIED_TAX_DELTA_ROUNDING - ); - if ($totalAppliedAmount + $appliedAmount > $rowTax) { - $appliedAmount = $rowTax - $totalAppliedAmount; - } - $totalAppliedAmount += $appliedAmount; - - $appliedTaxBuilder->setAmount($appliedAmount); - $appliedTaxBuilder->setPercent($appliedRate['percent']); - $appliedTaxBuilder->setTaxRateKey($appliedRate['id']); - - /** @var AppliedTaxRate[] $rateDataObjects */ - $rateDataObjects = []; - foreach ($appliedRate['rates'] as $rate) { - $appliedTaxRateBuilder->setPercent($rate['percent']); - $appliedTaxRateBuilder->setCode($rate['code']); - $appliedTaxRateBuilder->setTitle($rate['title']); - //Skipped position, priority and rule_id - $rateDataObjects[$rate['code']] = $appliedTaxRateBuilder->create(); - } - $appliedTaxBuilder->setRates($rateDataObjects); - $appliedTax = $appliedTaxBuilder->create(); - $appliedTaxes[$appliedTax->getTaxRateKey()] = $appliedTax; - } - - return $appliedTaxes; - } - - /** - * Calculate item price and row total including/excluding tax based on total price rounding level - * - * @param QuoteDetailsItem $item - * @param \Magento\Framework\Object $taxRateRequest - * @param int $storeId - * @return TaxDetailsItem - */ - protected function totalBaseCalculation( + protected function processItem( QuoteDetailsItem $item, - \Magento\Framework\Object $taxRateRequest, - $storeId + Calculation\AbstractCalculator $calculator ) { - /** @var \Magento\Tax\Service\V1\Data\TaxDetails\AppliedTax[] $appliedTaxes */ - $appliedTaxes = []; - $appliedTaxBuilder = $this->taxDetailsItemBuilder->getAppliedTaxBuilder(); - $appliedTaxRateBuilder = $appliedTaxBuilder->getAppliedTaxRateBuilder(); - - $taxRateRequest->setProductClassId($item->getTaxClassId()); - $appliedRates = $this->calculator->getAppliedRates($taxRateRequest); - $rate = $this->calculator->getRate($taxRateRequest); - $quantity = $this->getTotalQuantity($item); - $price = $priceInclTax = $this->calculator->round($item->getUnitPrice()); - $rowTotal = $rowTotalInclTax = $taxableAmount = $this->calcRowTotal($item); - - $discountAmount = $item->getDiscountAmount(); - $applyTaxAfterDiscount = $this->config->applyTaxAfterDiscount($storeId); - - $discountTaxCompensationAmount = 0; - - $isTotalBasedCalculation = ($this->config->getAlgorithm($storeId) == Calculation::CALC_TOTAL_BASE); - - if ($item->getTaxIncluded()) { - if ($taxRateRequest->getSameRateAsStore()) { - $rowTaxExact = $this->calculator->calcTaxAmount($rowTotalInclTax, $rate, true, false); - if ($isTotalBasedCalculation) { - $rowTax = $this->deltaRound($rowTaxExact, $rate, true); - } else { - $rowTax = $this->calculator->round($rowTaxExact); - } - $rowTotal = $rowTotalInclTax - $rowTax; - $price = $this->calculator->round($rowTotal / $quantity); - } else { - $storeRate = $this->calculator->getStoreRate($taxRateRequest, $storeId); - $priceInclTax = $this->calculatePriceInclTax($price, $storeRate, $rate); - $rowTotalInclTax = $priceInclTax * $quantity; - $taxableAmount = $rowTotalInclTax; - if ($isTotalBasedCalculation) { - $rowTax = $this->deltaRound( - $this->calculator->calcTaxAmount($rowTotalInclTax, $rate, true, false), - $rate, - true - ); - } else { - $rowTax = $this->calculator->calcTaxAmount($rowTotalInclTax, $rate, true, true); - } - $rowTotal = $rowTotalInclTax - $rowTax; - $price = $this->calculator->round($rowTotal / $quantity); - } - - //Handle discount - if ($discountAmount && $applyTaxAfterDiscount) { - //TODO: handle originalDiscountAmount - $taxableAmount = max($taxableAmount - $discountAmount, 0); - $rowTaxAfterDiscount = $this->calculator->calcTaxAmount( - $taxableAmount, - $rate, - true, - false - ); - if ($isTotalBasedCalculation) { - //Round the row tax using a different type so that we don't pollute the rounding deltas - $rowTaxAfterDiscount = $this->deltaRound( - $rowTaxAfterDiscount, - $rate, - true, - self::KEY_TAX_AFTER_DISCOUNT_DELTA_ROUNDING - ); - } else { - $rowTaxAfterDiscount = $this->calculator->round($rowTaxAfterDiscount); - } - - // Set discount tax compensation - $discountTaxCompensationAmount = $rowTax - $rowTaxAfterDiscount; - $rowTax = $rowTaxAfterDiscount; - } - - //save applied taxes - $appliedTaxes = $this->getAppliedTaxes( - $appliedTaxBuilder, - $rowTax, - $rate, - $appliedRates - ); - } else { //catalog price does not include tax - $appliedRates = $this->calculator->getAppliedRates($taxRateRequest); - $rowTaxes = []; - $rowTaxesBeforeDiscount = []; - //Apply each tax rate separately - foreach ($appliedRates as $appliedRate) { - $taxId = $appliedRate['id']; - $taxRate = $appliedRate['percent']; - if ($isTotalBasedCalculation) { - $rowTaxPerRate = $this->deltaRound( - $this->calculator->calcTaxAmount($rowTotal, $taxRate, false, false), - $taxId, - false - ); - } else { - $rowTaxPerRate = $this->calculator->calcTaxAmount($rowTotal, $taxRate, false, true); - } - $rowTaxAfterDiscount = $rowTaxPerRate; - //Handle discount - if ($discountAmount && $applyTaxAfterDiscount) { - //TODO: handle originalDiscountAmount - $rowTaxAfterDiscount = $this->calculator->calcTaxAmount( - max($rowTotal - $discountAmount, 0), - $taxRate, - false, - false - ); - if ($isTotalBasedCalculation) { - //Round the row tax using a different type so that we don't pollute the rounding deltas - $rowTaxAfterDiscount = $this->deltaRound( - $rowTaxAfterDiscount, - $taxRate, - false, - self::KEY_TAX_AFTER_DISCOUNT_DELTA_ROUNDING - ); - } else { - $rowTaxAfterDiscount = $this->calculator->round($rowTaxAfterDiscount); - } - } - $appliedTaxes[$appliedRate['id']] = $this->getAppliedTax( - $appliedTaxBuilder, - $rowTaxAfterDiscount, - $appliedRate - ); - $rowTaxes[] = $rowTaxAfterDiscount; - $rowTaxesBeforeDiscount[] = $rowTaxPerRate; - } - $rowTax = array_sum($rowTaxes); - $rowTaxBeforeDiscount = array_sum($rowTaxesBeforeDiscount); - $rowTotalInclTax = $rowTotal + $rowTaxBeforeDiscount; - $priceInclTax = $this->calculator->round($rowTotalInclTax / $quantity); - } - - $this->taxDetailsItemBuilder->setCode($item->getCode()); - $this->taxDetailsItemBuilder->setRowTax($rowTax); - $this->taxDetailsItemBuilder->setPrice($price); - $this->taxDetailsItemBuilder->setPriceInclTax($priceInclTax); - $this->taxDetailsItemBuilder->setRowTotal($rowTotal); - $this->taxDetailsItemBuilder->setRowTotalInclTax($rowTotalInclTax); - $this->taxDetailsItemBuilder->setCode($item->getCode()); - $this->taxDetailsItemBuilder->setType($item->getType()); - $this->taxDetailsItemBuilder->setTaxPercent($rate); - $this->taxDetailsItemBuilder->setDiscountTaxCompensationAmount($discountTaxCompensationAmount); - - $this->taxDetailsItemBuilder->setAppliedTaxes($appliedTaxes); - return $this->taxDetailsItemBuilder->create(); - } - - /** - * Round price based on previous rounding operation delta - * - * @param float $price - * @param string $rate - * @param bool $direction - * @param string $type - * @return float - */ - protected function deltaRound($price, $rate, $direction, $type = self::KEY_REGULAR_DELTA_ROUNDING) - { - if ($price) { - $rate = (string)$rate; - $type = $type . $direction; - // initialize the delta to a small number to avoid non-deterministic behavior with rounding of 0.5 - $delta = isset($this->roundingDeltas[$type][$rate]) - ? $this->roundingDeltas[$type][$rate] - : 0.000001; - $price += $delta; - $roundPrice = $this->calculator->round($price); - $this->roundingDeltas[$type][$rate] = $price - $roundPrice; - $price = $roundPrice; - } - return $price; + return $calculator->calculate($item, $quantity); } /** @@ -763,8 +313,8 @@ class TaxCalculationService implements TaxCalculationServiceInterface $taxableAmount += $child->getTaxableAmount(); } - $price = $this->calculator->round($rowTotal / $quantity); - $priceInclTax = $this->calculator->round($rowTotalInclTax / $quantity); + $price = $this->calculationTool->round($rowTotal / $quantity); + $priceInclTax = $this->calculationTool->round($rowTotalInclTax / $quantity); $this->taxDetailsItemBuilder->setPrice($price); $this->taxDetailsItemBuilder->setPriceInclTax($priceInclTax); @@ -775,24 +325,6 @@ class TaxCalculationService implements TaxCalculationServiceInterface return $this->taxDetailsItemBuilder; } - /** - * Given a store price that includes tax at the store rate, this function will back out the store's tax, and add in - * the customer's tax. Returns this new price which is the customer's price including tax. - * - * @param float $storePriceInclTax - * @param float $storeRate - * @param float $customerRate - * @return float - */ - protected function calculatePriceInclTax($storePriceInclTax, $storeRate, $customerRate) - { - $storeTax = $this->calculator->calcTaxAmount($storePriceInclTax, $storeRate, true, false); - $priceExclTax = $storePriceInclTax - $storeTax; - $customerTax = $this->calculator->calcTaxAmount($priceExclTax, $customerRate, false, false); - $customerPriceInclTax = $this->calculator->round($priceExclTax + $customerTax); - return $customerPriceInclTax; - } - /** * Add row total item amount to subtotal * @@ -813,8 +345,8 @@ class TaxCalculationService implements TaxCalculationServiceInterface + $item->getDiscountTaxCompensationAmount(); $itemAppliedTaxes = $item->getAppliedTaxes(); - if (!isset($taxDetailsData[TaxDetails::KEY_APPLIED_TAXES])) { - $taxDetailsData[TaxDetails::KEY_APPLIED_TAXES] = []; + if (is_null($itemAppliedTaxes)) { + return $taxDetailsData; } $appliedTaxes = $taxDetailsData[TaxDetails::KEY_APPLIED_TAXES]; foreach ($itemAppliedTaxes as $taxId => $itemAppliedTax) { @@ -861,20 +393,4 @@ class TaxCalculationService implements TaxCalculationServiceInterface } return $item->getQuantity(); } - - /** - * Calculate the row total for an item - * - * @param QuoteDetailsItem $item - * @return float - */ - protected function calcRowTotal(QuoteDetailsItem $item) - { - $qty = $this->getTotalQuantity($item); - - // Round unit price before multiplying to prevent losing 1 cent on subtotal - $total = $this->calculator->round($item->getUnitPrice()) * $qty; - - return $this->calculator->round($total); - } } diff --git a/app/code/Magento/Tax/Service/V1/TaxCalculationServiceInterface.php b/app/code/Magento/Tax/Service/V1/TaxCalculationServiceInterface.php index 1f663e8d179bb96ade6da1188f70e5faaa6fc2a8..b189b8f0e4d549f8062662696350f9d1d66835f9 100644 --- a/app/code/Magento/Tax/Service/V1/TaxCalculationServiceInterface.php +++ b/app/code/Magento/Tax/Service/V1/TaxCalculationServiceInterface.php @@ -26,6 +26,14 @@ namespace Magento\Tax\Service\V1; interface TaxCalculationServiceInterface { + /**#@+ + * Type of calculation used + */ + const CALC_UNIT_BASE = 'UNIT_BASE_CALCULATION'; + const CALC_ROW_BASE = 'ROW_BASE_CALCULATION'; + const CALC_TOTAL_BASE = 'TOTAL_BASE_CALCULATION'; + /**#@-*/ + /** * Calculate Tax * diff --git a/app/code/Magento/Tax/Service/V1/TaxClassService.php b/app/code/Magento/Tax/Service/V1/TaxClassService.php index fbcd6c71c2865df5005348f758a1e4bd7648fa95..4303b9f219410feb1751b4a4d12740aaef535b5d 100644 --- a/app/code/Magento/Tax/Service/V1/TaxClassService.php +++ b/app/code/Magento/Tax/Service/V1/TaxClassService.php @@ -27,13 +27,17 @@ namespace Magento\Tax\Service\V1; use Magento\Framework\Exception\InputException; use Magento\Framework\Model\Exception as ModelException; use Magento\Framework\Service\V1\Data\Search\FilterGroup; +use Magento\Framework\Service\V1\Data\FilterBuilder; use Magento\Framework\Service\V1\Data\SearchCriteria; +use Magento\Framework\Service\V1\Data\SearchCriteriaBuilder; use Magento\Tax\Model\ClassModelRegistry; use Magento\Tax\Model\Converter; use Magento\Tax\Model\Resource\TaxClass\Collection as TaxClassCollection; use Magento\Tax\Model\Resource\TaxClass\CollectionFactory as TaxClassCollectionFactory; +use Magento\Tax\Service\V1\Data\TaxClass; use Magento\Tax\Service\V1\Data\TaxClassSearchResultsBuilder; use Magento\Tax\Service\V1\Data\TaxClass as TaxClassDataObject; +use Magento\Tax\Service\V1\Data\TaxClassKey; use Magento\Framework\Exception\CouldNotDeleteException; /** @@ -63,20 +67,40 @@ class TaxClassService implements TaxClassServiceInterface const CLASS_ID_NOT_ALLOWED = 'class_id is not expected for this request.'; + /** + * Search Criteria Builder + * + * @var SearchCriteriaBuilder + */ + protected $searchCriteriaBuilder; + + /** + * Filter Builder + * + * @var FilterBuilder + */ + protected $filterBuilder; + /** * Initialize dependencies. * + * @param SearchCriteriaBuilder $searchCriteriaBuilder + * @param FilterBuilder $filterBuilder * @param TaxClassCollectionFactory $taxClassCollectionFactory * @param TaxClassSearchResultsBuilder $searchResultsBuilder * @param Converter $converter * @param ClassModelRegistry $classModelRegistry */ public function __construct( + SearchCriteriaBuilder $searchCriteriaBuilder, + FilterBuilder $filterBuilder, TaxClassCollectionFactory $taxClassCollectionFactory, TaxClassSearchResultsBuilder $searchResultsBuilder, Converter $converter, ClassModelRegistry $classModelRegistry ) { + $this->searchCriteriaBuilder = $searchCriteriaBuilder; + $this->filterBuilder = $filterBuilder; $this->taxClassCollectionFactory = $taxClassCollectionFactory; $this->searchResultsBuilder = $searchResultsBuilder; $this->converter = $converter; @@ -261,4 +285,32 @@ class TaxClassService implements TaxClassServiceInterface $collection->addFieldToFilter($fields, $conditions); } } + + /** + * {@inheritdoc} + */ + public function getTaxClassId($taxClassKey, $taxClassType = TaxClassServiceInterface::TYPE_PRODUCT) + { + if (!empty($taxClassKey)) { + switch ($taxClassKey->getType()) { + case TaxClassKey::TYPE_ID: + return $taxClassKey->getValue(); + case TaxClassKey::TYPE_NAME: + $searchCriteria = $this->searchCriteriaBuilder->addFilter( + [$this->filterBuilder->setField(TaxClass::KEY_TYPE)->setValue($taxClassType)->create()] + )->addFilter( + [ + $this->filterBuilder->setField(TaxClass::KEY_NAME) + ->setValue($taxClassKey->getValue()) + ->create() + ] + )->create(); + $taxClasses = $this->searchTaxClass($searchCriteria)->getItems(); + $taxClass = array_shift($taxClasses); + return (null == $taxClass) ? null : $taxClass->getClassId(); + default: + } + } + return null; + } } diff --git a/app/code/Magento/Tax/Service/V1/TaxClassServiceInterface.php b/app/code/Magento/Tax/Service/V1/TaxClassServiceInterface.php index 4a1b4e48f5e5015ff33dbc90d5cbf601d6c9a17b..3e0fecaec15042a66eb3fdcdea72eb0a35ee1ba4 100644 --- a/app/code/Magento/Tax/Service/V1/TaxClassServiceInterface.php +++ b/app/code/Magento/Tax/Service/V1/TaxClassServiceInterface.php @@ -84,4 +84,13 @@ interface TaxClassServiceInterface * @throws \Magento\Framework\Exception\InputException */ public function searchTaxClass(\Magento\Framework\Service\V1\Data\SearchCriteria $searchCriteria); + + /** + * Get tax class id + * + * @param \Magento\Tax\Service\V1\Data\TaxClassKey|null $taxClassKey + * @param string $taxClassType + * @return int|null + */ + public function getTaxClassId($taxClassKey, $taxClassType = self::TYPE_PRODUCT); } diff --git a/app/code/Magento/Tax/Service/V1/TaxRateService.php b/app/code/Magento/Tax/Service/V1/TaxRateService.php index 8c35f798926f1a645df2326f75da370941574d50..2c215d528cf3acf5e48326e2ed08af0ff2a4907d 100644 --- a/app/code/Magento/Tax/Service/V1/TaxRateService.php +++ b/app/code/Magento/Tax/Service/V1/TaxRateService.php @@ -26,14 +26,14 @@ namespace Magento\Tax\Service\V1; use Magento\Framework\Exception\InputException; use Magento\Framework\Model\Exception as ModelException; +use Magento\Framework\Service\V1\Data\Search\FilterGroup; +use Magento\Framework\Service\V1\Data\SearchCriteria; +use Magento\Tax\Model\Calculation\Rate as RateModel; use Magento\Tax\Model\Calculation\Rate\Converter; use Magento\Tax\Model\Calculation\RateFactory; -use Magento\Tax\Service\V1\Data\TaxRate as TaxRateDataObject; -use Magento\Tax\Model\Calculation\Rate as RateModel; use Magento\Tax\Model\Calculation\RateRegistry; -use Magento\Framework\Service\V1\Data\SearchCriteria; use Magento\Tax\Model\Resource\Calculation\Rate\Collection; -use Magento\Framework\Service\V1\Data\Search\FilterGroup; +use Magento\Tax\Service\V1\Data\TaxRate as TaxRateDataObject; use Magento\Tax\Service\V1\Data\TaxRateBuilder; /** @@ -155,7 +155,10 @@ class TaxRateService implements TaxRateServiceInterface $sortOrders = $searchCriteria->getSortOrders(); if ($sortOrders) { foreach ($sortOrders as $field => $direction) { - $collection->addOrder($field, $direction == SearchCriteria::SORT_ASC ? 'ASC' : 'DESC'); + $collection->addOrder( + $this->translateField($field), + $direction == SearchCriteria::SORT_ASC ? 'ASC' : 'DESC' + ); } } $collection->setCurPage($searchCriteria->getCurrentPage()); @@ -285,8 +288,12 @@ class TaxRateService implements TaxRateServiceInterface if ($zipRangeFromTo['zip_from'] > $zipRangeFromTo['zip_to']) { $exception->addError('Range To should be equal or greater than Range From.'); } - + } else { + if (!\Zend_Validate::is(trim($taxRate->getPostcode()), 'NotEmpty')) { + $exception->addError(InputException::REQUIRED_FIELD, ['fieldName' => 'postcode']); + } } + if ($exception->wasErrorAdded()) { throw $exception; } diff --git a/app/code/Magento/Tax/Service/V1/TaxRuleService.php b/app/code/Magento/Tax/Service/V1/TaxRuleService.php index 22f85d053c3df79b863d2b2c19eb958c28dd1323..02f2855cb7bc73cd4b2be7ad7bd6128c81c05dd3 100644 --- a/app/code/Magento/Tax/Service/V1/TaxRuleService.php +++ b/app/code/Magento/Tax/Service/V1/TaxRuleService.php @@ -25,16 +25,18 @@ namespace Magento\Tax\Service\V1; use Magento\Framework\Exception\InputException; -use Magento\Framework\Service\V1\Data\SearchCriteria; +use Magento\Framework\Model\Exception as ModelException; +use Magento\Framework\Service\V1\Data\FilterBuilder; use Magento\Framework\Service\V1\Data\Search\FilterGroup; +use Magento\Framework\Service\V1\Data\SearchCriteria; +use Magento\Framework\Service\V1\Data\SearchCriteriaBuilder; +use Magento\Tax\Model\Calculation\Rule as TaxRuleModel; +use Magento\Tax\Model\Calculation\RuleFactory as TaxRuleModelFactory; use Magento\Tax\Model\Calculation\TaxRuleConverter; use Magento\Tax\Model\Calculation\TaxRuleRegistry; +use Magento\Tax\Model\Resource\Calculation\Rule\Collection; use Magento\Tax\Service\V1\Data\TaxRule; use Magento\Tax\Service\V1\Data\TaxRuleBuilder; -use Magento\Tax\Model\Calculation\Rule as TaxRuleModel; -use Magento\Tax\Model\Calculation\RuleFactory as TaxRuleModelFactory; -use Magento\Tax\Model\Resource\Calculation\Rule\Collection; -use Magento\Framework\Model\Exception as ModelException; /** * TaxRuleService implementation. @@ -68,25 +70,49 @@ class TaxRuleService implements TaxRuleServiceInterface */ protected $taxRuleModelFactory; + /** + * @var FilterBuilder + */ + protected $filterBuilder; + + /** + * @var TaxRateServiceInterface + */ + protected $taxRateService; + + /** + * @var SearchCriteriaBuilder + */ + protected $searchCriteriaBuilder; + /** * @param TaxRuleBuilder $taxRuleBuilder * @param TaxRuleConverter $converter * @param TaxRuleRegistry $taxRuleRegistry * @param Data\TaxRuleSearchResultsBuilder $taxRuleSearchResultsBuilder * @param TaxRuleModelFactory $taxRuleModelFactory + * @param FilterBuilder $filterBuilder + * @param TaxRateServiceInterface $taxRateService + * @param SearchCriteriaBuilder $searchCriteriaBuilder */ public function __construct( TaxRuleBuilder $taxRuleBuilder, TaxRuleConverter $converter, TaxRuleRegistry $taxRuleRegistry, Data\TaxRuleSearchResultsBuilder $taxRuleSearchResultsBuilder, - TaxRuleModelFactory $taxRuleModelFactory + TaxRuleModelFactory $taxRuleModelFactory, + FilterBuilder $filterBuilder, + TaxRateServiceInterface $taxRateService, + SearchCriteriaBuilder $searchCriteriaBuilder ) { $this->taxRuleBuilder = $taxRuleBuilder; $this->converter = $converter; $this->taxRuleRegistry = $taxRuleRegistry; $this->taxRuleSearchResultsBuilder = $taxRuleSearchResultsBuilder; $this->taxRuleModelFactory = $taxRuleModelFactory; + $this->filterBuilder = $filterBuilder; + $this->taxRateService = $taxRateService; + $this->searchCriteriaBuilder = $searchCriteriaBuilder; } /** @@ -139,16 +165,27 @@ class TaxRuleService implements TaxRuleServiceInterface $this->taxRuleSearchResultsBuilder->setSearchCriteria($searchCriteria); $collection = $this->taxRuleModelFactory->create()->getCollection(); + $fields = []; + //Add filters from root filter group to the collection foreach ($searchCriteria->getFilterGroups() as $group) { $this->addFilterGroupToCollection($group, $collection); + foreach ($group->getFilters() as $filter) { + $fields[] = $this->translateField($filter->getField()); + } + } + if ($fields) { + if (in_array('cd.customer_tax_class_id', $fields) || in_array('cd.product_tax_class_id', $fields)) { + $collection->joinCalculationData('cd'); + } } + $this->taxRuleSearchResultsBuilder->setTotalCount($collection->getSize()); $sortOrders = $searchCriteria->getSortOrders(); if ($sortOrders) { - foreach ($sortOrders as $field => $direction) { - $field = $this->translateField($field); - $collection->addOrder($field, $direction == SearchCriteria::SORT_ASC ? 'ASC' : 'DESC'); + foreach ($sortOrders as $sortField => $direction) { + $sortField = $this->translateField($sortField); + $collection->addOrder($sortField, $direction == SearchCriteria::SORT_ASC ? 'ASC' : 'DESC'); } } $collection->setCurPage($searchCriteria->getCurrentPage()); @@ -165,6 +202,44 @@ class TaxRuleService implements TaxRuleServiceInterface return $this->taxRuleSearchResultsBuilder->create(); } + /** + * {@inheritdoc} + */ + public function getRatesByCustomerAndProductTaxClassId($customerTaxClassId, $productTaxClassId) + { + $this->searchCriteriaBuilder->addFilter( + [ + $this->filterBuilder + ->setField(TaxRule::CUSTOMER_TAX_CLASS_IDS) + ->setValue([$customerTaxClassId]) + ->create(), + ] + ); + + $this->searchCriteriaBuilder->addFilter( + [ + $this->filterBuilder + ->setField(TaxRule::PRODUCT_TAX_CLASS_IDS) + ->setValue([$productTaxClassId]) + ->create(), + ] + ); + + + $searchResults = $this->searchTaxRules($this->searchCriteriaBuilder->create()); + $taxRules = $searchResults->getItems(); + $rates = []; + foreach ($taxRules as $taxRule) { + $rateIds = $taxRule->getTaxRateIds(); + if (!empty($rateIds)) { + foreach ($rateIds as $rateId) { + $rates[] = $this->taxRateService->getTaxRate($rateId); + } + } + } + return $rates; + } + /** * Helper function that adds a FilterGroup to the collection. * @@ -212,6 +287,12 @@ class TaxRuleService implements TaxRuleServiceInterface switch ($field) { case TaxRule::ID: return 'tax_calculation_rule_id'; + case TaxRule::TAX_RATE_IDS: + return 'tax_calculation_rate_id'; + case TaxRule::CUSTOMER_TAX_CLASS_IDS: + return 'cd.customer_tax_class_id'; + case TaxRule::PRODUCT_TAX_CLASS_IDS: + return 'cd.product_tax_class_id'; case TaxRule::SORT_ORDER: return 'position'; default: @@ -258,6 +339,10 @@ class TaxRuleService implements TaxRuleServiceInterface { $exception = new InputException(); + // SortOrder is required and must be 0 or greater + if (!\Zend_Validate::is(trim($rule->getSortOrder()), 'NotEmpty')) { + $exception->addError(InputException::REQUIRED_FIELD, ['fieldName' => TaxRule::SORT_ORDER]); + } if (!\Zend_Validate::is(trim($rule->getSortOrder()), 'GreaterThan', [-1])) { $exception->addError( InputException::INVALID_FIELD_MIN_VALUE, @@ -265,6 +350,10 @@ class TaxRuleService implements TaxRuleServiceInterface ); } + // Priority is required and must be 0 or greater + if (!\Zend_Validate::is(trim($rule->getPriority()), 'NotEmpty')) { + $exception->addError(InputException::REQUIRED_FIELD, ['fieldName' => TaxRule::PRIORITY]); + } if (!\Zend_Validate::is(trim($rule->getPriority()), 'GreaterThan', [-1])) { $exception->addError( InputException::INVALID_FIELD_MIN_VALUE, diff --git a/app/code/Magento/Tax/Service/V1/TaxRuleServiceInterface.php b/app/code/Magento/Tax/Service/V1/TaxRuleServiceInterface.php index 7f031b65a0c6a6f35d784b330ab4558f2609c652..92a5f66116c78bb9193e2abb1db7e632070f5120 100644 --- a/app/code/Magento/Tax/Service/V1/TaxRuleServiceInterface.php +++ b/app/code/Magento/Tax/Service/V1/TaxRuleServiceInterface.php @@ -76,4 +76,13 @@ interface TaxRuleServiceInterface * @throws \Magento\Framework\Exception\InputException If there is a problem with the input */ public function searchTaxRules(\Magento\Framework\Service\V1\Data\SearchCriteria $searchCriteria); + + /** + * Get rates by customerTaxClassId and productTaxClassId + * + * @param int $customerTaxClassId + * @param int $productTaxClassId + * @return \Magento\Tax\Service\V1\Data\TaxRate[] + */ + public function getRatesByCustomerAndProductTaxClassId($customerTaxClassId, $productTaxClassId); } diff --git a/app/code/Magento/Tax/etc/module.xml b/app/code/Magento/Tax/etc/module.xml index 45ddd128035b102f7077c85966969e88c70b0e4d..1d69d97aeef6479dc64450cab358d7f6863c37d4 100644 --- a/app/code/Magento/Tax/etc/module.xml +++ b/app/code/Magento/Tax/etc/module.xml @@ -24,7 +24,7 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd"> - <module name="Magento_Tax" schema_version="1.6.0.6" active="true"> + <module name="Magento_Tax" schema_version="1.6.0.7" active="true"> <sequence> <module name="Magento_Catalog"/> <module name="Magento_Customer"/> diff --git a/app/code/Magento/Tax/etc/webapi.xml b/app/code/Magento/Tax/etc/webapi.xml index 84934d0208507f9b8a3240b95f865f3a0982dc84..24fd425954f18db87ef201eb5ae47b676be7359f 100644 --- a/app/code/Magento/Tax/etc/webapi.xml +++ b/app/code/Magento/Tax/etc/webapi.xml @@ -49,6 +49,12 @@ <resource ref="Magento_Tax::manage_tax"/> </resources> </route> + <route url="/V1/taxRate/search" method="PUT"> + <service class="Magento\Tax\Service\V1\TaxRateServiceInterface" method="searchTaxRates"/> + <resources> + <resource ref="Magento_Tax::manage_tax"/> + </resources> + </route> <route url="/V1/taxRules" method="POST"> <service class="Magento\Tax\Service\V1\TaxRuleServiceInterface" method="createTaxRule"/> <resources> diff --git a/app/code/Magento/Tax/sql/tax_setup/install-1.6.0.0.php b/app/code/Magento/Tax/sql/tax_setup/install-1.6.0.0.php index dd256acaf2396b63dd093a1192793bbd20552985..446d00f7ac5556bc1dac827f51c7af5b8121c79b 100644 --- a/app/code/Magento/Tax/sql/tax_setup/install-1.6.0.0.php +++ b/app/code/Magento/Tax/sql/tax_setup/install-1.6.0.0.php @@ -418,11 +418,11 @@ $catalogInstaller->addAttribute( 'required' => true, 'user_defined' => false, 'default' => '', - 'searchable' => true, + 'searchable' => false, 'filterable' => false, 'comparable' => false, 'visible_on_front' => false, - 'visible_in_advanced_search' => true, + 'visible_in_advanced_search' => false, 'used_in_product_listing' => true, 'unique' => false, 'apply_to' => implode($this->getTaxableItems(), ',') diff --git a/app/code/Magento/Tax/sql/tax_setup/upgrade-1.6.0.6-1.6.0.7.php b/app/code/Magento/Tax/sql/tax_setup/upgrade-1.6.0.6-1.6.0.7.php new file mode 100644 index 0000000000000000000000000000000000000000..ee47d2d995693616ac86b72585e7e6ffc2b4f424 --- /dev/null +++ b/app/code/Magento/Tax/sql/tax_setup/upgrade-1.6.0.6-1.6.0.7.php @@ -0,0 +1,113 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +/** @var \Magento\Tax\Model\Resource\Setup $installer */ +$installer = $this; +$connection = $installer->getConnection(); + +/** + * Add new field to 'sales_order_tax_item' + */ +$connection->addColumn( + $installer->getTable('sales_order_tax_item'), + 'amount', + [ + 'TYPE' => \Magento\Framework\DB\Ddl\Table::TYPE_DECIMAL, + 'SCALE' => 4, + 'PRECISION' => 12, + 'NULLABLE' => false, + 'COMMENT' => 'Tax amount for the item and tax rate.' + ] +); +$connection->addColumn( + $installer->getTable('sales_order_tax_item'), + 'base_amount', + [ + 'TYPE' => \Magento\Framework\DB\Ddl\Table::TYPE_DECIMAL, + 'SCALE' => 4, + 'PRECISION' => 12, + 'NULLABLE' => false, + 'COMMENT' => 'Base tax amount for the item and tax rate.' + ] +); +$connection->addColumn( + $installer->getTable('sales_order_tax_item'), + 'real_amount', + [ + 'TYPE' => \Magento\Framework\DB\Ddl\Table::TYPE_DECIMAL, + 'SCALE' => 4, + 'PRECISION' => 12, + 'NULLABLE' => false, + 'COMMENT' => 'Real tax amount for the item and tax rate.' + ] +); +$connection->addColumn( + $installer->getTable('sales_order_tax_item'), + 'real_base_amount', + [ + 'TYPE' => \Magento\Framework\DB\Ddl\Table::TYPE_DECIMAL, + 'SCALE' => 4, + 'PRECISION' => 12, + 'NULLABLE' => false, + 'COMMENT' => 'Real base tax amount for the item and tax rate.' + ] +); +$connection->addColumn( + $installer->getTable('sales_order_tax_item'), + 'associated_item_id', + [ + 'TYPE' => \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER, + 'UNSIGNED' => true, + 'NULLABLE' => true, + 'COMMENT' => 'Id of the associated item.' + ] +); +$connection->addColumn( + $installer->getTable('sales_order_tax_item'), + 'taxable_item_type', + [ + 'TYPE' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT, + 'length' => 32, + 'NULLABLE' => false, + 'COMMENT' => 'Type of the taxable item.' + ] +); +$connection->changeColumn( + $installer->getTable('sales_order_tax_item'), + 'item_id', + 'item_id', + [ + 'TYPE' => \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER, + 'NULLABLE' => true, + 'UNSIGNED' => true, + 'COMMENT' => 'Item Id', + ] +); +$connection->addForeignKey( + $installer->getFkName('sales_order_tax_item', 'associated_item_id', 'sales_flat_order_item', 'item_id'), + $installer->getTable('sales_order_tax_item'), + 'associated_item_id', + $installer->getTable('sales_flat_order_item'), + 'item_id' +); diff --git a/app/code/Magento/Tax/view/adminhtml/layout/tax_rate_block.xml b/app/code/Magento/Tax/view/adminhtml/layout/tax_rate_block.xml index 80a0368ed5665c54a0b7c2544f314873e5ff3634..b3909d69eb580319914779410561a6d26f307c0a 100644 --- a/app/code/Magento/Tax/view/adminhtml/layout/tax_rate_block.xml +++ b/app/code/Magento/Tax/view/adminhtml/layout/tax_rate_block.xml @@ -61,7 +61,7 @@ <arguments> <argument name="header" xsi:type="string" translate="true">Tax Identifier</argument> <argument name="header_export" xsi:type="string" translate="true">Code</argument> - <argument name="filter_index" xsi:type="string">main_table.code</argument> + <argument name="filter_index" xsi:type="string">code</argument> <argument name="index" xsi:type="string">code</argument> <argument name="column_css_class" xsi:type="string">col-name</argument> <argument name="header_css_class" xsi:type="string">col-name</argument> @@ -71,7 +71,7 @@ <arguments> <argument name="header" xsi:type="string" translate="true">Country</argument> <argument name="type" xsi:type="string">country</argument> - <argument name="filter_index" xsi:type="string">main_table.tax_country_id</argument> + <argument name="filter_index" xsi:type="string">tax_country_id</argument> <argument name="index" xsi:type="string">tax_country_id</argument> <argument name="renderer" xsi:type="string">Magento\Tax\Block\Adminhtml\Rate\Grid\Renderer\Country</argument> <argument name="sortable" xsi:type="string">0</argument> @@ -81,7 +81,7 @@ <arguments> <argument name="header" xsi:type="string" translate="true">State/Region</argument> <argument name="header_export" xsi:type="string" translate="true">State</argument> - <argument name="filter_index" xsi:type="string">region_table.code</argument> + <argument name="filter_index" xsi:type="string">region_name</argument> <argument name="index" xsi:type="string">region_name</argument> <argument name="default" xsi:type="string">*</argument> </arguments> diff --git a/app/code/Magento/Tax/view/frontend/templates/checkout/tax.phtml b/app/code/Magento/Tax/view/frontend/templates/checkout/tax.phtml index f89e769ac0d7f51d1b647779693c47d9f2851df4..9bc2d80357614dfbe57961b48a3c314b9bdc4ea9 100644 --- a/app/code/Magento/Tax/view/frontend/templates/checkout/tax.phtml +++ b/app/code/Magento/Tax/view/frontend/templates/checkout/tax.phtml @@ -31,39 +31,11 @@ $_style = $this->getTotal()->getStyle(); ?> <?php global $taxIter; $taxIter++; ?> -<?php if ($this->helper('Magento\Tax\Helper\Data')->displayFullSummary() && $_value!=0): ?> -<?php $isTop = 1; ?> - <?php foreach ($this->getTotal()->getFullInfo() as $info): ?> - <?php if (isset($info['hidden']) && $info['hidden']) continue; ?> - <?php $percent = $info['percent']; ?> - <?php $amount = $info['amount']; ?> - <?php $rates = $info['rates']; ?> - <?php $isFirst = 1; ?> - <?php foreach ($rates as $rate): ?> - <tr class="totals tax details details-<?php echo $taxIter; ?>"> - <td class="mark" style="<?php echo $_style ?>" colspan="<?php echo $this->getColspan(); ?>"> - <?php echo $this->escapeHtml($rate['title']); ?> - <?php if (!is_null($rate['percent'])): ?> - (<?php echo (float)$rate['percent']; ?>%) - <?php endif; ?> - <br /> - </td> - <?php if ($isFirst): ?> - <td style="<?php echo $_style ?>" class="amount" rowspan="<?php echo count($rates); ?>"> - <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($amount); ?> - </td> - <?php endif; ?> - </tr> - <?php $isFirst = 0; ?> - <?php $isTop = 0; ?> - <?php endforeach; ?> - <?php endforeach; ?> -<?php endif;?> <?php - $attributes = 'class="totals tax"'; + $attributes = 'class="totals-tax"'; if ($this->helper('Magento\Tax\Helper\Data')->displayFullSummary() && $_value!=0) { - $attributes = 'class="totals tax summary" data-mage-init=\'{"toggleAdvanced": {"selectorsToggleClass": "shown", "baseToggleClass": "expanded", "toggleContainers": ".totals.tax.details"}}\''; + $attributes = 'class="totals-tax-summary" data-mage-init=\'{"toggleAdvanced": {"selectorsToggleClass": "shown", "baseToggleClass": "expanded", "toggleContainers": ".totals-tax-details"}}\''; } ?> @@ -77,3 +49,33 @@ </td> <td style="<?php echo $_style ?>" class="amount"><?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_value) ?></td> </tr> + +<?php if ($this->helper('Magento\Tax\Helper\Data')->displayFullSummary() && $_value!=0): ?> + <?php $isTop = 1; ?> + <?php foreach ($this->getTotal()->getFullInfo() as $info): ?> + <?php if (isset($info['hidden']) && $info['hidden']) continue; ?> + <?php $percent = $info['percent']; ?> + <?php $amount = $info['amount']; ?> + <?php $rates = $info['rates']; ?> + <?php $isFirst = 1; ?> + + <?php foreach ($rates as $rate): ?> + <tr class="totals-tax-details details-<?php echo $taxIter; ?>"> + <td class="mark" style="<?php echo $_style ?>" colspan="<?php echo $this->getColspan(); ?>"> + <?php echo $this->escapeHtml($rate['title']); ?> + <?php if (!is_null($rate['percent'])): ?> + (<?php echo (float)$rate['percent']; ?>%) + <?php endif; ?> + <br /> + </td> + <?php if ($isFirst): ?> + <td style="<?php echo $_style ?>" class="amount" rowspan="<?php echo count($rates); ?>"> + <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($amount); ?> + </td> + <?php endif; ?> + </tr> + <?php $isFirst = 0; ?> + <?php $isTop = 0; ?> + <?php endforeach; ?> + <?php endforeach; ?> +<?php endif;?> diff --git a/app/code/Magento/Tax/view/frontend/templates/order/tax.phtml b/app/code/Magento/Tax/view/frontend/templates/order/tax.phtml index 21593380d2425db4bad49d8032f5a46e567027c3..cf069d794c268850213777051cdc27a3c92dac31 100644 --- a/app/code/Magento/Tax/view/frontend/templates/order/tax.phtml +++ b/app/code/Magento/Tax/view/frontend/templates/order/tax.phtml @@ -41,7 +41,7 @@ ?> <?php foreach ($rates as $rate): ?> <tr class="totals tax details details-<?php echo $taxIter; ?> <?php echo ($this->getIsPlaneMode()) ? ' plane' : '';?>"> - <td class="mark" <?php echo $this->getLabelProperties()?>> + <td <?php echo $this->getLabelProperties()?>> <?php echo $this->escapeHtml($rate['title']); ?> <?php if (!is_null($rate['percent'])): ?> (<?php echo (float)$rate['percent']; ?>%) @@ -49,7 +49,7 @@ <br /> </td> <?php if ($isFirst): ?> - <td class="amount" <?php echo $this->getValueProperties()?> rowspan="<?php echo count($rates); ?>"> + <td <?php echo $this->getValueProperties()?> rowspan="<?php echo count($rates); ?>"> <?php echo $_order->formatPrice($amount); ?> </td> <?php endif; ?> @@ -61,18 +61,18 @@ <?php endif;?> <?php if ($this->displayFullSummary() && $_fullInfo && !$this->getIsPlaneMode()): ?> -<tr class="totals tax summary"> +<tr class="totals-tax-summary"> <?php elseif ($this->displayFullSummary() && $_fullInfo && $this->getIsPlaneMode()): ?> -<tr class="totals tax summary plane"> +<tr class="totals-tax-summary plane"> <?php else: ?> -<tr class="totals tax"> +<tr class="totals-tax"> <?php endif; ?> - <td class="mark" <?php echo $this->getLabelProperties()?>> + <td <?php echo $this->getLabelProperties()?>> <?php if ($this->displayFullSummary()): ?> <div class="detailed"><?php echo __('Tax'); ?></div> <?php else: ?> <?php echo __('Tax'); ?> <?php endif;?> </td> - <td class="amount" <?php echo $this->getValueProperties()?>><?php echo $_order->formatPrice($_source->getTaxAmount()) ?></td> + <td <?php echo $this->getValueProperties()?>><?php echo $_order->formatPrice($_source->getTaxAmount()) ?></td> </tr> diff --git a/app/code/Magento/Theme/view/frontend/layout/default_head_blocks.xml b/app/code/Magento/Theme/view/frontend/layout/default_head_blocks.xml index 5f825917ac5ac9d9294386b71e44f0be53d2e919..b041e7e658e6f4d7d273cf5569eb7a89abf6dd12 100644 --- a/app/code/Magento/Theme/view/frontend/layout/default_head_blocks.xml +++ b/app/code/Magento/Theme/view/frontend/layout/default_head_blocks.xml @@ -51,6 +51,11 @@ <argument name="file" xsi:type="string">mage/jquery-no-conflict.js</argument> </arguments> </block> + <block class="Magento\Theme\Block\Html\Head\Script" name="jquery-mobile-custom-js"> + <arguments> + <argument name="file" xsi:type="string">jquery/jquery.mobile.custom.js</argument> + </arguments> + </block> <block class="Magento\Theme\Block\Html\Head\Script" name="js-head-js"> <arguments> <argument name="file" xsi:type="string">headjs/head.min.js</argument> diff --git a/app/code/Magento/Theme/view/frontend/templates/html/pager.phtml b/app/code/Magento/Theme/view/frontend/templates/html/pager.phtml index 8ed2a090f765c63d6fc27bc4b9e66e50492a3e9c..85171d2ccfe9e8b2c41b7ed01f3b647f31328152 100644 --- a/app/code/Magento/Theme/view/frontend/templates/html/pager.phtml +++ b/app/code/Magento/Theme/view/frontend/templates/html/pager.phtml @@ -35,39 +35,26 @@ <div class="pager"> <?php endif ?> - <?php if($this->getShowAmounts()): ?> - <p class="amount"> - <?php if($this->getLastPageNum()>1): ?> - <?php echo __('Items %1 to %2 of %3 total', $this->getFirstNum(), $this->getLastNum(), $this->getTotalNum()) ?> - <?php elseif ($this->getLastPageNum() == 1): ?> - <?php echo __('%1 Item', $this->getTotalNum()) ?> - <?php else: ?> - <?php echo __('%1 Item(s)', $this->getTotalNum()) ?> - <?php endif; ?> - </p> - <?php endif ?> - - <?php if($this->isShowPerPage()): ?> - <div class="limiter"> - <strong class="label"><?php echo __('Show') ?></strong> - <select id="limiter" data-mage-redirect="{'event':'change'}"> - <?php foreach ($this->getAvailableLimit() as $_key => $_limit): ?> - <option value="<?php echo $this->getLimitUrl($_key) ?>"<?php if ($this->isLimitCurrent($_key)): ?> - selected="selected"<?php endif ?>> - <?php echo $_limit ?> - </option> - <?php endforeach; ?> - </select> - <span class="text"><?php echo __('per page') ?></span> - </div> + <?php if($this->getShowAmounts()): ?> + <p class="toolbar-amount"> + <span class="toolbar-number"> + <?php if($this->getLastPageNum()>1): ?> + <?php echo __('Items %1 to %2 of %3 total', $this->getFirstNum(), $this->getLastNum(), $this->getTotalNum()) ?> + <?php elseif ($this->getLastPageNum() == 1): ?> + <?php echo __('%1 Item', $this->getTotalNum()) ?> + <?php else: ?> + <?php echo __('%1 Item(s)', $this->getTotalNum()) ?> + <?php endif; ?> + </span> + </p> <?php endif ?> <?php if($this->getLastPageNum()>1): ?> <div class="pages"> - <strong class="label" id="paging-label"><?php echo __('Page') ?></strong> - <ul class="items" aria-labelledby="paging-label"> + <strong class="label pages-label" id="paging-label"><?php echo __('Page') ?></strong> + <ul class="items pages-items" aria-labelledby="paging-label"> <?php if (!$this->isFirstPage()): ?> - <li class="item"> + <li class="item pages-item-previous"> <?php $text = $this->getAnchorTextForPrevious() ? $this->getAnchorTextForPrevious() : '';?> <a class="<?php echo $text ? 'link ' : 'action '?> previous" href="<?php echo $this->getPreviousPageUrl() ?>" title="<?php echo $text ? $text : __('Previous') ?>"> <span class="label"><?php echo __('Page') ?></span> @@ -129,7 +116,7 @@ <?php endif;?> <?php if (!$this->isLastPage()): ?> - <li class="item"> + <li class="item pages-item-next"> <?php $text = $this->getAnchorTextForNext() ? $this->getAnchorTextForNext() : '';?> <a class="<?php echo $text ? 'link ' : 'action '?> next" href="<?php echo $this->getNextPageUrl() ?>" title="<?php echo $text ? $text : __('Next') ?>"> <span class="label"><?php echo __('Page') ?></span> @@ -141,6 +128,21 @@ </div> <?php endif; ?> + <?php if($this->isShowPerPage()): ?> + <div class="limiter"> + <strong class="limiter-label"><?php echo __('Show') ?></strong> + <select id="limiter" data-mage-redirect="{'event':'change'}" class="limiter-options"> + <?php foreach ($this->getAvailableLimit() as $_key => $_limit): ?> + <option value="<?php echo $this->getLimitUrl($_key) ?>"<?php if ($this->isLimitCurrent($_key)): ?> + selected="selected"<?php endif ?>> + <?php echo $_limit ?> + </option> + <?php endforeach; ?> + </select> + <span class="limiter-text"><?php echo __('per page') ?></span> + </div> + <?php endif ?> + <?php if($this->getUseContainer()): ?> </div> <?php endif ?> diff --git a/app/code/Magento/Translation/Model/Js/DataProvider.php b/app/code/Magento/Translation/Model/Js/DataProvider.php index 2908b845229328c779c983644e66821fe70eaf5b..6dc3e5edbcbfe6d958814edabe8797aaee1ee18d 100644 --- a/app/code/Magento/Translation/Model/Js/DataProvider.php +++ b/app/code/Magento/Translation/Model/Js/DataProvider.php @@ -175,6 +175,7 @@ class DataProvider implements DataProviderInterface 'Ok' => __('Ok'), 'Please specify at least one search term.' => __('Please specify at least one search term.'), 'Create New Wish List' => __('Create New Wish List'), + 'Click Details for more required fields.' => __('Click Details for more required fields.'), ); } } diff --git a/app/code/Magento/Translation/Model/Resource/Translate.php b/app/code/Magento/Translation/Model/Resource/Translate.php index 3cf0b2bccead154fc40ecced3301294a9ea0b8a9..180e00f407106dcd975c691ceea579040e304712 100644 --- a/app/code/Magento/Translation/Model/Resource/Translate.php +++ b/app/code/Magento/Translation/Model/Resource/Translate.php @@ -90,16 +90,11 @@ class Translate extends \Magento\Framework\Model\Resource\Db\AbstractDb implemen return array(); } - $select = $adapter->select()->from( - $this->getMainTable(), - array('string', 'translate') - )->where( - 'store_id IN (0 , :store_id)' - )->where( - 'locale = :locale' - )->order( - 'store_id' - ); + $select = $adapter->select() + ->from($this->getMainTable(), array('string', 'translate')) + ->where('store_id IN (0 , :store_id)') + ->where('locale = :locale') + ->order('store_id'); $bind = array(':locale' => (string)$locale, ':store_id' => $storeId); @@ -133,15 +128,10 @@ class Translate extends \Magento\Framework\Model\Resource\Db\AbstractDb implemen } $bind = array(':store_id' => $storeId); - $select = $adapter->select()->from( - $this->getMainTable(), - array('string', 'translate') - )->where( - 'string IN (?)', - $strings - )->where( - 'store_id = :store_id' - ); + $select = $adapter->select() + ->from($this->getMainTable(), array('string', 'translate')) + ->where('string IN (?)', $strings) + ->where('store_id = :store_id'); return $adapter->fetchPairs($select, $bind); } diff --git a/app/code/Magento/UrlRedirect/Block/Catalog/Category/Edit.php b/app/code/Magento/UrlRedirect/Block/Catalog/Category/Edit.php new file mode 100644 index 0000000000000000000000000000000000000000..a0316d07eafb8c7317aa8e4771493a034e55e5f2 --- /dev/null +++ b/app/code/Magento/UrlRedirect/Block/Catalog/Category/Edit.php @@ -0,0 +1,131 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\UrlRedirect\Block\Catalog\Category; + +/** + * Block for Catalog Category URL rewrites + */ +class Edit extends \Magento\UrlRedirect\Block\Edit +{ + /** + * @var \Magento\Catalog\Model\CategoryFactory + */ + protected $_categoryFactory; + + /** + * @param \Magento\Backend\Block\Widget\Context $context + * @param \Magento\UrlRedirect\Model\UrlRedirectFactory $rewriteFactory + * @param \Magento\Backend\Helper\Data $adminhtmlData + * @param \Magento\Catalog\Model\CategoryFactory $categoryFactory + * @param array $data + */ + public function __construct( + \Magento\Backend\Block\Widget\Context $context, + \Magento\UrlRedirect\Model\UrlRedirectFactory $rewriteFactory, + \Magento\Backend\Helper\Data $adminhtmlData, + \Magento\Catalog\Model\CategoryFactory $categoryFactory, + array $data = array() + ) { + $this->_categoryFactory = $categoryFactory; + parent::__construct($context, $rewriteFactory, $adminhtmlData, $data); + } + + /** + * Prepare layout for URL rewrite creating for category + * + * @return void + */ + protected function _prepareLayoutFeatures() + { + if ($this->_getUrlRewrite()->getId()) { + $this->_headerText = __('Edit URL Rewrite for a Category'); + } else { + $this->_headerText = __('Add URL Rewrite for a Category'); + } + + if ($this->_getCategory()->getId()) { + $this->_addCategoryLinkBlock(); + $this->_addEditFormBlock(); + $this->_updateBackButtonLink($this->_adminhtmlData->getUrl('adminhtml/*/edit') . 'category'); + } else { + $this->_addUrlRewriteSelectorBlock(); + $this->_addCategoryTreeBlock(); + } + } + + /** + * Get or create new instance of category + * + * @return \Magento\Catalog\Model\Product + */ + private function _getCategory() + { + if (!$this->hasData('category')) { + $this->setCategory($this->_categoryFactory->create()); + } + return $this->getCategory(); + } + + /** + * Add child category link block + * + * @return void + */ + private function _addCategoryLinkBlock() + { + $this->addChild( + 'category_link', + 'Magento\UrlRedirect\Block\Link', + array( + 'item_url' => $this->_adminhtmlData->getUrl('adminhtml/*/*') . 'category', + 'item_name' => $this->_getCategory()->getName(), + 'label' => __('Category:') + ) + ); + } + + /** + * Add child category tree block + * + * @return void + */ + private function _addCategoryTreeBlock() + { + $this->addChild('categories_tree', 'Magento\UrlRedirect\Block\Catalog\Category\Tree'); + } + + /** + * Creates edit form block + * + * @return \Magento\UrlRedirect\Block\Catalog\Edit\Form + */ + protected function _createEditFormBlock() + { + return $this->getLayout()->createBlock( + 'Magento\UrlRedirect\Block\Catalog\Edit\Form', + '', + array('data' => array('category' => $this->_getCategory(), 'url_rewrite' => $this->_getUrlRewrite())) + ); + } +} diff --git a/app/code/Magento/UrlRedirect/Block/Catalog/Category/Tree.php b/app/code/Magento/UrlRedirect/Block/Catalog/Category/Tree.php new file mode 100644 index 0000000000000000000000000000000000000000..4032848799915ef11e5739579024931869440bad --- /dev/null +++ b/app/code/Magento/UrlRedirect/Block/Catalog/Category/Tree.php @@ -0,0 +1,196 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\UrlRedirect\Block\Catalog\Category; + +/** + * Categories tree block for URL rewrites editing process + * + * @author Magento Core Team <core@magentocommerce.com> + */ +class Tree extends \Magento\Catalog\Block\Adminhtml\Category\AbstractCategory +{ + /** + * List of allowed category ids + * + * @var int[]|null + */ + protected $_allowedCategoryIds = null; + + /** + * @var string + */ + protected $_template = 'categories.phtml'; + + /** + * Adminhtml data + * + * @var \Magento\Backend\Helper\Data + */ + protected $_adminhtmlData = null; + + /** + * @var \Magento\Catalog\Model\CategoryFactory + */ + protected $_categoryFactory; + + /** + * @var \Magento\Catalog\Model\ProductFactory + */ + protected $_productFactory; + + /** + * @var \Magento\Framework\Json\EncoderInterface + */ + protected $_jsonEncoder; + + /** + * @param \Magento\Backend\Block\Widget\Context $context + * @param \Magento\Catalog\Model\Resource\Category\Tree $categoryTree + * @param \Magento\Framework\Registry $registry + * @param \Magento\Framework\Json\EncoderInterface $jsonEncoder + * @param \Magento\Catalog\Model\ProductFactory $productFactory + * @param \Magento\Catalog\Model\CategoryFactory $categoryFactory + * @param \Magento\Backend\Helper\Data $adminhtmlData + * @param array $data + */ + public function __construct( + \Magento\Backend\Block\Widget\Context $context, + \Magento\Catalog\Model\Resource\Category\Tree $categoryTree, + \Magento\Framework\Registry $registry, + \Magento\Catalog\Model\CategoryFactory $categoryFactory, + \Magento\Framework\Json\EncoderInterface $jsonEncoder, + \Magento\Catalog\Model\ProductFactory $productFactory, + \Magento\Backend\Helper\Data $adminhtmlData, + array $data = array() + ) { + $this->_jsonEncoder = $jsonEncoder; + $this->_categoryFactory = $categoryFactory; + $this->_productFactory = $productFactory; + $this->_adminhtmlData = $adminhtmlData; + parent::__construct($context, $categoryTree, $registry, $categoryFactory, $data); + } + + /** + * Get categories tree as recursive array + * + * @param int $parentId + * @param bool $asJson + * @param int $recursionLevel + * @return array + */ + public function getTreeArray($parentId = null, $asJson = false, $recursionLevel = 3) + { + $productId = $this->_request->getParam('product'); + if ($productId) { + $product = $this->_productFactory->create()->setId($productId); + $this->_allowedCategoryIds = $product->getCategoryIds(); + unset($product); + } + + $result = array(); + if ($parentId) { + $category = $this->_categoryFactory->create()->load($parentId); + if (!empty($category)) { + $tree = $this->_getNodesArray($this->getNode($category, $recursionLevel)); + if (!empty($tree) && !empty($tree['children'])) { + $result = $tree['children']; + } + } + } else { + $result = $this->_getNodesArray($this->getRoot(null, $recursionLevel)); + } + + if ($asJson) { + return $this->_jsonEncoder->encode($result); + } + + $this->_allowedCategoryIds = null; + + return $result; + } + + /** + * Get categories collection + * + * @return \Magento\Catalog\Model\Resource\Category\Collection + */ + public function getCategoryCollection() + { + $collection = $this->_getData('category_collection'); + if (is_null($collection)) { + $collection = $this->_categoryFactory->create()->getCollection()->addAttributeToSelect( + array('name', 'is_active') + )->setLoadProductCount( + true + ); + $this->setData('category_collection', $collection); + } + + return $collection; + } + + /** + * Convert categories tree to array recursively + * + * @param \Magento\Framework\Data\Tree\Node $node + * @return array + */ + protected function _getNodesArray($node) + { + $result = array( + 'id' => (int)$node->getId(), + 'parent_id' => (int)$node->getParentId(), + 'children_count' => (int)$node->getChildrenCount(), + 'is_active' => (bool)$node->getIsActive(), + 'name' => $node->getName(), + 'level' => (int)$node->getLevel(), + 'product_count' => (int)$node->getProductCount() + ); + + if (is_array($this->_allowedCategoryIds) && !in_array($result['id'], $this->_allowedCategoryIds)) { + $result['disabled'] = true; + } + + if ($node->hasChildren()) { + $result['children'] = array(); + foreach ($node->getChildren() as $childNode) { + $result['children'][] = $this->_getNodesArray($childNode); + } + } + $result['cls'] = ($result['is_active'] ? '' : 'no-') . 'active-category'; + $result['expanded'] = !empty($result['children']); + + return $result; + } + + /** + * Get URL for categories tree ajax loader + * + * @return string + */ + public function getLoadTreeUrl() + { + return $this->_adminhtmlData->getUrl('adminhtml/*/categoriesJson'); + } +} diff --git a/app/code/Magento/UrlRedirect/Block/Catalog/Edit/Form.php b/app/code/Magento/UrlRedirect/Block/Catalog/Edit/Form.php new file mode 100644 index 0000000000000000000000000000000000000000..0875908a272676c642eb2f4bf6bd4d1e2e215703 --- /dev/null +++ b/app/code/Magento/UrlRedirect/Block/Catalog/Edit/Form.php @@ -0,0 +1,222 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +/** + * Edit form for Catalog product and category URL rewrites + */ +namespace Magento\UrlRedirect\Block\Catalog\Edit; + +use Magento\UrlRedirect\Controller\Adminhtml\UrlRedirect; + +/** + * @SuppressWarnings(PHPMD.DepthOfInheritance) + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ +class Form extends \Magento\UrlRedirect\Block\Edit\Form +{ + /** + * @var \Magento\Catalog\Model\Url + */ + protected $_catalogUrl; + + /** + * @var \Magento\Catalog\Model\ProductFactory + */ + protected $_productFactory; + + /** + * @var \Magento\Catalog\Model\CategoryFactory + */ + protected $_categoryFactory; + + /** + * @param \Magento\Backend\Block\Widget\Context $context + * @param \Magento\Framework\Registry $registry + * @param \Magento\Framework\Data\FormFactory $formFactory + * @param \Magento\UrlRedirect\Model\OptionProviderFactory $optionFactory + * @param \Magento\UrlRedirect\Model\UrlRedirectFactory $rewriteFactory + * @param \Magento\Store\Model\System\Store $systemStore + * @param \Magento\Backend\Helper\Data $adminhtmlData + * @param \Magento\Catalog\Model\ProductFactory $productFactory + * @param \Magento\Catalog\Model\CategoryFactory $categoryFactory + * @param \Magento\Catalog\Model\Url $catalogUrl + * @param array $data + * + * @SuppressWarnings(PHPMD.ExcessiveParameterList) + */ + public function __construct( + \Magento\Backend\Block\Widget\Context $context, + \Magento\Framework\Registry $registry, + \Magento\Framework\Data\FormFactory $formFactory, + \Magento\UrlRedirect\Model\OptionProviderFactory $optionFactory, + \Magento\UrlRedirect\Model\UrlRedirectFactory $rewriteFactory, + \Magento\Store\Model\System\Store $systemStore, + \Magento\Backend\Helper\Data $adminhtmlData, + \Magento\Catalog\Model\ProductFactory $productFactory, + \Magento\Catalog\Model\CategoryFactory $categoryFactory, + \Magento\Catalog\Model\Url $catalogUrl, + array $data = array() + ) { + $this->_productFactory = $productFactory; + $this->_categoryFactory = $categoryFactory; + $this->_catalogUrl = $catalogUrl; + parent::__construct( + $context, + $registry, + $formFactory, + $optionFactory, + $rewriteFactory, + $systemStore, + $adminhtmlData, + $data + ); + } + + /** + * Form post init + * + * @param \Magento\Framework\Data\Form $form + * @return $this + */ + protected function _formPostInit($form) + { + $form->setAction( + $this->_adminhtmlData->getUrl( + 'adminhtml/*/save', + array( + 'id' => $this->_getModel()->getId(), + 'product' => $this->_getProduct()->getId(), + 'category' => $this->_getCategory()->getId() + ) + ) + ); + + /** @var $requestPath \Magento\Framework\Data\Form\Element\AbstractElement */ + $requestPath = $this->getForm()->getElement('request_path'); + /** @var $targetPath \Magento\Framework\Data\Form\Element\AbstractElement */ + $targetPath = $this->getForm()->getElement('target_path'); + + $model = $this->_getModel(); + $disablePaths = false; + if (!$model->getId()) { + $product = null; + $category = null; + if ($this->_getProduct()->getId()) { + $product = $this->_getProduct(); + $category = $this->_getCategory(); + } elseif ($this->_getCategory()->getId()) { + $category = $this->_getCategory(); + } + + if ($product || $category) { + $sessionData = $this->_getSessionData(); + if (!isset($sessionData['request_path'])) { + $requestPath->setValue($this->_catalogUrl->generatePath('request', $product, $category, '')); + } + $targetPath->setValue($this->_catalogUrl->generatePath('target', $product, $category)); + $disablePaths = true; + } + } else { + $disablePaths = in_array( + $model->getEntityType(), + [UrlRedirect::ENTITY_TYPE_PRODUCT, UrlRedirect::ENTITY_TYPE_CATEGORY, UrlRedirect::ENTITY_TYPE_CMS_PAGE] + ); + } + + if ($disablePaths) { + $targetPath->setData('disabled', true); + } + + return $this; + } + + /** + * Get catalog entity associated stores + * + * @return array + * @throws \Magento\Store\Model\Exception + */ + protected function _getEntityStores() + { + $product = $this->_getProduct(); + $category = $this->_getCategory(); + $entityStores = array(); + + // showing websites that only associated to products + if ($product->getId()) { + $entityStores = (array)$product->getStoreIds(); + + //if category is chosen, reset stores which are not related with this category + if ($category->getId()) { + $categoryStores = (array)$category->getStoreIds(); + $entityStores = array_intersect($entityStores, $categoryStores); + } + if (!$entityStores) { + throw new \Magento\Store\Model\Exception( + __( + 'We can\'t set up a URL rewrite because the product you chose is not associated with a website.' + ) + ); + } + $this->_requireStoresFilter = true; + } elseif ($category->getId()) { + $entityStores = (array)$category->getStoreIds(); + $message = __( + 'We can\'t set up a URL rewrite because the category your chose is not associated with a website.' + ); + if (!$entityStores) { + throw new \Magento\Store\Model\Exception($message); + } + $this->_requireStoresFilter = true; + } + + return $entityStores; + } + + /** + * Get product model instance + * + * @return \Magento\Catalog\Model\Product + */ + protected function _getProduct() + { + if (!$this->hasData('product')) { + $this->setProduct($this->_productFactory->create()); + } + return $this->getProduct(); + } + + /** + * Get category model instance + * + * @return \Magento\Catalog\Model\Category + */ + protected function _getCategory() + { + if (!$this->hasData('category')) { + $this->setCategory($this->_categoryFactory->create()); + } + return $this->getCategory(); + } +} diff --git a/app/code/Magento/UrlRedirect/Block/Catalog/Product/Edit.php b/app/code/Magento/UrlRedirect/Block/Catalog/Product/Edit.php new file mode 100644 index 0000000000000000000000000000000000000000..895f0a45433a7fd91153b6d3fd78302bd893060e --- /dev/null +++ b/app/code/Magento/UrlRedirect/Block/Catalog/Product/Edit.php @@ -0,0 +1,230 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\UrlRedirect\Block\Catalog\Product; + +/** + * Block for Catalog Category URL rewrites editing + */ +class Edit extends \Magento\UrlRedirect\Block\Edit +{ + /** + * @var \Magento\Catalog\Model\ProductFactory + */ + protected $_productFactory; + + /** + * @var \Magento\Catalog\Model\CategoryFactory + */ + protected $_categoryFactory; + + /** + * @param \Magento\Backend\Block\Widget\Context $context + * @param \Magento\UrlRedirect\Model\UrlRedirectFactory $rewriteFactory + * @param \Magento\Backend\Helper\Data $adminhtmlData + * @param \Magento\Catalog\Model\ProductFactory $productFactory + * @param \Magento\Catalog\Model\CategoryFactory $categoryFactory + * @param array $data + */ + public function __construct( + \Magento\Backend\Block\Widget\Context $context, + \Magento\UrlRedirect\Model\UrlRedirectFactory $rewriteFactory, + \Magento\Backend\Helper\Data $adminhtmlData, + \Magento\Catalog\Model\ProductFactory $productFactory, + \Magento\Catalog\Model\CategoryFactory $categoryFactory, + array $data = array() + ) { + $this->_categoryFactory = $categoryFactory; + $this->_productFactory = $productFactory; + parent::__construct($context, $rewriteFactory, $adminhtmlData, $data); + } + + /** + * Prepare layout for URL rewrite creating for product + * + * @return void + */ + protected function _prepareLayoutFeatures() + { + if ($this->_getUrlRewrite()->getId()) { + $this->_headerText = __('Edit URL Rewrite for a Product'); + } else { + $this->_headerText = __('Add URL Rewrite for a Product'); + } + + if ($this->_getProduct()->getId()) { + $this->_addProductLinkBlock($this->_getProduct()); + } + + if ($this->_getCategory()->getId()) { + $this->_addCategoryLinkBlock(); + } + + if ($this->_getProduct()->getId()) { + if ($this->_getCategory()->getId() || !$this->getIsCategoryMode()) { + $this->_addEditFormBlock(); + $this->_updateBackButtonLink( + $this->_adminhtmlData->getUrl( + 'adminhtml/*/edit', + array('product' => $this->_getProduct()->getId()) + ) . 'category' + ); + } else { + // categories selector & skip categories button + $this->_addCategoriesTreeBlock(); + $this->_addSkipCategoriesBlock(); + $this->_updateBackButtonLink($this->_adminhtmlData->getUrl('adminhtml/*/edit') . 'product'); + } + } else { + $this->_addUrlRewriteSelectorBlock(); + $this->_addProductsGridBlock(); + } + } + + /** + * Get or create new instance of product + * + * @return \Magento\Catalog\Model\Product + */ + private function _getProduct() + { + if (!$this->hasData('product')) { + $this->setProduct($this->_productFactory->create()); + } + return $this->getProduct(); + } + + /** + * Get or create new instance of category + * + * @return \Magento\Catalog\Model\Category + */ + private function _getCategory() + { + if (!$this->hasData('category')) { + $this->setCategory($this->_categoryFactory->create()); + } + return $this->getCategory(); + } + + /** + * Add child product link block + * + * @return void + */ + private function _addProductLinkBlock() + { + $this->addChild( + 'product_link', + 'Magento\UrlRedirect\Block\Link', + array( + 'item_url' => $this->_adminhtmlData->getUrl('adminhtml/*/*') . 'product', + 'item_name' => $this->_getProduct()->getName(), + 'label' => __('Product:') + ) + ); + } + + /** + * Add child category link block + * + * @return void + */ + private function _addCategoryLinkBlock() + { + $this->addChild( + 'category_link', + 'Magento\UrlRedirect\Block\Link', + array( + 'item_url' => $this->_adminhtmlData->getUrl( + 'adminhtml/*/*', + array('product' => $this->_getProduct()->getId()) + ) . 'category', + 'item_name' => $this->_getCategory()->getName(), + 'label' => __('Category:') + ) + ); + } + + /** + * Add child products grid block + * + * @return void + */ + private function _addProductsGridBlock() + { + $this->addChild('products_grid', 'Magento\UrlRedirect\Block\Catalog\Product\Grid'); + } + + /** + * Add child Categories Tree block + * + * @return void + */ + private function _addCategoriesTreeBlock() + { + $this->addChild('categories_tree', 'Magento\UrlRedirect\Block\Catalog\Category\Tree'); + } + + /** + * Add child Skip Categories block + * + * @return void + */ + private function _addSkipCategoriesBlock() + { + $this->addChild( + 'skip_categories', + 'Magento\Backend\Block\Widget\Button', + array( + 'label' => __('Skip Category Selection'), + 'onclick' => 'window.location = \'' . $this->_adminhtmlData->getUrl( + 'adminhtml/*/*', + array('product' => $this->_getProduct()->getId()) + ) . '\'', + 'class' => 'save', + 'level' => -1 + ) + ); + } + + /** + * Creates edit form block + * + * @return \Magento\UrlRedirect\Block\Catalog\Edit\Form + */ + protected function _createEditFormBlock() + { + return $this->getLayout()->createBlock( + 'Magento\UrlRedirect\Block\Catalog\Edit\Form', + '', + array( + 'data' => array( + 'product' => $this->_getProduct(), + 'category' => $this->_getCategory(), + 'url_rewrite' => $this->_getUrlRewrite() + ) + ) + ); + } +} diff --git a/app/code/Magento/UrlRedirect/Block/Catalog/Product/Grid.php b/app/code/Magento/UrlRedirect/Block/Catalog/Product/Grid.php new file mode 100644 index 0000000000000000000000000000000000000000..ae56598e355d03626d29827338b8acc21e766049 --- /dev/null +++ b/app/code/Magento/UrlRedirect/Block/Catalog/Product/Grid.php @@ -0,0 +1,88 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\UrlRedirect\Block\Catalog\Product; + +/** + * Products grid for URL rewrites editing + * + * @author Magento Core Team <core@magentocommerce.com> + */ +class Grid extends \Magento\Catalog\Block\Adminhtml\Product\Grid +{ + /** + * Disable massaction + * + * @return $this + */ + protected function _prepareMassaction() + { + return $this; + } + + /** + * Prepare columns layout + * + * @return $this + */ + protected function _prepareColumns() + { + $this->addColumn('entity_id', array('header' => __('ID'), 'width' => 50, 'index' => 'entity_id')); + + $this->addColumn('name', array('header' => __('Name'), 'index' => 'name')); + + $this->addColumn('sku', array('header' => __('SKU'), 'width' => 80, 'index' => 'sku')); + $this->addColumn( + 'status', + array( + 'header' => __('Status'), + 'width' => 50, + 'index' => 'status', + 'type' => 'options', + 'options' => $this->_status->getOptionArray() + ) + ); + return $this; + } + + /** + * Get URL for dispatching grid ajax requests + * + * @return string + */ + public function getGridUrl() + { + return $this->getUrl('adminhtml/*/productGrid', array('_current' => true)); + } + + /** + * Return row url for js event handlers + * + * @param \Magento\Catalog\Model\Product|\Magento\Framework\Object $row + * @return string + */ + public function getRowUrl($row) + { + return $this->getUrl('adminhtml/*/edit', array('product' => $row->getId())) . 'category'; + } +} diff --git a/app/code/Magento/UrlRedirect/Block/Cms/Page/Edit.php b/app/code/Magento/UrlRedirect/Block/Cms/Page/Edit.php new file mode 100644 index 0000000000000000000000000000000000000000..fe4960b43a92871bf9a039a1e7047ff86a6d0955 --- /dev/null +++ b/app/code/Magento/UrlRedirect/Block/Cms/Page/Edit.php @@ -0,0 +1,131 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\UrlRedirect\Block\Cms\Page; + +/** + * Block for CMS pages URL rewrites + */ +class Edit extends \Magento\UrlRedirect\Block\Edit +{ + /** + * @var \Magento\Cms\Model\PageFactory + */ + protected $_pageFactory; + + /** + * @param \Magento\Backend\Block\Widget\Context $context + * @param \Magento\UrlRedirect\Model\UrlRedirectFactory $rewriteFactory + * @param \Magento\Backend\Helper\Data $adminhtmlData + * @param \Magento\Cms\Model\PageFactory $pageFactory + * @param array $data + */ + public function __construct( + \Magento\Backend\Block\Widget\Context $context, + \Magento\UrlRedirect\Model\UrlRedirectFactory $rewriteFactory, + \Magento\Backend\Helper\Data $adminhtmlData, + \Magento\Cms\Model\PageFactory $pageFactory, + array $data = array() + ) { + $this->_pageFactory = $pageFactory; + parent::__construct($context, $rewriteFactory, $adminhtmlData, $data); + } + + /** + * Prepare layout for URL rewrite creating for CMS page + * + * @return void + */ + protected function _prepareLayoutFeatures() + { + if ($this->_getUrlRewrite()->getId()) { + $this->_headerText = __('Edit URL Rewrite for CMS page'); + } else { + $this->_headerText = __('Add URL Rewrite for CMS page'); + } + + if ($this->_getCmsPage()->getId()) { + $this->_addCmsPageLinkBlock(); + $this->_addEditFormBlock(); + $this->_updateBackButtonLink($this->_adminhtmlData->getUrl('adminhtml/*/edit') . 'cms_page'); + } else { + $this->_addUrlRewriteSelectorBlock(); + $this->_addCmsPageGridBlock(); + } + } + + /** + * Get or create new instance of CMS page + * + * @return \Magento\Cms\Model\Page + */ + private function _getCmsPage() + { + if (!$this->hasData('cms_page')) { + $this->setCmsPage($this->_pageFactory->create()); + } + return $this->getCmsPage(); + } + + /** + * Add child CMS page link block + * + * @return void + */ + private function _addCmsPageLinkBlock() + { + $this->addChild( + 'cms_page_link', + 'Magento\UrlRedirect\Block\Link', + array( + 'item_url' => $this->_adminhtmlData->getUrl('adminhtml/*/*') . 'cms_page', + 'item_name' => $this->getCmsPage()->getTitle(), + 'label' => __('CMS page:') + ) + ); + } + + /** + * Add child CMS page block + * + * @return void + */ + private function _addCmsPageGridBlock() + { + $this->addChild('cms_pages_grid', 'Magento\UrlRedirect\Block\Cms\Page\Grid'); + } + + /** + * Creates edit form block + * + * @return \Magento\UrlRedirect\Block\Cms\Page\Edit\Form + */ + protected function _createEditFormBlock() + { + return $this->getLayout()->createBlock( + 'Magento\UrlRedirect\Block\Cms\Page\Edit\Form', + '', + array('data' => array('cms_page' => $this->_getCmsPage(), 'url_rewrite' => $this->_getUrlRewrite())) + ); + } +} diff --git a/app/code/Magento/UrlRedirect/Block/Cms/Page/Edit/Form.php b/app/code/Magento/UrlRedirect/Block/Cms/Page/Edit/Form.php new file mode 100644 index 0000000000000000000000000000000000000000..519589c91dd6b43b559de42d0450eb59d27fc0d8 --- /dev/null +++ b/app/code/Magento/UrlRedirect/Block/Cms/Page/Edit/Form.php @@ -0,0 +1,165 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\UrlRedirect\Block\Cms\Page\Edit; + +/** + * Edit form for CMS page URL rewrites + * + * @SuppressWarnings(PHPMD.DepthOfInheritance) + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ +class Form extends \Magento\UrlRedirect\Block\Edit\Form +{ + /** + * @var \Magento\Cms\Model\PageFactory + */ + protected $_pageFactory; + + /** + * @var \Magento\Cms\Model\Page\UrlrewriteFactory + */ + protected $_urlRewriteFactory; + + /** + * @param \Magento\Backend\Block\Widget\Context $context + * @param \Magento\Framework\Registry $registry + * @param \Magento\Framework\Data\FormFactory $formFactory + * @param \Magento\UrlRedirect\Model\OptionProviderFactory $optionFactory + * @param \Magento\UrlRedirect\Model\UrlRedirectFactory $rewriteFactory + * @param \Magento\Store\Model\System\Store $systemStore + * @param \Magento\Backend\Helper\Data $adminhtmlData + * @param \Magento\Cms\Model\Page\UrlrewriteFactory $urlRewriteFactory + * @param \Magento\Cms\Model\PageFactory $pageFactory + * @param array $data + * + * @SuppressWarnings(PHPMD.ExcessiveParameterList) + */ + public function __construct( + \Magento\Backend\Block\Widget\Context $context, + \Magento\Framework\Registry $registry, + \Magento\Framework\Data\FormFactory $formFactory, + \Magento\UrlRedirect\Model\OptionProviderFactory $optionFactory, + \Magento\UrlRedirect\Model\UrlRedirectFactory $rewriteFactory, + \Magento\Store\Model\System\Store $systemStore, + \Magento\Backend\Helper\Data $adminhtmlData, + \Magento\Cms\Model\Page\UrlrewriteFactory $urlRewriteFactory, + \Magento\Cms\Model\PageFactory $pageFactory, + array $data = array() + ) { + $this->_urlRewriteFactory = $urlRewriteFactory; + $this->_pageFactory = $pageFactory; + parent::__construct( + $context, + $registry, + $formFactory, + $optionFactory, + $rewriteFactory, + $systemStore, + $adminhtmlData, + $data + ); + } + + /** + * Form post init + * + * @param \Magento\Framework\Data\Form $form + * @return \Magento\UrlRedirect\Block\Cms\Page\Edit\Form + */ + protected function _formPostInit($form) + { + $cmsPage = $this->_getCmsPage(); + $form->setAction( + $this->_adminhtmlData->getUrl( + 'adminhtml/*/save', + array('id' => $this->_getModel()->getId(), 'cms_page' => $cmsPage->getId()) + ) + ); + + // Fill request path and target path elements + /** @var $requestPath \Magento\Framework\Data\Form\Element\AbstractElement */ + $requestPath = $this->getForm()->getElement('request_path'); + /** @var $targetPath \Magento\Framework\Data\Form\Element\AbstractElement */ + $targetPath = $this->getForm()->getElement('target_path'); + + $model = $this->_getModel(); + /** @var $cmsPageUrlrewrite \Magento\Cms\Model\Page\Urlrewrite */ + $cmsPageUrlrewrite = $this->_urlRewriteFactory->create(); + if (!$model->getId()) { + $sessionData = $this->_getSessionData(); + if (!isset($sessionData['request_path'])) { + $requestPath->setValue($cmsPageUrlrewrite->generateRequestPath($cmsPage)); + } + $targetPath->setValue($cmsPageUrlrewrite->generateTargetPath($cmsPage)); + $disablePaths = true; + } else { + $cmsPageUrlrewrite->load($this->_getModel()->getId(), 'url_rewrite_id'); + $disablePaths = $cmsPageUrlrewrite->getId() > 0; + } + if ($disablePaths) { + $targetPath->setData('disabled', true); + } + + return $this; + } + + /** + * Get catalog entity associated stores + * + * @return array + * @throws \Magento\Store\Model\Exception + */ + protected function _getEntityStores() + { + $cmsPage = $this->_getCmsPage(); + $entityStores = array(); + + // showing websites that only associated to CMS page + if ($this->_getCmsPage()->getId()) { + $entityStores = (array)$cmsPage->getResource()->lookupStoreIds($cmsPage->getId()); + $this->_requireStoresFilter = !in_array(0, $entityStores); + + if (!$entityStores) { + throw new \Magento\Store\Model\Exception( + __('Chosen cms page does not associated with any website.') + ); + } + } + + return $entityStores; + } + + /** + * Get CMS page model instance + * + * @return \Magento\Cms\Model\Page + */ + protected function _getCmsPage() + { + if (!$this->hasData('cms_page')) { + $this->setCmsPage($this->_pageFactory->create()); + } + return $this->getCmsPage(); + } +} diff --git a/app/code/Magento/UrlRedirect/Block/Cms/Page/Grid.php b/app/code/Magento/UrlRedirect/Block/Cms/Page/Grid.php new file mode 100644 index 0000000000000000000000000000000000000000..8cb6ca507abd377a59280c5af7be0cb9117095c0 --- /dev/null +++ b/app/code/Magento/UrlRedirect/Block/Cms/Page/Grid.php @@ -0,0 +1,113 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\UrlRedirect\Block\Cms\Page; + +/** + * CMS pages grid for URL rewrites + * + * @author Magento Core Team <core@magentocommerce.com> + */ +class Grid extends \Magento\Cms\Block\Adminhtml\Page\Grid +{ + /** + * Constructor + * + * @return void + */ + public function _construct() + { + parent::_construct(); + $this->setUseAjax(true); + } + + /** + * Disable massaction + * + * @return $this + */ + protected function _prepareMassaction() + { + return $this; + } + + /** + * Prepare columns layout + * + * @return $this + */ + protected function _prepareColumns() + { + $this->addColumn('title', array('header' => __('Title'), 'align' => 'left', 'index' => 'title')); + + $this->addColumn('identifier', array('header' => __('URL Key'), 'align' => 'left', 'index' => 'identifier')); + + if (!$this->_storeManager->isSingleStoreMode()) { + $this->addColumn( + 'store_id', + array( + 'header' => __('Store View'), + 'index' => 'store_id', + 'type' => 'store', + 'store_all' => true, + 'store_view' => true, + 'sortable' => false, + 'filter_condition_callback' => array($this, '_filterStoreCondition') + ) + ); + } + + $this->addColumn( + 'is_active', + array( + 'header' => __('Status'), + 'index' => 'is_active', + 'type' => 'options', + 'options' => $this->_cmsPage->getAvailableStatuses() + ) + ); + + return $this; + } + + /** + * Get URL for dispatching grid ajax requests + * + * @return string + */ + public function getGridUrl() + { + return $this->getUrl('adminhtml/*/cmsPageGrid', array('_current' => true)); + } + + /** + * Return row url for js event handlers + * + * @param \Magento\Cms\Model\Page|\Magento\Framework\Object $row + * @return string + */ + public function getRowUrl($row) + { + return $this->getUrl('adminhtml/*/edit', array('cms_page' => $row->getId())); + } +} diff --git a/app/code/Magento/UrlRedirect/Block/Edit.php b/app/code/Magento/UrlRedirect/Block/Edit.php new file mode 100644 index 0000000000000000000000000000000000000000..deb100ce6ff0c3363fa5cee52f24bc56894dfc75 --- /dev/null +++ b/app/code/Magento/UrlRedirect/Block/Edit.php @@ -0,0 +1,298 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\UrlRedirect\Block; + +/** + * Block for URL rewrites edit page + */ +class Edit extends \Magento\Backend\Block\Widget\Container +{ + /** + * @var \Magento\UrlRedirect\Block\Selector + */ + private $_selectorBlock; + + /** + * Part for building some blocks names + * + * @var string + */ + protected $_controller = 'urlredirect'; + + /** + * Generated buttons html cache + * + * @var string + */ + protected $_buttonsHtml; + + /** + * Adminhtml data + * + * @var \Magento\Backend\Helper\Data + */ + protected $_adminhtmlData = null; + + /** + * @var \Magento\UrlRedirect\Model\UrlRedirectFactory + */ + protected $_rewriteFactory; + + /** + * @param \Magento\Backend\Block\Widget\Context $context + * @param \Magento\UrlRedirect\Model\UrlRedirectFactory $rewriteFactory + * @param \Magento\Backend\Helper\Data $adminhtmlData + * @param array $data + */ + public function __construct( + \Magento\Backend\Block\Widget\Context $context, + \Magento\UrlRedirect\Model\UrlRedirectFactory $rewriteFactory, + \Magento\Backend\Helper\Data $adminhtmlData, + array $data = array() + ) { + $this->_rewriteFactory = $rewriteFactory; + $this->_adminhtmlData = $adminhtmlData; + parent::__construct($context, $data); + } + + /** + * Prepare URL rewrite editing layout + * + * @return $this + */ + protected function _prepareLayout() + { + $this->setTemplate('edit.phtml'); + + $this->_addBackButton(); + $this->_prepareLayoutFeatures(); + + return parent::_prepareLayout(); + } + + /** + * Prepare featured blocks for layout of URL rewrite editing + * + * @return void + */ + protected function _prepareLayoutFeatures() + { + if ($this->_getUrlRewrite()->getId()) { + $this->_headerText = __('Edit URL Rewrite'); + } else { + $this->_headerText = __('Add New URL Rewrite'); + } + + $this->_updateBackButtonLink( + $this->_adminhtmlData->getUrl('adminhtml/*/edit') . $this->_getSelectorBlock()->getDefaultMode() + ); + $this->_addUrlRewriteSelectorBlock(); + $this->_addEditFormBlock(); + } + + /** + * Add child edit form block + * + * @return void + */ + protected function _addEditFormBlock() + { + $this->setChild('form', $this->_createEditFormBlock()); + + if ($this->_getUrlRewrite()->getId()) { + $this->_addResetButton(); + $this->_addDeleteButton(); + } + + $this->_addSaveButton(); + } + + /** + * Add reset button + * + * @return void + */ + protected function _addResetButton() + { + $this->_addButton( + 'reset', + array( + 'label' => __('Reset'), + 'onclick' => '$(\'edit_form\').reset()', + 'class' => 'scalable', + 'level' => -1 + ) + ); + } + + /** + * Add back button + * + * @return void + */ + protected function _addBackButton() + { + $this->_addButton( + 'back', + array( + 'label' => __('Back'), + 'onclick' => 'setLocation(\'' . $this->_adminhtmlData->getUrl('adminhtml/*/') . '\')', + 'class' => 'back', + 'level' => -1 + ) + ); + } + + /** + * Update Back button location link + * + * @param string $link + * @return void + */ + protected function _updateBackButtonLink($link) + { + $this->_updateButton('back', 'onclick', 'setLocation(\'' . $link . '\')'); + } + + /** + * Add delete button + * + * @return void + */ + protected function _addDeleteButton() + { + $this->_addButton( + 'delete', + array( + 'label' => __('Delete'), + 'onclick' => 'deleteConfirm(' . json_encode(__('Are you sure you want to do this?')) + . ',' + . json_encode( + $this->_adminhtmlData->getUrl( + 'adminhtml/*/delete', + array('id' => $this->getUrlRewrite()->getId()) + ) + ) + . ')', + 'class' => 'scalable delete', + 'level' => -1 + ) + ); + } + + /** + * Add save button + * + * @return void + */ + protected function _addSaveButton() + { + $this->_addButton( + 'save', + array( + 'label' => __('Save'), + 'class' => 'save primary save-url-redirect', + 'level' => -1, + 'data_attribute' => array( + 'mage-init' => array('button' => array('event' => 'save', 'target' => '#edit_form')) + ) + ) + ); + } + + /** + * Creates edit form block + * + * @return \Magento\UrlRedirect\Block\Edit\Form + */ + protected function _createEditFormBlock() + { + return $this->getLayout()->createBlock( + 'Magento\UrlRedirect\Block\Edit\Form', + '', + array('data' => array('url_rewrite' => $this->_getUrlRewrite())) + ); + } + + /** + * Add child URL rewrite selector block + * + * @return void + */ + protected function _addUrlRewriteSelectorBlock() + { + $this->setChild('selector', $this->_getSelectorBlock()); + } + + /** + * Get selector block + * + * @return \Magento\UrlRedirect\Block\Selector + */ + private function _getSelectorBlock() + { + if (!$this->_selectorBlock) { + $this->_selectorBlock = $this->getLayout()->createBlock('Magento\UrlRedirect\Block\Selector'); + } + return $this->_selectorBlock; + } + + /** + * Get container buttons HTML + * + * Since buttons are set as children, we remove them as children after generating them + * not to duplicate them in future + * + * @param null $area + * @return string + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function getButtonsHtml($area = null) + { + if (null === $this->_buttonsHtml) { + $this->_buttonsHtml = parent::getButtonsHtml(); + $layout = $this->getLayout(); + foreach ($this->getChildNames() as $name) { + $alias = $layout->getElementAlias($name); + if (false !== strpos($alias, '_button')) { + $layout->unsetChild($this->getNameInLayout(), $alias); + } + } + } + return $this->_buttonsHtml; + } + + /** + * Get or create new instance of URL rewrite + * + * @return \Magento\UrlRedirect\Model\UrlRedirect + */ + protected function _getUrlRewrite() + { + if (!$this->hasData('url_rewrite')) { + $this->setUrlRewrite($this->_rewriteFactory->create()); + } + return $this->getUrlRewrite(); + } +} diff --git a/app/code/Magento/UrlRedirect/Block/Edit/Form.php b/app/code/Magento/UrlRedirect/Block/Edit/Form.php new file mode 100644 index 0000000000000000000000000000000000000000..82bc37e8b82edbc168c84f8ed9a167341898a0c3 --- /dev/null +++ b/app/code/Magento/UrlRedirect/Block/Edit/Form.php @@ -0,0 +1,387 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\UrlRedirect\Block\Edit; + +/** + * URL rewrites edit form + * + * @SuppressWarnings(PHPMD.DepthOfInheritance) + */ +class Form extends \Magento\Backend\Block\Widget\Form\Generic +{ + /** + * @var array + */ + protected $_sessionData = null; + + /** + * @var array + */ + protected $_allStores = null; + + /** + * @var bool + */ + protected $_requireStoresFilter = false; + + /** + * @var array + */ + protected $_formValues = array(); + + /** + * Adminhtml data + * + * @var \Magento\Backend\Helper\Data + */ + protected $_adminhtmlData = null; + + /** + * @var \Magento\Store\Model\System\Store + */ + protected $_systemStore; + + /** + * @var \Magento\UrlRedirect\Model\UrlRedirectFactory + */ + protected $_rewriteFactory; + + /** + * @var \Magento\UrlRedirect\Model\OptionProviderFactory + */ + protected $_optionFactory; + + /** + * @param \Magento\Backend\Block\Widget\Context $context + * @param \Magento\Framework\Registry $registry + * @param \Magento\Framework\Data\FormFactory $formFactory + * @param \Magento\UrlRedirect\Model\OptionProviderFactory $optionFactory + * @param \Magento\UrlRedirect\Model\UrlRedirectFactory $rewriteFactory + * @param \Magento\Store\Model\System\Store $systemStore + * @param \Magento\Backend\Helper\Data $adminhtmlData + * @param array $data + */ + public function __construct( + \Magento\Backend\Block\Widget\Context $context, + \Magento\Framework\Registry $registry, + \Magento\Framework\Data\FormFactory $formFactory, + \Magento\UrlRedirect\Model\OptionProviderFactory $optionFactory, + \Magento\UrlRedirect\Model\UrlRedirectFactory $rewriteFactory, + \Magento\Store\Model\System\Store $systemStore, + \Magento\Backend\Helper\Data $adminhtmlData, + array $data = array() + ) { + $this->_optionFactory = $optionFactory; + $this->_rewriteFactory = $rewriteFactory; + $this->_systemStore = $systemStore; + $this->_adminhtmlData = $adminhtmlData; + parent::__construct($context, $registry, $formFactory, $data); + } + + /** + * Set form id and title + * + * @return void + */ + protected function _construct() + { + parent::_construct(); + $this->setId('urlrewrite_form'); + $this->setTitle(__('Block Information')); + } + + /** + * Initialize form values + * Set form data either from model values or from session + * + * @return $this + */ + protected function _initFormValues() + { + $model = $this->_getModel(); + $this->_formValues = array( + 'store_id' => $model->getStoreId(), + 'entity_type' => $model->getEntityType(), + 'entity_id' => $model->getEntityId(), + 'request_path' => $model->getRequestPath(), + 'target_path' => $model->getTargetPath(), + 'redirect_type' => $model->getRedirectType(), + 'description' => $model->getDescription() + ); + + $sessionData = $this->_getSessionData(); + if ($sessionData) { + foreach (array_keys($this->_formValues) as $key) { + if (isset($sessionData[$key])) { + $this->_formValues[$key] = $sessionData[$key]; + } + } + } + + return $this; + } + + /** + * Prepare the form layout + * + * @return $this + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ + protected function _prepareForm() + { + $this->_initFormValues(); + + // Prepare form + /** @var \Magento\Framework\Data\Form $form */ + $form = $this->_formFactory->create( + array('data' => array('id' => 'edit_form', 'use_container' => true, 'method' => 'post')) + ); + + $fieldset = $form->addFieldset('base_fieldset', array('legend' => __('URL Rewrite Information'))); + + $fieldset->addField( + 'entity_type', + 'hidden', + array( + 'name' => 'entity_type', + 'value' => $this->_formValues['entity_type'] + ) + ); + + $fieldset->addField( + 'entity_id', + 'hidden', + array( + 'name' => 'entity_id', + 'value' => $this->_formValues['entity_id'] + ) + ); + + $this->_prepareStoreElement($fieldset); + + $fieldset->addField( + 'request_path', + 'text', + array( + 'label' => __('Request Path'), + 'title' => __('Request Path'), + 'name' => 'request_path', + 'required' => true, + 'value' => $this->_formValues['request_path'] + ) + ); + + $fieldset->addField( + 'target_path', + 'text', + array( + 'label' => __('Target Path'), + 'title' => __('Target Path'), + 'name' => 'target_path', + 'required' => true, + 'disabled' => false, + 'value' => $this->_formValues['target_path'] + ) + ); + + /** @var $optionsModel \Magento\UrlRedirect\Model\OptionProvider */ + $optionsModel = $this->_optionFactory->create(); + $fieldset->addField( + 'redirect_type', + 'select', + array( + 'label' => __('Redirect'), + 'title' => __('Redirect'), + 'name' => 'redirect_type', + 'options' => $optionsModel->getAllOptions(), + 'value' => $this->_formValues['redirect_type'] + ) + ); + + $fieldset->addField( + 'description', + 'textarea', + array( + 'label' => __('Description'), + 'title' => __('Description'), + 'name' => 'description', + 'cols' => 20, + 'rows' => 5, + 'value' => $this->_formValues['description'], + 'wrap' => 'soft' + ) + ); + + $this->setForm($form); + $this->_formPostInit($form); + + return parent::_prepareForm(); + } + + /** + * Prepare store element + * + * @param \Magento\Framework\Data\Form\Element\Fieldset $fieldset + * @return void + */ + protected function _prepareStoreElement($fieldset) + { + if ($this->_storeManager->isSingleStoreMode()) { + $fieldset->addField( + 'store_id', + 'hidden', + array('name' => 'store_id', 'value' => $this->_storeManager->getStore(true)->getId()) + ); + } else { + /** @var $renderer \Magento\Backend\Block\Store\Switcher\Form\Renderer\Fieldset\Element */ + $renderer = $this->getLayout()->createBlock( + 'Magento\Backend\Block\Store\Switcher\Form\Renderer\Fieldset\Element' + ); + + $storeElement = $fieldset->addField( + 'store_id', + 'select', + array( + 'label' => __('Store'), + 'title' => __('Store'), + 'name' => 'store_id', + 'required' => true, + 'values' => $this->_getRestrictedStoresList(), + 'value' => $this->_formValues['store_id'] + ) + ); + $storeElement->setRenderer($renderer); + } + } + + /** + * Form post init + * + * @param \Magento\Framework\Data\Form $form + * @return $this + */ + protected function _formPostInit($form) + { + $form->setAction( + $this->_adminhtmlData->getUrl('adminhtml/*/save', array('id' => $this->_getModel()->getId())) + ); + return $this; + } + + /** + * Get session data + * + * @return array + */ + protected function _getSessionData() + { + if (is_null($this->_sessionData)) { + $this->_sessionData = $this->_backendSession->getData('urlrewrite_data', true); + } + return $this->_sessionData; + } + + /** + * Get URL rewrite model instance + * + * @return \Magento\UrlRedirect\Model\UrlRedirect + */ + protected function _getModel() + { + if (!$this->hasData('url_rewrite')) { + $this->setUrlRewrite($this->_rewriteFactory->create()); + } + return $this->getUrlRewrite(); + } + + /** + * Get request stores + * + * @return array + */ + protected function _getAllStores() + { + if (is_null($this->_allStores)) { + $this->_allStores = $this->_systemStore->getStoreValuesForForm(); + } + + return $this->_allStores; + } + + /** + * Get entity stores + * + * @return array + */ + protected function _getEntityStores() + { + return $this->_getAllStores(); + } + + /** + * Get restricted stores list + * Stores should be filtered only if custom entity is specified. + * If we use custom rewrite, all stores are accepted. + * + * @return array + */ + protected function _getRestrictedStoresList() + { + $stores = $this->_getAllStores(); + $entityStores = $this->_getEntityStores(); + $stores = $this->_getStoresListRestrictedByEntityStores($stores, $entityStores); + + return $stores; + } + + /** + * Get stores list restricted by entity stores + * + * @param array $stores + * @param array $entityStores + * @return array + */ + private function _getStoresListRestrictedByEntityStores(array $stores, array $entityStores) + { + if ($this->_requireStoresFilter) { + foreach ($stores as $i => $store) { + if (isset($store['value']) && $store['value']) { + $found = false; + foreach ($store['value'] as $k => $v) { + if (isset($v['value']) && in_array($v['value'], $entityStores)) { + $found = true; + } else { + unset($stores[$i]['value'][$k]); + } + } + if (!$found) { + unset($stores[$i]); + } + } + } + } + + return $stores; + } +} diff --git a/app/code/Magento/UrlRedirect/Block/GridContainer.php b/app/code/Magento/UrlRedirect/Block/GridContainer.php new file mode 100644 index 0000000000000000000000000000000000000000..b949f48d40fc37f2d05c326826ff3b26b71db009 --- /dev/null +++ b/app/code/Magento/UrlRedirect/Block/GridContainer.php @@ -0,0 +1,90 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\UrlRedirect\Block; + +/** + * Block for Urlrewrites grid container + */ +class GridContainer extends \Magento\Backend\Block\Widget\Grid\Container +{ + /** + * Part for generating apropriate grid block name + * + * @var string + */ + protected $_controller = 'urlredirect'; + + /** + * @var \Magento\UrlRedirect\Block\Selector + */ + protected $_urlrewriteSelector; + + /** + * @param \Magento\Backend\Block\Widget\Context $context + * @param Selector $urlrewriteSelector + * @param array $data + */ + public function __construct( + \Magento\Backend\Block\Widget\Context $context, + \Magento\UrlRedirect\Block\Selector $urlrewriteSelector, + array $data = array() + ) { + $this->_urlrewriteSelector = $urlrewriteSelector; + parent::__construct($context, $data); + } + + /** + * Set custom labels and headers + * + * @return void + */ + protected function _construct() + { + $this->_headerText = __('URL Rewrite Management'); + $this->_addButtonLabel = __('Add URL Rewrite'); + parent::_construct(); + } + + /** + * Customize grid row URLs + * + * @return string + */ + public function getCreateUrl() + { + $url = $this->getUrl('adminhtml/*/edit'); + + $selectorBlock = $this->getSelectorBlock(); + if ($selectorBlock === null) { + $selectorBlock = $this->_urlrewriteSelector; + } + + if ($selectorBlock) { + $modes = array_keys($selectorBlock->getModes()); + $url .= reset($modes); + } + + return $url; + } +} diff --git a/app/code/Magento/UrlRedirect/Block/Link.php b/app/code/Magento/UrlRedirect/Block/Link.php new file mode 100644 index 0000000000000000000000000000000000000000..942f4db971a91b777973f6e9e083c04464377253 --- /dev/null +++ b/app/code/Magento/UrlRedirect/Block/Link.php @@ -0,0 +1,47 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +/** + * Label & link block + * + * @method string getLabel() + * @method string getItemUrl() + * @method string getItemName() + */ +namespace Magento\UrlRedirect\Block; + +class Link extends \Magento\Framework\View\Element\AbstractBlock +{ + /** + * Render output + * + * @return string + */ + protected function _toHtml() + { + return '<p>' . $this->getLabel() . ' <a href="' . $this->getItemUrl() . '">' . $this->escapeHtml( + $this->getItemName() + ) . '</a></p>'; + } +} diff --git a/app/code/Magento/UrlRedirect/Block/Selector.php b/app/code/Magento/UrlRedirect/Block/Selector.php new file mode 100644 index 0000000000000000000000000000000000000000..643c3f84d6537183c1bb5a68a446a236f7e34c3f --- /dev/null +++ b/app/code/Magento/UrlRedirect/Block/Selector.php @@ -0,0 +1,97 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\UrlRedirect\Block; + +class Selector extends \Magento\Framework\View\Element\Template +{ + /** + * List of available modes from source model + * key => label + * + * @var array + */ + protected $_modes; + + /** + * @var string + */ + protected $_template = 'selector.phtml'; + + /** + * Set block template and get available modes + * + * @return void + */ + protected function _construct() + { + $this->_modes = array( + 'category' => __('For category'), + 'product' => __('For product'), + 'cms_page' => __('For CMS page'), + 'id' => __('Custom') + ); + } + + /** + * Available modes getter + * + * @return array + */ + public function getModes() + { + return $this->_modes; + } + + /** + * Label getter + * + * @return string + */ + public function getSelectorLabel() + { + return __('Create URL Rewrite:'); + } + + /** + * Check whether selection is in specified mode + * + * @param string $mode + * @return bool + */ + public function isMode($mode) + { + return $this->getRequest()->has($mode); + } + + /** + * Get default mode + * + * @return string + */ + public function getDefaultMode() + { + $keys = array_keys($this->_modes); + return array_shift($keys); + } +} diff --git a/app/code/Magento/UrlRedirect/Controller/Adminhtml/UrlRedirect.php b/app/code/Magento/UrlRedirect/Controller/Adminhtml/UrlRedirect.php new file mode 100644 index 0000000000000000000000000000000000000000..d840d589a387f96ed1cc6e29c60b0e38607bf742 --- /dev/null +++ b/app/code/Magento/UrlRedirect/Controller/Adminhtml/UrlRedirect.php @@ -0,0 +1,468 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\UrlRedirect\Controller\Adminhtml; + +use Magento\Backend\App\Action; +use Magento\Catalog\Model\Category; +use Magento\Catalog\Model\Product; +use Magento\Framework\Model\Exception; + +class UrlRedirect extends Action +{ + /**#@+ + * Entity types + */ + const ENTITY_TYPE_CUSTOM = 'custom'; + const ENTITY_TYPE_PRODUCT = 'product'; + const ENTITY_TYPE_CATEGORY = 'category'; + const ENTITY_TYPE_CMS_PAGE = 'cms-page'; + /**#@-*/ + + const ID_MODE = 'id'; + + const PRODUCT_MODE = 'product'; + + const CATEGORY_MODE = 'category'; + + const CMS_PAGE_MODE = 'cms_page'; + + /** + * @var Product + */ + private $_product; + + /** + * @var Category + */ + private $_category; + + /** + * @var \Magento\Cms\Model\Page + */ + private $_cmsPage; + + /** + * @var \Magento\UrlRedirect\Model\UrlRedirect + */ + private $_urlRewrite; + + /** + * Show URL rewrites index page + * + * @return void + */ + public function indexAction() + { + $this->_title->add(__('URL Rewrites')); + + $this->_view->loadLayout(); + $this->_setActiveMenu('Magento_UrlRedirect::urlrewrite'); + $this->_view->renderLayout(); + } + + /** + * Show urlrewrite edit/create page + * + * @return void + */ + public function editAction() + { + $this->_title->add(__('URL Rewrites')); + $this->_title->add(__('[New/Edit] URL Rewrite')); + + $this->_view->loadLayout(); + $this->_setActiveMenu('Magento_UrlRedirect::urlrewrite'); + + $mode = $this->_getMode(); + switch ($mode) { + case self::PRODUCT_MODE: + $editBlock = $this->_view->getLayout()->createBlock( + 'Magento\UrlRedirect\Block\Catalog\Product\Edit', + '', + array( + 'data' => array( + 'category' => $this->_getCategory(), + 'product' => $this->_getProduct(), + 'is_category_mode' => $this->getRequest()->has('category'), + 'url_rewrite' => $this->_getUrlRewrite() + ) + ) + ); + break; + case self::CATEGORY_MODE: + $editBlock = $this->_view->getLayout()->createBlock( + 'Magento\UrlRedirect\Block\Catalog\Category\Edit', + '', + array( + 'data' => array('category' => $this->_getCategory(), 'url_rewrite' => $this->_getUrlRewrite()) + ) + ); + break; + case self::CMS_PAGE_MODE: + $editBlock = $this->_view->getLayout()->createBlock( + 'Magento\UrlRedirect\Block\Cms\Page\Edit', + '', + array( + 'data' => array('cms_page' => $this->_getCmsPage(), 'url_rewrite' => $this->_getUrlRewrite()) + ) + ); + break; + case self::ID_MODE: + default: + $editBlock = $this->_view->getLayout()->createBlock( + 'Magento\UrlRedirect\Block\Edit', + '', + array('data' => array('url_rewrite' => $this->_getUrlRewrite())) + ); + break; + } + + $this->_addContent($editBlock); + if (in_array($mode, array(self::PRODUCT_MODE, self::CATEGORY_MODE))) { + $this->_view->getLayout()->getBlock('head')->setCanLoadExtJs(true); + } + $this->_view->renderLayout(); + } + + /** + * Get current mode + * + * @return string + */ + private function _getMode() + { + if ($this->_getProduct()->getId() || $this->getRequest()->has('product')) { + $mode = self::PRODUCT_MODE; + } elseif ($this->_getCategory()->getId() || $this->getRequest()->has('category')) { + $mode = self::CATEGORY_MODE; + } elseif ($this->_getCmsPage()->getId() || $this->getRequest()->has('cms_page')) { + $mode = self::CMS_PAGE_MODE; + } elseif ($this->getRequest()->has('id')) { + $mode = self::ID_MODE; + } else { + $mode = $this->_objectManager->get('Magento\UrlRedirect\Block\Selector')->getDefaultMode(); + } + return $mode; + } + + /** + * Ajax products grid action + * + * @return void + */ + public function productGridAction() + { + $this->getResponse()->setBody( + $this->_view->getLayout()->createBlock('Magento\UrlRedirect\Block\Catalog\Product\Grid')->toHtml() + ); + } + + /** + * Ajax categories tree loader action + * + * @return void + */ + public function categoriesJsonAction() + { + $categoryId = $this->getRequest()->getParam('id', null); + $this->getResponse()->setBody( + $this->_objectManager->get( + 'Magento\UrlRedirect\Block\Catalog\Category\Tree' + )->getTreeArray( + $categoryId, + true, + 1 + ) + ); + } + + /** + * Ajax CMS pages grid action + * + * @return void + */ + public function cmsPageGridAction() + { + $this->getResponse()->setBody( + $this->_view->getLayout()->createBlock('Magento\UrlRedirect\Block\Cms\Page\Grid')->toHtml() + ); + } + + /** + * Urlrewrite save action + * + * @return void + */ + public function saveAction() + { + if ($data = $this->getRequest()->getPost()) { + /** @var $session \Magento\Backend\Model\Session */ + $session = $this->_objectManager->get('Magento\Backend\Model\Session'); + try { + /** @var $model \Magento\UrlRedirect\Model\UrlRedirect */ + $model = $this->_getUrlRewrite(); + + $requestPath = $this->getRequest()->getParam('request_path'); + $this->_objectManager->get('Magento\UrlRedirect\Helper\UrlRewrite')->validateRequestPath($requestPath); + + $model->setEntityType($this->getRequest()->getParam('entity_type', self::ENTITY_TYPE_CUSTOM)) + ->setStoreId($this->getRequest()->getParam('store_id', 0)) + ->setTargetPath($this->getRequest()->getParam('target_path')) + ->setRedirectType($this->getRequest()->getParam('redirect_type')) + ->setDescription($this->getRequest()->getParam('description')) + ->setRequestPath($requestPath); + + $this->_onUrlRewriteSaveBefore($model); + + $model->save(); + + $this->messageManager->addSuccess(__('The URL Rewrite has been saved.')); + $this->_redirect('adminhtml/*/'); + return; + } catch (Exception $e) { + $this->messageManager->addError($e->getMessage()); + $session->setUrlrewriteData($data); + } catch (\Exception $e) { + $this->messageManager->addException($e, __('An error occurred while saving URL Rewrite.')); + $session->setUrlrewriteData($data); + } + } + $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl($this->getUrl('*'))); + } + + /** + * Call before save urlrewrite handlers + * + * @param \Magento\UrlRedirect\Model\UrlRedirect $model + * @return void + */ + protected function _onUrlRewriteSaveBefore($model) + { + $this->_handleCatalogUrlRewrite($model); + $this->_handleCmsPageUrlRewrite($model); + } + + /** + * Override urlrewrite data, basing on current category and product + * + * @param \Magento\UrlRedirect\Model\UrlRedirect $model + * @return void + * @throws Exception + */ + protected function _handleCatalogUrlRewrite($model) + { + $product = $this->_getInitializedProduct($model); + $category = $this->_getInitializedCategory($model); + + if ($product || $category) { + /** @var $catalogUrlModel \Magento\Catalog\Model\Url */ + $catalogUrlModel = $this->_objectManager->get('Magento\Catalog\Model\Url'); + $model->setTargetPath($catalogUrlModel->generatePath('target', $product, $category)); + $model->setEntityType( + $product && $product->getId() ? self::ENTITY_TYPE_PRODUCT : self::ENTITY_TYPE_CATEGORY + ); + $model->setEntityId($product && $product->getId() ? $product->getId() : $category->getId()); + } + } + + /** + * Get product instance applicable for generatePath + * + * @param \Magento\UrlRedirect\Model\UrlRedirect $model + * @return Product|null + */ + private function _getInitializedProduct($model) + { + /** @var $product Product */ + $product = $this->_getProduct(); + if ($product->getId()) { + $model->setProductId($product->getId()); + } else { + $product = null; + } + + return $product; + } + + /** + * Get category instance applicable for generatePath + * + * @param \Magento\UrlRedirect\Model\UrlRedirect $model + * @return Category|null + */ + private function _getInitializedCategory($model) + { + /** @var $category Category */ + $category = $this->_getCategory(); + if ($category->getId()) { + $model->setCategoryId($category->getId()); + } else { + $category = null; + } + return $category; + } + + /** + * Override URL rewrite data, basing on current CMS page + * + * @param \Magento\UrlRedirect\Model\UrlRedirect $model + * @return void + * @throws \Magento\Framework\Model\Exception + */ + private function _handleCmsPageUrlRewrite($model) + { + /** @var $cmsPage \Magento\Cms\Model\Page */ + $cmsPage = $this->_getCmsPage(); + if (!$cmsPage->getId()) { + return; + } + + /** @var $cmsPageUrlRewrite \Magento\Cms\Model\Page\Urlrewrite */ + $cmsPageUrlRewrite = $this->_objectManager->create('Magento\Cms\Model\Page\Urlrewrite'); + + $model->setTargetPath($cmsPageUrlRewrite->generateTargetPath($cmsPage)); + $model->setEntityType(self::ENTITY_TYPE_CMS_PAGE); + $model->setEntityId($cmsPage->getId()); + } + + /** + * URL rewrite delete action + * + * @return void + */ + public function deleteAction() + { + if ($this->_getUrlRewrite()->getId()) { + try { + $this->_getUrlRewrite()->delete(); + $this->messageManager->addSuccess(__('The URL Rewrite has been deleted.')); + } catch (\Exception $e) { + $this->messageManager->addException($e, __('An error occurred while deleting URL Rewrite.')); + $this->_redirect('adminhtml/*/edit/', array('id' => $this->_getUrlRewrite()->getId())); + return; + } + } + $this->_redirect('adminhtml/*/'); + } + + /** + * Check whether this contoller is allowed in admin permissions + * + * @return bool + */ + protected function _isAllowed() + { + return $this->_authorization->isAllowed('Magento_UrlRedirect::urlrewrite'); + } + + /** + * Get Category from request + * + * @return Category + */ + private function _getCategory() + { + if (!$this->_category) { + $this->_category = $this->_objectManager->create('Magento\Catalog\Model\Category'); + $categoryId = (int)$this->getRequest()->getParam('category', 0); + + if (!$categoryId && $this->_getUrlRewrite()->getId() + && $this->_getUrlRewrite()->getEntityType() === self::ENTITY_TYPE_CATEGORY + ) { + $categoryId = $this->_getUrlRewrite()->getEntityId(); + } + + if ($categoryId) { + $this->_category->load($categoryId); + } + } + return $this->_category; + } + + /** + * Get Product from request + * + * @return Product + */ + private function _getProduct() + { + if (!$this->_product) { + $this->_product = $this->_objectManager->create('Magento\Catalog\Model\Product'); + $productId = (int)$this->getRequest()->getParam('product', 0); + + if (!$productId && $this->_getUrlRewrite()->getId() + && $this->_getUrlRewrite()->getEntityType() === self::ENTITY_TYPE_PRODUCT + ) { + $productId = $this->_getUrlRewrite()->getEntityId(); + } + + if ($productId) { + $this->_product->load($productId); + } + } + return $this->_product; + } + + /** + * Get CMS page from request + * + * @return \Magento\Cms\Model\Page + */ + private function _getCmsPage() + { + if (!$this->_cmsPage) { + $this->_cmsPage = $this->_objectManager->create('Magento\Cms\Model\Page'); + $cmsPageId = (int)$this->getRequest()->getParam('cms_page', 0); + + if (!$cmsPageId && $this->_getUrlRewrite()->getId() + && $this->_getUrlRewrite()->getEntityType() === self::ENTITY_TYPE_CMS_PAGE + ) { + $cmsPageId = $this->_getUrlRewrite()->getEntityId(); + } + + if ($cmsPageId) { + $this->_cmsPage->load($cmsPageId); + } + } + return $this->_cmsPage; + } + + /** + * Get URL rewrite from request + * + * @return \Magento\UrlRedirect\Model\UrlRedirect + */ + private function _getUrlRewrite() + { + if (!$this->_urlRewrite) { + $this->_urlRewrite = $this->_objectManager->create('Magento\UrlRedirect\Model\UrlRedirect'); + + $urlRewriteId = (int)$this->getRequest()->getParam('id', 0); + if ($urlRewriteId) { + $this->_urlRewrite->load((int)$this->getRequest()->getParam('id', 0)); + } + } + return $this->_urlRewrite; + } +} diff --git a/app/code/Magento/UrlRedirect/Controller/Router.php b/app/code/Magento/UrlRedirect/Controller/Router.php new file mode 100644 index 0000000000000000000000000000000000000000..916578caa61510d493df9f7d282f2162a7dcd897 --- /dev/null +++ b/app/code/Magento/UrlRedirect/Controller/Router.php @@ -0,0 +1,106 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\UrlRedirect\Controller; + +/** + * UrlRedirect Controller Router + */ +class Router implements \Magento\Framework\App\RouterInterface +{ + /** @var \Magento\Framework\UrlInterface */ + protected $url; + + /** @var \Magento\Framework\App\State */ + protected $appState; + + /** @var \Magento\Store\Model\StoreManagerInterface */ + protected $storeManager; + + /** @var \Magento\Framework\App\ResponseInterface */ + protected $response; + + /** @var \Magento\UrlRedirect\Service\V1\UrlMatcherInterface */ + protected $urlMatcher; + + /** + * @param \Magento\Framework\App\ActionFactory $actionFactory + * @param \Magento\Framework\UrlInterface $url + * @param \Magento\Framework\App\State $appState + * @param \Magento\Store\Model\StoreManagerInterface $storeManager + * @param \Magento\Framework\App\ResponseInterface $response + * @param \Magento\UrlRedirect\Service\V1\UrlMatcherInterface $urlMatcher + */ + public function __construct( + \Magento\Framework\App\ActionFactory $actionFactory, + \Magento\Framework\UrlInterface $url, + \Magento\Framework\App\State $appState, + \Magento\Store\Model\StoreManagerInterface $storeManager, + \Magento\Framework\App\ResponseInterface $response, + \Magento\UrlRedirect\Service\V1\UrlMatcherInterface $urlMatcher + ) { + parent::__construct($actionFactory); + $this->url = $url; + $this->appState = $appState; + $this->storeManager = $storeManager; + $this->response = $response; + $this->urlMatcher = $urlMatcher; + } + + /** + * Validate and Match Cms Page and modify request + * + * @param \Magento\Framework\App\RequestInterface $request + * @return mixed + */ + public function match(\Magento\Framework\App\RequestInterface $request) + { + if (!$this->appState->isInstalled()) { + $this->response->setRedirect($this->url->getUrl('install'))->sendResponse(); + return null; + } + + $identifier = trim($request->getPathInfo(), '/'); + $urlRewrite = $this->urlMatcher->match($identifier, $this->storeManager->getStore()->getId()); + if ($urlRewrite === null) { + return null; + } + + $redirectType = $urlRewrite->getRedirectType(); + if ($redirectType) { + $redirectCode = $redirectType == \Magento\UrlRedirect\Model\OptionProvider::PERMANENT ? 301 : 302; + $this->response->setRedirect($urlRewrite->getTargetPath(), $redirectCode); + $request->setDispatched(true); + return $this->_actionFactory->createController( + 'Magento\Framework\App\Action\Redirect', + array('request' => $request) + ); + } + + $request->setPathInfo('/' . $urlRewrite->getTargetPath()); + return $this->_actionFactory->createController( + 'Magento\Framework\App\Action\Forward', + array('request' => $request) + ); + } +} diff --git a/app/code/Magento/UrlRedirect/Helper/UrlRewrite.php b/app/code/Magento/UrlRedirect/Helper/UrlRewrite.php new file mode 100644 index 0000000000000000000000000000000000000000..806219890e7a515e19b2a083458770675d412736 --- /dev/null +++ b/app/code/Magento/UrlRedirect/Helper/UrlRewrite.php @@ -0,0 +1,95 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\UrlRedirect\Helper; + +class UrlRewrite extends \Magento\Framework\App\Helper\AbstractHelper +{ + /** + * Validation error constants + */ + const VERR_MANYSLASHES = 1; + + // Too many slashes in a row of request path, e.g. '///foo//' + const VERR_ANCHOR = 2; + + // Anchor is not supported in request path, e.g. 'foo#bar' + + /** + * @var \Magento\UrlRedirect\Model\OptionProvider + */ + protected $_urlrewrite; + + /** + * @param \Magento\Framework\App\Helper\Context $context + * @param \Magento\UrlRedirect\Model\OptionProvider $urlrewrite + */ + public function __construct( + \Magento\Framework\App\Helper\Context $context, + \Magento\UrlRedirect\Model\OptionProvider $urlrewrite + ) { + parent::__construct($context); + $this->_urlrewrite = $urlrewrite; + } + + /** + * Core func to validate request path + * If something is wrong with a path it throws localized error message and error code, + * that can be checked to by wrapper func to alternate error message + * + * @param string $requestPath + * @return bool + * @throws \Exception + */ + protected function _validateRequestPath($requestPath) + { + if (strpos($requestPath, '//') !== false) { + throw new \Exception( + __('Two and more slashes together are not permitted in request path'), + self::VERR_MANYSLASHES + ); + } + if (strpos($requestPath, '#') !== false) { + throw new \Exception(__('Anchor symbol (#) is not supported in request path'), self::VERR_ANCHOR); + } + return true; + } + + /** + * Validates request path + * Either returns TRUE (success) or throws error (validation failed) + * + * @param string $requestPath + * @throws \Magento\Framework\Model\Exception + * @return bool + */ + public function validateRequestPath($requestPath) + { + try { + $this->_validateRequestPath($requestPath); + } catch (\Exception $e) { + throw new \Magento\Framework\Model\Exception($e->getMessage()); + } + return true; + } +} diff --git a/app/code/Magento/UrlRedirect/Model/OptionProvider.php b/app/code/Magento/UrlRedirect/Model/OptionProvider.php new file mode 100644 index 0000000000000000000000000000000000000000..46d9a7357eba72ad31cf656dbc92d468dc487835 --- /dev/null +++ b/app/code/Magento/UrlRedirect/Model/OptionProvider.php @@ -0,0 +1,77 @@ +<?php +/** + * URL Rewrite Option Provider + * + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\UrlRedirect\Model; + +use Magento\Framework\Option\ArrayInterface; + +class OptionProvider implements ArrayInterface +{ + const TEMPORARY = 'R'; + + const PERMANENT = 'RP'; + + /** + * @var array|null + */ + protected $_options = null; + + /** + * Get all options + * + * @return array + */ + public function getAllOptions() + { + if (is_null($this->_options)) { + $this->_options = array( + '' => __('No'), + self::TEMPORARY => __('Temporary (302)'), + self::PERMANENT => __('Permanent (301)'), + ); + } + return $this->_options; + } + + /** + * Get options list (redirects only) + * + * @return string[] + */ + public function getRedirectOptions() + { + return array(self::TEMPORARY, self::PERMANENT); + } + + /** + * Return option array + * + * @return array + */ + public function toOptionArray() + { + return $this->getAllOptions(); + } +} diff --git a/app/code/Magento/UrlRedirect/Model/Resource/UrlRedirect.php b/app/code/Magento/UrlRedirect/Model/Resource/UrlRedirect.php new file mode 100644 index 0000000000000000000000000000000000000000..f19d49ef955765e2f587cfdc0f8ad6598c7e3e22 --- /dev/null +++ b/app/code/Magento/UrlRedirect/Model/Resource/UrlRedirect.php @@ -0,0 +1,77 @@ +<?php +/** + * URL rewrite resource model + * + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\UrlRedirect\Model\Resource; + +class UrlRedirect extends \Magento\Framework\Model\Resource\Db\AbstractDb +{ + /** + * Define main table + * + * @return void + */ + protected function _construct() + { + $this->_init('url_rewrite', 'url_rewrite_id'); + } + + /** + * Initialize array fields + * + * @return $this + */ + protected function _initUniqueFields() + { + $this->_uniqueFields = array( + array('field' => array('request_path', 'store_id'), 'title' => __('Request Path for Specified Store')) + ); + return $this; + } + + /** + * Retrieve select object for load object data + * + * @param string $field + * @param mixed $value + * @param \Magento\UrlRedirect\Model\UrlRedirect $object + * @return \Zend_Db_Select + */ + protected function _getLoadSelect($field, $value, $object) + { + /** @var $select \Magento\Framework\DB\Select */ + $select = parent::_getLoadSelect($field, $value, $object); + + if (!is_null($object->getStoreId())) { + $select->where( + 'store_id IN(?)', + array(\Magento\Store\Model\Store::DEFAULT_STORE_ID, $object->getStoreId()) + ); + $select->order('store_id ' . \Magento\Framework\DB\Select::SQL_DESC); + $select->limit(1); + } + + return $select; + } +} diff --git a/app/code/Magento/UrlRedirect/Model/Resource/UrlRedirect/Collection.php b/app/code/Magento/UrlRedirect/Model/Resource/UrlRedirect/Collection.php new file mode 100644 index 0000000000000000000000000000000000000000..9cc9f17e6f3b6cb4948cf94043bce37f75795055 --- /dev/null +++ b/app/code/Magento/UrlRedirect/Model/Resource/UrlRedirect/Collection.php @@ -0,0 +1,89 @@ +<?php +/** + * URL rewrite collection + * + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\UrlRedirect\Model\Resource\UrlRedirect; + +class Collection extends \Magento\Framework\Model\Resource\Db\Collection\AbstractCollection +{ + /** + * Store Manager Model + * + * @var \Magento\Store\Model\StoreManagerInterface + */ + protected $_storeManager; + + /** + * @param \Magento\Framework\Data\Collection\EntityFactoryInterface $entityFactory + * @param \Magento\Framework\Logger $logger + * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy + * @param \Magento\Framework\Event\ManagerInterface $eventManager + * @param \Magento\Store\Model\StoreManagerInterface $storeManager + * @param mixed $connection + * @param \Magento\Framework\Model\Resource\Db\AbstractDb $resource + */ + public function __construct( + \Magento\Framework\Data\Collection\EntityFactoryInterface $entityFactory, + \Magento\Framework\Logger $logger, + \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy, + \Magento\Framework\Event\ManagerInterface $eventManager, + \Magento\Store\Model\StoreManagerInterface $storeManager, + $connection = null, + \Magento\Framework\Model\Resource\Db\AbstractDb $resource = null + ) { + parent::__construct($entityFactory, $logger, $fetchStrategy, $eventManager, $connection, $resource); + $this->_storeManager = $storeManager; + } + + /** + * Define resource model + * + * @return void + */ + protected function _construct() + { + $this->_init('Magento\UrlRedirect\Model\UrlRedirect', 'Magento\UrlRedirect\Model\Resource\UrlRedirect'); + } + + /** + * Filter collections by stores + * + * @param mixed $store + * @param bool $withAdmin + * @return $this + */ + public function addStoreFilter($store, $withAdmin = true) + { + if (!is_array($store)) { + $store = array($this->_storeManager->getStore($store)->getId()); + } + if ($withAdmin) { + $store[] = 0; + } + + $this->addFieldToFilter('store_id', array('in' => $store)); + + return $this; + } +} diff --git a/app/code/Magento/UrlRedirect/Model/Storage/AbstractStorage.php b/app/code/Magento/UrlRedirect/Model/Storage/AbstractStorage.php new file mode 100644 index 0000000000000000000000000000000000000000..6d8dca8b501b9c5f82cf121ddb7e00f990361ea0 --- /dev/null +++ b/app/code/Magento/UrlRedirect/Model/Storage/AbstractStorage.php @@ -0,0 +1,119 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\UrlRedirect\Model\Storage; + +use Magento\Framework\App\Resource; +use Magento\UrlRedirect\Model\StorageInterface; +use Magento\UrlRedirect\Service\V1\Data\Converter; +use Magento\UrlRedirect\Service\V1\Data\Filter; + +/** + * Abstract db storage + */ +abstract class AbstractStorage implements StorageInterface +{ + /** + * @var Converter + */ + protected $converter; + + /** + * @param Converter $converter + */ + public function __construct(Converter $converter) + { + $this->converter = $converter; + } + + /** + * {@inheritdoc} + */ + public function findAllByFilter(Filter $filter) + { + $rows = $this->doFindAllByFilter($filter); + + $urlRewrites = []; + foreach ($rows as $row) { + $urlRewrites[] = $this->createUrlRewrite($row); + } + return $urlRewrites; + } + + /** + * Find all rows by specific filter. Template method + * + * @param Filter $filter + * @return array + */ + abstract protected function doFindAllByFilter($filter); + + /** + * {@inheritdoc} + */ + public function findByFilter(Filter $filter) + { + $row = $this->doFindByFilter($filter); + + return $row ? $this->createUrlRewrite($row) : null; + } + + /** + * Find row by specific filter. Template method + * + * @param Filter $filter + * @return array + */ + abstract protected function doFindByFilter($filter); + + /** + * {@inheritdoc} + */ + public function addMultiple(array $urls) + { + $flatData = []; + foreach ($urls as $url) { + $flatData[] = $this->converter->convertObjectToArray($url); + } + $this->doAddMultiple($flatData); + } + + /** + * Add multiple data to storage. Template method + * + * @param array $data + * @return int + */ + abstract protected function doAddMultiple($data); + + /** + * Create url rewrite object + * + * @param array $data + * @return \Magento\UrlRedirect\Service\V1\Data\UrlRewrite + */ + protected function createUrlRewrite($data) + { + return $this->converter->convertArrayToObject($data); + } +} diff --git a/app/code/Magento/UrlRedirect/Model/Storage/Db.php b/app/code/Magento/UrlRedirect/Model/Storage/Db.php new file mode 100644 index 0000000000000000000000000000000000000000..0a477302d77afd2774a5ffc11494fb512a76e806 --- /dev/null +++ b/app/code/Magento/UrlRedirect/Model/Storage/Db.php @@ -0,0 +1,104 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\UrlRedirect\Model\Storage; + +use Magento\Framework\App\Resource; +use Magento\UrlRedirect\Service\V1\Data\Converter; +use Magento\UrlRedirect\Service\V1\Data\Filter; + +/** + * Db storage + */ +class Db extends AbstractStorage +{ + /** + * DB Storage table name + */ + const TABLE_NAME = 'url_rewrite'; + + /** + * @var \Magento\Framework\DB\Adapter\AdapterInterface + */ + protected $connection; + + /** + * @param Converter $converter + * @param Resource $resource + */ + public function __construct(Converter $converter, Resource $resource) + { + $this->connection = $resource->getConnection(Resource::DEFAULT_WRITE_RESOURCE); + + parent::__construct($converter); + } + + /** + * Prepare select statement for specific filter + * + * @param Filter $filter + * @return \Magento\Framework\DB\Select + */ + protected function prepareSelect($filter) + { + $select = $this->connection->select(); + $select->from(self::TABLE_NAME); + + foreach ($filter->getFilter() as $column => $value) { + $select->where($this->connection->quoteIdentifier($column) . ' IN (?)', $value); + } + return $select; + } + + /** + * {@inheritdoc} + */ + protected function doFindAllByFilter($filter) + { + return $this->connection->fetchAll($this->prepareSelect($filter)); + } + + /** + * {@inheritdoc} + */ + protected function doFindByFilter($filter) + { + return $this->connection->fetchRow($this->prepareSelect($filter)); + } + + /** + * {@inheritdoc} + */ + protected function doAddMultiple($data) + { + $this->connection->insertMultiple(self::TABLE_NAME, $data); + } + + /** + * {@inheritdoc} + */ + public function deleteByFilter(Filter $filter) + { + $this->connection->query($this->prepareSelect($filter)->deleteFromSelect(self::TABLE_NAME)); + } +} diff --git a/app/code/Magento/UrlRedirect/Model/StorageInterface.php b/app/code/Magento/UrlRedirect/Model/StorageInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..c362c56460ca8c0a25e65d3da2445b9906f5906d --- /dev/null +++ b/app/code/Magento/UrlRedirect/Model/StorageInterface.php @@ -0,0 +1,64 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\UrlRedirect\Model; + +use Magento\UrlRedirect\Service\V1\Data\Filter; + +/** + * Url Storage Interface + */ +interface StorageInterface +{ + /** + * Find all rows by specific filter + * + * @param Filter $filter + * @return \Magento\UrlRedirect\Service\V1\Data\UrlRewrite[] + */ + public function findAllByFilter(Filter $filter); + + /** + * Find row by specific filter + * + * @param Filter $filter + * @return \Magento\UrlRedirect\Service\V1\Data\UrlRewrite + */ + public function findByFilter(Filter $filter); + + /** + * Add multiple urls to storage + * + * @param array $urls + * @return void + */ + public function addMultiple(array $urls); + + /** + * Delete data from storage by specific filter + * + * @param Filter $filter + * @return void + */ + public function deleteByFilter(Filter $filter); +} diff --git a/app/code/Magento/UrlRedirect/Model/UrlRedirect.php b/app/code/Magento/UrlRedirect/Model/UrlRedirect.php new file mode 100644 index 0000000000000000000000000000000000000000..4935d63bc805f2b18d69cd2f60310a50ca621674 --- /dev/null +++ b/app/code/Magento/UrlRedirect/Model/UrlRedirect.php @@ -0,0 +1,45 @@ +<?php +/** + * URL Rewrite Model + * + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\UrlRedirect\Model; + +/** + * @method string getEntityType() + * @method UrlRedirect setEntityType(string $value) + * @method int getEntityId() + * @method UrlRedirect setEntityId(int $value) + */ +class UrlRedirect extends \Magento\Framework\Model\AbstractModel +{ + /** + * Initialize corresponding resource model + * + * @return void + */ + protected function _construct() + { + $this->_init('Magento\UrlRedirect\Model\Resource\UrlRedirect'); + } +} diff --git a/app/code/Magento/UrlRedirect/Service/V1/Data/Converter.php b/app/code/Magento/UrlRedirect/Service/V1/Data/Converter.php new file mode 100644 index 0000000000000000000000000000000000000000..a7847b0d84b4bd5b77855e77414d76ce9f0956ac --- /dev/null +++ b/app/code/Magento/UrlRedirect/Service/V1/Data/Converter.php @@ -0,0 +1,68 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\UrlRedirect\Service\V1\Data; + +use Magento\Framework\Service\DataObjectConverter; +use Magento\UrlRedirect\Service\V1\Data\UrlRewriteBuilderFactory; + +/** + * Data object converter + */ +class Converter +{ + /** + * @var UrlRewriteBuilderFactory + */ + protected $builderFactory; + + /** + * @param UrlRewriteBuilderFactory $builderFactory + */ + public function __construct(UrlRewriteBuilderFactory $builderFactory) + { + $this->builderFactory = $builderFactory; + } + + /** + * Convert array to Service Data Object + * + * @param array $data + * @return UrlRewrite + */ + public function convertArrayToObject(array $data) + { + return $this->builderFactory->create()->populateWithArray($data)->create(); + } + + /** + * Convert Service Data Object to array + * + * @param UrlRewrite $object + * @return array + */ + public function convertObjectToArray(UrlRewrite $object) + { + return DataObjectConverter::toFlatArray($object); + } +} diff --git a/app/code/Magento/UrlRedirect/Service/V1/Data/Filter.php b/app/code/Magento/UrlRedirect/Service/V1/Data/Filter.php new file mode 100644 index 0000000000000000000000000000000000000000..f2fc91a18a336d255e0514ed90c87760b0c1e7ea --- /dev/null +++ b/app/code/Magento/UrlRedirect/Service/V1/Data/Filter.php @@ -0,0 +1,138 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\UrlRedirect\Service\V1\Data; + +/** + * Url rewrite search filter + */ +class Filter +{ + /** + * Data with filter values + * + * @var array + */ + protected $data = []; + + /** + * Possible fields for filter + * + * @var array + */ + protected $possibleFields = [ + UrlRewrite::ENTITY_ID, + UrlRewrite::ENTITY_TYPE, + UrlRewrite::STORE_ID, + UrlRewrite::REQUEST_PATH, + UrlRewrite::REDIRECT_TYPE, + ]; + + /** + * Filter constructor + * + * @param array $filterData + * @throws \InvalidArgumentException + */ + public function __construct(array $filterData = []) + { + if ($filterData) { + if ($wrongFields = array_diff(array_keys($filterData), $this->possibleFields)) { + throw new \InvalidArgumentException( + sprintf('There is wrong fields passed to filter: "%s"', implode(', ', $wrongFields)) + ); + } + $this->data = $filterData; + } + return $this; + } + + /** + * @param string $key + * @param mixed $value + * @return $this + */ + protected function _set($key, $value) + { + $this->data[$key] = $value; + return $this; + } + + /** + * @return array + */ + public function getFilter() + { + return $this->data; + } + + /** + * @param int $entityId + * + * @return $this + */ + public function setEntityId($entityId) + { + return $this->_set(UrlRewrite::ENTITY_ID, $entityId); + } + + /** + * @param int|array $entityType + * + * @return $this + */ + public function setEntityType($entityType) + { + return $this->_set(UrlRewrite::ENTITY_TYPE, $entityType); + } + + /** + * @param string $requestPath + * + * @return $this + */ + public function setRequestPath($requestPath) + { + return $this->_set(UrlRewrite::REQUEST_PATH, $requestPath); + } + + /** + * @param int $storeId + * + * @return $this + */ + public function setStoreId($storeId) + { + return $this->_set(UrlRewrite::STORE_ID, $storeId); + } + + /** + * @param string|array $redirectType + * + * @return $this + */ + public function setRedirectType($redirectType) + { + return $this->_set(UrlRewrite::REDIRECT_TYPE, $redirectType); + } +} diff --git a/app/code/Magento/UrlRedirect/Service/V1/Data/UrlRewrite.php b/app/code/Magento/UrlRedirect/Service/V1/Data/UrlRewrite.php new file mode 100644 index 0000000000000000000000000000000000000000..a922491f668e77e9789d03555478d2c412c8e99e --- /dev/null +++ b/app/code/Magento/UrlRedirect/Service/V1/Data/UrlRewrite.php @@ -0,0 +1,111 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\UrlRedirect\Service\V1\Data; + +use Magento\Framework\Service\Data\AbstractObject; + +/** + * Data abstract class for url storage + */ +class UrlRewrite extends AbstractObject +{ + /**#@+ + * Value object attribute names + */ + const ENTITY_ID = 'entity_id'; + const ENTITY_TYPE = 'entity_type'; + const REQUEST_PATH = 'request_path'; + const TARGET_PATH = 'target_path'; + const STORE_ID = 'store_id'; + const REDIRECT_TYPE = 'redirect_type'; + const DESCRIPTION = 'description'; + /**#@-*/ + + /** + * Get data by key + * + * @param string $key + * @return mixed|null + */ + public function getByKey($key) + { + return $this->_get($key); + } + + /** + * @return int + */ + public function getEntityId() + { + return $this->_get(self::ENTITY_ID); + } + + /** + * @return int + */ + public function getEntityType() + { + return $this->_get(self::ENTITY_TYPE); + } + + /** + * @return string + */ + public function getRequestPath() + { + return $this->_get(self::REQUEST_PATH); + } + + /** + * @return string + */ + public function getTargetPath() + { + return $this->_get(self::TARGET_PATH); + } + + /** + * @return int + */ + public function getStoreId() + { + return $this->_get(self::STORE_ID); + } + + /** + * @return string + */ + public function getRedirectType() + { + return $this->_get(self::REDIRECT_TYPE); + } + + /** + * @return string + */ + public function getDescription() + { + return $this->_get(self::DESCRIPTION); + } +} diff --git a/app/code/Magento/UrlRedirect/Service/V1/Data/UrlRewriteBuilder.php b/app/code/Magento/UrlRedirect/Service/V1/Data/UrlRewriteBuilder.php new file mode 100644 index 0000000000000000000000000000000000000000..e23a3e622a4db79c6a782c3ac7242c8b1c40ecd8 --- /dev/null +++ b/app/code/Magento/UrlRedirect/Service/V1/Data/UrlRewriteBuilder.php @@ -0,0 +1,102 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\UrlRedirect\Service\V1\Data; + +use Magento\Framework\Service\Data\AbstractObjectBuilder; + +/** + * Data builder class for url rewrite + */ +class UrlRewriteBuilder extends AbstractObjectBuilder +{ + /** + * @param int $entityId + * + * @return $this + */ + public function setEntityId($entityId) + { + return $this->_set(UrlRewrite::ENTITY_ID, $entityId); + } + + /** + * @param int $entityType + * + * @return $this + */ + public function setEntityType($entityType) + { + return $this->_set(UrlRewrite::ENTITY_TYPE, $entityType); + } + + /** + * @param string $requestPath + * + * @return $this + */ + public function setRequestPath($requestPath) + { + return $this->_set(UrlRewrite::REQUEST_PATH, $requestPath); + } + + /** + * @param string $targetPath + * + * @return $this + */ + public function setTargetPath($targetPath) + { + return $this->_set(UrlRewrite::TARGET_PATH, $targetPath); + } + + /** + * @param int $storeId + * + * @return $this + */ + public function setStoreId($storeId) + { + return $this->_set(UrlRewrite::STORE_ID, $storeId); + } + + /** + * @param int $redirectCode + * + * @return $this + */ + public function setRedirectCode($redirectCode) + { + return $this->_set(UrlRewrite::REDIRECT_TYPE, $redirectCode); + } + + /** + * @param string $description + * + * @return $this + */ + public function setDescription($description) + { + return $this->_set(UrlRewrite::DESCRIPTION, $description); + } +} diff --git a/app/code/Magento/UrlRedirect/Service/V1/UrlManager.php b/app/code/Magento/UrlRedirect/Service/V1/UrlManager.php new file mode 100644 index 0000000000000000000000000000000000000000..0e29a14db255388881808f95b946bd90f4be0b3f --- /dev/null +++ b/app/code/Magento/UrlRedirect/Service/V1/UrlManager.php @@ -0,0 +1,127 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\UrlRedirect\Service\V1; + +use Magento\UrlRedirect\Service\V1\Data\Filter; +use Magento\UrlRedirect\Service\V1\Data\FilterFactory; +use Magento\UrlRedirect\Service\V1\Data\UrlRewrite; +use Magento\UrlRedirect\Model\StorageInterface; + +/** + * Url Manager + */ +class UrlManager implements UrlMatcherInterface, UrlSaveInterface +{ + /** + * @var StorageInterface + */ + protected $storage; + + /** + * @var FilterFactory + */ + protected $filterFactory; + + /** + * @param StorageInterface $storage + * @param FilterFactory $filterFactory + */ + public function __construct(StorageInterface $storage, FilterFactory $filterFactory) + { + $this->storage = $storage; + $this->filterFactory = $filterFactory; + } + + /** + * {@inheritdoc} + */ + public function save(array $urls) + { + $this->storage->deleteByFilter($this->createFilter($urls)); + + $this->storage->addMultiple($urls); + } + + /** + * {@inheritdoc} + */ + public function match($requestPath, $storeId) + { + /** @var Filter $filter */ + $filter = $this->filterFactory->create(); + $filter->setRequestPath($requestPath)->setStoreId($storeId); + + return $this->findByFilter($filter); + } + + /** + * {@inheritdoc} + */ + public function findByEntity($entityId, $entityType, $storeId = 0) + { + /** @var Filter $filter */ + $filter = $this->filterFactory->create(); + $filter->setEntityId($entityId)->setEntityType($entityType)->setStoreId($storeId); + + return $this->findByFilter($filter); + } + + /** + * {@inheritdoc} + */ + public function findByFilter(Filter $filter) + { + return $this->storage->findByFilter($filter); + } + + /** + * {@inheritdoc} + */ + public function findAllByFilter(Filter $filter) + { + return $this->storage->findAllByFilter($filter); + } + + /** + * Get filter for url rows deletion due to provided urls + * + * @param UrlRewrite[] $urls + * @return Filter + */ + protected function createFilter($urls) + { + $filterData = []; + $uniqueKeys = [UrlRewrite::ENTITY_ID, UrlRewrite::ENTITY_TYPE, UrlRewrite::STORE_ID]; + foreach ($urls as $url) { + foreach ($uniqueKeys as $key) { + $fieldValue = $url->getByKey($key); + + if (!isset($filterData[$key]) || !in_array($fieldValue, $filterData[$key])) { + $filterData[$key][] = $fieldValue; + } + } + } + return $this->filterFactory->create(['filterData' => $filterData]); + } +} diff --git a/app/code/Magento/UrlRedirect/Service/V1/UrlMatcherInterface.php b/app/code/Magento/UrlRedirect/Service/V1/UrlMatcherInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..2ebc555c6947fc9c9286049af1a93b71a2dc473d --- /dev/null +++ b/app/code/Magento/UrlRedirect/Service/V1/UrlMatcherInterface.php @@ -0,0 +1,67 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\UrlRedirect\Service\V1; + +use Magento\UrlRedirect\Service\V1\Data\Filter; + +/** + * Url Matcher Interface + */ +interface UrlMatcherInterface +{ + /** + * Match provided request path for store and if matched - return corresponding Data Object + * + * @param string $requestPath + * @param int $storeId + * @return \Magento\UrlRedirect\Service\V1\Data\UrlRewrite|null + */ + public function match($requestPath, $storeId); + + /** + * Match provided entity for store and if matched - return corresponding Data Object + * + * @param int $entityId + * @param int $entityType + * @param int $storeId + * @return \Magento\UrlRedirect\Service\V1\Data\UrlRewrite|null + */ + public function findByEntity($entityId, $entityType, $storeId); + + /** + * Find row by specific filter + * + * @param Filter $filter + * @return \Magento\UrlRedirect\Service\V1\Data\UrlRewrite|null + */ + public function findByFilter(Filter $filter); + + /** + * Find rows by specific filter + * + * @param Filter $filter + * @return \Magento\UrlRedirect\Service\V1\Data\UrlRewrite[] + */ + public function findAllByFilter(Filter $filter); +} diff --git a/app/code/Magento/UrlRedirect/Service/V1/UrlSaveInterface.php b/app/code/Magento/UrlRedirect/Service/V1/UrlSaveInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..c07e3b084d26830d4fe2ac2815eaa38bdb557b32 --- /dev/null +++ b/app/code/Magento/UrlRedirect/Service/V1/UrlSaveInterface.php @@ -0,0 +1,38 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\UrlRedirect\Service\V1; + +/** + * Url Save Interface + */ +interface UrlSaveInterface +{ + /** + * Save url rewrites. Return number of saved urls + * + * @param \Magento\UrlRedirect\Service\V1\Data\UrlRewrite[] $urls + * @return void + */ + public function save(array $urls); +} diff --git a/app/code/Magento/UrlRedirect/etc/adminhtml/acl.xml b/app/code/Magento/UrlRedirect/etc/adminhtml/acl.xml new file mode 100644 index 0000000000000000000000000000000000000000..8f2d7946e10928bb4e5fa3d943ad1776f6ad8d7d --- /dev/null +++ b/app/code/Magento/UrlRedirect/etc/adminhtml/acl.xml @@ -0,0 +1,38 @@ +<?xml version="1.0"?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/Acl/etc/acl.xsd"> + <acl> + <resources> + <resource id="Magento_Adminhtml::admin"> + <resource id="Magento_Adminhtml::marketing"> + <resource id="Magento_Adminhtml::marketing_seo"> + <resource id="Magento_UrlRedirect::urlrewrite" title="URL Rewrites" sortOrder="20" /> + </resource> + </resource> + </resource> + </resources> + </acl> +</config> diff --git a/app/code/Magento/UrlRedirect/etc/adminhtml/menu.xml b/app/code/Magento/UrlRedirect/etc/adminhtml/menu.xml new file mode 100644 index 0000000000000000000000000000000000000000..5ae310d19f71623e70a53f72f79d7dd12ec875ed --- /dev/null +++ b/app/code/Magento/UrlRedirect/etc/adminhtml/menu.xml @@ -0,0 +1,32 @@ +<?xml version="1.0"?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../Backend/etc/menu.xsd"> + <menu> + <add id="Magento_UrlRedirect::catalog_urlrewrite" title="URL Rewrites" module="Magento_UrlRedirect" + sortOrder="20" parent="Magento_Backend::marketing_seo" + action="adminhtml/urlRedirect/index" resource="Magento_UrlRedirect::urlrewrite"/> + </menu> +</config> diff --git a/app/code/Magento/UrlRedirect/etc/adminhtml/routes.xml b/app/code/Magento/UrlRedirect/etc/adminhtml/routes.xml new file mode 100644 index 0000000000000000000000000000000000000000..312f40563c2a8e80606cfcd4373ac78a69b30bf5 --- /dev/null +++ b/app/code/Magento/UrlRedirect/etc/adminhtml/routes.xml @@ -0,0 +1,32 @@ +<?xml version="1.0"?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/App/etc/routes.xsd"> + <router id="admin"> + <route id="adminhtml"> + <module name="Magento_UrlRedirect" before="Magento_Adminhtml" /> + </route> + </router> +</config> diff --git a/app/code/Magento/UrlRedirect/etc/config.xml b/app/code/Magento/UrlRedirect/etc/config.xml new file mode 100644 index 0000000000000000000000000000000000000000..c32718649d84f7242780b8740ccc5cf3ff6d28b9 --- /dev/null +++ b/app/code/Magento/UrlRedirect/etc/config.xml @@ -0,0 +1,42 @@ +<?xml version="1.0"?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../Core/etc/config.xsd"> + <default> + <url_rewrite> + <entity_types> + <product> + <generator>Magento\Framework\Object</generator> + </product> + <category> + <generator>Magento\Framework\Object</generator> + </category> + <cms-page> + <generator>Magento\Framework\Object</generator> + </cms-page> + </entity_types> + </url_rewrite> + </default> +</config> diff --git a/app/code/Magento/UrlRedirect/etc/di.xml b/app/code/Magento/UrlRedirect/etc/di.xml new file mode 100644 index 0000000000000000000000000000000000000000..888bf6a467b880c2b07f30d927fe89d2ff307246 --- /dev/null +++ b/app/code/Magento/UrlRedirect/etc/di.xml @@ -0,0 +1,30 @@ +<?xml version="1.0"?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd"> + <preference for="Magento\UrlRedirect\Model\StorageInterface" type="Magento\UrlRedirect\Model\Storage\Db"/> + <preference for="Magento\UrlRedirect\Service\V1\UrlMatcherInterface" type="Magento\UrlRedirect\Service\V1\UrlManager"/> + <preference for="Magento\UrlRedirect\Service\V1\UrlSaveInterface" type="Magento\UrlRedirect\Service\V1\UrlManager"/> +</config> diff --git a/app/code/Magento/UrlRedirect/etc/frontend/di.xml b/app/code/Magento/UrlRedirect/etc/frontend/di.xml new file mode 100644 index 0000000000000000000000000000000000000000..7b7acb7b3de3dd0fdeac02e8456261c9fce122ad --- /dev/null +++ b/app/code/Magento/UrlRedirect/etc/frontend/di.xml @@ -0,0 +1,38 @@ +<?xml version="1.0"?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd"> + <type name="Magento\Framework\App\RouterList"> + <arguments> + <argument name="routerList" xsi:type="array"> + <item name="urlredirect" xsi:type="array"> + <item name="class" xsi:type="string">Magento\UrlRedirect\Controller\Router</item> + <item name="disable" xsi:type="boolean">false</item> + <item name="sortOrder" xsi:type="string">40</item> + </item> + </argument> + </arguments> + </type> +</config> diff --git a/app/code/Magento/UrlRedirect/etc/module.xml b/app/code/Magento/UrlRedirect/etc/module.xml new file mode 100644 index 0000000000000000000000000000000000000000..1202c64f7285f0189fcdeac1b6e4463c834d4d4f --- /dev/null +++ b/app/code/Magento/UrlRedirect/etc/module.xml @@ -0,0 +1,37 @@ +<?xml version="1.0"?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd"> + <module name="Magento_UrlRedirect" schema_version="1.0.0.0" active="false"> + <depends> + <module name="Magento_Catalog"/> + <module name="Magento_Cms"/> + <module name="Magento_Core"/> + <module name="Magento_Backend"/> + <module name="Magento_Install"/> + <module name="Magento_Store"/> + </depends> + </module> +</config> diff --git a/app/code/Magento/UrlRedirect/i18n/de_DE.csv b/app/code/Magento/UrlRedirect/i18n/de_DE.csv new file mode 100644 index 0000000000000000000000000000000000000000..8b6c4909ac30884e66b24d11978dce0e6ec7c71a --- /dev/null +++ b/app/code/Magento/UrlRedirect/i18n/de_DE.csv @@ -0,0 +1,57 @@ +Custom,Custom +Back,Back +ID,ID +SKU,SKU +No,No +Action,Action +Reset,Reset +Edit,Edit +"Two and more slashes together are not permitted in request path","Two and more slashes together are not permitted in request path" +"Anchor symbol (#) is not supported in request path","Anchor symbol (#) is not supported in request path" +"Request Path for Specified Store","Request Path for Specified Store" +"Temporary (302)","Temporary (302)" +"Permanent (301)","Permanent (301)" +"Edit URL Rewrite for a Category","Edit URL Rewrite for a Category" +"Add URL Rewrite for a Category","Add URL Rewrite for a Category" +"Category:","Category:" +"We can't set up a URL rewrite because the product you chose is not associated with a website.","We can't set up a URL rewrite because the product you chose is not associated with a website." +"We can't set up a URL rewrite because the category your chose is not associated with a website.","We can't set up a URL rewrite because the category your chose is not associated with a website." +"Edit URL Rewrite for a Product","Edit URL Rewrite for a Product" +"Add URL Rewrite for a Product","Add URL Rewrite for a Product" +"Product:","Product:" +"Skip Category Selection","Skip Category Selection" +"Name","Name" +"Status","Status" +"Edit URL Rewrite for CMS page","Edit URL Rewrite for CMS page" +"Add URL Rewrite for CMS page","Add URL Rewrite for CMS page" +"CMS page:","CMS page:" +"Chosen cms page does not associated with any website.","Chosen cms page does not associated with any website." +"Title","Title" +"URL Key","URL Key" +"Store View","Store View" +"Edit URL Rewrite","Edit URL Rewrite" +"Add New URL Rewrite","Add New URL Rewrite" +"Delete","Delete" +"Are you sure you want to do this?","Are you sure you want to do this?" +"Save","Save" +"Block Information","Block Information" +"URL Rewrite Information","URL Rewrite Information" +"Request Path","Request Path" +"Target Path","Target Path" +"Redirect","Redirect" +"Description","Description" +"Store","Store" +"URL Rewrite Management","URL Rewrite Management" +"Add URL Rewrite","Add URL Rewrite" +"For category","For category" +"For product","For product" +"For CMS page","For CMS page" +"Create URL Rewrite:","Create URL Rewrite:" +"URL Rewrites","URL Rewrites" +"[New/Edit] URL Rewrite","[New/Edit] URL Rewrite" +"The URL Rewrite has been saved.","The URL Rewrite has been saved." +"An error occurred while saving URL Rewrite.","An error occurred while saving URL Rewrite." +"The URL Rewrite has been deleted.","The URL Rewrite has been deleted." +"An error occurred while deleting URL Rewrite.","An error occurred while deleting URL Rewrite." +"Select Category","Select Category" +"Options","Options" diff --git a/app/code/Magento/UrlRedirect/i18n/en_US.csv b/app/code/Magento/UrlRedirect/i18n/en_US.csv new file mode 100644 index 0000000000000000000000000000000000000000..2d0c4e9330abff7649b009a699f64e122f41061d --- /dev/null +++ b/app/code/Magento/UrlRedirect/i18n/en_US.csv @@ -0,0 +1,62 @@ +Custom,Custom +Back,Back +ID,ID +SKU,SKU +No,No +Custom,Custom +Back,Back +ID,ID +SKU,SKU +No,No +Action,Action +Reset,Reset +Edit,Edit +"Two and more slashes together are not permitted in request path","Two and more slashes together are not permitted in request path" +"Anchor symbol (#) is not supported in request path","Anchor symbol (#) is not supported in request path" +"Request Path for Specified Store","Request Path for Specified Store" +"Temporary (302)","Temporary (302)" +"Permanent (301)","Permanent (301)" +"Edit URL Rewrite for a Category","Edit URL Rewrite for a Category" +"Add URL Rewrite for a Category","Add URL Rewrite for a Category" +"Category:","Category:" +"We can't set up a URL rewrite because the product you chose is not associated with a website.","We can't set up a URL rewrite because the product you chose is not associated with a website." +"We can't set up a URL rewrite because the category your chose is not associated with a website.","We can't set up a URL rewrite because the category your chose is not associated with a website." +"Edit URL Rewrite for a Product","Edit URL Rewrite for a Product" +"Add URL Rewrite for a Product","Add URL Rewrite for a Product" +"Product:","Product:" +"Skip Category Selection","Skip Category Selection" +"Name","Name" +"Status","Status" +"Edit URL Rewrite for CMS page","Edit URL Rewrite for CMS page" +"Add URL Rewrite for CMS page","Add URL Rewrite for CMS page" +"CMS page:","CMS page:" +"Chosen cms page does not associated with any website.","Chosen cms page does not associated with any website." +"Title","Title" +"URL Key","URL Key" +"Store View","Store View" +"Edit URL Rewrite","Edit URL Rewrite" +"Add New URL Rewrite","Add New URL Rewrite" +"Delete","Delete" +"Are you sure you want to do this?","Are you sure you want to do this?" +"Save","Save" +"Block Information","Block Information" +"URL Rewrite Information","URL Rewrite Information" +"Request Path","Request Path" +"Target Path","Target Path" +"Redirect","Redirect" +"Description","Description" +"Store","Store" +"URL Rewrite Management","URL Rewrite Management" +"Add URL Rewrite","Add URL Rewrite" +"For category","For category" +"For product","For product" +"For CMS page","For CMS page" +"Create URL Rewrite:","Create URL Rewrite:" +"URL Rewrites","URL Rewrites" +"[New/Edit] URL Rewrite","[New/Edit] URL Rewrite" +"The URL Rewrite has been saved.","The URL Rewrite has been saved." +"An error occurred while saving URL Rewrite.","An error occurred while saving URL Rewrite." +"The URL Rewrite has been deleted.","The URL Rewrite has been deleted." +"An error occurred while deleting URL Rewrite.","An error occurred while deleting URL Rewrite." +"Select Category","Select Category" +"Options","Options" diff --git a/app/code/Magento/UrlRedirect/i18n/es_ES.csv b/app/code/Magento/UrlRedirect/i18n/es_ES.csv new file mode 100644 index 0000000000000000000000000000000000000000..8b6c4909ac30884e66b24d11978dce0e6ec7c71a --- /dev/null +++ b/app/code/Magento/UrlRedirect/i18n/es_ES.csv @@ -0,0 +1,57 @@ +Custom,Custom +Back,Back +ID,ID +SKU,SKU +No,No +Action,Action +Reset,Reset +Edit,Edit +"Two and more slashes together are not permitted in request path","Two and more slashes together are not permitted in request path" +"Anchor symbol (#) is not supported in request path","Anchor symbol (#) is not supported in request path" +"Request Path for Specified Store","Request Path for Specified Store" +"Temporary (302)","Temporary (302)" +"Permanent (301)","Permanent (301)" +"Edit URL Rewrite for a Category","Edit URL Rewrite for a Category" +"Add URL Rewrite for a Category","Add URL Rewrite for a Category" +"Category:","Category:" +"We can't set up a URL rewrite because the product you chose is not associated with a website.","We can't set up a URL rewrite because the product you chose is not associated with a website." +"We can't set up a URL rewrite because the category your chose is not associated with a website.","We can't set up a URL rewrite because the category your chose is not associated with a website." +"Edit URL Rewrite for a Product","Edit URL Rewrite for a Product" +"Add URL Rewrite for a Product","Add URL Rewrite for a Product" +"Product:","Product:" +"Skip Category Selection","Skip Category Selection" +"Name","Name" +"Status","Status" +"Edit URL Rewrite for CMS page","Edit URL Rewrite for CMS page" +"Add URL Rewrite for CMS page","Add URL Rewrite for CMS page" +"CMS page:","CMS page:" +"Chosen cms page does not associated with any website.","Chosen cms page does not associated with any website." +"Title","Title" +"URL Key","URL Key" +"Store View","Store View" +"Edit URL Rewrite","Edit URL Rewrite" +"Add New URL Rewrite","Add New URL Rewrite" +"Delete","Delete" +"Are you sure you want to do this?","Are you sure you want to do this?" +"Save","Save" +"Block Information","Block Information" +"URL Rewrite Information","URL Rewrite Information" +"Request Path","Request Path" +"Target Path","Target Path" +"Redirect","Redirect" +"Description","Description" +"Store","Store" +"URL Rewrite Management","URL Rewrite Management" +"Add URL Rewrite","Add URL Rewrite" +"For category","For category" +"For product","For product" +"For CMS page","For CMS page" +"Create URL Rewrite:","Create URL Rewrite:" +"URL Rewrites","URL Rewrites" +"[New/Edit] URL Rewrite","[New/Edit] URL Rewrite" +"The URL Rewrite has been saved.","The URL Rewrite has been saved." +"An error occurred while saving URL Rewrite.","An error occurred while saving URL Rewrite." +"The URL Rewrite has been deleted.","The URL Rewrite has been deleted." +"An error occurred while deleting URL Rewrite.","An error occurred while deleting URL Rewrite." +"Select Category","Select Category" +"Options","Options" diff --git a/app/code/Magento/UrlRedirect/i18n/fr_FR.csv b/app/code/Magento/UrlRedirect/i18n/fr_FR.csv new file mode 100644 index 0000000000000000000000000000000000000000..8b6c4909ac30884e66b24d11978dce0e6ec7c71a --- /dev/null +++ b/app/code/Magento/UrlRedirect/i18n/fr_FR.csv @@ -0,0 +1,57 @@ +Custom,Custom +Back,Back +ID,ID +SKU,SKU +No,No +Action,Action +Reset,Reset +Edit,Edit +"Two and more slashes together are not permitted in request path","Two and more slashes together are not permitted in request path" +"Anchor symbol (#) is not supported in request path","Anchor symbol (#) is not supported in request path" +"Request Path for Specified Store","Request Path for Specified Store" +"Temporary (302)","Temporary (302)" +"Permanent (301)","Permanent (301)" +"Edit URL Rewrite for a Category","Edit URL Rewrite for a Category" +"Add URL Rewrite for a Category","Add URL Rewrite for a Category" +"Category:","Category:" +"We can't set up a URL rewrite because the product you chose is not associated with a website.","We can't set up a URL rewrite because the product you chose is not associated with a website." +"We can't set up a URL rewrite because the category your chose is not associated with a website.","We can't set up a URL rewrite because the category your chose is not associated with a website." +"Edit URL Rewrite for a Product","Edit URL Rewrite for a Product" +"Add URL Rewrite for a Product","Add URL Rewrite for a Product" +"Product:","Product:" +"Skip Category Selection","Skip Category Selection" +"Name","Name" +"Status","Status" +"Edit URL Rewrite for CMS page","Edit URL Rewrite for CMS page" +"Add URL Rewrite for CMS page","Add URL Rewrite for CMS page" +"CMS page:","CMS page:" +"Chosen cms page does not associated with any website.","Chosen cms page does not associated with any website." +"Title","Title" +"URL Key","URL Key" +"Store View","Store View" +"Edit URL Rewrite","Edit URL Rewrite" +"Add New URL Rewrite","Add New URL Rewrite" +"Delete","Delete" +"Are you sure you want to do this?","Are you sure you want to do this?" +"Save","Save" +"Block Information","Block Information" +"URL Rewrite Information","URL Rewrite Information" +"Request Path","Request Path" +"Target Path","Target Path" +"Redirect","Redirect" +"Description","Description" +"Store","Store" +"URL Rewrite Management","URL Rewrite Management" +"Add URL Rewrite","Add URL Rewrite" +"For category","For category" +"For product","For product" +"For CMS page","For CMS page" +"Create URL Rewrite:","Create URL Rewrite:" +"URL Rewrites","URL Rewrites" +"[New/Edit] URL Rewrite","[New/Edit] URL Rewrite" +"The URL Rewrite has been saved.","The URL Rewrite has been saved." +"An error occurred while saving URL Rewrite.","An error occurred while saving URL Rewrite." +"The URL Rewrite has been deleted.","The URL Rewrite has been deleted." +"An error occurred while deleting URL Rewrite.","An error occurred while deleting URL Rewrite." +"Select Category","Select Category" +"Options","Options" diff --git a/app/code/Magento/UrlRedirect/i18n/nl_NL.csv b/app/code/Magento/UrlRedirect/i18n/nl_NL.csv new file mode 100644 index 0000000000000000000000000000000000000000..8b6c4909ac30884e66b24d11978dce0e6ec7c71a --- /dev/null +++ b/app/code/Magento/UrlRedirect/i18n/nl_NL.csv @@ -0,0 +1,57 @@ +Custom,Custom +Back,Back +ID,ID +SKU,SKU +No,No +Action,Action +Reset,Reset +Edit,Edit +"Two and more slashes together are not permitted in request path","Two and more slashes together are not permitted in request path" +"Anchor symbol (#) is not supported in request path","Anchor symbol (#) is not supported in request path" +"Request Path for Specified Store","Request Path for Specified Store" +"Temporary (302)","Temporary (302)" +"Permanent (301)","Permanent (301)" +"Edit URL Rewrite for a Category","Edit URL Rewrite for a Category" +"Add URL Rewrite for a Category","Add URL Rewrite for a Category" +"Category:","Category:" +"We can't set up a URL rewrite because the product you chose is not associated with a website.","We can't set up a URL rewrite because the product you chose is not associated with a website." +"We can't set up a URL rewrite because the category your chose is not associated with a website.","We can't set up a URL rewrite because the category your chose is not associated with a website." +"Edit URL Rewrite for a Product","Edit URL Rewrite for a Product" +"Add URL Rewrite for a Product","Add URL Rewrite for a Product" +"Product:","Product:" +"Skip Category Selection","Skip Category Selection" +"Name","Name" +"Status","Status" +"Edit URL Rewrite for CMS page","Edit URL Rewrite for CMS page" +"Add URL Rewrite for CMS page","Add URL Rewrite for CMS page" +"CMS page:","CMS page:" +"Chosen cms page does not associated with any website.","Chosen cms page does not associated with any website." +"Title","Title" +"URL Key","URL Key" +"Store View","Store View" +"Edit URL Rewrite","Edit URL Rewrite" +"Add New URL Rewrite","Add New URL Rewrite" +"Delete","Delete" +"Are you sure you want to do this?","Are you sure you want to do this?" +"Save","Save" +"Block Information","Block Information" +"URL Rewrite Information","URL Rewrite Information" +"Request Path","Request Path" +"Target Path","Target Path" +"Redirect","Redirect" +"Description","Description" +"Store","Store" +"URL Rewrite Management","URL Rewrite Management" +"Add URL Rewrite","Add URL Rewrite" +"For category","For category" +"For product","For product" +"For CMS page","For CMS page" +"Create URL Rewrite:","Create URL Rewrite:" +"URL Rewrites","URL Rewrites" +"[New/Edit] URL Rewrite","[New/Edit] URL Rewrite" +"The URL Rewrite has been saved.","The URL Rewrite has been saved." +"An error occurred while saving URL Rewrite.","An error occurred while saving URL Rewrite." +"The URL Rewrite has been deleted.","The URL Rewrite has been deleted." +"An error occurred while deleting URL Rewrite.","An error occurred while deleting URL Rewrite." +"Select Category","Select Category" +"Options","Options" diff --git a/app/code/Magento/UrlRedirect/i18n/pt_BR.csv b/app/code/Magento/UrlRedirect/i18n/pt_BR.csv new file mode 100644 index 0000000000000000000000000000000000000000..8b6c4909ac30884e66b24d11978dce0e6ec7c71a --- /dev/null +++ b/app/code/Magento/UrlRedirect/i18n/pt_BR.csv @@ -0,0 +1,57 @@ +Custom,Custom +Back,Back +ID,ID +SKU,SKU +No,No +Action,Action +Reset,Reset +Edit,Edit +"Two and more slashes together are not permitted in request path","Two and more slashes together are not permitted in request path" +"Anchor symbol (#) is not supported in request path","Anchor symbol (#) is not supported in request path" +"Request Path for Specified Store","Request Path for Specified Store" +"Temporary (302)","Temporary (302)" +"Permanent (301)","Permanent (301)" +"Edit URL Rewrite for a Category","Edit URL Rewrite for a Category" +"Add URL Rewrite for a Category","Add URL Rewrite for a Category" +"Category:","Category:" +"We can't set up a URL rewrite because the product you chose is not associated with a website.","We can't set up a URL rewrite because the product you chose is not associated with a website." +"We can't set up a URL rewrite because the category your chose is not associated with a website.","We can't set up a URL rewrite because the category your chose is not associated with a website." +"Edit URL Rewrite for a Product","Edit URL Rewrite for a Product" +"Add URL Rewrite for a Product","Add URL Rewrite for a Product" +"Product:","Product:" +"Skip Category Selection","Skip Category Selection" +"Name","Name" +"Status","Status" +"Edit URL Rewrite for CMS page","Edit URL Rewrite for CMS page" +"Add URL Rewrite for CMS page","Add URL Rewrite for CMS page" +"CMS page:","CMS page:" +"Chosen cms page does not associated with any website.","Chosen cms page does not associated with any website." +"Title","Title" +"URL Key","URL Key" +"Store View","Store View" +"Edit URL Rewrite","Edit URL Rewrite" +"Add New URL Rewrite","Add New URL Rewrite" +"Delete","Delete" +"Are you sure you want to do this?","Are you sure you want to do this?" +"Save","Save" +"Block Information","Block Information" +"URL Rewrite Information","URL Rewrite Information" +"Request Path","Request Path" +"Target Path","Target Path" +"Redirect","Redirect" +"Description","Description" +"Store","Store" +"URL Rewrite Management","URL Rewrite Management" +"Add URL Rewrite","Add URL Rewrite" +"For category","For category" +"For product","For product" +"For CMS page","For CMS page" +"Create URL Rewrite:","Create URL Rewrite:" +"URL Rewrites","URL Rewrites" +"[New/Edit] URL Rewrite","[New/Edit] URL Rewrite" +"The URL Rewrite has been saved.","The URL Rewrite has been saved." +"An error occurred while saving URL Rewrite.","An error occurred while saving URL Rewrite." +"The URL Rewrite has been deleted.","The URL Rewrite has been deleted." +"An error occurred while deleting URL Rewrite.","An error occurred while deleting URL Rewrite." +"Select Category","Select Category" +"Options","Options" diff --git a/app/code/Magento/UrlRedirect/i18n/zh_CN.csv b/app/code/Magento/UrlRedirect/i18n/zh_CN.csv new file mode 100644 index 0000000000000000000000000000000000000000..8b6c4909ac30884e66b24d11978dce0e6ec7c71a --- /dev/null +++ b/app/code/Magento/UrlRedirect/i18n/zh_CN.csv @@ -0,0 +1,57 @@ +Custom,Custom +Back,Back +ID,ID +SKU,SKU +No,No +Action,Action +Reset,Reset +Edit,Edit +"Two and more slashes together are not permitted in request path","Two and more slashes together are not permitted in request path" +"Anchor symbol (#) is not supported in request path","Anchor symbol (#) is not supported in request path" +"Request Path for Specified Store","Request Path for Specified Store" +"Temporary (302)","Temporary (302)" +"Permanent (301)","Permanent (301)" +"Edit URL Rewrite for a Category","Edit URL Rewrite for a Category" +"Add URL Rewrite for a Category","Add URL Rewrite for a Category" +"Category:","Category:" +"We can't set up a URL rewrite because the product you chose is not associated with a website.","We can't set up a URL rewrite because the product you chose is not associated with a website." +"We can't set up a URL rewrite because the category your chose is not associated with a website.","We can't set up a URL rewrite because the category your chose is not associated with a website." +"Edit URL Rewrite for a Product","Edit URL Rewrite for a Product" +"Add URL Rewrite for a Product","Add URL Rewrite for a Product" +"Product:","Product:" +"Skip Category Selection","Skip Category Selection" +"Name","Name" +"Status","Status" +"Edit URL Rewrite for CMS page","Edit URL Rewrite for CMS page" +"Add URL Rewrite for CMS page","Add URL Rewrite for CMS page" +"CMS page:","CMS page:" +"Chosen cms page does not associated with any website.","Chosen cms page does not associated with any website." +"Title","Title" +"URL Key","URL Key" +"Store View","Store View" +"Edit URL Rewrite","Edit URL Rewrite" +"Add New URL Rewrite","Add New URL Rewrite" +"Delete","Delete" +"Are you sure you want to do this?","Are you sure you want to do this?" +"Save","Save" +"Block Information","Block Information" +"URL Rewrite Information","URL Rewrite Information" +"Request Path","Request Path" +"Target Path","Target Path" +"Redirect","Redirect" +"Description","Description" +"Store","Store" +"URL Rewrite Management","URL Rewrite Management" +"Add URL Rewrite","Add URL Rewrite" +"For category","For category" +"For product","For product" +"For CMS page","For CMS page" +"Create URL Rewrite:","Create URL Rewrite:" +"URL Rewrites","URL Rewrites" +"[New/Edit] URL Rewrite","[New/Edit] URL Rewrite" +"The URL Rewrite has been saved.","The URL Rewrite has been saved." +"An error occurred while saving URL Rewrite.","An error occurred while saving URL Rewrite." +"The URL Rewrite has been deleted.","The URL Rewrite has been deleted." +"An error occurred while deleting URL Rewrite.","An error occurred while deleting URL Rewrite." +"Select Category","Select Category" +"Options","Options" diff --git a/app/code/Magento/UrlRedirect/sql/urlredirect_setup/install-1.0.0.0.php b/app/code/Magento/UrlRedirect/sql/urlredirect_setup/install-1.0.0.0.php new file mode 100644 index 0000000000000000000000000000000000000000..26f675220af82dc7c905b77ed65d004988eb71c9 --- /dev/null +++ b/app/code/Magento/UrlRedirect/sql/urlredirect_setup/install-1.0.0.0.php @@ -0,0 +1,109 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +/* @var $installer \Magento\Core\Model\Resource\Setup */ +$installer = $this; + +$installer->startSetup(); + +/** + * Create table 'url_rewrite' + */ +$table = $installer->getConnection()->newTable( + $installer->getTable('url_rewrite') +)->addColumn( + 'url_rewrite_id', + \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER, + null, + array('identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true), + 'Redirect Id' +)->addColumn( + 'entity_id', + \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER, + null, + array('unsigned' => true, 'nullable' => false), + 'Entity ID' +)->addColumn( + 'entity_type', + \Magento\Framework\DB\Ddl\Table::TYPE_TEXT, + 32, + array('nullable' => false), + 'Entity type code' +)->addColumn( + 'request_path', + \Magento\Framework\DB\Ddl\Table::TYPE_TEXT, + 255, + array(), + 'Request Path' +)->addColumn( + 'target_path', + \Magento\Framework\DB\Ddl\Table::TYPE_TEXT, + 255, + array(), + 'Target Path' +)->addColumn( + 'redirect_type', + \Magento\Framework\DB\Ddl\Table::TYPE_TEXT, + 2, + array('nullable' => true), + 'Redirect Type' +)->addColumn( + 'store_id', + \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT, + null, + array('unsigned' => true, 'nullable' => false, 'default' => '0'), + 'Store Id' +)->addColumn( + 'description', + \Magento\Framework\DB\Ddl\Table::TYPE_TEXT, + 255, + array(), + 'Description' +)->addIndex( + $installer->getIdxName( + 'url_rewrite', + array('request_path', 'store_id'), + \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE + ), + array('request_path', 'store_id'), + array('type' => \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE) +)->addIndex( + $installer->getIdxName('url_rewrite', array('target_path', 'store_id')), + array('target_path', 'store_id') +)->addIndex( + $installer->getIdxName('url_rewrite', array('store_id')), + array('store_id') +)->addForeignKey( + $installer->getFkName('url_rewrite', 'store_id', 'store', 'store_id'), + 'store_id', + $installer->getTable('store'), + 'store_id', + \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE, + \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE +)->setComment( + 'Url Rewrites' +); +$installer->getConnection()->createTable($table); + +$installer->endSetup(); diff --git a/app/code/Magento/UrlRedirect/view/adminhtml/layout/adminhtml_urlredirect_index.xml b/app/code/Magento/UrlRedirect/view/adminhtml/layout/adminhtml_urlredirect_index.xml new file mode 100644 index 0000000000000000000000000000000000000000..6fc0be6b9568fe91470f7552423960da8c70939e --- /dev/null +++ b/app/code/Magento/UrlRedirect/view/adminhtml/layout/adminhtml_urlredirect_index.xml @@ -0,0 +1,110 @@ +<?xml version="1.0"?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_single.xsd"> + <referenceContainer name="content"> + <block class="Magento\UrlRedirect\Block\GridContainer" name="adminhtml.block.urlredirect.grid.container"> + <block class="Magento\Backend\Block\Widget\Grid" name="adminhtml.block.urlredirect.grid" as="grid"> + <arguments> + <argument name="id" xsi:type="string">urlredirectGrid</argument> + <argument name="dataSource" xsi:type="object">Magento\UrlRedirect\Model\Resource\UrlRedirect\Collection</argument> + <argument name="default_sort" xsi:type="string">url_rewrite_id</argument> + </arguments> + <block class="Magento\Backend\Block\Widget\Grid\ColumnSet" as="grid.columnSet" name="adminhtml.urlredirect.grid.columnSet"> + <arguments> + <argument name="rowUrl" xsi:type="array"> + <item name="path" xsi:type="string">adminhtml/*/edit</item> + <item name="extraParamsTemplate" xsi:type="array"> + <item name="id" xsi:type="string">getId</item> + </item> + </argument> + </arguments> + <block class="Magento\Backend\Block\Widget\Grid\Column" as="url_rewrite_id"> + <arguments> + <argument name="header" xsi:type="string" translate="true">ID</argument> + <argument name="type" xsi:type="string">text</argument> + <argument name="id" xsi:type="string">url_rewrite_id</argument> + <argument name="index" xsi:type="string">url_rewrite_id</argument> + <argument name="column_css_class" xsi:type="string">col-id</argument> + <argument name="header_css_class" xsi:type="string">col-id</argument> + </arguments> + </block> + <block class="Magento\Backend\Block\Widget\Grid\Column\Multistore" as="store_id"> + <arguments> + <argument name="header" xsi:type="string" translate="true">Store View</argument> + <argument name="type" xsi:type="string">store</argument> + <argument name="id" xsi:type="string">store_id</argument> + <argument name="index" xsi:type="string">store_id</argument> + <argument name="store_view" xsi:type="string">true</argument> + </arguments> + </block> + <block class="Magento\Backend\Block\Widget\Grid\Column" as="request_path"> + <arguments> + <argument name="header" xsi:type="string" translate="true">Request Path</argument> + <argument name="type" xsi:type="string">text</argument> + <argument name="id" xsi:type="string">request_path</argument> + <argument name="index" xsi:type="string">request_path</argument> + </arguments> + </block> + <block class="Magento\Backend\Block\Widget\Grid\Column" as="target_path"> + <arguments> + <argument name="header" xsi:type="string" translate="true">Target Path</argument> + <argument name="type" xsi:type="string">text</argument> + <argument name="id" xsi:type="string">target_path</argument> + <argument name="index" xsi:type="string">target_path</argument> + </arguments> + </block> + <block class="Magento\Backend\Block\Widget\Grid\Column" as="options"> + <arguments> + <argument name="header" xsi:type="string" translate="true">Options</argument> + <argument name="type" xsi:type="string">text</argument> + <argument name="id" xsi:type="string">options</argument> + <argument name="index" xsi:type="string">options</argument> + </arguments> + </block> + <block class="Magento\Backend\Block\Widget\Grid\Column" as="actions"> + <arguments> + <argument name="header" xsi:type="string" translate="true">Action</argument> + <argument name="sortable" xsi:type="string">0</argument> + <argument name="filter" xsi:type="string">0</argument> + <argument name="type" xsi:type="string">action</argument> + <argument name="id" xsi:type="string">actions</argument> + <argument name="index" xsi:type="string">url_rewrite_id</argument> + <argument name="actions" xsi:type="array"> + <item name="view_action" xsi:type="array"> + <item name="caption" xsi:type="string" translate="true">Edit</item> + <item name="url" xsi:type="array"> + <item name="base" xsi:type="string">adminhtml/*/edit</item> + </item> + <item name="field" xsi:type="string">id</item> + </item> + </argument> + </arguments> + </block> + </block> + </block> + </block> + </referenceContainer> +</layout> diff --git a/app/code/Magento/UrlRedirect/view/adminhtml/templates/categories.phtml b/app/code/Magento/UrlRedirect/view/adminhtml/templates/categories.phtml new file mode 100644 index 0000000000000000000000000000000000000000..c5888579d548182941371bb14e823b3c2e35ef8d --- /dev/null +++ b/app/code/Magento/UrlRedirect/view/adminhtml/templates/categories.phtml @@ -0,0 +1,41 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +/** @var $this \Magento\UrlRedirect\Block\Catalog\Category\Tree */ +?> +<fieldset class="fieldset" data-ui-id="category-selector"> + <legend class="legend"><span><?php echo __('Select Category') ?></span></legend> + <div class="content" style="clear: both;"> + <input type="hidden" name="categories" id="product_categories" value="" /> + <?php if ($this->getRoot()): ?> + <div data-mage-init='<?php + echo $this->escapeHtml($this->helper('Magento\Core\Helper\Data')->jsonEncode(array( + 'categoryTree' => array( + 'data' => $this->getTreeArray(null), + 'url' => $this->getLoadTreeUrl(), + ) + ))); + ?>' class="jstree-default"></div> + <?php endif; ?> + </div> +</fieldset> diff --git a/app/code/Magento/UrlRedirect/view/adminhtml/templates/edit.phtml b/app/code/Magento/UrlRedirect/view/adminhtml/templates/edit.phtml new file mode 100644 index 0000000000000000000000000000000000000000..74cd2357bdc527dc6444d805acbebb99e229cc48 --- /dev/null +++ b/app/code/Magento/UrlRedirect/view/adminhtml/templates/edit.phtml @@ -0,0 +1,38 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ + +/** + * Urlrewrites edit container + * + * @var $this \Magento\UrlRedirect\Block\Edit + */ +?> +<?php echo $this->getChildHtml() ?> + +<?php if ($this->getChildBlock('form')): ?> +<script type="text/javascript"> + jQuery('#edit_form').mage('form') + .mage('validation', {validationUrl: '<?php echo $this->getValidationUrl() ?>'}); +</script> +<?php endif; ?> diff --git a/app/code/Magento/UrlRedirect/view/adminhtml/templates/selector.phtml b/app/code/Magento/UrlRedirect/view/adminhtml/templates/selector.phtml new file mode 100644 index 0000000000000000000000000000000000000000..c6db4f73ad984213ef5aee0e07b0c4be58c768e8 --- /dev/null +++ b/app/code/Magento/UrlRedirect/view/adminhtml/templates/selector.phtml @@ -0,0 +1,40 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +/** @var $this \Magento\UrlRedirect\Block\Selector */ +?> +<div class="form-inline"> + <fieldset class="fieldset" data-ui-id="entity-type-selector"> + <div class="field field-url-rewrite-option-select"> + <label for="url-rewrite-option-select" class="label"><?php echo $this->getSelectorLabel() ?></label> + <div class="control"> + <?php $url = $this->helper('Magento\Backend\Helper\Data')->getUrl('adminhtml/*/*')?> + <select id="url-rewrite-option-select" class="select" onchange="window.location = this.value;"> + <?php foreach ($this->getModes() as $mode => $label): ?> + <option <?php echo ($this->isMode($mode) ? 'selected="selected" ' :'' ) ?>value="<?php echo $url . $mode ?>"><?php echo $label ?></option> + <?php endforeach; ?> + </select> + </div> + </div> + </fieldset> +</div> diff --git a/app/code/Magento/Webapi/Model/Soap/Wsdl/Generator.php b/app/code/Magento/Webapi/Model/Soap/Wsdl/Generator.php index 1a35175e4bdfb2e6a3e85835c6e05e9c46be188d..027a5e93445a3b63e0e86c2e04f07453c8f1d400 100644 --- a/app/code/Magento/Webapi/Model/Soap/Wsdl/Generator.php +++ b/app/code/Magento/Webapi/Model/Soap/Wsdl/Generator.php @@ -61,6 +61,11 @@ class Generator */ protected $_registeredTypes = array(); + /** + * @var \Magento\Store\Model\StoreManagerInterface + */ + protected $storeManager; + /** * Initialize dependencies. * @@ -68,17 +73,20 @@ class Generator * @param Factory $wsdlFactory * @param \Magento\Webapi\Model\Cache\Type $cache * @param \Magento\Webapi\Model\Config\ClassReflector\TypeProcessor $typeProcessor + * @param \Magento\Store\Model\StoreManagerInterface $storeManager */ public function __construct( \Magento\Webapi\Model\Soap\Config $apiConfig, Factory $wsdlFactory, \Magento\Webapi\Model\Cache\Type $cache, - \Magento\Webapi\Model\Config\ClassReflector\TypeProcessor $typeProcessor + \Magento\Webapi\Model\Config\ClassReflector\TypeProcessor $typeProcessor, + \Magento\Store\Model\StoreManagerInterface $storeManager ) { $this->_apiConfig = $apiConfig; $this->_wsdlFactory = $wsdlFactory; $this->_cache = $cache; $this->_typeProcessor = $typeProcessor; + $this->storeManager = $storeManager; } /** @@ -93,7 +101,8 @@ class Generator { /** Sort requested services by names to prevent caching of the same wsdl file more than once. */ ksort($requestedServices); - $cacheId = self::WSDL_CACHE_ID . hash('md5', serialize($requestedServices)); + $currentStore = $this->storeManager->getStore(); + $cacheId = self::WSDL_CACHE_ID . hash('md5', serialize($requestedServices) . $currentStore->getCode()); $cachedWsdlContent = $this->_cache->load($cacheId); if ($cachedWsdlContent !== false) { return $cachedWsdlContent; diff --git a/app/code/Magento/Weee/Model/Config.php b/app/code/Magento/Weee/Model/Config.php index 0cc476aa9605d0125aa2f1b338f7e5d9b59d8051..e832c4940b5199f937a9fcbe4fa4cf254e3c9565 100644 --- a/app/code/Magento/Weee/Model/Config.php +++ b/app/code/Magento/Weee/Model/Config.php @@ -35,6 +35,22 @@ class Config */ const XML_PATH_FPT_ENABLED = 'tax/weee/enable'; + // display settings + const XML_PATH_FPT_DISPLAY_PRODUCT_VIEW = 'tax/weee/display'; + + const XML_PATH_FPT_DISPLAY_PRODUCT_LIST = 'tax/weee/display_list'; + + const XML_PATH_FPT_DISPLAY_SALES = 'tax/weee/display_sales'; + + const XML_PATH_FPT_DISPLAY_EMAIL = 'tax/weee/display_email'; + + // misc + const XML_PATH_FPT_INCLUDE_IN_SUBTOTAL = 'tax/weee/include_in_subtotal'; + + const XML_PATH_FPT_DISCOUNTED = 'tax/weee/discount'; + + const XML_PATH_FPT_TAXABLE = 'tax/weee/apply_vat'; + /** * Core store config * @@ -63,7 +79,7 @@ class Config public function getPriceDisplayType($store = null) { return $this->scopeConfig->getValue( - 'tax/weee/display', + self::XML_PATH_FPT_DISPLAY_PRODUCT_VIEW, \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $store ); @@ -78,7 +94,7 @@ class Config public function getListPriceDisplayType($store = null) { return $this->scopeConfig->getValue( - 'tax/weee/display_list', + self::XML_PATH_FPT_DISPLAY_PRODUCT_LIST, \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $store ); @@ -93,7 +109,7 @@ class Config public function getSalesPriceDisplayType($store = null) { return $this->scopeConfig->getValue( - 'tax/weee/display_sales', + self::XML_PATH_FPT_DISPLAY_SALES, \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $store ); @@ -108,7 +124,7 @@ class Config public function getEmailPriceDisplayType($store = null) { return $this->scopeConfig->getValue( - 'tax/weee/display_email', + self::XML_PATH_FPT_DISPLAY_EMAIL, \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $store ); @@ -139,7 +155,7 @@ class Config public function includeInSubtotal($store = null) { return $this->scopeConfig->isSetFlag( - 'tax/weee/include_in_subtotal', + self::XML_PATH_FPT_INCLUDE_IN_SUBTOTAL, \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $store ); @@ -154,7 +170,7 @@ class Config public function isDiscounted($store = null) { return $this->scopeConfig->isSetFlag( - 'tax/weee/discount', + self::XML_PATH_FPT_DISCOUNTED, \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $store ); @@ -169,7 +185,7 @@ class Config public function isTaxable($store = null) { return $this->scopeConfig->isSetFlag( - 'tax/weee/apply_vat', + self::XML_PATH_FPT_TAXABLE, \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $store ); diff --git a/app/code/Magento/Weee/Model/Total/Quote/Weee.php b/app/code/Magento/Weee/Model/Total/Quote/Weee.php index 5b9e38184a26ffc8036235b3e68aac28083d0da3..b03e4c08bb0880c47728135c02f01ca55b73ae39 100644 --- a/app/code/Magento/Weee/Model/Total/Quote/Weee.php +++ b/app/code/Magento/Weee/Model/Total/Quote/Weee.php @@ -25,43 +25,53 @@ namespace Magento\Weee\Model\Total\Quote; use Magento\Store\Model\Store; use Magento\Tax\Model\Calculation; +use Magento\Sales\Model\Quote\Address\Total\AbstractTotal; +use Magento\Tax\Model\Sales\Total\Quote\CommonTaxCollector; -class Weee extends \Magento\Tax\Model\Sales\Total\Quote\Tax +class Weee extends CommonTaxCollector { + /** + * Constant for weee item code prefix + */ + const ITEM_CODE_WEEE_PREFIX = 'weee'; + /** + * Constant for weee item type + */ + const ITEM_TYPE = 'weee'; + /** * @var \Magento\Weee\Helper\Data */ - protected $_weeeData; - + protected $weeeData; + /** * @var \Magento\Store\Model\Store */ protected $_store; /** - * @var \Magento\Tax\Model\Calculation + * Static counter + * + * @var int */ - protected $_calculator; + protected static $counter = 0; + + /** + * Array to keep track of weee taxable item code to quote item + * + * @var array + */ + protected $weeeCodeToItemMap; + /** - * @param \Magento\Tax\Helper\Data $taxData - * @param \Magento\Tax\Model\Config $taxConfig - * @param \Magento\Tax\Service\V1\TaxCalculationService $taxCalculationService - * @param \Magento\Tax\Service\V1\Data\QuoteDetailsBuilder $quoteDetailsBuilder - * @param \Magento\Tax\Model\Calculation $calculation * @param \Magento\Weee\Helper\Data $weeeData */ public function __construct( - \Magento\Tax\Helper\Data $taxData, - \Magento\Tax\Model\Config $taxConfig, - \Magento\Tax\Service\V1\TaxCalculationService $taxCalculationService, - \Magento\Tax\Service\V1\Data\QuoteDetailsBuilder $quoteDetailsBuilder, - \Magento\Tax\Model\Calculation $calculation, \Magento\Weee\Helper\Data $weeeData ) { - $this->_weeeData = $weeeData; - $this->_calculator = $calculation; - parent::__construct($taxData, $taxConfig, $taxCalculationService, $quoteDetailsBuilder); + $this->weeeData = $weeeData; $this->setCode('weee'); + $this->weeeCodeToItemMap = []; } /** @@ -72,16 +82,17 @@ class Weee extends \Magento\Tax\Model\Sales\Total\Quote\Tax */ public function collect(\Magento\Sales\Model\Quote\Address $address) { - \Magento\Sales\Model\Quote\Address\Total\AbstractTotal::collect($address); + AbstractTotal::collect($address); + $this->_store = $address->getQuote()->getStore(); + if (!$this->weeeData->isEnabled($this->_store)) { + return $this; + } + $items = $this->_getAddressItems($address); if (!count($items)) { return $this; } - $address->setAppliedTaxesReset(true); - $address->setAppliedTaxes(array()); - - $this->_store = $address->getQuote()->getStore(); foreach ($items as $item) { if ($item->getParentItemId()) { continue; @@ -98,6 +109,7 @@ class Weee extends \Magento\Tax\Model\Sales\Total\Quote\Tax } } + $address->setWeeeCodeToItemMap($this->weeeCodeToItemMap); return $this; } @@ -110,28 +122,15 @@ class Weee extends \Magento\Tax\Model\Sales\Total\Quote\Tax */ protected function _process(\Magento\Sales\Model\Quote\Address $address, $item) { - if (!$this->_weeeData->isEnabled($this->_store)) { - return $this; - } - - $attributes = $this->_weeeData->getProductWeeeAttributes( + $attributes = $this->weeeData->getProductWeeeAttributes( $item->getProduct(), $address, $address->getQuote()->getBillingAddress(), $this->_store->getWebsiteId() ); - $applied = array(); $productTaxes = array(); - $defaultRateRequest = $this->_calculator->getRateOriginRequest($this->_store); - $rateRequest = $this->_calculator->getRateRequest( - $address, - $address->getQuote()->getBillingAddress(), - $address->getQuote()->getCustomerTaxClassId(), - $this->_store - ); - $totalValueInclTax = 0; $baseTotalValueInclTax = 0; $totalRowValueInclTax = 0; @@ -142,60 +141,19 @@ class Weee extends \Magento\Tax\Model\Sales\Total\Quote\Tax $totalRowValueExclTax = 0; $baseTotalRowValueExclTax = 0; - $priceIncludesTax = $this->_taxData->priceIncludesTax($this->_store); - $calculationAlgorithm = $this->_taxData->getCalculationAgorithm($this->_store); - $defaultPercent = $currentPercent = 0; //when FPT is not taxable + $associatedTaxables = $item->getAssociatedTaxables(); + if (!$associatedTaxables) { + $associatedTaxables = []; + } foreach ($attributes as $key => $attribute) { $title = $attribute->getName(); - $baseValue = $attribute->getAmount(); - $value = $this->_store->convertPrice($baseValue); - $value = $this->_store->roundPrice($value); - - if ($this->_weeeData->isTaxable($this->_store)) { - $defaultPercent = $this->_calculator->getRate( - $defaultRateRequest->setProductClassId($item->getProduct()->getTaxClassId()) - ); - $currentPercent = $this->_calculator->getRate( - $rateRequest->setProductClassId($item->getProduct()->getTaxClassId()) - ); - } - - if ($priceIncludesTax) { - //Make sure that price including tax is rounded first - $baseValueInclTax = $baseValue / (100 + $defaultPercent) * (100 + $currentPercent); - $baseValueInclTax = $this->_store->roundPrice($baseValueInclTax); - $valueInclTax = $value / (100 + $defaultPercent) * (100 + $currentPercent); - $valueInclTax = $this->_store->roundPrice($valueInclTax); - - $baseValueExclTax = $baseValueInclTax / (100 + $currentPercent) * 100; - $valueExclTax = $valueInclTax / (100 + $currentPercent) * 100; - if ($calculationAlgorithm == Calculation::CALC_UNIT_BASE) { - $baseValueExclTax = $this->_store->roundPrice($baseValueExclTax); - $valueExclTax = $this->_store->roundPrice($valueExclTax); - } - } else { - $valueExclTax = $value; - $baseValueExclTax = $baseValue; - - $valueInclTax = $valueExclTax * (100 + $currentPercent) / 100; - $baseValueInclTax = $baseValueExclTax * (100 + $currentPercent) / 100; - if ($calculationAlgorithm == Calculation::CALC_UNIT_BASE) { - $baseValueInclTax = $this->_store->roundPrice($baseValueInclTax); - $valueInclTax = $this->_store->roundPrice($valueInclTax); - } - } - - $rowValueInclTax = $this->_store->roundPrice($valueInclTax * $item->getTotalQty()); - $baseRowValueInclTax = $this->_store->roundPrice($baseValueInclTax * $item->getTotalQty()); - $rowValueExclTax = $this->_store->roundPrice($valueExclTax * $item->getTotalQty()); - $baseRowValueExclTax = $this->_store->roundPrice($baseValueExclTax * $item->getTotalQty()); + $baseValueExclTax = $baseValueInclTax = $attribute->getAmount(); + $valueExclTax = $valueInclTax = $this->_store->roundPrice($this->_store->convertPrice($baseValueExclTax)); - //Now, round the unit price just in case - $valueExclTax = $this->_store->roundPrice($valueExclTax); - $baseValueExclTax = $this->_store->roundPrice($baseValueExclTax); - $valueInclTax = $this->_store->roundPrice($valueInclTax); - $baseValueInclTax = $this->_store->roundPrice($baseValueInclTax); + $rowValueInclTax = $rowValueExclTax = $this->_store->roundPrice($valueInclTax * $item->getTotalQty()); + $baseRowValueInclTax = $this->_store->roundPrice($baseValueInclTax * $item->getTotalQty()); + $baseRowValueExclTax = $baseRowValueInclTax; $totalValueInclTax += $valueInclTax; $baseTotalValueInclTax += $baseValueInclTax; @@ -220,23 +178,22 @@ class Weee extends \Magento\Tax\Model\Sales\Total\Quote\Tax 'base_row_amount_incl_tax' => $baseRowValueInclTax, ); - //This include FPT as applied tax, since tax on FPT is calculated separately, we use value excluding tax - $applied[] = array( - 'id' => $attribute->getCode(), - 'percent' => null, - 'hidden' => $this->_weeeData->includeInSubtotal($this->_store), - 'rates' => array(array( - 'base_real_amount'=> $baseRowValueExclTax, - 'base_amount' => $baseRowValueExclTax, - 'amount' => $rowValueExclTax, - 'code' => $attribute->getCode(), - 'title' => $title, - 'percent' => null, - 'position' => 1, - 'priority' => -1000 + $key, - )) - ); + if ($this->weeeData->isTaxable($this->_store)) { + $itemTaxCalculationId = $item->getTaxCalculationItemId(); + $weeeItemCode = self::ITEM_CODE_WEEE_PREFIX . $this->getNextIncrement(); + $weeeItemCode .= '-' . $title; + $associatedTaxables[] = [ + self::KEY_ASSOCIATED_TAXABLE_TYPE => self::ITEM_TYPE, + self::KEY_ASSOCIATED_TAXABLE_CODE => $weeeItemCode, + self::KEY_ASSOCIATED_TAXABLE_UNIT_PRICE => $valueExclTax, + self::KEY_ASSOCIATED_TAXABLE_BASE_UNIT_PRICE => $baseValueExclTax, + self::KEY_ASSOCIATED_TAXABLE_QUANTITY => $item->getQty(), + self::KEY_ASSOCIATED_TAXABLE_TAX_CLASS_ID => $item->getProduct()->getTaxClassId(), + ]; + $this->weeeCodeToItemMap[$weeeItemCode] = $item; + } } + $item->setAssociatedTaxables($associatedTaxables); $item->setWeeeTaxAppliedAmount($totalValueExclTax) ->setBaseWeeeTaxAppliedAmount($baseTotalValueExclTax) @@ -248,24 +205,7 @@ class Weee extends \Magento\Tax\Model\Sales\Total\Quote\Tax ->setWeeeTaxAppliedRowAmountInclTax($totalRowValueInclTax) ->setBaseWeeeTaxAppliedRowAmntInclTax($baseTotalRowValueInclTax); - if ($priceIncludesTax) { - $this->_processTaxSettings( - $item, - $totalValueInclTax, - $baseTotalValueInclTax, - $totalRowValueInclTax, - $baseTotalRowValueInclTax - ); - } else { - $this->_processTaxSettings( - $item, - $totalValueExclTax, - $baseTotalValueExclTax, - $totalRowValueExclTax, - $baseTotalRowValueExclTax - ); - } - $this->_processTotalAmount( + $this->processTotalAmount( $address, $totalRowValueExclTax, $baseTotalRowValueExclTax, @@ -273,56 +213,7 @@ class Weee extends \Magento\Tax\Model\Sales\Total\Quote\Tax $baseTotalRowValueInclTax ); - $this->_weeeData->setApplied($item, array_merge($this->_weeeData->getApplied($item), $productTaxes)); - - //Update the applied taxes for the quote - if ($applied) { - $this->_saveAppliedTaxes( - $address, - $applied, - $item->getWeeeTaxAppliedAmount(), - $item->getBaseWeeeTaxAppliedAmount(), - null - ); - } - } - - /** - * Check if discount should be applied to weee and add weee to discounted price - * - * @deprecated - * @param \Magento\Sales\Model\Quote\Item\AbstractItem $item - * @param float $value - * @param float $baseValue - * @return $this - */ - protected function _processDiscountSettings($item, $value, $baseValue) - { - if ($this->_weeeData->isDiscounted($this->_store)) { - $this->_weeeData->addItemDiscountPrices($item, $baseValue, $value); - } - return $this; - } - - /** - * Add extra amount which should be taxable by regular tax - * - * @param \Magento\Sales\Model\Quote\Item\AbstractItem $item - * @param float $value - * @param float $baseValue - * @param float $rowValue - * @param float $baseRowValue - * @return $this - */ - protected function _processTaxSettings($item, $value, $baseValue, $rowValue, $baseRowValue) - { - if ($this->_weeeData->isTaxable($this->_store) && $rowValue) { - $item->setExtraTaxableAmount($value) - ->setBaseExtraTaxableAmount($baseValue) - ->setExtraRowTaxableAmount($rowValue) - ->setBaseExtraRowTaxableAmount($baseRowValue); - } - return $this; + $this->weeeData->setApplied($item, array_merge($this->weeeData->getApplied($item), $productTaxes)); } /** @@ -335,24 +226,38 @@ class Weee extends \Magento\Tax\Model\Sales\Total\Quote\Tax * @param float $baseRowValueInclTax * @return $this */ - protected function _processTotalAmount($address, $rowValueExclTax, $baseRowValueExclTax, $rowValueInclTax, $baseRowValueInclTax) + protected function processTotalAmount($address, $rowValueExclTax, $baseRowValueExclTax, $rowValueInclTax, $baseRowValueInclTax) { - //TODO: use tax service to calculate tax - if ($this->_weeeData->includeInSubtotal($this->_store)) { - $address->setExtraSubtotalAmount($this->_store->roundPrice($rowValueExclTax)); - $address->setBaseExtraSubtotalAmount($this->_store->roundPrice($baseRowValueExclTax)); - } else { - $address->addTotalAmount('weee', $rowValueExclTax); - $address->addBaseTotalAmount('weee', $baseRowValueExclTax); + if (!$this->weeeData->isTaxable($this->_store)) { + //otherwise, defer to weee_tax collector to update subtotal and tax + if ($this->weeeData->includeInSubtotal($this->_store)) { + $address->addTotalAmount('subtotal', $this->_store->roundPrice($rowValueExclTax)); + $address->addBaseTotalAmount('subtotal', $this->_store->roundPrice($baseRowValueExclTax)); + } else { + $address->addTotalAmount('weee', $rowValueExclTax); + $address->addBaseTotalAmount('weee', $baseRowValueExclTax); + } } - $address->setExtraTaxAmount($rowValueInclTax - $rowValueExclTax); - $address->setBaseExtraTaxAmount($baseRowValueInclTax - $baseRowValueExclTax); - + + //This value is used to calculate shipping cost, it will be overridden by tax collector $address->setSubtotalInclTax($address->getSubtotalInclTax() + $this->_store->roundPrice($rowValueInclTax)); - $address->setBaseSubtotalInclTax($address->getBaseSubtotalInclTax() + $this->_store->roundPrice($baseRowValueInclTax)); + $address->setBaseSubtotalInclTax( + $address->getBaseSubtotalInclTax() + $this->_store->roundPrice($baseRowValueInclTax) + ); return $this; } + /** + * Increment and return static counter. This function is intended to be used to generate temporary + * id for an item. + * + * @return int + */ + protected function getNextIncrement() + { + return ++self::$counter; + } + /** * Recalculate parent item amounts based on children results * @@ -373,7 +278,7 @@ class Weee extends \Magento\Tax\Model\Sales\Total\Quote\Tax */ protected function _resetItemData($item) { - $this->_weeeData->setApplied($item, array()); + $this->weeeData->setApplied($item, array()); $item->setBaseWeeeTaxDisposition(0); $item->setWeeeTaxDisposition(0); @@ -389,28 +294,13 @@ class Weee extends \Magento\Tax\Model\Sales\Total\Quote\Tax } /** - * Fetch the Weee total amount for display in totals block when building the initial quote + * Delegate this to WeeeTax collector * * @param \Magento\Sales\Model\Quote\Address $address * @return $this */ public function fetch(\Magento\Sales\Model\Quote\Address $address) { - /** @var $items \Magento\Sales\Model\Order\Item[] */ - $items = $this->_getAddressItems($address); - $store = $address->getQuote()->getStore(); - - $weeeTotal = $this->_weeeData->getTotalAmounts($items, $store); - if ($weeeTotal) { - $address->addTotal( - array( - 'code' => $this->getCode(), - 'title' => __('FPT'), - 'value' => $weeeTotal, - 'area' => null - ) - ); - } return $this; } diff --git a/app/code/Magento/Weee/Model/Total/Quote/WeeeTax.php b/app/code/Magento/Weee/Model/Total/Quote/WeeeTax.php new file mode 100644 index 0000000000000000000000000000000000000000..e947c88e53957a123498415df80d74fa512f997e --- /dev/null +++ b/app/code/Magento/Weee/Model/Total/Quote/WeeeTax.php @@ -0,0 +1,192 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Weee\Model\Total\Quote; + +use Magento\Store\Model\Store; +use Magento\Tax\Model\Calculation; +use Magento\Sales\Model\Quote\Address\Total\AbstractTotal; +use Magento\Tax\Model\Sales\Total\Quote\CommonTaxCollector; + +class WeeeTax extends Weee +{ + /** + * Collect Weee taxes amount and prepare items prices for taxation and discount + * + * @param \Magento\Sales\Model\Quote\Address $address + * @return $this + */ + public function collect(\Magento\Sales\Model\Quote\Address $address) + { + \Magento\Sales\Model\Quote\Address\Total\AbstractTotal::collect($address); + $this->store = $address->getQuote()->getStore(); + if (!$this->weeeData->isEnabled($this->_store) || !$this->weeeData->isTaxable($this->_store)) { + return $this; + } + + $items = $this->_getAddressItems($address); + if (!count($items)) { + return $this; + } + + $weeeCodeToItemMap = $address->getWeeeCodeToItemMap(); + $extraTaxableDetails = $address->getExtraTaxableDetails(); + + if (isset($extraTaxableDetails[self::ITEM_TYPE])) { + foreach ($extraTaxableDetails[self::ITEM_TYPE] as $itemCode => $weeeAttributesTaxDetails) { + $weeeCode = $weeeAttributesTaxDetails[0]['code']; + $item = $weeeCodeToItemMap[$weeeCode]; + $this->weeeData->setApplied($item, []); + + $productTaxes = []; + + $totalValueInclTax = 0; + $baseTotalValueInclTax = 0; + $totalRowValueInclTax = 0; + $baseTotalRowValueInclTax = 0; + + $totalValueExclTax = 0; + $baseTotalValueExclTax = 0; + $totalRowValueExclTax = 0; + $baseTotalRowValueExclTax = 0; + + //Process each weee attribute of an item + foreach ($weeeAttributesTaxDetails as $weeeTaxDetails) { + $weeeCode = $weeeTaxDetails[self::KEY_TAX_DETAILS_CODE]; + $attributeCode = explode('-', $weeeCode)[1]; + + $valueExclTax = $weeeTaxDetails[self::KEY_TAX_DETAILS_PRICE_EXCL_TAX]; + $baseValueExclTax = $weeeTaxDetails[self::KEY_TAX_DETAILS_BASE_PRICE_EXCL_TAX]; + $valueInclTax = $weeeTaxDetails[self::KEY_TAX_DETAILS_PRICE_INCL_TAX]; + $baseValueInclTax = $weeeTaxDetails[self::KEY_TAX_DETAILS_BASE_PRICE_INCL_TAX]; + + $rowValueExclTax = $weeeTaxDetails[self::KEY_TAX_DETAILS_ROW_TOTAL]; + $baseRowValueExclTax = $weeeTaxDetails[self::KEY_TAX_DETAILS_BASE_ROW_TOTAL]; + $rowValueInclTax = $weeeTaxDetails[self::KEY_TAX_DETAILS_ROW_TOTAL_INCL_TAX]; + $baseRowValueInclTax = $weeeTaxDetails[self::KEY_TAX_DETAILS_BASE_ROW_TOTAL_INCL_TAX]; + + $totalValueInclTax += $valueInclTax; + $baseTotalValueInclTax += $baseValueInclTax; + $totalRowValueInclTax += $rowValueInclTax; + $baseTotalRowValueInclTax += $baseRowValueInclTax; + + + $totalValueExclTax += $valueExclTax; + $baseTotalValueExclTax += $baseValueExclTax; + $totalRowValueExclTax += $rowValueExclTax; + $baseTotalRowValueExclTax += $baseRowValueExclTax; + + $productTaxes[] = array( + 'title' => $attributeCode, //TODO: fix this + 'base_amount' => $baseValueExclTax, + 'amount' => $valueExclTax, + 'row_amount' => $rowValueExclTax, + 'base_row_amount' => $baseRowValueExclTax, + 'base_amount_incl_tax' => $baseValueInclTax, + 'amount_incl_tax' => $valueInclTax, + 'row_amount_incl_tax' => $rowValueInclTax, + 'base_row_amount_incl_tax' => $baseRowValueInclTax, + ); + + } + $item->setWeeeTaxAppliedAmount($totalValueExclTax) + ->setBaseWeeeTaxAppliedAmount($baseTotalValueExclTax) + ->setWeeeTaxAppliedRowAmount($totalRowValueExclTax) + ->setBaseWeeeTaxAppliedRowAmnt($baseTotalRowValueExclTax); + + $item->setWeeeTaxAppliedAmountInclTax($totalValueInclTax) + ->setBaseWeeeTaxAppliedAmountInclTax($baseTotalValueInclTax) + ->setWeeeTaxAppliedRowAmountInclTax($totalRowValueInclTax) + ->setBaseWeeeTaxAppliedRowAmntInclTax($baseTotalRowValueInclTax); + + $this->processTotalAmount( + $address, + $totalRowValueExclTax, + $baseTotalRowValueExclTax, + $totalRowValueInclTax, + $baseTotalRowValueInclTax + ); + + $this->weeeData->setApplied($item, array_merge($this->weeeData->getApplied($item), $productTaxes)); + } + } + + return $this; + } + + /** + * Process row amount based on FPT total amount configuration setting + * + * @param \Magento\Sales\Model\Quote\Address $address + * @param float $rowValueExclTax + * @param float $baseRowValueExclTax + * @param float $rowValueInclTax + * @param float $baseRowValueInclTax + * @return $this + */ + protected function processTotalAmount( + $address, + $rowValueExclTax, + $baseRowValueExclTax, + $rowValueInclTax, + $baseRowValueInclTax + ) { + if ($this->weeeData->includeInSubtotal($this->_store)) { + $address->addTotalAmount('subtotal', $rowValueExclTax); + $address->addBaseTotalAmount('subtotal', $baseRowValueExclTax); + } else { + $address->addTotalAmount('weee', $rowValueExclTax); + $address->addBaseTotalAmount('weee', $baseRowValueExclTax); + } + + $address->setSubtotalInclTax($address->getSubtotalInclTax() + $rowValueInclTax); + $address->setBaseSubtotalInclTax($address->getBaseSubtotalInclTax() + $baseRowValueInclTax); + return $this; + } + + /** + * Fetch the Weee total amount for display in totals block when building the initial quote + * + * @param \Magento\Sales\Model\Quote\Address $address + * @return $this + */ + public function fetch(\Magento\Sales\Model\Quote\Address $address) + { + /** @var $items \Magento\Sales\Model\Order\Item[] */ + $items = $this->_getAddressItems($address); + $store = $address->getQuote()->getStore(); + + $weeeTotal = $this->weeeData->getTotalAmounts($items, $store); + if ($weeeTotal) { + $address->addTotal( + array( + 'code' => $this->getCode(), + 'title' => __('FPT'), + 'value' => $weeeTotal, + 'area' => null + ) + ); + } + return $this; + } +} diff --git a/app/code/Magento/Weee/etc/sales.xml b/app/code/Magento/Weee/etc/sales.xml index fd8aa161ea110737fe406b0436cff1e023d410ca..9899527fa3c63797dde550b709f70c43e2405bbc 100644 --- a/app/code/Magento/Weee/etc/sales.xml +++ b/app/code/Magento/Weee/etc/sales.xml @@ -27,6 +27,7 @@ <section name="quote"> <group name="totals"> <item name="weee" instance="Magento\Weee\Model\Total\Quote\Weee" sort_order="225"/> + <item name="weee_tax" instance="Magento\Weee\Model\Total\Quote\WeeeTax" sort_order="460"/> </group> <group name="nominal_totals"> <item name="nominal_weee" instance="Magento\Weee\Model\Total\Quote\Nominal\Weee" sort_order="600"/> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/list.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/list.phtml index acd2b410731a8e1829ed5174957777b5761535c8..da4421f4f50f9e1dd8e1c2938377749a724fa82f 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/list.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/list.phtml @@ -26,7 +26,7 @@ /** @var \Magento\Wishlist\Block\Customer\Wishlist\Items $this */ $columns = $this->getColumns(); ?> -<div class="wishlist table wrapper"> +<div class="wishlist table-wrapper"> <table class="table data wishlist" id="wishlist-table"> <caption class="table caption"><?php echo __('Wish List') ?></caption> <thead> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/shared.phtml b/app/code/Magento/Wishlist/view/frontend/templates/shared.phtml index c540f0b04407c6a318015a89dc20a799ed831d12..6620bdcab6a9bdbc54e7c464722c7ae05fcb71a7 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/shared.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/shared.phtml @@ -27,7 +27,7 @@ $imageBlock = $this->getLayout()->createBlock('Magento\Catalog\Block\Product\Im <?php if ($this->hasWishlistItems()): ?> <form class="form shared wishlist" action="<?php echo $this->getUrl('*/*/update') ?>" method="post"> - <div class="wishlist table wrapper"> + <div class="wishlist table-wrapper"> <table class="table data wishlist" id="wishlist-table"> <thead> <tr> diff --git a/app/design/frontend/Magento/blank/Magento_Bundle/web/css/source/module.less b/app/design/frontend/Magento/blank/Magento_Bundle/web/css/source/module.less index 3d5f3b03652dfde650dbc8dadbd4dcdaa72bcbe8..2e7073e03aeaca530783c764d991343cb01dfda1 100644 --- a/app/design/frontend/Magento/blank/Magento_Bundle/web/css/source/module.less +++ b/app/design/frontend/Magento/blank/Magento_Bundle/web/css/source/module.less @@ -42,7 +42,7 @@ } .input-text.qty { - &:extend(.input-qty all); + &:extend(.abstract-input-qty all); } .product-options-wrapper { diff --git a/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/module.less b/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/module.less index f527eb55d116a648c08f1a59aa8db38bdf33294c..8dd6f5343de2204ca1b0e6b31a93fa7694899747 100644 --- a/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/module.less +++ b/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/module.less @@ -472,7 +472,7 @@ .action.tocompare { &:extend(.abstract-action-addto all); } - .product.reviews.summary .reviews.actions { + .product-reviews-summary .reviews-actions { .font-size(@font-size-base); } } diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/cart.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/cart.less index 8d79a752015f3a3fd10078e9c1dd47cca219ceb0..a3dbfa007515fcdbb09bddbf0168c35680052e33 100644 --- a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/cart.less +++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/cart.less @@ -48,14 +48,14 @@ cursor: pointer; display: block; font-weight: @font-weight-semibold; - line-height: 36px; margin-bottom: 0; - padding: 0 20px 0 5px; + overflow: hidden; + padding: 7px 20px 7px 5px; position: relative; &:after { position: absolute; right: 0; - top: 0; + top: -5px; } strong { .column.main & { @@ -64,18 +64,21 @@ } } } + > .content { + display: none; + } &.active { - .content { - display: block; - } > .title { .icon-font-symbol( @_icon-font-content: @icon-prev, @_icon-font-position: after ); } + > .content { + display: block; + } } - .item.options { + .item-options { margin-left: 0; } .fieldset { @@ -108,67 +111,97 @@ padding-right: 4px; text-align: right; } - .grand .mark, - .grand .amount { - padding-top: 25px; - } - .grand .mark strong { - font-weight: @font-weight-base; + .grand { + .mark, + .amount { + padding-top: 25px; + } + .mark strong { + font-weight: @font-weight-base; + } } .msrp { margin-bottom: @indent-s-base; } - } - - // Products table - &.table.wrapper { - thead { - .col.price, - .col.subtotal { - display: none; - } - } - .cart.items { - .action { - &:extend(button all); - .link-as-button(); - margin-left: 10px; - &:first-child { - margin-left: 0; + .totals-tax { + &-summary { + .mark, + .amount { + border-top: @border-width-base solid @border-color-base; + border-bottom: @border-width-base solid @border-color-base; + cursor: pointer; } - &.help.map { - &:extend(.abstract-action-button-as-link all); - font-weight: @font-weight-base; + .amount .price { + position: relative; + padding-right: 25px; + .icon-font( + @icon-down, + @_icon-font-size: 30px, + @_icon-font-text-hide: true, + @_icon-font-position: after, + @_icon-font-display: block + ); + &:after { + position: absolute; + right: -5px; + top: -12px; + } + } + &.expanded { + .mark, + .amount { + border-bottom: 0; + } + .amount .price { + .icon-font-symbol( + @_icon-font-content: @icon-up, + @_icon-font-position: after + ); + } } } - thead + .cart.item { + &-details { + display: none; + border-bottom: @border-width-base solid @border-color-base; + &.shown { + display: table-row; + } + } + } + } + + // Products table + &.table-wrapper { + .items { + thead + .item { border-top: @border-width-base solid @border-color-base; } - > .item.cart { + > .item { border-bottom: @border-width-base solid @border-color-base; - display: block; position: relative; } } - .col.price, - .col.subtotal { - display: block; - text-align: left; - white-space: nowrap; - &:before { - content: attr(data-th) ":"; - color: @color-primary-lighter; - display: inline-block; - font-size: @font-size-s; - padding-left: 5px; + .col { + &.qty, + &.price, + &.subtotal, + &.msrp { + padding-top: 20px; + &:extend(.abstract-incl-excl-tax all); + } + &.qty { + .input-text { + margin-top: -3px; + width: 45px; + } } - } - .col.qty { - right: 0; - position: absolute; - width: 45px; } .item { + &-actions td { + padding-bottom: 20px; + text-align: center; + white-space: normal; + } .col { &.item { display: block; @@ -177,19 +210,26 @@ min-height: 75px; } &.qty { - top: 0; - padding-top: 20px; .input-text { - &:extend(.input-qty all); + &:extend(.abstract-input-qty all); } } } - &.actions td { - padding-bottom: 20px; + } + .action { + &:extend(button all); + .link-as-button(); + margin-left: 10px; + &:first-child { + margin-left: 0; + } + &.help.map { + &:extend(.abstract-action-button-as-link all); + font-weight: @font-weight-base; } } .product { - &.photo { + &-item-photo { display: block; max-width: 60px; left: 0; @@ -198,23 +238,31 @@ top: 15px; width: 100%; } - &.details { + &-item-details { display: table-cell; vertical-align: top; + white-space: normal; width: 99%; - .product.name { - font-weight: @font-weight-base; - } + } + &-item-name { + display: inline-block; + font-weight: @font-weight-base; + max-width: 130px; + overflow: hidden; + text-overflow: ellipsis; } } // Product options - .item.options { + .cart-item-options { font-size: @font-size-s; margin-top: @indent-s-base; margin-bottom: @indent-s-base; &:extend(.product-options-list all); &:extend(.add-clearfix all); } + .cart-tax-total { + &:extend(.abstract-tax-total all); + } } &-container { .form.cart { @@ -255,7 +303,7 @@ } } } - .checkout.methods { + .checkout-methods-items { &:extend(.reset-list all); text-align: center; margin-top: @indent-s-base; @@ -271,11 +319,55 @@ // // Cross sell //-------------------------------------- - .block.crosssell { margin-top: 70px; } +// +// Mobile +//-------------------------------------- +.responsive-smaller(@break) when (@break = @break-point-1) { + .cart { + &.table-wrapper { + thead { + .col { + &.price, + &.qty, + &.subtotal, + &.msrp { + display: none; + } + } + } + .col { + &.qty, + &.price, + &.subtotal, + &.msrp { + .box-sizing(); + display: block; + float: left; + text-align: center; + white-space: nowrap; + width: 33%; + &:before { + content: attr(data-th) ":"; + display: block; + font-weight: @font-weight-bold; + padding-bottom: 10px; + } + } + &.msrp { + white-space: normal; + } + } + .item .col.item { + padding-bottom: 0; + } + } + } +} + // // Desktop //-------------------------------------- @@ -287,11 +379,10 @@ float: left; width: 73%; position: relative; - .actions.main { + .actions { text-align: left; } .action { - margin-bottom: 0; &.continue { float: left; } @@ -314,7 +405,7 @@ width: 23%; .actions-toolbar { .column.main & { - margin-left: 0; + &:extend(.reset-left-margin-desktop all); > .secondary { float: none; } @@ -330,40 +421,18 @@ } } - &.table.wrapper { - thead { - .col.price, - .col.subtotal { - display: table-cell; - } - } - .cart.items > .item.cart { - display: table-row-group; - } - .col { - &.price, - &.subtotal { - display: table-cell; - text-align: center; - padding-top: 27px; - &:before { - display: none; - } - } - &.qty { - position: static; - } - } - + &.table-wrapper { .item { - .col.item { - padding: 27px 8px 10px; + .col { + &.item { + padding: 27px 8px 10px; + } } &.actions td { text-align: right; } } - .product.photo { + .product-item-photo { display: table-cell; padding-right: 20px; vertical-align: top; diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module.less index 6b321311f259c44744aed639ab846adb28a9cfdc..dde2b9b948bdf6a9e6e778e41b83768af104108e 100644 --- a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module.less +++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module.less @@ -149,6 +149,7 @@ th.col.subtotal { text-align: center; } + .mark, .amount { text-align: right; } @@ -217,7 +218,7 @@ overflow: hidden; } .action, - .payment.method .title { + .payment-method .title { font-weight: @font-weight-base; } .data.table { diff --git a/app/design/frontend/Magento/blank/Magento_Customer/web/css/source/module.less b/app/design/frontend/Magento/blank/Magento_Customer/web/css/source/module.less index c7a50d4a76cda76d9057a9760d959fc3fec38aeb..1455462bd7c7123457b9e4cb7dcea15c6cc510c0 100644 --- a/app/design/frontend/Magento/blank/Magento_Customer/web/css/source/module.less +++ b/app/design/frontend/Magento/blank/Magento_Customer/web/css/source/module.less @@ -22,6 +22,13 @@ // * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) // */ +@account-nav-background: #e8e8e8; +@account-nav-color: false; +@account-nav-current-color: false; +@account-nav-current-font-weight: @font-weight-base; +@account-nav-current-border: 3px solid transparent; +@account-nav-current-border-color: #ff5501; + .login.container { .block { &.new { @@ -42,7 +49,7 @@ } } -.block.addresses.list { +.block-addresses-list { .items.addresses { > .item { margin-bottom: @indent-base; @@ -53,24 +60,23 @@ } } -.address.edit { +.form-address-edit { #region_id { - display: none; - } + display: none; + } } -.form.edit.account{ - .fieldset.password{ +.form-edit-account { + .fieldset.password { display: none; - } + } } -.address.billing, -.address.shipping, -.box.information, -.box.newsletter { - address, - p { +.box-address-billing, +.box-address-shipping, +.box-information, +.box-newsletter { + .box-content { line-height: 26px; } } @@ -85,12 +91,14 @@ h2 { margin-top: 0; } - .products.toolbar { - background: transparent; - margin-bottom: @indent-base; + .toolbar { + text-align: center; + .limiter-options { + width: auto; + } } .block:not(.widget) { - .title { + .block-title { > strong { .heading(h3); } @@ -99,7 +107,7 @@ margin-left: 15px; } } - .subtitle { + .box-title { > span { .heading(h4); } @@ -110,7 +118,7 @@ margin-left: 15px; } } - .content { + .block-content { p:last-child { margin-bottom: 0; } @@ -120,8 +128,8 @@ } } } - .block.account.nav { - background: @sidebar-background; + .block.account-nav { + .css(background, @sidebar-background); padding: 15px 0; .title { padding: 0 18px; @@ -146,32 +154,29 @@ border-left: 3px solid transparent; } a { + .css(color, @account-nav-color); text-decoration: none; &:hover { - background: #e8e8e8; + .css(background, @account-nav-background); } } &.current { strong { - border-color: #ff5501; + .css(color, @account-nav-current-color); + .css(border-color, @account-nav-current-border-color); font-weight: normal; } } } } } - - .wrapper.table { + .table-wrapper { margin-bottom: @indent-base; &:last-child { margin-bottom: 0; } .data.table { - .table-bordered( - @_type: light, - @_border-width: 1px - ); - margin-bottom: 0; + .table-striped(@_stripped-highlight: even); .col.actions { .action { margin-right: 15px; @@ -180,7 +185,7 @@ } } } - } + } } } @@ -201,6 +206,12 @@ } margin-bottom: @indent-s-base; } + p:last-child { + margin: 0; + } + .box-actions { + margin-top: @indent-xs-base; + } } @@ -269,7 +280,7 @@ .account { .column.main { .block:not(.widget) { - .content { + .block-content { &:extend(.add-clearfix-desktop all); .box { &:extend(.blocks-2columns all); @@ -277,9 +288,38 @@ } } } + .data.table { + .table-bordered( + @_type: light, + @_border-width: 1px + ); + margin-bottom: 0; + } + .toolbar { + position: relative; + margin-bottom: @indent-base; + &:extend(.add-clearfix-desktop all); + .limiter { + float: right; + position: relative; + z-index: 1; + } + .toolbar-amount { + float: left; + line-height: normal; + padding: 7px 0 0; + position: relative; + z-index: 1; + } + .pages { + position: absolute; + z-index: 0; + width: 100%; + } + } } - .block.addresses.list { + .block-addresses-list { .items.addresses { &:extend(.add-clearfix-desktop all); > .item { @@ -297,3 +337,28 @@ clear: both; } } + +// +// Mobile +//-------------------------------------- +.responsive-smaller(@break) when (@break = @break-point-0) { + .account { + .data.table { + &:extend(.table-vertical-mobile all); + .col.actions { + padding-top: 9px; + padding-bottom: 15px; + &:before { + &:extend(.visually-hidden-mobile all); + } + } + } + .toolbar { + .toolbar-amount, + .limiter, + .pages { + margin-bottom: 25px; + } + } + } +} diff --git a/app/design/frontend/Magento/blank/Magento_Downloadable/web/css/source/module.less b/app/design/frontend/Magento/blank/Magento_Downloadable/web/css/source/module.less index fd1768f6b28443e209f7ed00f9bd5e04c1f0969e..056e7779ae48df6dca62cc5bcd56e59c1ab58bc2 100644 --- a/app/design/frontend/Magento/blank/Magento_Downloadable/web/css/source/module.less +++ b/app/design/frontend/Magento/blank/Magento_Downloadable/web/css/source/module.less @@ -28,3 +28,8 @@ margin: 0 0 @indent-s-base; } } +.table-downloadable-products { + .product-name { + margin-right: 15px; + } +} diff --git a/app/design/frontend/Magento/blank/Magento_Paypal/web/css/source/module.less b/app/design/frontend/Magento/blank/Magento_Paypal/web/css/source/module.less index 31afa08f51c7ecdfbd0d030a7629c9f937265696..a577bbb64431080640b30620df57fd670fd1e200 100644 --- a/app/design/frontend/Magento/blank/Magento_Paypal/web/css/source/module.less +++ b/app/design/frontend/Magento/blank/Magento_Paypal/web/css/source/module.less @@ -42,7 +42,7 @@ } } -.form.new.agreement { +.form-new-agreement { .actions-toolbar { &:extend(.reset-left-margin all); } diff --git a/app/design/frontend/Magento/blank/Magento_Review/web/css/source/module.less b/app/design/frontend/Magento/blank/Magento_Review/web/css/source/module.less index 8b07a3b0fc104f0f84b8e11ebefea077b27d5cf8..694752b2b22b64ebb6e7088fe9af6030336a5fb2 100644 --- a/app/design/frontend/Magento/blank/Magento_Review/web/css/source/module.less +++ b/app/design/frontend/Magento/blank/Magento_Review/web/css/source/module.less @@ -22,6 +22,25 @@ // * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) // */ + +.rating-summary { + .mixin-rating-summary(); + .rating-result { + margin-left: -5px; + } +} + +.product-reviews-summary, +.table-reviews { + .rating-summary { + .mixin-rating-summary-label-hide(); + } +} + +.review-control-vote { + .mixin-rating-vote(); +} + // // Add reviewblock //-------------------------------------- @@ -64,7 +83,7 @@ } .data.table.reviews { - .rating.summary { + .rating-summary { margin-top: -4px; } } @@ -77,7 +96,7 @@ } } -.product.reviews.summary { +.product-reviews-summary { display: table; .products.wrapper.list & { margin: 0 auto; @@ -85,14 +104,14 @@ &.empty { margin-left: 0; } - .rating.summary { + .rating-summary { position: relative; left: -@indent-xs-base; display: table-cell; vertical-align: middle; text-align: left; } - .reviews.actions { + .reviews-actions { display: table-cell; vertical-align: middle; line-height: floor(@rating-icon-font-size * @line-height-base); @@ -109,9 +128,55 @@ // Desktop //-------------------------------------- .responsive(@break) when (@break = @break-point-1) { - .product.reviews.summary { + .product-reviews-summary { .products.wrapper.list & { margin: 0; } } } + +.customer-review { + .product-details { + &:extend(.add-clearfix all); + margin-bottom: @indent-xl-base; + .rating-average-label { + } + } + .product-media { + width: 30%; + max-width: 285px; + float: left; + margin-right: 3%; + } + .product-info { + } + .review-details { + .title { + } + .customer-review-rating { + .css(margin-bottom, @indent-base); + .item { + .css(margin-bottom, @indent-s-base); + &:last-child { + margin-bottom: 0; + } + } + } + .review-title { + .heading(h3); + .css(font-weight, @font-weight-semibold); + .css(margin-bottom, @indent-base); + } + .review-content { + .css(margin-bottom, @indent-base); + } + .review-date { + } + } + .product-reviews-summary { + .rating-summary, + .reviews-actions { + display: block; + } + } +} diff --git a/app/design/frontend/Magento/blank/Magento_Sales/web/css/source/module.less b/app/design/frontend/Magento/blank/Magento_Sales/web/css/source/module.less index b6e4b22ad5d5ef09bcaa9c43d0ff31201e38c5bb..dd693905d1179710eb5ac9c81b8a9d23ad48ddd9 100644 --- a/app/design/frontend/Magento/blank/Magento_Sales/web/css/source/module.less +++ b/app/design/frontend/Magento/blank/Magento_Sales/web/css/source/module.less @@ -22,43 +22,81 @@ // * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) // */ -.order.details { - ul.items { - &:extend(.reset-list all); - margin-bottom: @indent-base; - .label:after { - content: ": "; +.order-links { + border-bottom: @border-width-base solid @border-color-base; + margin-bottom: 10px; + .item { + display: inline-block; + margin-right: 20px; + } +} + +.order-actions-toolbar { + .action { + margin: 0 20px 0 0; + } +} + +.order-details-items { + border-bottom: @border-width-base solid @border-color-base; + margin-bottom: 20px; + padding-bottom: 10px; + .order-title { + > strong { + .heading(h3); + display: inline-block; } - strong { - font-weight: normal; + } + .col { + &.price, + &.subtotal { + &:extend(.abstract-incl-excl-tax all); } } - .order.status { - display: inline-block; - .heading(h2); - margin-top: 0; - } - .order.date { - margin-bottom: @indent-base; - } - .order.toolbar { - float: right; - .action { - margin-left: 15px; - &:first-child { - margin-left: 0; + .cart-tax-total { + &:extend(.abstract-tax-total all); + } + .items-qty { + &:extend(.reset-list all); + .item { + white-space: nowrap; + } + .title { + &:after { + content: ": "; } } } - .order.subtitle.caption, - .order.title { - strong { - .heading(h3); + .table-order-items { + .table-bordered( + @_type: horizontal + ); + .account & { + tfoot { + tr:first-child td { + border-top: @table-border-width @table-border-style @table-border-color; + } + } } - .action { - margin-left: 15px; + .item.options { + dt { + margin: 0; + } + dd { + margin: 0 0 15px; + } + &.links { + dt { + display: inline-block; + &:after { + content: ": "; + } + } + dd { + margin: 0; + } + } } - margin-bottom: @indent-base; } } @@ -89,14 +127,93 @@ } } +.block-order-details { + &-comments { + margin: 0 0 40px; + .comment-date { + font-weight: @font-weight-semibold; + } + .comment-content { + line-height: 1.6; + margin: 0 0 20px; + } + } + + &-view { + .box-content { + .payment-method { + .title { + font-weight: @font-weight-base; + } + .content { + margin: 0; + > strong { + font-weight: @font-weight-base; + &:after { + content: ': '; + } + } + } + } + } + } +} + +.order-tracking { + border-bottom: @border-width-base solid @border-color-base; + margin: 0; + padding: 20px 0; + .tracking-title { + display: inline-block; + } + .tracking-content { + display: inline-block; + margin: 0 0 0 5px; + } +} + // // Desktop //-------------------------------------- .responsive(@break) when (@break = @break-point-1) { - .order.details { - &:extend(.add-clearfix-desktop all); - .block { - &:extend(.blocks-2columns all); + .account { + .page-title { + .order-actions-toolbar { + margin: -20px 0 0; + text-align: right; + .action { + margin: 0 0 0 20px; + } + } + } + .table-order-items { + .col { + &.subtotal { + text-align: right; + } + } + .mark, + .amount { + text-align: right; + } + } + } +} + +// +// Mobile +//-------------------------------------- +.responsive-smaller(@break) when (@break = @break-point-0) { + .account { + .order-details-items { + .table-order-items { + tbody, + tfoot { + > tr > td { + border: none; + } + } + } } } } diff --git a/app/design/frontend/Magento/blank/Magento_Wishlist/web/css/source/module.less b/app/design/frontend/Magento/blank/Magento_Wishlist/web/css/source/module.less index de10fd08903f8818517bc0a948f031a6e78d48e9..fa04146e02100fe5013acb036d633092d5ac76d5 100644 --- a/app/design/frontend/Magento/blank/Magento_Wishlist/web/css/source/module.less +++ b/app/design/frontend/Magento/blank/Magento_Wishlist/web/css/source/module.less @@ -35,7 +35,7 @@ } } -.account .table.wrapper .data.table.wishlist { +.account .table-wrapper .data.table.wishlist { .table-bordered(@_type: horizontal); thead > tr > th { border-bottom: 0; @@ -51,7 +51,7 @@ margin: @indent-s-base 0; .qty { vertical-align: middle; - &:extend(.input-qty all); + &:extend(.abstract-input-qty all); } } .col { diff --git a/app/design/frontend/Magento/blank/web/css/source/abstract.less b/app/design/frontend/Magento/blank/web/css/source/abstract.less index 3bde20e922e2ba0b2deb708fdaa3ad1aa2436900..38fc00f5edd91e08955d7dc15260f224a9fa3c6c 100644 --- a/app/design/frontend/Magento/blank/web/css/source/abstract.less +++ b/app/design/frontend/Magento/blank/web/css/source/abstract.less @@ -32,21 +32,17 @@ } } -// -// Primary button -//-------------------------------------- -.action-primary { - .button-primary(); - border-radius: @button-border-radius; -} - // // Link as a button //-------------------------------------- .action-link-button { - .button(); - .link-as-button(); - border-radius: @button-border-radius; + .button(); + .link-as-button(); + border-radius: @button-border-radius; + &:active, + &:focus { + box-shadow: none; + } } // @@ -123,7 +119,7 @@ // // Input quantity //-------------------------------------- -.input-qty { +.abstract-input-qty { .form-element-size(@_width: 47px); text-align: center; } @@ -275,6 +271,12 @@ .visually-hidden(); } +.responsive-smaller(@break) when (@break = @break-point-0) { + .visually-hidden-mobile { + .visually-hidden(); + } +} + // // Clearfix //-------------------------------------- @@ -288,6 +290,12 @@ } } +.responsive-smaller(@break) when (@break = @break-point-0) { + .add-clearfix-mobile { + .clearfix(); + } +} + // // Box-sizing //-------------------------------------- @@ -393,3 +401,77 @@ .abstract-box-tocart { margin: @indent-s-base 0; } + +// +// Vertical Table +//-------------------------------------- +.responsive-smaller(@break) when (@break = @break-point-0) { + .table-vertical-mobile { + .table-responsive(); + tbody > tr { + > td { + padding-left: 0; + padding-right: 0; + } + &:not(:last-child) { + td:last-child { + padding-bottom: @indent-base; + } + } + } + } +} + +// +// Excl/Incl tax +//-------------------------------------- +.abstract-incl-excl-tax { + .tax { + display: block; + .font-size(18); + line-height: 1; + .price { + font-weight: @font-weight-bold; + } + } + + .incl.tax + .excl.tax, + .weee { + display: block; + .font-size(18); + &:before { + content: attr(data-th) ": "; + .font-size(11); + } + .price { + .font-size(11); + } + } +} + +// +// Cart tax total +//-------------------------------------- +.abstract-tax-total { + cursor: pointer; + position: relative; + padding-right: 12px; + .icon-font( + @icon-down, + @_icon-font-size: 26px, + @_icon-font-line-height: 10px, + @_icon-font-margin: 3px 0 0 0, + @_icon-font-position: after + ); + &:after { + position: absolute; + right: -7px; + top: 3px; + } + &-expanded { + .icon-font-symbol( + @_icon-font-content: @icon-up, + @_icon-font-position: after + ); + } +} diff --git a/app/design/frontend/Magento/blank/web/css/source/buttons.less b/app/design/frontend/Magento/blank/web/css/source/buttons.less index ff95002797404c48426176a42172917c8a07cb50..bb9acced2ccda34aa213f697f6144575f9938965 100644 --- a/app/design/frontend/Magento/blank/web/css/source/buttons.less +++ b/app/design/frontend/Magento/blank/web/css/source/buttons.less @@ -24,7 +24,7 @@ // // Using buttons mixins -//-------------------------------------- */ +//-------------------------------------- button { border-radius: @button-border-radius; &:active, diff --git a/app/design/frontend/Magento/blank/web/css/source/forms.less b/app/design/frontend/Magento/blank/web/css/source/forms.less index 1e8a6def1b96b98b570756222e3c3665e97024b1..9b9f437b208766d3dbb4fee34aed33ebeb89feec 100644 --- a/app/design/frontend/Magento/blank/web/css/source/forms.less +++ b/app/design/frontend/Magento/blank/web/css/source/forms.less @@ -46,6 +46,7 @@ &.choice { .label { font-weight: normal; + display: inline; } } .label { diff --git a/app/design/frontend/Magento/blank/web/css/source/rating.less b/app/design/frontend/Magento/blank/web/css/source/rating.less index 64c7c814bd75c3093cf83bd181224e9526ec3934..44d20b26e20c523599adc0ed9892488722eaa5d5 100644 --- a/app/design/frontend/Magento/blank/web/css/source/rating.less +++ b/app/design/frontend/Magento/blank/web/css/source/rating.less @@ -23,20 +23,8 @@ // */ // .block.reviews.dashboard, -// .product.reviews.summary, +// .product-reviews-summary, // .data.table.reviews, // .block.reviews.list, -// .customer.review.view +// .customer.review.view -.rating.summary { - .rating-summary(); -} - -.product.reviews.summary, -.data.table.reviews { - .rating-summary-label-hide(); -} - -.control.rating.vote { - .rating-vote(); -} diff --git a/app/design/frontend/Magento/blank/web/css/source/tables.less b/app/design/frontend/Magento/blank/web/css/source/tables.less index 04a1c24ad5d30a109af272d7caf471199ed8b218..91e66d34923274baf1edeff84822d5e1b3fc146e 100644 --- a/app/design/frontend/Magento/blank/web/css/source/tables.less +++ b/app/design/frontend/Magento/blank/web/css/source/tables.less @@ -22,7 +22,7 @@ // * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) // */ -.wrapper.table { +.table-wrapper { .table-overflow(); position: relative; // to hide unnecessary horizontal scrollbar in Safari > table { @@ -35,7 +35,7 @@ // Desktop //-------------------------------------- .responsive(@break) when (@break = @break-point-1) { - .wrapper.table { + .table-wrapper { overflow-y: visible; overflow-x: visible; > table { @@ -45,7 +45,7 @@ > tr { > th, > td { - white-space: normal; + //white-space: normal; } } } diff --git a/app/design/frontend/Magento/blank/web/js/theme.js b/app/design/frontend/Magento/blank/web/js/theme.js index f492c996cc6ea7b298805f5a3abe1651e0f48adf..d23207ae1ca5cd306ebd79275bd316d2e94e0488 100644 --- a/app/design/frontend/Magento/blank/web/js/theme.js +++ b/app/design/frontend/Magento/blank/web/js/theme.js @@ -34,6 +34,11 @@ }); } } + if($('.cart-summary').length){ + $('.cart-summary').mage('sticky', { + container: '.cart-container' + }); + } }); })(window.jQuery); diff --git a/app/i18n/Magento/de_DE/language.xml b/app/i18n/magento/de_de/language.xml similarity index 95% rename from app/i18n/Magento/de_DE/language.xml rename to app/i18n/magento/de_de/language.xml index 1c019d56b856343140a8963dc9560a1872c20dd0..2aca9717fea826070d3092f17b54e756994f00f3 100644 --- a/app/i18n/Magento/de_DE/language.xml +++ b/app/i18n/magento/de_de/language.xml @@ -25,5 +25,6 @@ --> <language xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../lib/internal/Magento/Framework/App/Language/package.xsd"> <code>de_DE</code> - <vendor>Magento</vendor> + <vendor>magento</vendor> + <package>de_de</package> </language> diff --git a/app/i18n/Magento/en_US/language.xml b/app/i18n/magento/en_us/language.xml similarity index 95% rename from app/i18n/Magento/en_US/language.xml rename to app/i18n/magento/en_us/language.xml index 4f7b0310a0ad9537c33ff34291c78cc0ecee200c..d7c59ae84e3c6d8301b858c5a526858eb51c00cb 100644 --- a/app/i18n/Magento/en_US/language.xml +++ b/app/i18n/magento/en_us/language.xml @@ -25,5 +25,6 @@ --> <language xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../lib/internal/Magento/Framework/App/Language/package.xsd"> <code>en_US</code> - <vendor>Magento</vendor> + <vendor>magento</vendor> + <package>en_us</package> </language> diff --git a/app/i18n/Magento/es_ES/language.xml b/app/i18n/magento/es_es/language.xml similarity index 95% rename from app/i18n/Magento/es_ES/language.xml rename to app/i18n/magento/es_es/language.xml index f0466320b88579dcf6b552be17998d6a267e80e6..e2ed071a4614956804831642796c94509bc26f23 100644 --- a/app/i18n/Magento/es_ES/language.xml +++ b/app/i18n/magento/es_es/language.xml @@ -25,5 +25,6 @@ --> <language xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../lib/internal/Magento/Framework/App/Language/package.xsd"> <code>es_ES</code> - <vendor>Magento</vendor> + <vendor>magento</vendor> + <package>es_es</package> </language> diff --git a/app/i18n/Magento/fr_FR/language.xml b/app/i18n/magento/fr_fr/language.xml similarity index 95% rename from app/i18n/Magento/fr_FR/language.xml rename to app/i18n/magento/fr_fr/language.xml index 461fdf7a05d7767c5545ece3d8450e8be89a9e31..065b5c46706c99fbbc41f5365bd161c7a59c519f 100644 --- a/app/i18n/Magento/fr_FR/language.xml +++ b/app/i18n/magento/fr_fr/language.xml @@ -25,5 +25,6 @@ --> <language xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../lib/internal/Magento/Framework/App/Language/package.xsd"> <code>fr_FR</code> - <vendor>Magento</vendor> + <vendor>magento</vendor> + <package>fr_fr</package> </language> diff --git a/app/i18n/Magento/nl_NL/language.xml b/app/i18n/magento/nl_nl/language.xml similarity index 95% rename from app/i18n/Magento/nl_NL/language.xml rename to app/i18n/magento/nl_nl/language.xml index 99fbfee22d806945a1e7396f6151df3f321c5f23..a96ef312fb12fec60c0814ea85b0061be636fbfd 100644 --- a/app/i18n/Magento/nl_NL/language.xml +++ b/app/i18n/magento/nl_nl/language.xml @@ -25,5 +25,6 @@ --> <language xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../lib/internal/Magento/Framework/App/Language/package.xsd"> <code>nl_NL</code> - <vendor>Magento</vendor> + <vendor>magento</vendor> + <package>nl_nl</package> </language> diff --git a/app/i18n/Magento/pt_BR/language.xml b/app/i18n/magento/pt_br/language.xml similarity index 95% rename from app/i18n/Magento/pt_BR/language.xml rename to app/i18n/magento/pt_br/language.xml index 401fc7016a56fc8096d02588f018d264a0311777..6f88d457d0f7669e4ce1afe2885988f98eeec7d9 100644 --- a/app/i18n/Magento/pt_BR/language.xml +++ b/app/i18n/magento/pt_br/language.xml @@ -25,5 +25,6 @@ --> <language xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../lib/internal/Magento/Framework/App/Language/package.xsd"> <code>pt_BR</code> - <vendor>Magento</vendor> + <vendor>magento</vendor> + <package>pt_br</package> </language> diff --git a/app/i18n/Magento/zh_CN/language.xml b/app/i18n/magento/zh_cn/language.xml similarity index 95% rename from app/i18n/Magento/zh_CN/language.xml rename to app/i18n/magento/zh_cn/language.xml index af174e14d44f1cd44cdcd5f047d6ed83e8f4ee66..02fc124179bd7f636140bd5d0afbbebecf66198f 100644 --- a/app/i18n/Magento/zh_CN/language.xml +++ b/app/i18n/magento/zh_cn/language.xml @@ -25,5 +25,6 @@ --> <language xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../lib/internal/Magento/Framework/App/Language/package.xsd"> <code>zh_CN</code> - <vendor>Magento</vendor> + <vendor>magento</vendor> + <package>zh_cn</package> </language> diff --git a/dev/tests/functional/.htaccess b/dev/tests/functional/.htaccess index 0a28bdaf0303a310ed6612bcd1751c0b2bf5bdee..db0b8f66ad0008c5f765391d0b93515d711ab1b7 100644 --- a/dev/tests/functional/.htaccess +++ b/dev/tests/functional/.htaccess @@ -191,4 +191,4 @@ ## If running in cluster environment, uncomment this ## http://developer.yahoo.com/performance/rules.html#etags - #FileETag none + #FileETag none \ No newline at end of file diff --git a/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/ConditionsElement.php b/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/ConditionsElement.php index e8d5572c9354efbef0961dcd062dca3f341b6a3f..4fee295b916d85f755248fa68b91db0fd1ecaeac 100644 --- a/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/ConditionsElement.php +++ b/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/ConditionsElement.php @@ -27,6 +27,7 @@ namespace Mtf\Client\Driver\Selenium\Element; use Mtf\Client\Element; use Mtf\Client\Element\Locator; use Mtf\Client\Driver\Selenium\Element as AbstractElement; +use Mtf\ObjectManager; /** * Class ConditionsElement @@ -61,6 +62,13 @@ class ConditionsElement extends AbstractElement */ protected $mainCondition = './/ul[contains(@id,"__1__children")]/..'; + /** + * Identification for chooser grid + * + * @var string + */ + protected $chooserLocator = '.rule-chooser-trigger'; + /** * Button add condition * @@ -163,6 +171,13 @@ class ConditionsElement extends AbstractElement */ protected $loader = './/ancestor::body/div[@id="loading-mask"]'; + /** + * Chooser grid locator + * + * @var string + */ + protected $chooserGridLocator = 'div[id*=chooser]'; + /** * Set value to conditions * @@ -254,6 +269,20 @@ class ConditionsElement extends AbstractElement $param = $this->findNextParam($element); $param->find('a')->click(); + if (preg_match('`%(.*?)%`', $rule, $chooserGrid)) { + $chooserConfig = explode('#', $chooserGrid[1]); + $param->find($this->chooserLocator)->click(); + $rule = preg_replace('`%(.*?)%`', '', $rule); + $grid = ObjectManager::getInstance()->create( + str_replace('/', '\\', $chooserConfig[0]), + [ + 'element' => $this->find($this->chooserGridLocator) + ] + ); + $grid->searchAndSelect([$chooserConfig[1] => $rule]); + continue; + } + $value = $param->find('select', Locator::SELECTOR_CSS, 'select'); if ($value->isVisible()) { $value->setValue($rule); diff --git a/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/DatepickerElement.php b/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/DatepickerElement.php index 39b76ffce6e2bf20cefc8db0fe2881deff8e2cf1..5d1f89325ac503c109a9f5f0ceedf8d694711714 100644 --- a/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/DatepickerElement.php +++ b/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/DatepickerElement.php @@ -85,13 +85,15 @@ class DatepickerElement extends Element public function setValue($value) { $date = $this->parseDate($value); - + $date[1] = ltrim($date[1], '0'); $this->find($this->datePickerButton, Locator::SELECTOR_XPATH)->click(); $datapicker = $this->find($this->datePickerBlock, Locator::SELECTOR_XPATH); $datapicker->find($this->datePickerMonth, Locator::SELECTOR_XPATH, 'select')->setValue($date[0]); $datapicker->find($this->datePickerYear, Locator::SELECTOR_XPATH, 'select')->setValue($date[2]); $datapicker->find(sprintf($this->datePickerCalendar, $date[1]), Locator::SELECTOR_XPATH)->click(); - $datapicker->find($this->datePickerButtonClose, Locator::SELECTOR_XPATH)->click(); + if ($datapicker->isVisible()) { + $datapicker->find($this->datePickerButtonClose, Locator::SELECTOR_XPATH)->click(); + } } /** diff --git a/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/JquerytreeElement.php b/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/JquerytreeElement.php index 2f6a7c38982d43b10fad305c3837930a521c046d..db5ce08dc54af680617b711716ceaa37efa307f8 100644 --- a/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/JquerytreeElement.php +++ b/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/JquerytreeElement.php @@ -175,6 +175,6 @@ class JquerytreeElement extends Tree foreach ($pathsArray as $pathArray) { $this->getPathFromArray($pathArray); } - return $this->checkedNodesPaths; + return array_filter($this->checkedNodesPaths); } } diff --git a/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/MultisuggestElement.php b/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/MultisuggestElement.php new file mode 100644 index 0000000000000000000000000000000000000000..e2cfe0991ffd3744555f2a5ad5b87499087fdb95 --- /dev/null +++ b/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/MultisuggestElement.php @@ -0,0 +1,126 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Mtf\Client\Driver\Selenium\Element; + +use Mtf\Client\Driver\Selenium\Element; +use Mtf\Client\Element\Locator; + +/** + * Class MultisuggestElement + * Typified element class for multi suggest element + */ +class MultisuggestElement extends SuggestElement +{ + /** + * Selector list choice + * + * @var string + */ + protected $listChoice = './/ul[contains(@class,"mage-suggest-choices")]'; + + /** + * Selector choice item + * + * @var string + */ + protected $choice = './/li/div[text()="%s"]/..'; + + /** + * Selector choice value + * + * @var string + */ + protected $choiceValue = './/li[contains(@class,"mage-suggest-choice")]/div'; + + /** + * Selector remove choice item + * + * @var string + */ + protected $choiceClose = '.mage-suggest-choice-close'; + + /** + * Set value + * + * @param array|string $values + * @return void + */ + public function setValue($values) + { + $this->_eventManager->dispatchEvent(['set_value'], [__METHOD__, $this->getAbsoluteSelector()]); + + $this->clear(); + foreach ((array)$values as $value) { + if (!$this->isChoice($value)) { + parent::setValue($value); + } + } + } + + /** + * Get value + * + * @return array + */ + public function getValue() + { + $this->_eventManager->dispatchEvent(['get_value'], [(string) $this->_locator]); + + $listChoice = $this->find($this->listChoice, Locator::SELECTOR_XPATH); + $choices = $listChoice->find($this->choiceValue, Locator::SELECTOR_XPATH)->getElements(); + $values = []; + + foreach ($choices as $choice) { + /** @var Element $choice */ + $values[] = $choice->getText(); + } + return $values; + } + + /** + * Check exist selected item + * + * @param string $value + * @return bool + */ + protected function isChoice($value) + { + return $this->find(sprintf($this->choice, $value), Locator::SELECTOR_XPATH)->isVisible(); + } + + /** + * Clear element + * + * @return void + */ + protected function clear() + { + $choiceClose = $this->find($this->choiceClose); + while ($choiceClose->isVisible()) { + $choiceClose->click(); + $choiceClose = $this->find($this->choiceClose); + } + } +} diff --git a/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/SuggestElement.php b/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/SuggestElement.php old mode 100644 new mode 100755 index aca42a1d95feacc104340cec9a0cbf9aa4865a32..a1d028108947cc93f113c125d0d7fe415d8295df --- a/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/SuggestElement.php +++ b/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/SuggestElement.php @@ -62,6 +62,8 @@ class SuggestElement extends Element */ public function setValue($value) { + $this->_eventManager->dispatchEvent(['set_value'], [__METHOD__, $this->getAbsoluteSelector()]); + $this->find($this->suggest)->setValue($value); $this->waitResult(); $this->find(sprintf($this->resultItem, $value), Locator::SELECTOR_XPATH)->click(); @@ -90,6 +92,8 @@ class SuggestElement extends Element */ public function getValue() { + $this->_eventManager->dispatchEvent(['get_value'], [(string) $this->_locator]); + return $this->find($this->suggest)->getValue(); } } diff --git a/dev/tests/functional/lib/Mtf/Constraint/AbstractAssertForm.php b/dev/tests/functional/lib/Mtf/Constraint/AbstractAssertForm.php index 32b2d087b110ba4794dc81178adc002b522965e7..76198d9674d088d82edf86dfe3b2a032f7b2dd45 100755 --- a/dev/tests/functional/lib/Mtf/Constraint/AbstractAssertForm.php +++ b/dev/tests/functional/lib/Mtf/Constraint/AbstractAssertForm.php @@ -27,9 +27,19 @@ namespace Mtf\Constraint; /** * Class AssertForm * Abstract class AssertForm + * Implements: + * - verify fixture data and form data + * - sort multidimensional array by paths */ abstract class AbstractAssertForm extends AbstractConstraint { + /** + * Skipped fields for verify data + * + * @var array + */ + protected $skippedFields = []; + /** * Verify fixture and form data * @@ -47,6 +57,9 @@ abstract class AbstractAssertForm extends AbstractConstraint $errors = []; foreach ($fixtureData as $key => $value) { + if (in_array($key, $this->skippedFields)) { + continue; + } $formValue = isset($formData[$key]) ? $formData[$key] : null; if (is_numeric($formValue)) { $formValue = floatval($formValue); @@ -83,40 +96,95 @@ abstract class AbstractAssertForm extends AbstractConstraint return $errors; } + /** + * Sort array by value + * + * @param array $data + * @return array + */ + protected function sortData(array $data) + { + $scalarValues = []; + $arrayValues = []; + + foreach ($data as $key => $value) { + if (is_array($value)) { + $arrayValues[$key] = $this->dataSort($value); + } else { + $scalarValues[$key] = $value; + } + } + asort($scalarValues); + foreach (array_keys($arrayValues) as $key) { + if (!is_numeric($key)) { + ksort($arrayValues); + break; + } + } + + return $scalarValues + $arrayValues; + } + /** * Sort multidimensional array by paths + * Pattern path: key/subKey::sorkKey. + * Exapmle: + * $data = [ + * 'custom_options' => [ + * 'options' => [ + * 0 => [ + * 'title' => 'title_2', + * ], + * 1 => [ + * 'title' => 'title_1' + * ] + * ] + * ] + * ]; + * $paths = ['custom_options/options::title']; + * + * Result: + * $data = [ + * 'custom_options' => [ + * 'options' => [ + * title_1 => [ + * 'title' => 'title_1', + * ], + * title_2 => [ + * 'title' => 'title_2' + * ] + * ] + * ] + * ]; * * @param array $data - * @param array|string $paths + * @param string $path + * @param string $path * @return array + * @throws \Exception + * + * @SuppressWarnings(PHPMD.NPathComplexity) */ - protected function sortData(array $data, $paths) + protected function sortDataByPath(array $data, $path) { - $paths = is_array($paths) ? $paths : [$paths]; - foreach ($paths as $path) { - $values = &$data; - $keys = explode('/', $path); - - $key = array_shift($keys); - $order = null; - while (null !== $key) { - if (false !== strpos($key, '::')) { - list($key, $order) = explode('::', $key); - } - if ($key && !isset($values[$key])) { - $key = null; - continue; - } + $steps = explode('/', $path); + $key = array_shift($steps); + $order = null; + $nextPath = empty($steps) ? null : implode('/', $steps); - if ($key) { - $values = &$values[$key]; - } - if ($order) { - $values = $this->sortMultidimensionalArray($values, $order); - $order = null; - } - $key = array_shift($keys); - } + if (false !== strpos($key, '::')) { + list($key, $order) = explode('::', $key); + } + if ($key && !isset($data[$key])) { + return $data; + } + + if ($key) { + $data[$key] = $order ? $this->sortMultidimensionalArray($data[$key], $order) : $data[$key]; + $data[$key] = $nextPath ? $this->sortData($data[$key], $nextPath) : $data[$key]; + } else { + $data = $this->sortMultidimensionalArray($data, $order); + $data = $nextPath ? $this->sortData($data, $nextPath) : $data; } return $data; @@ -133,7 +201,8 @@ abstract class AbstractAssertForm extends AbstractConstraint { $result = []; foreach ($data as $value) { - $result[$value[$key]] = $value; + $sortKey = is_numeric($value[$key]) ? floatval($value[$key]) : $value[$key]; + $result[$sortKey] = $value; } ksort($result); @@ -162,7 +231,7 @@ abstract class AbstractAssertForm extends AbstractConstraint * * @param array $errors * @param string|null $notice - * @param string $indent + * @param string $indent [optional] * @return string */ protected function prepareErrors(array $errors, $notice = null, $indent = '') diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/FormPageActions.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/FormPageActions.php index a17327a5c59d18e0c4de538248f64b40aac512b5..24ba6559bde71a7cbea18238191c05849f1eeee5 100644 --- a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/FormPageActions.php +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/FormPageActions.php @@ -29,6 +29,8 @@ use Mtf\Client\Element\Locator; /** * Class FormPageActions * Form page actions block + * + * @SuppressWarnings(PHPMD.NumberOfChildren) */ class FormPageActions extends PageActions { diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Store/Delete/StoreForm.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Store/Delete/StoreForm.php new file mode 100644 index 0000000000000000000000000000000000000000..87172a11980baea1fed34be69a7f5aa74b94fc51 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Store/Delete/StoreForm.php @@ -0,0 +1,49 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Backend\Test\Block\System\Store\Delete; + +use Mtf\Client\Element; +use Mtf\Block\Form; +use Mtf\Client\Element\Locator; + +/** + * Class StoreForm + * Form for Store View deletion + */ +class StoreForm extends Form +{ + /** + * Fill Backup Option in Delete Store View + * + * @param array $data + * @param Element $element + * @return void + */ + public function fillForm(array $data, Element $element = null) + { + $mapping = $this->dataMapping($data); + $this->_fill($mapping, $element); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Store/Delete/StoreForm.xml b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Store/Delete/StoreForm.xml new file mode 100644 index 0000000000000000000000000000000000000000..5e6ba1de31c497befe3c885fdc932d318426271a --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Store/Delete/StoreForm.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" ?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<mapping strict="0"> + <fields> + <create_backup> + <selector>[name="create_backup"]</selector> + <input>select</input> + </create_backup> + </fields> +</mapping> \ No newline at end of file diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Store/Edit.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Store/Edit/StoreForm.php similarity index 83% rename from dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Store/Edit.php rename to dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Store/Edit/StoreForm.php index 9792e3fa085316bb519c49f630196ce16220b7da..f093986d7f123041033d76178f2a4922d8e5c80c 100644 --- a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Store/Edit.php +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Store/Edit/StoreForm.php @@ -1,7 +1,5 @@ <?php /** - * Store edit form - * * Magento * * NOTICE OF LICENSE @@ -24,14 +22,15 @@ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ -namespace Magento\Backend\Test\Block\System\Store; +namespace Magento\Backend\Test\Block\System\Store\Edit; + +use Mtf\Block\Form; /** - * Class Edit - * Adminhtml store content block - * + * Class StoreForm + * Form for Store View creation */ -class Edit extends \Magento\Backend\Test\Block\Widget\Form +class StoreForm extends Form { // } diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Store/Edit.xml b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Store/Edit/StoreForm.xml similarity index 87% rename from dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Store/Edit.xml rename to dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Store/Edit/StoreForm.xml index 8b0c89b7de33e14cd2cb61045cf078215140c1ab..17e1c7b63a9abf28b8f677280d0abd477e13099a 100644 --- a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Store/Edit.xml +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Store/Edit/StoreForm.xml @@ -26,15 +26,11 @@ <mapping strict="0"> <wrapper>store</wrapper> <fields> - <group> - <selector>[name='store[group_id]']</selector> + <group_id> <input>select</input> - </group> - <name /> - <code /> + </group_id> <is_active> <input>select</input> </is_active> - <sort_order /> </fields> -</mapping> +</mapping> \ No newline at end of file diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Store/Grid.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Store/FormPageActions.php similarity index 73% rename from dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Store/Grid.php rename to dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Store/FormPageActions.php index f36cfae3edcdb2b1afcfbc402e8a25294f41c0a5..7ab073981dac5b0c76298fed3e9767fe38f903a2 100644 --- a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Store/Grid.php +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Store/FormPageActions.php @@ -1,7 +1,5 @@ <?php /** - * Store grid - * * Magento * * NOTICE OF LICENSE @@ -23,21 +21,24 @@ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ + namespace Magento\Backend\Test\Block\System\Store; -use Mtf\Client\Element\Locator; +use Magento\Backend\Test\Block\FormPageActions as ParentFormPageActions; -class Grid extends \Magento\Backend\Test\Block\Widget\Grid +/** + * Class FormPageActions + * Form page actions block in Store page + */ +class FormPageActions extends ParentFormPageActions { /** - * Check if store exists + * Click on "Delete" button without acceptAlert * - * @param string $title - * @return bool + * @return void */ - public function isStoreExists($title) + public function delete() { - $element = $this->_rootElement->find($title, Locator::SELECTOR_LINK_TEXT); - return $element && $element->isVisible(); + $this->_rootElement->find($this->deleteButton)->click(); } } diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Store/GridPageActions.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Store/GridPageActions.php new file mode 100644 index 0000000000000000000000000000000000000000..66151d69496dcf429ee28de5c09d9eaa6ceb0f76 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Store/GridPageActions.php @@ -0,0 +1,51 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Backend\Test\Block\System\Store; + +use Magento\Backend\Test\Block\GridPageActions as ParentGridPageActions; + +/** + * Class GridPageActions + * Grid page actions block in Cms Block grid page + */ +class GridPageActions extends ParentGridPageActions +{ + /** + * Add Store View button + * + * @var string + */ + protected $addStoreViewButton = '#add_store'; + + /** + * Click on Add Store View button + * + * @return void + */ + public function addStoreView() + { + $this->_rootElement->find($this->addStoreViewButton)->click(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Store/StoreGrid.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Store/StoreGrid.php new file mode 100644 index 0000000000000000000000000000000000000000..71da0c14b80811d018120f20bf3e243a3126d894 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Store/StoreGrid.php @@ -0,0 +1,72 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Backend\Test\Block\System\Store; + +use Mtf\Client\Element\Locator; +use Magento\Backend\Test\Block\Widget\Grid as GridInterface; + +/** + * Class StoreGrid + * Adminhtml Store View management grid + */ +class StoreGrid extends GridInterface +{ + /** + * Locator value for opening needed row + * + * @var string + */ + protected $editLink = 'td[data-column="store_title"] > a'; + + /** + * Filters array mapping + * + * @var array + */ + protected $filters = [ + 'store_title' => [ + 'selector' => '#storeGrid_filter_store_title', + ], + ]; + + /** + * Store title format for XPATH + * + * @var string + */ + protected $titleFormat = '//td[a[.="%s"]]'; + + /** + * Check if store exists + * + * @param string $title + * @return bool + */ + public function isStoreExists($title) + { + $element = $this->_rootElement->find(sprintf($this->titleFormat, $title), Locator::SELECTOR_XPATH); + return $element->isVisible(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Variable/Edit/VariableForm.xml b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Variable/Edit/VariableForm.xml index c103192abb9d3556bbfdb2fcc4f71d14d34f78f0..b21f663a2e7dc6140b97c4c49dd3817d2b0b67fc 100644 --- a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Variable/Edit/VariableForm.xml +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Variable/Edit/VariableForm.xml @@ -28,6 +28,9 @@ <fields> <code /> <name /> + <use_default_value> + <input>select</input> + </use_default_value> <html_value /> <plain_value /> </fields> diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/Adminhtml/StoreDelete.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/Adminhtml/StoreDelete.php new file mode 100644 index 0000000000000000000000000000000000000000..094121f227de0959ca6798269f0f6affd957df39 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/Adminhtml/StoreDelete.php @@ -0,0 +1,81 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Backend\Test\Page\Adminhtml; + +use Mtf\Page\BackendPage; + +/** + * Class StoreDelete + * Backend Store delete page + */ +class StoreDelete extends BackendPage +{ + const MCA = 'admin/system_store/deleteStore'; + + protected $_blocks = [ + 'messagesBlock' => [ + 'name' => 'messagesBlock', + 'class' => 'Magento\Core\Test\Block\Messages', + 'locator' => '#messages', + 'strategy' => 'css selector', + ], + 'storeForm' => [ + 'name' => 'form', + 'class' => 'Magento\Backend\Test\Block\System\Store\Delete\StoreForm', + 'locator' => '#edit_form', + 'strategy' => 'css selector', + ], + 'formPageActions' => [ + 'name' => 'formPageActions', + 'class' => 'Magento\Backend\Test\Block\System\Store\FormPageActions', + 'locator' => '.content-footer', + 'strategy' => 'css selector', + ], + ]; + + /** + * @return \Magento\Core\Test\Block\Messages + */ + public function getMessagesBlock() + { + return $this->getBlockInstance('messagesBlock'); + } + + /** + * @return \Magento\Backend\Test\Block\System\Store\Delete\StoreForm + */ + public function getStoreForm() + { + return $this->getBlockInstance('storeForm'); + } + + /** + * @return \Magento\Backend\Test\Block\System\Store\FormPageActions + */ + public function getFormPageActions() + { + return $this->getBlockInstance('formPageActions'); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/Adminhtml/StoreDelete.xml b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/Adminhtml/StoreDelete.xml new file mode 100644 index 0000000000000000000000000000000000000000..54f0501806f2d67e6f349a572a0d6768979bd7c9 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/Adminhtml/StoreDelete.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" ?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<page mca="admin/system_store/deleteStore" > + <block> + <name>messagesBlock</name> + <class>Magento\Core\Test\Block\Messages</class> + <locator>#messages</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>storeForm</name> + <class>Magento\Backend\Test\Block\System\Store\Delete\StoreForm</class> + <locator>#edit_form</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>formPageActions</name> + <class>Magento\Backend\Test\Block\System\Store\FormPageActions</class> + <locator>.content-footer</locator> + <strategy>css selector</strategy> + </block> +</page> diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/Adminhtml/StoreIndex.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/Adminhtml/StoreIndex.php new file mode 100644 index 0000000000000000000000000000000000000000..363ccc5a128f6aacef40201ddeafc16588ec44b9 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/Adminhtml/StoreIndex.php @@ -0,0 +1,81 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Backend\Test\Page\Adminhtml; + +use Mtf\Page\BackendPage; + +/** + * Class StoreIndex + * Backend Store index page + */ +class StoreIndex extends BackendPage +{ + const MCA = 'admin/system_store'; + + protected $_blocks = [ + 'messagesBlock' => [ + 'name' => 'messagesBlock', + 'class' => 'Magento\Core\Test\Block\Messages', + 'locator' => '#messages', + 'strategy' => 'css selector', + ], + 'gridPageActions' => [ + 'name' => 'gridPageActions', + 'class' => 'Magento\Backend\Test\Block\System\Store\GridPageActions', + 'locator' => '.page-main-actions', + 'strategy' => 'css selector', + ], + 'storeGrid' => [ + 'name' => 'storeGrid', + 'class' => 'Magento\Backend\Test\Block\System\Store\StoreGrid', + 'locator' => '[id="page:main-container"]', + 'strategy' => 'css selector', + ], + ]; + + /** + * @return \Magento\Core\Test\Block\Messages + */ + public function getMessagesBlock() + { + return $this->getBlockInstance('messagesBlock'); + } + + /** + * @return \Magento\Backend\Test\Block\System\Store\GridPageActions + */ + public function getGridPageActions() + { + return $this->getBlockInstance('gridPageActions'); + } + + /** + * @return \Magento\Backend\Test\Block\System\Store\StoreGrid + */ + public function getStoreGrid() + { + return $this->getBlockInstance('storeGrid'); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/Adminhtml/StoreIndex.xml b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/Adminhtml/StoreIndex.xml new file mode 100644 index 0000000000000000000000000000000000000000..6e858a105199bb5d9d7eb50253c1ec078468f1c0 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/Adminhtml/StoreIndex.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" ?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<page mca="admin/system_store" > + <block> + <name>messagesBlock</name> + <class>Magento\Core\Test\Block\Messages</class> + <locator>#messages</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>gridPageActions</name> + <class>Magento\Backend\Test\Block\System\Store\GridPageActions</class> + <locator>.page-main-actions</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>storeGrid</name> + <class>Magento\Backend\Test\Block\System\Store\StoreGrid</class> + <locator>[id="page:main-container"]</locator> + <strategy>css selector</strategy> + </block> +</page> diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/Adminhtml/StoreNew.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/Adminhtml/StoreNew.php new file mode 100644 index 0000000000000000000000000000000000000000..5a965e4adad39986648984040aefe18978048456 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/Adminhtml/StoreNew.php @@ -0,0 +1,81 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Backend\Test\Page\Adminhtml; + +use Mtf\Page\BackendPage; + +/** + * Class StoreNew + * Backend new Store page + */ +class StoreNew extends BackendPage +{ + const MCA = 'admin/system_store/newStore'; + + protected $_blocks = [ + 'formPageActions' => [ + 'name' => 'formPageActions', + 'class' => 'Magento\Backend\Test\Block\System\Store\FormPageActions', + 'locator' => '.page-main-actions', + 'strategy' => 'css selector', + ], + 'storeForm' => [ + 'name' => 'storeForm', + 'class' => 'Magento\Backend\Test\Block\System\Store\Edit\StoreForm', + 'locator' => '[id="page:main-container"]', + 'strategy' => 'css selector', + ], + 'messagesBlock' => [ + 'name' => 'messagesBlock', + 'class' => 'Magento\Core\Test\Block\Messages', + 'locator' => '#messages', + 'strategy' => 'css selector', + ], + ]; + + /** + * @return \Magento\Backend\Test\Block\System\Store\FormPageActions + */ + public function getFormPageActions() + { + return $this->getBlockInstance('formPageActions'); + } + + /** + * @return \Magento\Backend\Test\Block\System\Store\Edit\StoreForm + */ + public function getStoreForm() + { + return $this->getBlockInstance('storeForm'); + } + + /** + * @return \Magento\Core\Test\Block\Messages + */ + public function getMessagesBlock() + { + return $this->getBlockInstance('messagesBlock'); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/Adminhtml/StoreNew.xml b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/Adminhtml/StoreNew.xml new file mode 100644 index 0000000000000000000000000000000000000000..5fd621e3fbc0fda6c755b63e115cf658bf1f8b99 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/Adminhtml/StoreNew.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" ?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<page mca="admin/system_store/newStore" > + <block> + <name>formPageActions</name> + <class>Magento\Backend\Test\Block\System\Store\FormPageActions</class> + <locator>.page-main-actions</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>storeForm</name> + <class>Magento\Backend\Test\Block\System\Store\Edit\StoreForm</class> + <locator>[id="page:main-container"]</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>messagesBlock</name> + <class>Magento\Core\Test\Block\Messages</class> + <locator>#messages</locator> + <strategy>css selector</strategy> + </block> +</page> diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/System/Store/ItemList.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/System/Store/ItemList.php deleted file mode 100644 index 82efd6173bc78f0b417bc02c740a4a45d993ad00..0000000000000000000000000000000000000000 --- a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/System/Store/ItemList.php +++ /dev/null @@ -1,101 +0,0 @@ -<?php -/** - * Store list page - * - * Magento - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://opensource.org/licenses/osl-3.0.php - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@magentocommerce.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade Magento to newer - * versions in the future. If you wish to customize Magento for your - * needs please refer to http://www.magentocommerce.com for more information. - * - * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) - */ -namespace Magento\Backend\Test\Page\System\Store; - -use Mtf\Page\Page; -use Mtf\Factory\Factory; -use \Magento\Core\Test\Block\Messages; -use \Magento\Backend\Test\Block\System\Store\Actions; -use \Magento\Backend\Test\Block\System\Store\Grid; - -class ItemList extends Page -{ - /** - * Url - */ - const MCA = 'admin/system_store'; - - /** - * Messages block selector - * - * @var string - */ - protected $messagesBlock = '#messages .messages'; - - /** - * Actions block selector - * - * @var string - */ - protected $pageActionsBlock = '.page-actions'; - - /** - * Store grid selector - * - * @var string - */ - protected $gridBlock = '#storeGrid'; - - /** - * Constructor - */ - protected function _init() - { - $this->_url = $_ENV['app_backend_url'] . self::MCA; - } - - /** - * Retrieve actions block - * - * @return Actions - */ - public function getPageActionsBlock() - { - return Factory::getBlockFactory()->getMagentoBackendSystemStoreActions( - $this->_browser->find($this->pageActionsBlock) - ); - } - - /** - * Retrieve store grid block - * - * @return Grid - */ - public function getGridBlock() - { - return Factory::getBlockFactory()->getMagentoBackendSystemStoreGrid($this->_browser->find($this->gridBlock)); - } - - /** - * Retrieve messages block - * - * @return Messages - */ - public function getMessagesBlock() - { - return Factory::getBlockFactory()->getMagentoCoreMessages($this->_browser->find($this->messagesBlock)); - } -} diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/System/Store/NewStore.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/System/Store/NewStore.php deleted file mode 100644 index 35a9b14d68e9887375c7ee4d0f14b20da0ca372d..0000000000000000000000000000000000000000 --- a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/System/Store/NewStore.php +++ /dev/null @@ -1,79 +0,0 @@ -<?php -/** - * Store creation page - * Magento - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://opensource.org/licenses/osl-3.0.php - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@magentocommerce.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade Magento to newer - * versions in the future. If you wish to customize Magento for your - * needs please refer to http://www.magentocommerce.com for more information. - * - * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) - */ -namespace Magento\Backend\Test\Page\System\Store; - -use Mtf\Factory\Factory; -use Mtf\Page\Page; - -class NewStore extends Page -{ - const MCA = 'admin/system_store/newStore'; - - /** - * Store edit form block - * - * @var string - */ - protected $formBlock = '#edit_form'; - - /** - * Page actions block - * - * @var string - */ - protected $actionsBlock = '.page-actions'; - - /** - * Initialize page - */ - protected function _init() - { - $this->_url = $_ENV['app_frontend_url'] . self::MCA; - } - - /** - * Retrieve form block - * - * @return \Magento\Backend\Test\Block\System\Store\Edit - */ - public function getFormBlock() - { - return Factory::getBlockFactory()->getMagentoBackendSystemStoreEdit( - $this->_browser->find($this->formBlock) - ); - } - - /** - * Retrieve actions block - * - * @return \Magento\Backend\Test\Block\System\Store\Actions - */ - public function getPageActionsBlock() - { - return Factory::getBlockFactory()->getMagentoBackendSystemStoreActions( - $this->_browser->find($this->actionsBlock) - ); - } -} diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/etc/global/page.xml b/dev/tests/functional/tests/app/Magento/Backend/Test/etc/global/page.xml index 9085814b562432a3a061319b8cfb56bc089a6357..7706202b03c56e5cd80cea5df9690813122088e4 100644 --- a/dev/tests/functional/tests/app/Magento/Backend/Test/etc/global/page.xml +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/etc/global/page.xml @@ -24,9 +24,24 @@ */ --> <page> - <config> + <systemConfig> <mca>admin/system_config</mca> <area>adminhtml</area> <class>Magento\Backend\Test\Page\Adminhtml\SystemConfig</class> - </config> + </systemConfig> + <systemStoreIndex> + <mca>admin/system_store</mca> + <area>adminhtml</area> + <class>Magento\Backend\Test\Page\Adminhtml\StoreIndex</class> + </systemStoreIndex> + <systemStoreNew> + <mca>admin/system_store/newStore</mca> + <area>adminhtml</area> + <class>Magento\Backend\Test\Page\Adminhtml\StoreNew</class> + </systemStoreNew> + <systemStoreDelete> + <mca>admin/system_store/deleteStore</mca> + <area>adminhtml</area> + <class>Magento\Backend\Test\Page\Adminhtml\StoreDelete</class> + </systemStoreDelete> </page> diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle.php index bcaf9cbb617912ecbf37f97d7c9788a719112219..ff2a43e7792e9c4b5d2033b983d4ab0ab117d8ed 100644 --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle.php +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle.php @@ -25,40 +25,40 @@ namespace Magento\Bundle\Test\Block\Adminhtml\Catalog\Product\Edit\Tab; use Mtf\Client\Element; -use Mtf\Factory\Factory; use Magento\Backend\Test\Block\Widget\Tab; -use Magento\Catalog\Test\Fixture\CatalogProductSimple; +use Magento\Bundle\Test\Block\Adminhtml\Catalog\Product\Edit\Tab\Bundle\Option; /** * Class Bundle - * Bundle options section + * Bundle options section block on product-details tab */ class Bundle extends Tab { /** - * 'Create New Option' button + * Selector for 'Create New Option' button * * @var string */ protected $addNewOption = '#add_new_option'; /** - * Bundle options block + * Open option section * * @var string */ - protected $bundleOptionBlock = '#bundle_option_'; + protected $openOption = '[data-target="#bundle_option_%d-content"]'; /** * Get bundle options block * * @param int $blockNumber - * @return \Magento\Bundle\Test\Block\Adminhtml\Catalog\Product\Edit\Tab\Bundle\Option + * @return Option */ protected function getBundleOptionBlock($blockNumber) { - return Factory::getBlockFactory()->getMagentoBundleAdminhtmlCatalogProductEditTabBundleOption( - $this->_rootElement->find($this->bundleOptionBlock . $blockNumber) + return $this->blockFactory->create( + 'Magento\Bundle\Test\Block\Adminhtml\Catalog\Product\Edit\Tab\Bundle\Option', + ['element' => $this->_rootElement->find('#bundle_option_' . $blockNumber)] ); } @@ -74,68 +74,42 @@ class Bundle extends Tab if (!isset($fields['bundle_selections'])) { return $this; } - $bundleOptions = $this->prepareBundleOptions($fields['bundle_selections']['value']['bundle_options']); - $blocksNumber = 0; - foreach ($bundleOptions as $bundleOption) { - $this->_rootElement->find($this->addNewOption)->click(); - $bundleOptionsBlock = $this->getBundleOptionBlock($blocksNumber); - $bundleOptionsBlock->fillBundleOption($bundleOption, $this->_rootElement); - $blocksNumber++; + foreach ($fields['bundle_selections']['value']['bundle_options'] as $key => $bundleOption) { + $itemOption = $this->_rootElement->find(sprintf($this->openOption, $key)); + if ($itemOption->isVisible()) { + $itemOption->click(); + } else { + $this->_rootElement->find($this->addNewOption)->click(); + } + $this->getBundleOptionBlock($key)->fillBundleOption($bundleOption); } - return $this; } /** - * Update bundle options + * Get data to fields on downloadable tab * - * @param array $fields + * @param array|null $fields * @param Element|null $element - * @return void - */ - public function updateFormTab(array $fields, Element $element = null) - { - if (!isset($fields['bundle_selections'])) { - return; - } - $bundleOptions = $this->prepareBundleOptions($fields['bundle_selections']['value']); - $blocksNumber = 0; - foreach ($$bundleOptions as $bundleOption) { - $bundleOptionsBlock = $this->getBundleOptionBlock($blocksNumber, $element); - $bundleOptionsBlock->expand(); - $bundleOptionsBlock->updateBundleOption($bundleOption, $element); - $blocksNumber++; - } - } - - /** - * Prepare Bundle Options array from preset - * - * @param array $bundleSelections * @return array - * @throws \InvalidArgumentException */ - protected function prepareBundleOptions(array $bundleSelections) + public function getDataFormTab($fields = null, Element $element = null) { - if (!isset($bundleSelections['preset'])) { - return $bundleSelections; + $newFields = []; + if (!isset($fields['bundle_selections'])) { + return $this; } - - $preset = $bundleSelections['preset']; - $products = $bundleSelections['products']; - foreach ($preset['items'] as & $item) { - foreach ($item['assigned_products'] as $productIncrement => & $selection) { - if (!isset($products[$productIncrement])) { - throw new \InvalidArgumentException( - sprintf('Not sufficient number of products for bundle preset: %s', $preset['name']) - ); - } - /** @var $fixture CatalogProductSimple */ - $fixture = $products[$productIncrement]; - $selection['search_data']['name'] = $fixture->getName(); - $selection['data']['product_id']['value'] = $fixture->getId(); + $index = 0; + foreach ($fields['bundle_selections']['value']['bundle_options'] as $key => &$bundleOption) { + $this->_rootElement->find(sprintf($this->openOption, $index))->click(); + foreach ($bundleOption['assigned_products'] as &$product) { + $product['data']['getProductName'] = $product['search_data']['name']; } + $newFields['bundle_selections'][$key] = $this->getBundleOptionBlock($key) + ->getBundleOptionData($bundleOption); + $index++; } - return $preset['items']; + + return $newFields; } } diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option.php index 5aacc6f8d6f65bf14016c57848d81fab696b7926..cf1ae7edca2b8dc40706b995d05a70d3a7a21ec0 100644 --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option.php +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option.php @@ -24,19 +24,20 @@ namespace Magento\Bundle\Test\Block\Adminhtml\Catalog\Product\Edit\Tab\Bundle; -use Mtf\Block\Block; +use Mtf\Block\Form; use Mtf\Client\Element; -use Mtf\Factory\Factory; use Mtf\Client\Element\Locator; +use Magento\Bundle\Test\Block\Adminhtml\Catalog\Product\Edit\Tab\Bundle\Option\Selection; +use Magento\Bundle\Test\Block\Adminhtml\Catalog\Product\Edit\Tab\Bundle\Option\Search\Grid; /** * Class Option - * Bundle product options block + * Bundle option block on backend */ -class Option extends Block +class Option extends Form { /** - * Grid to assign products to bundle option + * Selector block Grid * * @var string */ @@ -47,22 +48,15 @@ class Option extends Block * * @var string */ - protected $selectionBlock = '#bundle_selection_row'; + protected $selectionBlock = './/tr[contains(@id, "bundle_selection_row_")][not(@style="display: none;")][%d]'; /** - * 'Add Products to Option' button + * Selector for 'Add Products to Option' button * * @var string */ protected $addProducts = '[data-ui-id$=add-selection-button]'; - /** - * Bundle option toggle - * - * @var string - */ - protected $optionToggle = '[data-target$=content]'; - /** * Bundle option title * @@ -71,105 +65,79 @@ class Option extends Block protected $title = '[name$="[title]"]'; /** - * Bundle option type + * Remove selection button selector * * @var string */ - protected $type = '[name$="[type]"]'; - - /** - * Determine whether bundle options is require to fill - * - * @var string - */ - protected $required = '#field-option-req'; + protected $removeSelection = 'button.delete'; /** * Get grid for assigning products for bundle option * - * @return \Magento\Bundle\Test\Block\Adminhtml\Catalog\Product\Edit\Tab\Bundle\Option\Search\Grid + * @return Grid */ protected function getSearchGridBlock() { - return Factory::getBlockFactory()->getMagentoBundleAdminhtmlCatalogProductEditTabBundleOptionSearchGrid( - $this->_rootElement->find($this->searchGridBlock, Locator::SELECTOR_XPATH) + return $this->blockFactory->create( + 'Magento\Bundle\Test\Block\Adminhtml\Catalog\Product\Edit\Tab\Bundle\Option\Search\Grid', + ['element' => $this->_rootElement->find($this->searchGridBlock, Locator::SELECTOR_XPATH)] ); } /** * Get product row assigned to bundle option * - * @param int $rowNumber - * @param Element $context - * @return \Magento\Bundle\Test\Block\Adminhtml\Catalog\Product\Edit\Tab\Bundle\Option\Selection + * @param int $rowIndex + * @return Selection */ - protected function getSelectionBlock($rowNumber, Element $context = null) + protected function getSelectionBlock($rowIndex) { - $element = $context !== null ? $context : $this->_rootElement; - return Factory::getBlockFactory()->getMagentoBundleAdminhtmlCatalogProductEditTabBundleOptionSelection( - $element->find($this->selectionBlock . '_' . $rowNumber) + return $this->blockFactory->create( + 'Magento\Bundle\Test\Block\Adminhtml\Catalog\Product\Edit\Tab\Bundle\Option\Selection', + ['element' => $this->_rootElement->find(sprintf($this->selectionBlock, $rowIndex), Locator::SELECTOR_XPATH)] ); } - /** - * Expand block - * - * @return void - */ - public function expand() - { - if (!$this->_rootElement->find($this->title)->isVisible()) { - $this->_rootElement->find($this->optionToggle)->click(); - } - } - /** * Fill bundle option * * @param array $fields - * @param Element $context * @return void * * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function fillBundleOption(array $fields, Element $context) + public function fillBundleOption(array $fields) { - $rowNumber = 0; - $this->fillOptionData($fields); - foreach ($fields['assigned_products'] as $field) { - if (is_array($field)) { - $this->_rootElement->find($this->addProducts)->click(); - $searchBlock = $this->getSearchGridBlock(); - $searchBlock->searchAndSelect($field['search_data']); - $searchBlock->addProducts(); - $this->getSelectionBlock($rowNumber)->fillProductRow($field['data']); - $rowNumber++; + $mapping = $this->dataMapping($fields); + $this->_fill($mapping); + $selections = $this->_rootElement->find($this->removeSelection)->getElements(); + if (count($selections)) { + foreach ($selections as $itemSelection) { + $itemSelection->click(); } } + foreach ($fields['assigned_products'] as $key => $field) { + $this->_rootElement->find($this->addProducts)->click(); + $searchBlock = $this->getSearchGridBlock(); + $searchBlock->searchAndSelect($field['search_data']); + $searchBlock->addProducts(); + $this->getSelectionBlock(++$key)->fillProductRow($field['data']); + } } /** - * Update bundle option (now only general data, skipping assignments) - * - * @param array $fields - * @return void - */ - public function updateBundleOption(array $fields) - { - $this->fillOptionData($fields); - } - - /** - * Fill in general data to bundle option + * Get data bundle option * * @param array $fields - * @return void + * @return array */ - private function fillOptionData(array $fields) + public function getBundleOptionData(array $fields) { - $this->_rootElement->find($this->title)->setValue($fields['title']); - $this->_rootElement->find($this->type, Locator::SELECTOR_CSS, 'select')->setValue($fields['type']); - $this->_rootElement->find($this->required, Locator::SELECTOR_CSS, 'checkbox') - ->setValue($fields['required']); + $mapping = $this->dataMapping($fields); + $newField = $this->_getData($mapping); + foreach ($fields['assigned_products'] as $key => $field) { + $newField['assigned_products'][$key] = $this->getSelectionBlock($key + 1)->getProductRow($field['data']); + } + return $newField; } } diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option.xml b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option.xml new file mode 100644 index 0000000000000000000000000000000000000000..b8610f0050198e422a86065c9ebde9645865d5ee --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option.xml @@ -0,0 +1,43 @@ +<?xml version="1.0" ?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<mapping strict="1"> + <fields> + <title> + <selector>[name$="[title]"]</selector> + <strategy>css selector</strategy> + </title> + <type> + <selector>[name$='[type]']</selector> + <strategy>css selector</strategy> + <input>select</input> + </type> + <required> + <selector>#field-option-req</selector> + <strategy>css selector</strategy> + <input>checkbox</input> + </required> + </fields> +</mapping> diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option/Search/Grid.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option/Search/Grid.php index 832a49e8d1ad93a97d266ef199df17f233551ce0..d0e2c1e280e950b1d107d60f94a9e755544b5b1f 100644 --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option/Search/Grid.php +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option/Search/Grid.php @@ -24,18 +24,16 @@ namespace Magento\Bundle\Test\Block\Adminhtml\Catalog\Product\Edit\Tab\Bundle\Option\Search; -use Mtf\Client\Element\Locator; use Magento\Backend\Test\Block\Widget\Grid as GridInterface; /** * Class Grid * 'Add Products to Bundle Option' grid - * */ class Grid extends GridInterface { /** - * 'Add Selected Products' button + * Selector for 'Add Selected Products' button * * @var string */ @@ -49,20 +47,23 @@ class Grid extends GridInterface protected $selectItem = 'tbody tr .col-id'; /** - * {@inheritdoc} + * Filters param for grid + * + * @var array */ - protected $filters = array( - 'name' => array( + protected $filters = [ + 'name' => [ 'selector' => 'input[name=name]' - ), - 'sku' => array( + ], + 'sku' => [ 'selector' => 'input[name=sku]' - ), - ); - + ], + ]; /** * Press 'Add Selected Products' button + * + * @return void */ public function addProducts() { diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option/Selection.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option/Selection.php index fff6f222d75d7e9bbf1200b60834825a891ba827..b7f919e508747967d97502d417068191b1c2433f 100644 --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option/Selection.php +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option/Selection.php @@ -24,63 +24,43 @@ namespace Magento\Bundle\Test\Block\Adminhtml\Catalog\Product\Edit\Tab\Bundle\Option; -use Mtf\Block\Block; -use Mtf\Client\Element; -use Mtf\Client\Element\Locator; +use Mtf\Block\Form; /** * Class Selection * Assigned product row to bundle option - * */ -class Selection extends Block +class Selection extends Form { /** - * Fields mapping + * Fill data to product row * - * @var array - */ - protected $mapping = array(); - - /** - * Initialize block elements + * @param array $fields + * @return void */ - protected function _init() + public function fillProductRow(array $fields) { - $this->mapping = [ - 'selection_price_value' => [ - 'selector' => "[name$='[selection_price_value]']", - 'type' => 'input', - - ], - 'selection_price_type' => [ - 'selector' => "[name$='[selection_price_type]']", - 'type' => 'select', - - ], - 'selection_qty' => [ - 'selector' => "[name$='[selection_qty]']", - 'type' => 'input', - - ], - ]; + unset($fields['product_id']); + $mapping = $this->dataMapping($fields); + $this->_fill($mapping); } /** - * Fill data to product row + * Get data item selection * * @param array $fields + * @return array */ - public function fillProductRow(array $fields) + public function getProductRow(array $fields) { - foreach ($fields as $key => $value) { - if (isset($this->mapping[$key])) { - $this->_rootElement->find( - $this->mapping[$key]['selector'], - Locator::SELECTOR_CSS, - $this->mapping[$key]['type'] - )->setValue($value); - } + $mapping = $this->dataMapping($fields); + $newFields = $this->_getData($mapping); + if (isset($mapping['getProductName'])) { + $newFields['getProductName'] = $this->_rootElement->find( + $mapping['getProductName']['selector'], + $mapping['getProductName']['strategy'] + )->getText(); } + return $newFields; } } diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option/Selection.xml b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option/Selection.xml new file mode 100644 index 0000000000000000000000000000000000000000..2c7ba5bbb41d5ced6c5036d9261e32d36bca9a9e --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option/Selection.xml @@ -0,0 +1,50 @@ +<?xml version="1.0" ?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<mapping strict="0"> + <fields> + <is_default> + <selector>[name$="[is_default]"]</selector> + <input>checkbox</input> + </is_default> + <selection_price_value> + <selector>[name$='[selection_price_value]']</selector> + </selection_price_value> + <selection_price_type> + <selector>[name$='[selection_price_type]']</selector> + <input>select</input> + </selection_price_type> + <selection_qty> + <selector>[name$='[selection_qty]']</selector> + </selection_qty> + <get_is_default> + <selector>[name$="[is_default]"]</selector> + <input>checkbox</input> + </get_is_default> + <getProductName> + <selector>td.col-name</selector> + </getProductName> + </fields> +</mapping> diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Product/ProductForm.xml b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Product/ProductForm.xml index 02ec36bd3bde19d9a0747dadb209ba950326471b..c1f5383c0d572fbea438b6e9d8ef0fb7de465841 100644 --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Product/ProductForm.xml +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Product/ProductForm.xml @@ -30,6 +30,9 @@ <strategy>css selector</strategy> <wrapper>product</wrapper> <fields> + <shipment_type> + <input>select</input> + </shipment_type> <sku_type> <input>select</input> </sku_type> @@ -39,9 +42,6 @@ <weight_type> <input>select</input> </weight_type> - <shipment_type> - <input>select</input> - </shipment_type> </fields> </product-details> <bundle> @@ -49,4 +49,15 @@ <selector>#product_info_tabs_product-details</selector> <strategy>css selector</strategy> </bundle> + <advanced-pricing> + <class>\Magento\Catalog\Test\Block\Adminhtml\Product\Edit\AdvancedPricingTab</class> + <selector>#product_info_tabs_advanced-pricing</selector> + <strategy>css selector</strategy> + <wrapper>product</wrapper> + <fields> + <price_view> + <input>select</input> + </price_view> + </fields> + </advanced-pricing> </tabs> diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/Select.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View.php similarity index 56% rename from dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/Select.php rename to dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View.php index cd69d77d78d620bb8b6f5a344170be26902c9a8e..be2d98aef7ddce09e033560e067fe3034ba8dd38 100644 --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/Select.php +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View.php @@ -22,33 +22,35 @@ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ -namespace Magento\Bundle\Test\Block\Catalog\Product\View\Type\Option; +namespace Magento\Bundle\Test\Block\Catalog\Product; -use Mtf\Block\Form; -use Mtf\Client\Element; use Mtf\Client\Element\Locator; +use Magento\Catalog\Test\Block\Product\View as ParentView; +use Magento\Bundle\Test\Block\Catalog\Product\View\Type\Bundle; /** - * Class Select - * Bundle option dropdown type - * + * Class View + * Bundle product view block on the product page */ -class Select extends Form +class View extends ParentView { /** - * Set data in bundle option + * Bundle options block * - * @param array $data + * @var string */ - public function fillOption(array $data) - { - $this->waitForElementVisible($this->mapping['value']['selector']); + protected $bundleBlock = '//*[@id="product-options-wrapper"]//fieldset[contains(@class,"bundle")]'; - $select = $this->_rootElement->find($this->mapping['value']['selector'], Locator::SELECTOR_CSS, 'select'); - $select->setValue($data['value']); - $qtyField = $this->_rootElement->find($this->mapping['qty']['selector']); - if (!$qtyField->isDisabled()) { //TODO should be remove after fix qty field - $qtyField->setValue($data['qty']); - } + /** + * Get bundle options block + * + * @return Bundle + */ + public function getBundleBlock() + { + return $this->blockFactory->create( + 'Magento\Bundle\Test\Block\Catalog\Product\View\Type\Bundle', + ['element' => $this->_rootElement->find($this->bundleBlock, Locator::SELECTOR_XPATH)] + ); } } diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Bundle.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Bundle.php index 11efcbd7f85114e2f71da9b1ed91519c10ffcb19..4e2ab8a141280a1007cc5a10a312137e7b86d89b 100644 --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Bundle.php +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Bundle.php @@ -24,16 +24,98 @@ namespace Magento\Bundle\Test\Block\Catalog\Product\View\Type; -use Mtf\Client\Element; -use Mtf\Factory\Factory; -use Magento\Catalog\Test\Block\Product\View\CustomOptions; +use Mtf\Block\Block; +use Mtf\Client\Element\Locator; +use Magento\Bundle\Test\Page\Product\CatalogProductView; +use Magento\Bundle\Test\Block\Catalog\Product\View\Type\Option; /** * Class Bundle * Catalog bundle product info block */ -class Bundle extends CustomOptions +class Bundle extends Block { + /** + * Bundle options block + * + * @var string + */ + protected $bundleBlock = './div[%d]'; + + /** + * Label item option + * + * @var string + */ + protected $requiredOptions = '[%s(contains(@class,"required"))]'; + + /** + * Label item option + * + * @var string + */ + protected $optionSelect = './/select/option[@value != ""][%d][contains(text(), "%s")]'; + + /** + * Label item option + * + * @var string + */ + protected $optionLabel = './/div[%d][contains(@class, "field")]//*[contains(text(), "%s")]'; + + /** + * Selector DropDown type + * + * @var string + */ + protected $typeDropDown = './/select[contains(@class,"bundle-option-select")]'; + + /** + * Selector Multiselect type + * + * @var string + */ + protected $typeMultiple = './/select[contains(@class,"multiselect")]'; + + /** + * Selector RadioButton type + * + * @var string + */ + protected $typeRadio = './/input[contains(@class,"radio")]'; + + /** + * Selector Checkbox type + * + * @var string + */ + protected $typeCheckbox = './/input[contains(@class,"checkbox")]'; + + /** + * Selector bundle option block for fill + * + * @var string + */ + protected $bundleOptionBlock = './/div[label[span[contains(text(), "%s")]]]'; + + /** + * Fill bundle option on frontend add click "Add to cart" button + * + * @param array $fillData + * @param CatalogProductView $catalogProductView + * @return void + */ + public function addToCart(array $fillData, CatalogProductView $catalogProductView) + { + $this->fillBundleOptions($fillData['bundle_options']); + if (isset($fillData['custom_options'])) { + foreach ($fillData['custom_options'] as $option) { + $catalogProductView->getCustomOptionsBlock()->fillCustomOptions($option); + } + } + $catalogProductView->getViewBlock()->clickAddToCart(); + } + /** * Fill bundle options * @@ -42,15 +124,74 @@ class Bundle extends CustomOptions */ public function fillBundleOptions($bundleOptions) { - $index = 1; foreach ($bundleOptions as $option) { - /** @var $optionBlock \Magento\Bundle\Test\Block\Catalog\Product\View\Type\Option\Radio| - * \Magento\Bundle\Test\Block\Catalog\Product\View\Type\Option\Select */ - $getClass = 'getMagentoBundleCatalogProductViewTypeOption' . ucfirst($option['type']); - $optionBlock = Factory::getBlockFactory()->$getClass( - $this->_rootElement->find('.field.option.required:nth-of-type(' . $index++ . ')') + $selector = sprintf($this->bundleOptionBlock, $option['title']); + /** @var Option $optionBlock */ + $optionBlock = $this->blockFactory->create( + 'Magento\Bundle\Test\Block\Catalog\Product\View\Type\Option\\' + . $this->optionNameConvert($option['type']), + ['element' => $this->_rootElement->find($selector, Locator::SELECTOR_XPATH)] ); - $optionBlock->fillOption($option); + $optionBlock->fillOption($option['value']); + } + } + + /** + * Get bundle item option + * + * @param array $fields + * @param int $index + * @return bool|string + * + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * @SuppressWarnings(PHPMD.NPathComplexity) + */ + public function displayedBundleItemOption(array $fields, $index) + { + $bundleOptionBlock = $this->_rootElement->find(sprintf($this->bundleBlock, $index), Locator::SELECTOR_XPATH); + $option = $bundleOptionBlock->find( + $this->{'type' . $this->optionNameConvert($fields['type'])}, + Locator::SELECTOR_XPATH + ); + if (!$option->isVisible()) { + return '"' . $fields['title'] . '" Option does not equal to fixture option type.'; + } + + $formatRequired = sprintf( + $this->bundleBlock . $this->requiredOptions, + $index, + (($fields['required'] == 'Yes') ? '' : 'not') + ); + if (!$this->_rootElement->find($formatRequired, Locator::SELECTOR_XPATH)->isVisible()) { + return "This Option must be " . ($fields['required'] == 'Yes') ? '' : 'not' . " required."; + } + + foreach ($fields['assigned_products'] as $increment => $item) { + $isMultiAssigned = count($fields['assigned_products']) > 1; + $isSelectType = $fields['type'] == 'Drop-down' || $fields['type'] == 'Multiple Select'; + $selectOptions = $isMultiAssigned && $isSelectType ? $this->optionSelect : $this->optionLabel; + $formatOption = sprintf($selectOptions, ++$increment, $item['name']); + if (!$bundleOptionBlock->find($formatOption, Locator::SELECTOR_XPATH)->isVisible()) { + return 'SelectOption ' . $item['name'] . ' with index ' + . $increment . ' data is not equals with fixture SelectOption data.'; + } + } + return true; + } + + /** + * Convert option name + * + * @param string $optionName + * @return string + */ + protected function optionNameConvert($optionName) + { + if ($end = strpos($optionName, ' ')) { + $optionName = substr($optionName, 0, $end); + } elseif ($end = strpos($optionName, '-')) { + $optionName = substr($optionName, 0, $end) . ucfirst(substr($optionName, ($end + 1))); } + return $optionName; } } diff --git a/app/code/Magento/Tax/Model/Sales/Total/Quote/Discount.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option.php similarity index 69% rename from app/code/Magento/Tax/Model/Sales/Total/Quote/Discount.php rename to dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option.php index 821cc0feb06df7dcdf4825b201efa2138127b94d..10fec3f02cb790ba3ac929e6d4820e5e92dd75f9 100644 --- a/app/code/Magento/Tax/Model/Sales/Total/Quote/Discount.php +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option.php @@ -18,25 +18,32 @@ * versions in the future. If you wish to customize Magento for your * needs please refer to http://www.magentocommerce.com for more information. * + * @category Mtf + * @package Mtf + * @subpackage functional_tests * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ +namespace Magento\Bundle\Test\Block\Catalog\Product\View\Type; + +use Mtf\Block\Form; + /** - * Tax discount totals calculation model + * Class Option + * Bundle option */ -namespace Magento\Tax\Model\Sales\Total\Quote; - -class Discount extends \Magento\Sales\Model\Quote\Address\Total\AbstractTotal +class Option extends Form { /** - * Calculate discount tac amount + * Set data in bundle option * - * @param \Magento\Sales\Model\Quote\Address $address - * @return \Magento\Tax\Model\Sales\Total\Quote\Address + * @param array $data + * @return void */ - public function collect(\Magento\Sales\Model\Quote\Address $address) + public function fillOption(array $data) { - // echo 'discount'; + $mapping = $this->dataMapping($data); + $this->_fill($mapping); } } diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/Checkbox.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/Checkbox.php new file mode 100644 index 0000000000000000000000000000000000000000..a1d16d225d19a1b461d9b98e8d39f2e2cee72efc --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/Checkbox.php @@ -0,0 +1,34 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Bundle\Test\Block\Catalog\Product\View\Type\Option; + +/** + * Class Checkbox + * Bundle option checkbox type + */ +class Checkbox extends Radio +{ + // Parent behavior +} diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/Checkbox.xml b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/Checkbox.xml new file mode 100644 index 0000000000000000000000000000000000000000..c42d667d526b959f7c7be4972e76de713b9a589b --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/Checkbox.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" ?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<mapping strict="0"> + <fields> + <name> + <selector>.//div[label[//span[contains(text(), "%product_name%")]]]/input</selector> + <strategy>xpath</strategy> + <input>checkbox</input> + </name> + </fields> +</mapping> diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Handler/Ui/CreateBundle.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/DropDown.php similarity index 78% rename from dev/tests/functional/tests/app/Magento/Bundle/Test/Handler/Ui/CreateBundle.php rename to dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/DropDown.php index 85e35b08acbceb93f52a0f9de1e9caac7b11b021..f49b2e934e6b032367a026fe265ecdeac1277399 100644 --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Handler/Ui/CreateBundle.php +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/DropDown.php @@ -18,22 +18,19 @@ * versions in the future. If you wish to customize Magento for your * needs please refer to http://www.magentocommerce.com for more information. * - * @spi * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ -namespace Magento\Bundle\Test\Handler\Ui; +namespace Magento\Bundle\Test\Block\Catalog\Product\View\Type\Option; -use Mtf\Fixture\FixtureInterface; -use Mtf\Factory\Factory; -use \Magento\Catalog\Test\Handler\Ui\CreateProduct; +use Magento\Bundle\Test\Block\Catalog\Product\View\Type\Option; /** - * Class CreateBundle - * Create a bundle product - * + * Class DropDown + * Bundle option drop-down type */ -class CreateBundle extends CreateProduct +class DropDown extends Option { + // Parent behavior } diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/DropDown.xml b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/DropDown.xml new file mode 100644 index 0000000000000000000000000000000000000000..55fa034b2d8f7bfaffbdbd49900a5fe5c29cd7c7 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/DropDown.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" ?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<mapping strict="0"> + <fields> + <name> + <selector>select</selector> + <input>select</input> + </name> + <qty> + <selector>//input[@class = "qty"]</selector> + <strategy>xpath</strategy> + </qty> + </fields> +</mapping> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab/OptionField.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/Multiple.php similarity index 77% rename from dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab/OptionField.php rename to dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/Multiple.php index a23bb8728c6225472c89222879228fedcf1a73ea..c38f846d8e8c646c38e570a95cf2541f6a4cec2e 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab/OptionField.php +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/Multiple.php @@ -22,16 +22,15 @@ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ -namespace Magento\Catalog\Test\Block\Adminhtml\Product\Edit\CustomOptionsTab; +namespace Magento\Bundle\Test\Block\Catalog\Product\View\Type\Option; -use Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Options; +use Magento\Bundle\Test\Block\Catalog\Product\View\Type\Option; /** - * Class OptionField - * - * @package Magento\Catalog\Test\Block\Adminhtml\Product\Edit\CustomOptionsTab + * Class Multiple + * Bundle option Multiple type */ -class OptionField extends Options +class Multiple extends Option { // Parent behavior } diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/Select.xml b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/Multiple.xml similarity index 90% rename from dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/Select.xml rename to dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/Multiple.xml index cec08d7435696dabd950f3a69cd08fe2e7055809..53dd5f87a19bdbcbcae2ae832dea90ec09a2d3d5 100644 --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/Select.xml +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/Multiple.xml @@ -25,11 +25,9 @@ --> <mapping strict="0"> <fields> - <value> + <name> <selector>select</selector> - </value> - <qty> - <selector>input.qty</selector> - </qty> + <input>multiselect</input> + </name> </fields> </mapping> diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/Radio.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/Radio.php index 463a30caab0f16683e5aff2cbbe89137ecc6e5a1..6c44e031be0cae799a706602ba85320d76c295fb 100644 --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/Radio.php +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/Radio.php @@ -24,25 +24,25 @@ namespace Magento\Bundle\Test\Block\Catalog\Product\View\Type\Option; -use Mtf\Block\Form; -use Mtf\Client\Element; -use Mtf\Client\Element\Locator; +use Magento\Bundle\Test\Block\Catalog\Product\View\Type\Option; /** * Class Radio - * Bundle option radiobutton type - * + * Bundle option radio button type */ -class Radio extends Form +class Radio extends Option { /** * Set data in bundle option * * @param array $data + * @return void */ public function fillOption(array $data) { - $this->_rootElement->find('//*[contains(text(), ' . $data['value'] . ')]', Locator::SELECTOR_XPATH)->click(); - $this->_rootElement->find($this->mapping['qty']['selector'])->setValue($data['qty']); + $mapping = $this->dataMapping($data); + $mapping['name']['selector'] = str_replace('%product_name%', $data['name'], $mapping['name']['selector']); + $mapping['name']['value'] = 'Yes'; + $this->_fill($mapping); } } diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/Radio.xml b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/Radio.xml index f32831a6f725f1ae882dd1943bf7f256e7c9f769..d79a54b300f647a5c831ca635c9554c84a165755 100644 --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/Radio.xml +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/Radio.xml @@ -25,8 +25,14 @@ --> <mapping strict="0"> <fields> + <name> + <selector>//div[label[//span[contains(text(), "%product_name%")]]]/input</selector> + <strategy>xpath</strategy> + <input>checkbox</input> + </name> <qty> - <selector>.qty-holder input</selector> + <selector>//input[@class = "qty"]</selector> + <strategy>xpath</strategy> </qty> </fields> </mapping> diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertBundleInCategory.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertBundleInCategory.php new file mode 100644 index 0000000000000000000000000000000000000000..c12d06ca0a0f66739612e4aa1aec5561f9e67306 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertBundleInCategory.php @@ -0,0 +1,108 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Bundle\Test\Constraint; + +use Magento\Cms\Test\Page\CmsIndex; +use Mtf\Constraint\AbstractConstraint; +use Magento\Bundle\Test\Fixture\CatalogProductBundle; +use Magento\Catalog\Test\Fixture\CatalogCategory; +use Magento\Catalog\Test\Page\Category\CatalogCategoryView; + +/** + * Class AssertProductInCategory + */ +class AssertBundleInCategory extends AbstractConstraint +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Check bundle product on the category page + * + * @param CatalogCategoryView $catalogCategoryView + * @param CmsIndex $cmsIndex + * @param CatalogProductBundle $product + * @param CatalogCategory $category + * @return void + */ + public function processAssert( + CatalogCategoryView $catalogCategoryView, + CmsIndex $cmsIndex, + CatalogProductBundle $product, + CatalogCategory $category + ) { + //Open category view page + $cmsIndex->open(); + $cmsIndex->getTopmenu()->selectCategoryByName($category->getName()); + + //Process asserts + $this->assertPrice($product, $catalogCategoryView); + } + + /** + * Verify product price on category view page + * + * @param CatalogProductBundle $bundle + * @param CatalogCategoryView $catalogCategoryView + * @return void + */ + protected function assertPrice(CatalogProductBundle $bundle, CatalogCategoryView $catalogCategoryView) + { + $priceData = $bundle->getDataFieldConfig('price')['source']->getPreset(); + //Price from/to verification + $priceBlock = $catalogCategoryView->getListProductBlock()->getProductPriceBlock($bundle->getName()); + + $priceLow = ($bundle->getPriceView() == 'Price Range') + ? $priceBlock->getPriceFrom() + : $priceBlock->getRegularPrice(); + + \PHPUnit_Framework_Assert::assertEquals( + $priceData['price_from'], + $priceLow, + 'Bundle price From on category page is not correct.' + ); + if ($bundle->getPriceView() == 'Price Range') { + \PHPUnit_Framework_Assert::assertEquals( + $priceData['price_to'], + $priceBlock->getPriceTo(), + 'Bundle price To on category page is not correct.' + ); + } + } + + /** + * Text of Visible in category assert + * + * @return string + */ + public function toString() + { + return 'Bundle price on category page is not correct.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertBundleItemsOnProductPage.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertBundleItemsOnProductPage.php new file mode 100644 index 0000000000000000000000000000000000000000..ec58d09f4e03f1424abb27d2492734af5295c9d1 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertBundleItemsOnProductPage.php @@ -0,0 +1,100 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Bundle\Test\Constraint; + +use Mtf\Constraint\AbstractConstraint; +use Magento\Bundle\Test\Fixture\CatalogProductBundle; +use Magento\Bundle\Test\Page\Product\CatalogProductView; + +/** + * Class AssertBundleItemsOnProductPage + */ +class AssertBundleItemsOnProductPage extends AbstractConstraint +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Assert that displayed product bundle items data on product page equals passed from fixture preset + * + * @param CatalogProductView $catalogProductView + * @param CatalogProductBundle $product + * @return void + */ + public function processAssert(CatalogProductView $catalogProductView, CatalogProductBundle $product) + { + $catalogProductView->init($product); + $catalogProductView->open(); + $catalogProductView->getViewBlock()->clickCustomize(); + $result = $this->displayedBundleBlock($catalogProductView, $product); + \PHPUnit_Framework_Assert::assertTrue(empty($result), $result); + } + + /** + * Displayed bundle block on frontend with correct fixture product + * + * @param CatalogProductView $catalogProductView + * @param CatalogProductBundle $product + * @return string|null + */ + protected function displayedBundleBlock(CatalogProductView $catalogProductView, CatalogProductBundle $product) + { + $fields = $product->getData(); + $bundleOptions = $fields['bundle_selections']['bundle_options']; + if (!isset($bundleOptions)) { + return 'Bundle options data on product page is not equals to fixture preset.'; + } + + $catalogProductView->getViewBlock()->clickCustomize(); + foreach ($bundleOptions as $index => $item) { + foreach ($item['assigned_products'] as &$selection) { + $selection = $selection['search_data']; + } + $result = $catalogProductView->getBundleViewBlock()->getBundleBlock()->displayedBundleItemOption( + $item, + ++$index + ); + + if ($result !== true) { + return $result; + } + } + return null; + } + + /** + * Return Text if displayed on frontend equals with fixture + * + * @return string + */ + public function toString() + { + return 'Bundle options data on product page equals to passed from fixture preset.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertBundlePriceType.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertBundlePriceType.php new file mode 100644 index 0000000000000000000000000000000000000000..c05c517b04ec7e8cfc171bd391baf11db886af96 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertBundlePriceType.php @@ -0,0 +1,157 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Bundle\Test\Constraint; + +use Mtf\Constraint\AbstractConstraint; +use Magento\Checkout\Test\Page\CheckoutCart; +use Magento\Bundle\Test\Fixture\CatalogProductBundle; +use Magento\Bundle\Test\Page\Product\CatalogProductView; + +/** + * Class AssertBundlePriceType + */ +class AssertBundlePriceType extends AbstractConstraint +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Product price type + * + * @var string + */ + protected $productPriceType = 'Dynamic'; + + /** + * Assert that displayed price for bundle items on shopping cart page equals to passed from fixture. + * Price for bundle items has two options: + * 1. Fixed (price of bundle product) + * 2. Dynamic (price of bundle item) + * + * @param CatalogProductView $catalogProductView + * @param CatalogProductBundle $product + * @param CheckoutCart $checkoutCartView + * @param CatalogProductBundle $originalProduct [optional] + * @return void + */ + public function processAssert( + CatalogProductView $catalogProductView, + CatalogProductBundle $product, + CheckoutCart $checkoutCartView, + CatalogProductBundle $originalProduct = null + ) { + $checkoutCartView->open()->getCartBlock()->clearShoppingCart(); + //Open product view page + $catalogProductView->init($product); + $catalogProductView->open(); + + //Process assertions + $this->assertPrice($product, $catalogProductView, $checkoutCartView, $originalProduct); + } + + /** + * Assert prices on the product view page and shopping cart page. + * + * @param CatalogProductBundle $product + * @param CatalogProductView $catalogProductView + * @param CheckoutCart $checkoutCartView + * @param CatalogProductBundle $originalProduct [optional] + * @return void + * + * @SuppressWarnings(PHPMD.NPathComplexity) + */ + protected function assertPrice( + CatalogProductBundle $product, + CatalogProductView $catalogProductView, + CheckoutCart $checkoutCartView, + CatalogProductBundle $originalProduct = null + ) { + $customerGroup = 'NOT LOGGED IN'; + $catalogProductView->getViewBlock()->clickCustomize(); + $bundleData = $product->getData(); + $this->productPriceType = $originalProduct !== null + ? $originalProduct->getPriceType() + : $product->getPriceType(); + $fillData = $product->getDataFieldConfig('checkout_data')['source']->getPreset(); + $bundleBlock = $catalogProductView->getBundleViewBlock()->getBundleBlock(); + $bundleBlock->addToCart($fillData, $catalogProductView); + $cartBlock = $checkoutCartView->getCartBlock(); + $specialPrice = 0; + if (isset($bundleData['group_price'])) { + $specialPrice = + $bundleData['group_price'][array_search($customerGroup, $bundleData['group_price'])]['price'] / 100; + } + + $optionPrice = []; + foreach ($fillData['bundle_options'] as $key => $data) { + $subProductPrice = 0; + foreach ($bundleData['bundle_selections']['products'][$key] as $productKey => $itemProduct) { + if (strpos($itemProduct->getName(), $data['value']['name']) !== false) { + $data['value']['key'] = $productKey; + $subProductPrice = $itemProduct->getPrice(); + } + } + + $optionPrice[$key]['price'] = $this->productPriceType == 'Fixed' + ? number_format( + $bundleData['bundle_selections']['bundle_options'][$key]['assigned_products'][$data['value']['key']] + ['data']['selection_price_value'], + 2 + ) + : number_format($subProductPrice, 2); + } + + foreach ($optionPrice as $index => $item) { + $item['price'] -= $item['price'] * $specialPrice; + \PHPUnit_Framework_Assert::assertEquals( + number_format($item['price'], 2), + $cartBlock->getPriceBundleOptions($index + 1), + 'Bundle item ' . ($index + 1) . ' options on frontend don\'t equal to fixture.' + ); + } + $sumOptionsPrice = $product->getDataFieldConfig('price')['source']->getPreset()['cart_price']; + + $subTotal = number_format($cartBlock->getCartItemUnitPrice($product), 2); + \PHPUnit_Framework_Assert::assertEquals( + $sumOptionsPrice, + $subTotal, + 'Bundle unit price on frontend doesn\'t equal to fixture.' + ); + } + + /** + * Returns a string representation of the object + * + * @return string + */ + public function toString() + { + return 'Bundle price on shopping cart page is not correct.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertBundlePriceView.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertBundlePriceView.php new file mode 100644 index 0000000000000000000000000000000000000000..7837398d77fc58a1ba0735dfcdb141e0329ff55f --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertBundlePriceView.php @@ -0,0 +1,102 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Bundle\Test\Constraint; + +use Mtf\Constraint\AbstractConstraint; +use Magento\Bundle\Test\Page\Product\CatalogProductView; +use Magento\Bundle\Test\Fixture\CatalogProductBundle; + +/** + * Class AssertBundlePriceView + */ +class AssertBundlePriceView extends AbstractConstraint +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Assert that displayed price view for bundle product on product page equals passed from fixture. + * + * @param CatalogProductView $catalogProductView + * @param CatalogProductBundle $product + * @return void + */ + public function processAssert( + CatalogProductView $catalogProductView, + CatalogProductBundle $product + ) { + //Open product view page + $catalogProductView->init($product); + $catalogProductView->open(); + + //Process assertions + $this->assertPrice($product, $catalogProductView); + } + + /** + * Assert prices on the product view Page + * + * @param CatalogProductBundle $product + * @param CatalogProductView $catalogProductView + * @return void + */ + protected function assertPrice(CatalogProductBundle $product, CatalogProductView $catalogProductView) + { + $priceData = $product->getDataFieldConfig('price')['source']->getPreset(); + $priceBlock = $catalogProductView->getViewBlock()->getProductPriceBlock(); + + $priceLow = ($product->getPriceView() == 'Price Range') + ? $priceBlock->getPriceFrom() + : $priceBlock->getRegularPrice(); + + \PHPUnit_Framework_Assert::assertEquals( + $priceData['price_from'], + $priceLow, + 'Bundle price From on product view page is not correct.' + ); + + if ($product->getPriceView() == 'Price Range') { + \PHPUnit_Framework_Assert::assertEquals( + $priceData['price_to'], + $priceBlock->getPriceTo(), + 'Bundle price To on product view page is not correct.' + ); + } + } + + /** + * Returns a string representation of the object + * + * @return string + */ + public function toString() + { + return 'Bundle price on product view page is not correct.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertBundleProductForm.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertBundleProductForm.php new file mode 100755 index 0000000000000000000000000000000000000000..4eff17432fefa6e3125dbd21682f1937fde8d842 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertBundleProductForm.php @@ -0,0 +1,133 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Bundle\Test\Constraint; + +use Mtf\Fixture\FixtureInterface; +use Magento\Catalog\Test\Constraint\AssertProductForm; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductEdit; + +/** + * Class AssertBundleProductForm + */ +class AssertBundleProductForm extends AssertProductForm +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Formatting options for array values + * + * @var array + */ + protected $specialArray = [ + 'special_from_date' => [ + 'type' => 'date' + ], + 'special_to_date' => [ + 'type' => 'date' + ] + ]; + + /** + * Assert form data equals fixture data + * + * @param FixtureInterface $product + * @param CatalogProductIndex $productGrid + * @param CatalogProductEdit $productPage + * @return void + */ + public function processAssert( + FixtureInterface $product, + CatalogProductIndex $productGrid, + CatalogProductEdit $productPage + ) { + $filter = ['sku' => $product->getSku()]; + $productGrid->open(); + $productGrid->getProductGrid()->searchAndOpen($filter); + + $formData = $productPage->getForm()->getData($product); + $fixtureData = $this->prepareFixtureData($product->getData()); + $errors = $this->verifyData($fixtureData, $formData); + \PHPUnit_Framework_Assert::assertEmpty($errors, $errors); + } + + /** + * Prepares fixture data for comparison + * + * @param array $data + * @param array $sortFields [optional] + * @return array + */ + protected function prepareFixtureData(array $data, array $sortFields = []) + { + $data = $this->prepareSpecialPriceArray($data); + $data['bundle_selections'] = $this->prepareBundleOptions( + $data['bundle_selections']['bundle_options'] + ); + + return parent::prepareFixtureData($data, $sortFields); + } + + /** + * Prepare special price array for Bundle product + * + * @param array $fields + * @return array + */ + protected function prepareSpecialPriceArray(array $fields) + { + foreach ($this->specialArray as $key => $value) { + if (array_key_exists($key, $fields)) { + if (isset($value['type']) && $value['type'] == 'date') { + $fields[$key] = vsprintf('%d/%d/%d', explode('/', $fields[$key])); + } + } + } + return $fields; + } + + /** + * Prepare Bundle Options array from preset + * + * @param array $bundleSelections + * @return array + */ + protected function prepareBundleOptions(array $bundleSelections) + { + foreach ($bundleSelections as &$item) { + foreach ($item['assigned_products'] as &$selection) { + $selection['data']['getProductName'] = $selection['search_data']['name']; + $selection = $selection['data']; + } + } + + return $bundleSelections; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertBundleProductPage.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertBundleProductPage.php new file mode 100644 index 0000000000000000000000000000000000000000..874df95f117b3b8d1cce4699d1b93c8796d642cf --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertBundleProductPage.php @@ -0,0 +1,90 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Bundle\Test\Constraint; + +use Magento\Catalog\Test\Constraint\AssertProductPage; + +/** + * Class AssertBundleProductPage + */ +class AssertBundleProductPage extends AssertProductPage +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Error messages + * + * @var array + */ + protected $errorsMessages = [ + 'name' => '- product name on product view page is not correct.', + 'sku' => '- product sku on product view page is not correct.', + 'price_from' => '- bundle product price from on product view page is not correct.', + 'price_to' => '- bundle product price to on product view page is not correct.', + 'short_description' => '- product short description on product view page is not correct.', + 'description' => '- product description on product view page is not correct.' + ]; + + /** + * Prepare Price data + * + * @param array $price + * @return array + */ + protected function preparePrice($price) + { + $priceData = $this->product->getDataFieldConfig('price')['source']->getPreset(); + $priceView = $this->product->getPriceView(); + if ($priceView === null || $priceView == 'Price Range') { + if (isset($price['price_from']) && isset($price['price_to'])) { + return [ + ['price_from' => $price['price_from'], 'price_to' => $price['price_to']], + [ + 'price_from' => number_format($priceData['price_from'], 2), + 'price_to' => number_format($priceData['price_to'], 2) + ] + ]; + } + return [ + ['price_regular_price' => $price['price_regular_price']], + ['price_regular_price' => number_format($priceData['price_from'], 2)] + ]; + } else { + return [ + ['price_from' => $price['price_regular_price']], + [ + 'price_from' => is_numeric($priceData['price_from']) + ? number_format($priceData['price_from'], 2) + : $priceData['price_from'] + ] + ]; + } + } +} diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertGroupedPriceOnBundleProductPage.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertGroupedPriceOnBundleProductPage.php new file mode 100644 index 0000000000000000000000000000000000000000..1b2369329c2b5eb46ac8d8edf80a89d15cf5b05d --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertGroupedPriceOnBundleProductPage.php @@ -0,0 +1,53 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Bundle\Test\Constraint; + +use Mtf\Fixture\FixtureInterface; +use Magento\Catalog\Test\Block\Product\View; +use Magento\Catalog\Test\Constraint\AssertProductGroupedPriceOnProductPage; + +/** + * Class AssertGroupedPriceOnBundleProductPage + */ +class AssertGroupedPriceOnBundleProductPage extends AssertProductGroupedPriceOnProductPage +{ + /** + * Get grouped price with fixture product and product page + * + * @param View $view + * @param FixtureInterface $product + * @return array + */ + protected function getGroupedPrice(View $view, FixtureInterface $product) + { + $groupPrice['onPage'] = $view->getProductPrice(); + $groupPrice['onPage'] = isset($groupPrice['onPage']['price_regular_price']) + ? str_replace('As low as $', '', $groupPrice['onPage']['price_regular_price']) + : str_replace('$', '', $groupPrice['onPage']['price_from']); + $groupPrice['fixture'] = $product->getDataFieldConfig('price')['source']->getPreset()['price_from']; + + return $groupPrice; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertTierPriceOnBundleProductPage.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertTierPriceOnBundleProductPage.php new file mode 100644 index 0000000000000000000000000000000000000000..2c83ca887ef77e74bcd1816352754d741c5076ee --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertTierPriceOnBundleProductPage.php @@ -0,0 +1,75 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Bundle\Test\Constraint; + +use Mtf\Fixture\FixtureInterface; +use Magento\Catalog\Test\Page\Product\CatalogProductView; +use Magento\Catalog\Test\Constraint\AssertProductTierPriceOnProductPage; + +/** + * Class AssertTierPriceOnBundleProductPage + */ +class AssertTierPriceOnBundleProductPage extends AssertProductTierPriceOnProductPage +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Tier price block + * + * @var string + */ + protected $tierBlock = '.prices.tier.items'; + + /** + * Decimals for price format + * + * @var int + */ + protected $priceFormat = 4; + + /** + * Assertion that tier prices are displayed correctly + * + * @param CatalogProductView $catalogProductView + * @param FixtureInterface $product + * @return void + */ + public function processAssert(CatalogProductView $catalogProductView, FixtureInterface $product) + { + //Open product view page + $catalogProductView->init($product); + $catalogProductView->open(); + $viewBlock = $catalogProductView->getViewBlock(); + $viewBlock->clickCustomize(); + + //Process assertions + $this->assertPrice($product, $catalogProductView); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/Bundle.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/Bundle.php index c2633656f9f80249a60a691f378437aa83a043ba..a6f6acd904439dd74e6018c326d3c52e7e92aabd 100644 --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/Bundle.php +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/Bundle.php @@ -114,18 +114,16 @@ class Bundle extends Product */ public function getSelectionData() { - $typeMapping = [ - 'Drop-down' => 'select' - ]; $options = $this->getData('checkout/selection'); $selectionData = []; foreach ($options as $option => $selection) { $fieldPrefix = 'fields/bundle_selections/value/bundle_options/'; - $selectionItem['type'] = $typeMapping[$this->getData($fieldPrefix . $option . '/type')]; - $selectionItem['qty'] = $this->getData( + $selectionItem['type'] = $this->getData($fieldPrefix . $option . '/type'); + $selectionItem['title'] = $this->getData($fieldPrefix . $option . '/title'); + $selectionItem['value']['qty'] = $this->getData( $fieldPrefix . $option . '/assigned_products/' . $selection . '/data/selection_qty' ); - $selectionItem['value'] = $this->getData( + $selectionItem['value']['name'] = $this->getData( $fieldPrefix . $option . '/assigned_products/' . $selection . '/search_data/name' ); $selectionData[] = $selectionItem; diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/BundleDynamic.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/BundleDynamic.php index 9e05a48b88dd6334f898ff9959e821f9d0204f85..f66686255f80f46f01f457e9852da4e81362a1e9 100644 --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/BundleDynamic.php +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/BundleDynamic.php @@ -28,6 +28,7 @@ use Mtf\Factory\Factory; /** * Class BundleDynamic + * Fixture for Bundle dynamic */ class BundleDynamic extends Bundle { @@ -36,83 +37,81 @@ class BundleDynamic extends Bundle */ protected function _initData() { - $this->_data['checkout'] = array( - 'prices' => array( + $this->_data['checkout'] = [ + 'prices' => [ 'price_from' => 10, 'price_to' => 15 - ), - 'selection' => array( - 'bundle_item_0' => 'assigned_product_0' - ) - ); + ], + 'selection' => [0] + ]; parent::_initData(); $this->_data['fields'] = array_merge_recursive( $this->_data['fields'], - array( - 'sku_type' => array( + [ + 'sku_type' => [ 'value' => 'Dynamic', 'input_value' => '0', 'group' => static::GROUP_PRODUCT_DETAILS, 'input' => 'select' - ), - 'price_type' => array( + ], + 'price_type' => [ 'value' => 'Dynamic', 'input_value' => '0', 'group' => static::GROUP_PRODUCT_DETAILS, 'input' => 'select' - ), - 'weight_type' => array( + ], + 'weight_type' => [ 'value' => 'Dynamic', 'input_value' => '0', 'group' => static::GROUP_PRODUCT_DETAILS, 'input' => 'select' - ), - 'product_website_1' => array( + ], + 'product_website_1' => [ 'value' => 'Yes', - 'input_value' => array(1), + 'input_value' => [1], 'group' => static::GROUP_PRODUCT_WEBSITE, 'input' => 'checkbox', 'input_name' => 'website_ids' - ), - 'shipment_type' => array( + ], + 'shipment_type' => [ 'value' => 'Separately', 'input_value' => '1', 'group' => static::GROUP_PRODUCT_DETAILS, 'input' => 'select' - ), - 'bundle_selections' => array( - 'value' => array( - 'bundle_options' => array( - 'bundle_item_0' => array( + ], + 'bundle_selections' => [ + 'value' => [ + 'bundle_options' => [ + [ 'title' => 'Drop-down Option', 'type' => 'Drop-down', 'required' => 'Yes', - 'assigned_products' => array( - 'assigned_product_0' => array( - 'search_data' => array( + 'assigned_products' => [ + [ + 'search_data' => [ 'name' => '%item1_simple1::getName%', - ), - 'data' => array( + ], + 'data' => [ 'selection_qty' => 1, 'product_id' => '%item1_simple1::getProductId%' - ) - ), - 'assigned_product_1' => array( - 'search_data' => array( + ] + ], + [ + 'search_data' => [ 'name' => '%item1_virtual2::getName%', - ), - 'data' => array( + ], + 'data' => [ 'selection_qty' => 1, 'product_id' => '%item1_virtual2::getProductId%' - ) - ) - ) - ) - ) - ), + ] + ] + ] + ] + ] + ], 'group' => static::GROUP - ) - ) + ] + ] ); $this->_repository = Factory::getRepositoryFactory() ->getMagentoBundleBundle($this->_dataConfig, $this->_data); diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/BundleFixed.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/BundleFixed.php index 7ec001adb6b9f1efca08d23a3e0d93462e79e96c..395ae740ead8da6b14aeb3b8628c705d632ece9c 100644 --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/BundleFixed.php +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/BundleFixed.php @@ -28,6 +28,7 @@ use Mtf\Factory\Factory; /** * Class BundleFixed + * Fixture for Bundle fixed */ class BundleFixed extends Bundle { @@ -38,101 +39,99 @@ class BundleFixed extends Bundle */ protected function _initData() { - $this->_data['checkout'] = array( - 'prices' => array( + $this->_data['checkout'] = [ + 'prices' => [ 'price_from' => 110, 'price_to' => 120 - ), - 'selection' => array( - 'bundle_item_0' => 'assigned_product_0' - ) - ); + ], + 'selection' => [0] + ]; parent::_initData(); $this->_data['fields'] = array_merge_recursive( $this->_data['fields'], - array( - 'sku_type' => array( + [ + 'sku_type' => [ 'value' => 'Fixed', 'input_value' => '1', 'group' => static::GROUP_PRODUCT_DETAILS, 'input' => 'select' - ), - 'price_type' => array( + ], + 'price_type' => [ 'value' => 'Fixed', 'input_value' => '1', 'group' => static::GROUP_PRODUCT_DETAILS, 'input' => 'select' - ), - 'price' => array( + ], + 'price' => [ 'value' => 100, 'group' => static::GROUP_PRODUCT_DETAILS - ), - 'tax_class_id' => array( + ], + 'tax_class_id' => [ 'value' => 'Taxable Goods', 'input_value' => '2', 'group' => static::GROUP_PRODUCT_DETAILS, 'input' => 'select' - ), - 'weight_type' => array( + ], + 'weight_type' => [ 'value' => 'Fixed', 'input_value' => '1', 'group' => static::GROUP_PRODUCT_DETAILS, 'input' => 'select' - ), - 'weight' => array( + ], + 'weight' => [ 'value' => '1', 'group' => static::GROUP_PRODUCT_DETAILS - ), - 'product_website_1' => array( + ], + 'product_website_1' => [ 'value' => 'Yes', - 'input_value' => array(1), + 'input_value' => [1], 'group' => static::GROUP_PRODUCT_WEBSITE, 'input' => 'checkbox', 'input_name' => 'website_ids' - ), - 'shipment_type' => array( + ], + 'shipment_type' => [ 'value' => 'Separately', 'input_value' => '1', 'group' => static::GROUP_PRODUCT_DETAILS, 'input' => 'select' - ), - 'bundle_selections' => array( - 'value' => array( - 'bundle_options' => array( - 'bundle_item_0' => array( + ], + 'bundle_selections' => [ + 'value' => [ + 'bundle_options' => [ + [ 'title' => 'Drop-down Option', 'type' => 'Drop-down', 'required' => 'Yes', - 'assigned_products' => array( - 'assigned_product_0' => array( - 'search_data' => array( + 'assigned_products' => [ + [ + 'search_data' => [ 'name' => '%item1_simple1::getName%', - ), - 'data' => array( + ], + 'data' => [ 'selection_price_value' => 10, 'selection_price_type' => 'Fixed', 'selection_qty' => 1, 'product_id' => '%item1_simple1::getProductId%' - ) - ), - 'assigned_product_1' => array( - 'search_data' => array( + ] + ], + [ + 'search_data' => [ 'name' => '%item1_virtual2::getName%', - ), - 'data' => array( + ], + 'data' => [ 'selection_price_value' => 20, 'selection_price_type' => 'Percent', 'selection_qty' => 1, 'product_id' => '%item1_virtual2::getProductId%' - ) - ) - ) - ) - ) - ), + ] + ] + ] + ] + ] + ], 'group' => static::GROUP - ) - ) + ] + ] ); $this->_repository = Factory::getRepositoryFactory() ->getMagentoBundleBundle($this->_dataConfig, $this->_data); diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/CatalogProductBundle.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/CatalogProductBundle.php index bf03465b8c63fe7da2414982572ac0d779538907..2b1819dab070cea1788a9332845fd5e07b056227 100644 --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/CatalogProductBundle.php +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/CatalogProductBundle.php @@ -36,7 +36,7 @@ use Mtf\System\Event\EventManagerInterface; * Fixture for Bundle product * * @SuppressWarnings(PHPMD.ExcessivePublicCount) - * @SuppressWarnings(PHPMD.TooManyFields) + * @SuppressWarnings(PHPMD.TooManyFields) */ class CatalogProductBundle extends InjectableFixture { @@ -109,6 +109,7 @@ class CatalogProductBundle extends InjectableFixture 'is_required' => '0', 'default_value' => '', 'input' => 'text', + 'group' => 'product-details', 'source' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\CategoryIds', ]; @@ -616,6 +617,13 @@ class CatalogProductBundle extends InjectableFixture 'source' => 'Magento\Bundle\Test\Fixture\CatalogProductBundle\BundleSelections', ]; + protected $checkout_data = [ + 'attribute_code' => 'checkout_data', + 'backend_type' => 'virtual', + 'is_required' => '1', + 'source' => 'Magento\Bundle\Test\Fixture\CatalogProductBundle\CheckoutData', + ]; + protected $custom_options = [ 'attribute_code' => 'custom_options', 'backend_type' => 'virtual', @@ -633,15 +641,20 @@ class CatalogProductBundle extends InjectableFixture ]; protected $stock_data = [ - 'attribute_code' => 'stock_data' + 'attribute_code' => 'stock_data', + 'group' => 'advanced-inventory' ]; protected $category_id = [ - 'attribute_code' => 'category_id' + 'attribute_code' => 'category_id', + 'group' => 'product-details' ]; protected $website_ids = [ - 'attribute_code' => 'website_ids' + 'attribute_code' => 'website_ids', + 'backend_type' => 'virtual', + 'default_value' => ['Main Website'], + 'group' => 'websites', ]; public function getCategoryIds() diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/CatalogProductBundle.xml b/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/CatalogProductBundle.xml index 21874f301c9e4fd06e7e01a5dda024559cb1cd0b..3400eb8faf2c9a78da9db8483bc7801665d18972 100644 --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/CatalogProductBundle.xml +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/CatalogProductBundle.xml @@ -429,7 +429,7 @@ <backend_type>virtual</backend_type> <is_required>1</is_required> <group>bundle</group> - <source>Magento\Bundle\Test\Fixture\CatalogProductBundle\BundleSelections</source> + <fixture>Magento\Bundle\Test\Fixture\Bundle\BundleSelections</fixture> </bundle_selections> <custom_options> <attribute_code>custom_options</attribute_code> diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/CatalogProductBundle/BundleSelections.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/CatalogProductBundle/BundleSelections.php index d0bb920f995d63aab6d1274acd55084a231a6467..3a48675641374a0869570e5f34211c9790e37296 100644 --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/CatalogProductBundle/BundleSelections.php +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/CatalogProductBundle/BundleSelections.php @@ -26,11 +26,10 @@ namespace Magento\Bundle\Test\Fixture\CatalogProductBundle; use Mtf\Fixture\FixtureFactory; use Mtf\Fixture\FixtureInterface; -use Mtf\Fixture\InjectableFixture; /** * Class BundleSelections - * "Selections" for the bundle product + * Bundle selections preset */ class BundleSelections implements FixtureInterface { @@ -56,12 +55,12 @@ class BundleSelections implements FixtureInterface protected $currentPreset; /** - * "Selections" source constructor + * Constructor * + * @constructor * @param FixtureFactory $fixtureFactory * @param array $data * @param array $params [optional] - * @throws \Exception */ public function __construct(FixtureFactory $fixtureFactory, array $data, array $params = []) { @@ -72,39 +71,32 @@ class BundleSelections implements FixtureInterface $this->data = $this->getPreset($this->currentPreset); if (!empty($data['products'])) { $this->data['products'] = []; - $this->data['products'][] = explode(',', $data['products']); + $this->data['products'] = explode('|', $data['products']); + foreach ($this->data['products'] as $key => $products) { + $this->data['products'][$key] = explode(',', $products); + } } } if (!empty($this->data['products'])) { $productsSelections = $this->data['products']; $this->data['products'] = []; - foreach ($productsSelections as $products) { + foreach ($productsSelections as $index => $products) { $productSelection = []; - foreach ($products as $product) { + foreach ($products as $key => $product) { list($fixture, $dataSet) = explode('::', $product); - /** @var $productFixture InjectableFixture */ - $productFixture = $fixtureFactory->createByCode($fixture, ['dataSet' => $dataSet]); - if (!$productFixture->hasData('id')) { - $productFixture->persist(); - } - $productSelection[] = $productFixture; + $productSelection[$key] = $fixtureFactory->createByCode($fixture, ['dataSet' => $dataSet]); + $productSelection[$key]->persist(); + $this->data['bundle_options'][$index]['assigned_products'][$key]['search_data']['name'] = + $productSelection[$key]->getName(); } $this->data['products'][] = $productSelection; } - - foreach ($this->data['bundle_options'] as $optionKey => &$bundleOption) { - foreach ($bundleOption['assigned_products'] as $productKey => &$assignedProducts) { - $assignedProducts['search_data']['name'] = $this->data['products'][$optionKey][$productKey] - ->getName(); - } - unset($bundleOption, $assignedProducts); - } } } /** - * Persists prepared data into application + * Persist bundle selections products * * @return void */ @@ -113,43 +105,10 @@ class BundleSelections implements FixtureInterface // } - /** - * Get selection for performing checkout - * - * @return array|null - */ - public function getSelectionForCheckout() - { - /** @var \Magento\Catalog\Test\Fixture\CatalogProductSimple $product */ - $product = reset($this->data['products'])[0]; - $selectionsForCheckout = [ - 'default' => [ - 0 => [ - 'value' => $product->getName(), - 'type' => 'select', - 'qty' => 1 - ] - ], - 'second' => [ - 0 => [ - 'value' => $product->getName(), - 'type' => 'select', - 'qty' => 1 - ] - ], - ]; - - if (!isset($selectionsForCheckout[$this->currentPreset])) { - return null; - } - - return $selectionsForCheckout[$this->currentPreset]; - } - /** * Return prepared data set * - * @param string|null $key [optional] + * @param string $key [optional] * @return mixed * * @SuppressWarnings(PHPMD.UnusedFormalParameter) @@ -170,7 +129,7 @@ class BundleSelections implements FixtureInterface } /** - * Getting preset data + * Preset array * * @param string $name * @return mixed @@ -181,7 +140,7 @@ class BundleSelections implements FixtureInterface protected function getPreset($name) { $presets = [ - 'default' => [ + 'default_dynamic' => [ 'bundle_options' => [ [ 'title' => 'Drop-down Option', @@ -210,11 +169,11 @@ class BundleSelections implements FixtureInterface 'products' => [ [ 'catalogProductSimple::default', - 'catalogProductSimple::default' + 'catalogProductSimple::100_dollar_product' ] ] ], - 'default_dynamic' => [ + 'default_fixed' => [ 'bundle_options' => [ [ 'title' => 'Drop-down Option', @@ -226,6 +185,8 @@ class BundleSelections implements FixtureInterface 'name' => '%product_name%' ], 'data' => [ + 'selection_price_value' => 5.00, + 'selection_price_type' => 'Fixed', 'selection_qty' => 1, ] ], @@ -234,6 +195,8 @@ class BundleSelections implements FixtureInterface 'name' => '%product_name%' ], 'data' => [ + 'selection_price_value' => 6.00, + 'selection_price_type' => 'Fixed', 'selection_qty' => 1, ] ] @@ -243,11 +206,11 @@ class BundleSelections implements FixtureInterface 'products' => [ [ 'catalogProductSimple::default', - 'catalogProductSimple::default' - ] + 'catalogProductSimple::100_dollar_product' + ], ] ], - 'default_fixed' => [ + 'second' => [ 'bundle_options' => [ [ 'title' => 'Drop-down Option', @@ -262,7 +225,6 @@ class BundleSelections implements FixtureInterface 'selection_price_value' => 5.00, 'selection_price_type' => 'Fixed', 'selection_qty' => 1, - 'selection_can_change_qty' => 'Yes', ] ], [ @@ -270,10 +232,9 @@ class BundleSelections implements FixtureInterface 'name' => '%product_name%' ], 'data' => [ - 'selection_price_value' => 5.00, + 'selection_price_value' => 10.00, 'selection_price_type' => 'Fixed', 'selection_qty' => 1, - 'selection_can_change_qty' => 'Yes', ] ] ] @@ -282,11 +243,11 @@ class BundleSelections implements FixtureInterface 'products' => [ [ 'catalogProductSimple::default', - 'catalogProductSimple::default' - ] + 'catalogProductSimple::100_dollar_product' + ], ] ], - 'second' => [ + 'all_types_fixed' => [ 'bundle_options' => [ [ 'title' => 'Drop-down Option', @@ -301,7 +262,6 @@ class BundleSelections implements FixtureInterface 'selection_price_value' => 5.00, 'selection_price_type' => 'Fixed', 'selection_qty' => 1, - 'selection_can_change_qty' => 'Yes', ] ], [ @@ -309,10 +269,90 @@ class BundleSelections implements FixtureInterface 'name' => '%product_name%' ], 'data' => [ - 'selection_price_value' => 10.00, + 'selection_price_value' => 6.00, + 'selection_price_type' => 'Fixed', + 'selection_qty' => 1, + ] + ] + ] + ], + [ + 'title' => 'Radio Button Option', + 'type' => 'Radio Buttons', + 'required' => 'Yes', + 'assigned_products' => [ + [ + 'search_data' => [ + 'name' => '%product_name%' + ], + 'data' => [ + 'selection_price_value' => 5.00, + 'selection_price_type' => 'Fixed', + 'selection_qty' => 1, + ] + ], + [ + 'search_data' => [ + 'name' => '%product_name%' + ], + 'data' => [ + 'selection_price_value' => 6.00, + 'selection_price_type' => 'Fixed', + 'selection_qty' => 1, + ] + ] + ] + ], + [ + 'title' => 'Checkbox Option', + 'type' => 'Checkbox', + 'required' => 'Yes', + 'assigned_products' => [ + [ + 'search_data' => [ + 'name' => '%product_name%' + ], + 'data' => [ + 'selection_price_value' => 5.00, + 'selection_price_type' => 'Fixed', + 'selection_qty' => 1, + ] + ], + [ + 'search_data' => [ + 'name' => '%product_name%' + ], + 'data' => [ + 'selection_price_value' => 6.00, + 'selection_price_type' => 'Fixed', + 'selection_qty' => 1, + ] + ] + ] + ], + [ + 'title' => 'Multiple Select Option', + 'type' => 'Multiple Select', + 'required' => 'Yes', + 'assigned_products' => [ + [ + 'search_data' => [ + 'name' => '%product_name%' + ], + 'data' => [ + 'selection_price_value' => 5.00, + 'selection_price_type' => 'Fixed', + 'selection_qty' => 1, + ] + ], + [ + 'search_data' => [ + 'name' => '%product_name%' + ], + 'data' => [ + 'selection_price_value' => 6.00, 'selection_price_type' => 'Fixed', 'selection_qty' => 1, - 'selection_can_change_qty' => 'Yes', ] ] ] @@ -321,18 +361,210 @@ class BundleSelections implements FixtureInterface 'products' => [ [ 'catalogProductSimple::default', - 'catalogProductSimple::default' + 'catalogProductSimple::100_dollar_product' + ], + [ + 'catalogProductSimple::default', + 'catalogProductSimple::100_dollar_product' + ], + [ + 'catalogProductSimple::default', + 'catalogProductSimple::100_dollar_product' + ], + [ + 'catalogProductSimple::default', + 'catalogProductSimple::100_dollar_product' + ], + ] + ], + 'all_types_dynamic' => [ + 'bundle_options' => [ + [ + 'title' => 'Drop-down Option', + 'type' => 'Drop-down', + 'required' => 'Yes', + 'assigned_products' => [ + [ + 'search_data' => [ + 'name' => '%product_name%' + ], + 'data' => [ + 'selection_qty' => 1, + ] + ], + [ + 'search_data' => [ + 'name' => '%product_name%' + ], + 'data' => [ + 'selection_qty' => 1, + ] + ] + ] + ], + [ + 'title' => 'Radio Button Option', + 'type' => 'Radio Buttons', + 'required' => 'Yes', + 'assigned_products' => [ + [ + 'search_data' => [ + 'name' => '%product_name%' + ], + 'data' => [ + 'selection_qty' => 1, + ] + ], + [ + 'search_data' => [ + 'name' => '%product_name%' + ], + 'data' => [ + 'selection_qty' => 1, + ] + ] + ] + ], + [ + 'title' => 'Checkbox Option', + 'type' => 'Checkbox', + 'required' => 'Yes', + 'assigned_products' => [ + [ + 'search_data' => [ + 'name' => '%product_name%' + ], + 'data' => [ + 'selection_qty' => 1, + ] + ], + [ + 'search_data' => [ + 'name' => '%product_name%' + ], + 'data' => [ + 'selection_qty' => 1, + ] + ] + ] + ], + [ + 'title' => 'Multiple Select Option', + 'type' => 'Multiple Select', + 'required' => 'Yes', + 'assigned_products' => [ + [ + 'search_data' => [ + 'name' => '%product_name%' + ], + 'data' => [ + 'selection_qty' => 1, + ] + ], + [ + 'search_data' => [ + 'name' => '%product_name%' + ], + 'data' => [ + 'selection_qty' => 1, + ] + ] + ] + ], + ], + 'products' => [ + [ + 'catalogProductSimple::default', + 'catalogProductSimple::100_dollar_product' + ], + [ + 'catalogProductSimple::default', + 'catalogProductSimple::100_dollar_product' + ], + [ + 'catalogProductSimple::default', + 'catalogProductSimple::100_dollar_product' + ], + [ + 'catalogProductSimple::default', + 'catalogProductSimple::100_dollar_product' + ], + ] + ], + 'with_not_required_options' => [ + 'bundle_options' => [ + [ + 'title' => 'Drop-down Option', + 'type' => 'Drop-down', + 'required' => 'No', + 'assigned_products' => [ + [ + 'search_data' => [ + 'name' => '%product_name%' + ], + 'data' => [ + 'selection_qty' => 1, + 'selection_price_value' => 45, + 'selection_price_type' => 'Fixed', + ] + ], + [ + 'search_data' => [ + 'name' => '%product_name%' + ], + 'data' => [ + 'selection_qty' => 1, + 'selection_price_value' => 43, + 'selection_price_type' => 'Fixed', + ] + ] + ] + ], + [ + 'title' => 'Radio Button Option', + 'type' => 'Radio Buttons', + 'required' => 'No', + 'assigned_products' => [ + [ + 'search_data' => [ + 'name' => '%product_name%' + ], + 'data' => [ + 'selection_qty' => 1, + 'selection_price_value' => 45, + 'selection_price_type' => 'Fixed', + ] + ], + [ + 'search_data' => [ + 'name' => '%product_name%' + ], + 'data' => [ + 'selection_qty' => 1, + 'selection_price_value' => 43, + 'selection_price_type' => 'Fixed', + ] + ] + ] + ], + ], + 'products' => [ + [ + 'catalogProductSimple::default', + 'catalogProductSimple::100_dollar_product' + ], + [ + 'catalogProductSimple::default', + 'catalogProductSimple::100_dollar_product' ] ] - ] + ], ]; - if (!isset($presets[$name])) { throw new \InvalidArgumentException( sprintf('Wrong Bundle Selections preset name: %s', $name) ); } - return $presets[$name]; } } diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/CatalogProductBundle/CheckoutData.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/CatalogProductBundle/CheckoutData.php new file mode 100644 index 0000000000000000000000000000000000000000..fcd9289437fe862e59ac68713f265fc2efb0e736 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/CatalogProductBundle/CheckoutData.php @@ -0,0 +1,228 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Bundle\Test\Fixture\CatalogProductBundle; + +use Magento\Catalog\Test\Fixture\CatalogProductSimple\CheckoutData as AbstractCheckoutData; + +/** + * Class CheckoutData + * Data keys: + * - preset (Checkout data verification preset name) + * + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ +class CheckoutData extends AbstractCheckoutData +{ + /** + * Get preset array + * + * @return array|null + */ + public function getPreset() + { + $presets = [ + 'default' => [ + 'bundle_options' => [ + [ + 'title' => 'Drop-down Option', + 'type' => 'Drop-down', + 'value' => [ + 'name' => '100_dollar_product' + ] + ], + ], + ], + 'with_not_required_options' => [ + 'bundle_options' => [ + [ + 'title' => 'Drop-down Option', + 'type' => 'Drop-down', + 'value' => [ + 'name' => '100_dollar_product' + ] + ], + [ + 'title' => 'Radio Button Option', + 'type' => 'Radio Buttons', + 'value' => [ + 'name' => '100_dollar_product' + ] + ], + ], + ], + 'with_custom_options_1' => [ + 'bundle_options' => [ + [ + 'title' => 'Drop-down Option', + 'type' => 'Drop-down', + 'value' => [ + 'name' => '100_dollar_product' + ] + ], + ], + 'custom_options' => [ + [ + 'type' => 'Drop-down', + 'title' => 'custom option drop down', + 'value' => ['30 bucks'], + ], + ] + ], + 'with_custom_options_2' => [ + 'bundle_options' => [ + [ + 'title' => 'Drop-down Option', + 'type' => 'Drop-down', + 'value' => [ + 'name' => '100_dollar_product' + ] + ], + ], + 'custom_options' => [ + [ + 'type' => 'Drop-down', + 'title' => 'custom option drop down', + 'value' => ['10 percent'], + ], + ] + ], + 'all_types_bundle_fixed_and_custom_options' => [ + 'bundle_options' => [ + [ + 'title' => 'Drop-down Option', + 'type' => 'Drop-down', + 'value' => [ + 'name' => '100_dollar_product' + ] + ], + [ + 'title' => 'Radio Button Option', + 'type' => 'Radio Buttons', + 'value' => [ + 'name' => '100_dollar_product' + ] + ], + [ + 'title' => 'Checkbox Option', + 'type' => 'Checkbox', + 'value' => [ + 'name' => '100_dollar_product' + ] + ], + [ + 'title' => 'Multiple Select Option', + 'type' => 'Multiple', + 'value' => [ + 'name' => '100_dollar_product' + ] + ], + ], + 'custom_options' => [ + [ + 'type' => 'Field', + 'title' => 'custom option field', + 'value' => ['Field'], + ], + [ + 'type' => 'Area', + 'title' => 'custom option Area', + 'value' => ['Area'], + ], + [ + 'type' => 'Radio Buttons', + 'title' => 'custom option Radio Buttons', + 'value' => ['20 percent'], + ], + [ + 'type' => 'Drop-down', + 'title' => 'custom option drop down', + 'value' => ['20 percent'], + ], + [ + 'type' => 'Checkbox', + 'title' => 'custom option Checkbox', + 'value' => ['20 percent'], + ], + [ + 'type' => 'Multiple Select', + 'title' => 'custom option Multiple Select', + 'value' => ['20 percent'], + ], + [ + 'type' => 'Date', + 'title' => 'custom option Date', + 'value' => ['12/12/2014'], + ], + [ + 'type' => 'Date & Time', + 'title' => 'custom option Date & Time', + 'value' => ['12/12/2014/12/30/AM'], + ], + [ + 'type' => 'Time', + 'title' => 'custom option Time', + 'value' => ['12/12/2014/12/30/AM'], + ], + ] + ], + 'all_types_bundle_options' => [ + 'bundle_options' => [ + [ + 'title' => 'Drop-down Option', + 'type' => 'Drop-down', + 'value' => [ + 'name' => '100_dollar_product' + ] + ], + [ + 'title' => 'Radio Button Option', + 'type' => 'Radio Buttons', + 'value' => [ + 'name' => '100_dollar_product' + ] + ], + [ + 'title' => 'Checkbox Option', + 'type' => 'Checkbox', + 'value' => [ + 'name' => '100_dollar_product' + ] + ], + [ + 'title' => 'Multiple Select Option', + 'type' => 'Multiple', + 'value' => [ + 'name' => '100_dollar_product' + ] + ], + ], + ], + ]; + if (!isset($presets[$this->currentPreset])) { + return null; + } + return $presets[$this->currentPreset]; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/CatalogProductBundle/Price.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/CatalogProductBundle/Price.php index 3a119dbf82f02d6a1e6219ebd24083a83ca2e540..b054a40a8a2b0ba514a7d0b5f8512cee629b1501 100644 --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/CatalogProductBundle/Price.php +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/CatalogProductBundle/Price.php @@ -28,34 +28,44 @@ use Mtf\Fixture\FixtureInterface; /** * Class Price - * * Data keys: * - preset (Price verification preset name) * - value (Price value) - * */ class Price implements FixtureInterface { /** - * @var \Mtf\Fixture\FixtureFactory + * Prepared dataSet data + * + * @var array */ - protected $fixtureFactory; + protected $data; /** + * Data set configuration settings + * + * @var array + */ + protected $params; + + /** + * Current preset + * * @var string */ protected $currentPreset; /** + * Constructor + * + * @constructor * @param array $params - * @param array $data + * @param array $data [optional] */ public function __construct(array $params, array $data = []) { $this->params = $params; - if (isset($data['value'])) { - $this->data = $data['value']; - } + $this->data = (isset($data['value']) && $data['value'] != '-') ? $data['value'] : null; if (isset($data['preset'])) { $this->currentPreset = $data['preset']; } @@ -95,37 +105,104 @@ class Price implements FixtureInterface } /** + * Get preset array + * * @return array|null */ public function getPreset() { $presets = [ 'MAGETWO-23066' => [ - 'price_from' => '$115.00', - 'price_to' => '$120.00', + 'price_from' => '115.00', + 'price_to' => '120.00', 'cart_price' => '145.00' ], 'MAGETWO-23069' => [ - 'price_from' => '$115.00', - 'price_to' => '$120.00', + 'price_from' => '115.00', + 'price_to' => '120.00', 'cart_price' => '126.00' ], 'MAGETWO-23070' => [ - 'price_from' => '$40.00', - 'price_to' => '$100.00', + 'price_from' => '40.00', + 'price_to' => '100.00', 'cart_price' => '100.00' ], 'MAGETWO-23061' => [ - 'price_from' => '$32.00', - 'price_to' => '$80.00', + 'price_from' => '32.00', + 'price_to' => '80.00', + 'cart_price' => '80.00' + ], + 'dynamic-200' => [ + 'price_from' => '200.00', + 'price_to' => '500.00', + 'cart_price' => '400.00' + ], + 'fixed-24' => [ + 'price_from' => '96.00', + 'price_to' => '97.00', + 'cart_price' => '252.00' + ], + 'fixed-1' => [ + 'price_from' => '1.00', + 'price_to' => '10.00', + 'cart_price' => '80.00' + ], + 'dynamic-8' => [ + 'price_from' => '8.00', + 'price_to' => '20.00', + 'cart_price' => '80.00' + ], + 'dynamic-32' => [ + 'price_from' => '32.00', + 'price_to' => '80.00', + 'cart_price' => '80.00' + ], + 'dynamic-40' => [ + 'price_from' => '40.00', + 'price_to' => '100.00', + 'cart_price' => '100.00' + ], + 'dynamic-50' => [ + 'price_from' => 'As low as $50.00', + ], + 'fixed-115' => [ + 'price_from' => '115.00', + 'price_to' => '120.00', + 'cart_price' => '145.00' + ], + 'fixed-126' => [ + 'price_from' => '115.00', + 'price_to' => '120.00', + 'cart_price' => '126.00' + ], + 'fixed-15' => [ + 'price_from' => '15.00', + 'price_to' => '16.00', 'cart_price' => '80.00' - ] + ], + 'default_fixed' => [ + 'compare_price' => '755.00' + ], + 'default_dynamic' => [ + 'compare_price' => [ + 'price_from' => '100.00', + 'price_to' => '560.00' + ], + ], + 'dynamic-100' => [ + 'price_from' => '100.00', + 'price_to' => '560.00', + 'cart_price' => '100.00' + ], + 'fixed-756' => [ + 'price_from' => '755.00', + 'price_to' => '756.00', + 'cart_price' => '756.00' + ], ]; - if (!isset($presets[$this->currentPreset])) { return null; } - return $presets[$this->currentPreset]; } } diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Handler/Curl/CreateBundle.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Handler/Curl/CreateBundle.php index 118f5679e772f29f4bcd78d204a0ceea9a609f18..6004f9dbc3461a83f57e37610071e5e13f27d5ef 100644 --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Handler/Curl/CreateBundle.php +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Handler/Curl/CreateBundle.php @@ -89,7 +89,7 @@ class CreateBundle extends Curl */ protected function _prepareData(array $params, $prefix = null) { - $data = array(); + $data = []; foreach ($params as $key => $values) { if ($key == 'bundle_selections') { $data = array_merge($data, $this->_getBundleData($values['value'])); @@ -171,7 +171,7 @@ class CreateBundle extends Curl */ protected function _getUrl(array $config) { - $requestParams = isset($config['create_url_params']) ? $config['create_url_params'] : array(); + $requestParams = isset($config['create_url_params']) ? $config['create_url_params'] : []; $params = ''; foreach ($requestParams as $key => $value) { $params .= $key . '/' . $value . '/'; @@ -187,9 +187,9 @@ class CreateBundle extends Curl */ protected function _getSelections(array $products) { - $data = array(); + $data = []; foreach ($products as $product) { - $product = isset($product['data']) ? $product['data'] : array(); + $product = isset($product['data']) ? $product['data'] : []; $data[] = $this->_prepareData($product) + ['delete' => '']; } return $data; @@ -214,7 +214,7 @@ class CreateBundle extends Curl $url = $this->_getUrl($config); $curl = new BackendDecorator(new CurlTransport(), new Config); $curl->addOption(CURLOPT_HEADER, 1); - $curl->write(CurlInterface::POST, $url, '1.0', array(), $data); + $curl->write(CurlInterface::POST, $url, '1.0', [], $data); $response = $curl->read(); $curl->close(); diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Page/Product/CatalogProductView.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Page/Product/CatalogProductView.php new file mode 100644 index 0000000000000000000000000000000000000000..455f7dbe322c662f4b8eb42bf89ceab2751e069a --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Page/Product/CatalogProductView.php @@ -0,0 +1,62 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Bundle\Test\Page\Product; + +use Magento\Catalog\Test\Page\Product\CatalogProductView as ParentCatalogProductView; + +/** + * Class CatalogProductView + * Frontend bundle product view page + */ +class CatalogProductView extends ParentCatalogProductView +{ + const MCA = 'bundle/catalog/product/view'; + + /** + * Custom constructor + * + * @return void + */ + protected function _init() + { + $this->_blocks['bundleViewBlock'] = [ + 'name' => 'bundleViewBlock', + 'class' => 'Magento\Bundle\Test\Block\Catalog\Product\View', + 'locator' => '.bundle-options-container', + 'strategy' => 'css selector', + ]; + parent::_init(); + } + + /** + * Bundle block on frontend + * + * @return \Magento\Bundle\Test\Block\Catalog\Product\View + */ + public function getBundleViewBlock() + { + return $this->getBlockInstance('bundleViewBlock'); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Page/Product/CatalogProductView.xml b/dev/tests/functional/tests/app/Magento/Bundle/Test/Page/Product/CatalogProductView.xml new file mode 100644 index 0000000000000000000000000000000000000000..789d4eabfc2d28fde1126bc7a2963ab94a5952a1 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Page/Product/CatalogProductView.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" ?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<page mca="catalog/product/view"> + <block> + <name>bundleViewBlock</name> + <class>Magento\Bundle\Test\Block\Catalog\Product\View</class> + <locator>.bundle-options-container</locator> + <strategy>css selector</strategy> + </block> +</page> diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/Bundle.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/Bundle.php index 6bb0cd180c3c9978f976635b55f7623ac493d597..5adb3bfafd0064ae9ff44c76ebcc7666e8f805bb 100644 --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/Bundle.php +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/Bundle.php @@ -43,22 +43,22 @@ class Bundle extends Product if (isset($this->_data[$productType]['data']['fields']['price'])) { $required = array_merge_recursive( $required, - array( - 'data' => array( - 'fields' => array( - 'price' => array( + [ + 'data' => [ + 'fields' => [ + 'price' => [ 'value' => 60, 'group' => Fixture\Product::GROUP_PRODUCT_DETAILS - ) - ), - 'checkout' => array( - 'prices' => array( + ] + ], + 'checkout' => [ + 'prices' => [ 'price_from' => 70, 'price_to' => 72 - ) - ) - ) - ) + ] + ] + ] + ] ); } else { $required['data']['checkout']['prices'] = $this->_data[$productType]['data']['checkout']['prices']; diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/CatalogProductBundle.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/CatalogProductBundle.php index 36d9d4e624eba64a487c896fcd6c4e6ab04efad7..709c1f2bcfb4d97b78a1269fadb036aecedf6818 100644 --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/CatalogProductBundle.php +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/CatalogProductBundle.php @@ -82,6 +82,7 @@ class CatalogProductBundle extends AbstractRepository 'sku' => 'sku_bundle_dynamic_product_%isolation%', 'sku_type' => 'Dynamic', 'price_type' => 'Dynamic', + 'price' => ['value' => '-', 'preset' => 'default_dynamic'], 'quantity_and_stock_status' => [ 'qty' => 666.0000, 'is_in_stock' => 'In Stock', @@ -107,7 +108,7 @@ class CatalogProductBundle extends AbstractRepository 'sku' => 'sku_bundle_fixed_product_%isolation%', 'sku_type' => 'Fixed', 'price_type' => 'Fixed', - 'price' => ['value' => 750.00, 'preset' => '-'], + 'price' => ['value' => 750.00, 'preset' => 'default_fixed'], 'tax_class_id' => ['dataSet' => 'Taxable Goods'], 'quantity_and_stock_status' => [ 'qty' => 666.0000, diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/BundleDynamicTest.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/BundleDynamicTest.php old mode 100644 new mode 100755 index 54c801aa0cbe9b0aac5dc68cb05f751c221bfd20..3e5aed8a36ba3915030ba85e20c6cb88de182d91 --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/BundleDynamicTest.php +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/BundleDynamicTest.php @@ -61,8 +61,9 @@ class BundleDynamicTest extends Functional $productForm = $createProductPage->getForm(); //Steps $manageProductsGrid->open(); - $manageProductsGrid->getProductBlock()->addProduct('bundle'); - $productForm->fillProduct($bundle); + $manageProductsGrid->getGridPageActionBlock()->addProduct('bundle'); + $category = $bundle->getCategories()['category']; + $productForm->fill($bundle, null, $category); $createProductPage->getFormAction()->save(); //Verification $createProductPage->getMessagesBlock()->assertSuccessMessage(); @@ -107,7 +108,10 @@ class BundleDynamicTest extends Functional $frontendHomePage->getTopmenu()->selectCategoryByName($product->getCategoryName()); //Verification on category product list $productListBlock = $categoryPage->getListProductBlock(); - $this->assertTrue($productListBlock->isProductVisible($product->getName())); + $this->assertTrue( + $productListBlock->isProductVisible($product->getName()), + 'Product "' . $product->getName() . '" is absent on category page' + ); $productListBlock->openProductViewPage($product->getName()); //Verification on product detail page $productViewBlock = $productPage->getViewBlock(); diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/BundleFixedTest.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/BundleFixedTest.php old mode 100644 new mode 100755 index bdb76ea8d8add043d539e7b426e1ed657cec5383..0fb7cab4454a0510be4aabcf5e99cb8246520a2d --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/BundleFixedTest.php +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/BundleFixedTest.php @@ -60,9 +60,10 @@ class BundleFixedTest extends Functional $createProductPage = Factory::getPageFactory()->getCatalogProductNew(); //Steps $manageProductsGrid->open(); - $manageProductsGrid->getProductBlock()->addProduct('bundle'); + $manageProductsGrid->getGridPageActionBlock()->addProduct('bundle'); $productForm = $createProductPage->getForm(); - $productForm->fillProduct($bundle); + $category = $bundle->getCategories()['category']; + $productForm->fill($bundle, null, $category); $createProductPage->getFormAction()->save(); //Verification $createProductPage->getMessagesBlock()->assertSuccessMessage(); diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/CreateBundleProductEntityTest.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/CreateBundleProductEntityTest.php new file mode 100755 index 0000000000000000000000000000000000000000..3c8ca29df084bf21546c9c7e4f1bf18dc9cfafca --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/CreateBundleProductEntityTest.php @@ -0,0 +1,108 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Bundle\Test\TestCase; + +use Mtf\TestCase\Injectable; +use Magento\Catalog\Test\Fixture\CatalogCategory; +use Magento\Bundle\Test\Fixture\CatalogProductBundle; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductNew; + +/** + * Test Creation for CreateBundleProductEntity + * + * Test Flow: + * 1. Login as admin + * 2. Navigate to the Products>Inventory>Catalog + * 3. Click on "+" dropdown and select Bundle Product type + * 4. Fill in all data according to data set + * 5. Save product + * 6. Verify created product + * + * @group Bundle_Product_(CS) + * @ZephyrId MAGETWO-24118 + */ +class CreateBundleProductEntityTest extends Injectable +{ + /** + * Page product on backend + * + * @var CatalogProductIndex + */ + protected $catalogProductIndex; + + /** + * New page on backend + * + * @var CatalogProductNew + */ + protected $catalogProductNew; + + /** + * Persist category + * + * @param CatalogCategory $category + * @return array + */ + public function __prepare(CatalogCategory $category) + { + $category->persist(); + + return [ + 'category' => $category + ]; + } + + /** + * Filling objects of the class + * + * @param CatalogProductIndex $catalogProductIndexNewPage + * @param CatalogProductNew $catalogProductNewPage + * @return void + */ + public function __inject( + CatalogProductIndex $catalogProductIndexNewPage, + CatalogProductNew $catalogProductNewPage + ) { + $this->catalogProductIndex = $catalogProductIndexNewPage; + $this->catalogProductNew = $catalogProductNewPage; + } + + /** + * Test create bundle product + * + * @param CatalogProductBundle $product + * @param CatalogCategory $category + * @return void + */ + public function test(CatalogProductBundle $product, CatalogCategory $category) + { + $this->catalogProductIndex->open(); + $this->catalogProductIndex->getGridPageActionBlock()->addProduct('bundle'); + $productBlockForm = $this->catalogProductNew->getForm(); + $productBlockForm->fill($product, null, $category); + $this->catalogProductNew->getFormAction()->save(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/CreateBundleProductEntityTest/test.csv b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/CreateBundleProductEntityTest/test.csv new file mode 100644 index 0000000000000000000000000000000000000000..35d7c6279827ec87de81dffba59c17bf70b5ad26 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/CreateBundleProductEntityTest/test.csv @@ -0,0 +1,15 @@ +"product/data/name";"product/data/sku_type";"product/data/sku";"product/data/status";"product/data/price_type";"product/data/price/value";"product/data/price/preset";"product/data/tax_class_id/dataSet";"product/data/quantity_and_stock_status/is_in_stock";"product/data/weight_type";"product/data/weight";"product/data/category";"product/data/description";"product/data/group_price/preset";"product/data/special_price";"product/data/special_from_date/pattern";"product/data/special_to_date/pattern";"product/data/tier_price/preset";"product/data/price_view";"product/data/stock_data/use_config_manage_stock";"product/data/stock_data/manage_stock";"product/data/shipment_type";"product/data/bundle_selections/preset";"product/data/bundle_selections/products";"product/data/checkout_data/preset";"product/data/custom_options/preset";"product/data/visibility";"product/data/use_config_gift_message_available";"product/data/gift_message_available";"constraint" +"BundleProduct %isolation%";"-";"bundle_sku_%isolation%";"-";"-";"-";"-";"-";"-";"-";"-";"-";"Bundle Product Dynamic Required";"-";"-";"-";"-";"-";"-";"No";"No";"-";"default_dynamic";"catalogProductSimple::100_dollar_product,catalogProductVirtual::50_dollar_product";"default";"-";"-";"-";"-";"assertProductSaveMessage, assertProductInGrid, assertBundleItemsOnProductPage" +"BundleProduct %isolation%";"Fixed";"bundle_sku_%isolation%";"Product offline";"Dynamic";"-";"-";"-";"Out of Stock";"Dynamic";"-";"category_%isolation%";"-";"-";"-";"-";"-";"-";"-";"-";"-";"Separately";"default_dynamic";"catalogProductSimple::100_dollar_product,catalogProductVirtual::50_dollar_product";"default";"-";"Catalog, Search";"No";"Yes";"assertProductSaveMessage, assertProductNotSearchableBySku" +"BundleProduct %isolation%";"Dynamic";"bundle_sku_%isolation%";"Product online";"Dynamic";"-";"dynamic-200";"-";"In Stock";"Dynamic";"-";"category_%isolation%";"Bundle Product Dynamic";"-";"-";"-";"-";"-";"Price Range";"-";"-";"Together";"all_types_dynamic";"catalogProductSimple::100_dollar_product,catalogProductVirtual::50_dollar_product|catalogProductSimple::100_dollar_product,catalogProductVirtual::50_dollar_product|catalogProductSimple::100_dollar_product,catalogProductVirtual::50_dollar_product|catalogProductSimple::100_dollar_product,catalogProductVirtual::50_dollar_product";"all_types_bundle_options";"-";"Catalog, Search";"No";"Yes";"assertProductSaveMessage, assertProductInGrid, assertBundleProductForm, assertProductSearchableBySku, assertBundleProductPage, assertProductInStock, assertBundleItemsOnProductPage, assertProductVisibleInCategory, assertBundlePriceView, assertBundlePriceType" +"BundleProduct %isolation%";"Fixed";"bundle_sku_%isolation%";"-";"Fixed";"10";"fixed-15";"None";"-";"Fixed";"10";"-";"Bundle Product Fixed Required";"-";"-";"-";"-";"-";"-";"-";"-";"-";"default_fixed";"catalogProductSimple::100_dollar_product,catalogProductVirtual::50_dollar_product";"default";"-";"-";"-";"-";"assertProductSaveMessage, assertProductInGrid, assertBundleProductForm, assertProductSearchableBySku, assertBundleProductPage, assertBundleItemsOnProductPage" +"BundleProduct %isolation%";"Fixed";"bundle_sku_%isolation%";"Product online";"Fixed";"100";"fixed-24";"Taxable Goods";"In Stock";"Fixed";"10";"category_%isolation%";"Bundle Product Fixed";"default";"-";"-";"-";"-";"As Low as";"-";"-";"Separately";"all_types_fixed";"catalogProductSimple::100_dollar_product,catalogProductVirtual::50_dollar_product|catalogProductSimple::100_dollar_product,catalogProductVirtual::50_dollar_product|catalogProductSimple::100_dollar_product,catalogProductVirtual::50_dollar_product|catalogProductSimple::100_dollar_product,catalogProductVirtual::50_dollar_product";"all_types_bundle_fixed_and_custom_options";"all_types";"Catalog, Search";"No";"No";"assertProductSaveMessage, assertProductInGrid, assertBundleProductForm, assertProductVisibleInCategory, assertBundleProductPage, assertProductInStock, assertGroupedPriceOnBundleProductPage, assertBundleItemsOnProductPage, assertBundlePriceView, assertBundlePriceType" +"BundleProduct %isolation%";"Fixed";"bundle_sku_%isolation%";"Product online";"Fixed";"10";"fixed-1";"Taxable Goods";"Out of Stock";"Fixed";"10";"category_%isolation%";"-";"-";"10";"m/d/Y";"m/d/Y +3 days";"-";"Price Range";"No";"Yes";"Together";"with_not_required_options";"catalogProductSimple::100_dollar_product,catalogProductVirtual::50_dollar_product|catalogProductSimple::100_dollar_product,catalogProductVirtual::50_dollar_product";"with_not_required_options";"-";"Catalog";"No";"No";"assertProductSaveMessage, assertProductInGrid, assertBundleProductForm, assertBundleProductPage, assertProductOutOfStock, assertBundlePriceView" +"BundleProduct %isolation%";"Dynamic";"bundle_sku_%isolation%";"-";"Dynamic";"-";"dynamic-50";"-";"-";"Fixed";"10";"-";"-";"-";"-";"-";"-";"default";"As Low as";"No";"No";"Together";"default_dynamic";"catalogProductSimple::100_dollar_product,catalogProductVirtual::50_dollar_product";"default";"-";"Search";"-";"-";"assertProductSaveMessage, assertProductInGrid, assertBundleProductForm, assertProductSearchableBySku, assertBundleProductPage, assertBundleItemsOnProductPage, assertTierPriceOnBundleProductPage" +"Bundle Dynamic %isolation%";"Dynamic";"sku_bundle_dynamic_%isolation%";"-";"Dynamic";"-";"dynamic-8";"-";"-";"-";"-";"-";"-";"-";"20";"-";"-";"-";"-";"-";"-";"-";"default_dynamic";"catalogProductSimple::100_dollar_product,catalogProductSimple::40_dollar_product";"default";"-";"-";"-";"-";"assertProductSaveMessage, assertBundleInCategory" +"Bundle Dynamic %isolation%";"Dynamic";"sku_bundle_dynamic_%isolation%";"-";"Dynamic";"-";"dynamic-32";"-";"-";"-";"-";"-";"-";"MAGETWO-23061";"-";"-";"-";"-";"-";"-";"-";"-";"default_dynamic";"catalogProductSimple::100_dollar_product,catalogProductSimple::40_dollar_product";"default";"-";"-";"-";"-";"assertProductSaveMessage, assertBundleInCategory, assertBundlePriceView, assertBundlePriceType" +"Bundle Dynamic %isolation%";"Dynamic";"sku_bundle_dynamic_%isolation%";"-";"Dynamic";"-";"dynamic-40";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"default_dynamic";"catalogProductSimple::100_dollar_product,catalogProductSimple::40_dollar_product";"default";"-";"-";"-";"-";"assertProductSaveMessage, assertBundleInCategory, assertBundlePriceView, assertBundlePriceType" +"Bundle Fixed %isolation%";"Fixed";"sku_bundle_fixed_%isolation%";"-";"Fixed";"110";"fixed-115";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"second";"catalogProductSimple::100_dollar_product,catalogProductSimple::40_dollar_product";"with_custom_options_1";"MAGETWO-23066";"-";"-";"-";"assertProductSaveMessage, assertBundleInCategory, assertBundlePriceView, assertBundlePriceType" +"Bundle Fixed %isolation%";"Fixed";"sku_bundle_fixed_%isolation%";"-";"Fixed";"110";"fixed-126";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"second";"catalogProductSimple::100_dollar_product,catalogProductSimple::40_dollar_product";"with_custom_options_2";"MAGETWO-23069";"-";"-";"-";"assertProductSaveMessage, assertBundleInCategory, assertBundlePriceView, assertBundlePriceType" +"Bundle Dynamic %isolation%";"Dynamic";"sku_bundle_dynamic_%isolation%";"-";"Dynamic";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"default_dynamic";"catalogProductSimple::100_dollar_product,catalogProductSimple::40_dollar_product";"default";"-";"-";"-";"-";"assertProductSaveMessage" +"Bundle Fixed %isolation%";"Fixed";"sku_bundle_fixed_%isolation%";"-";"Fixed";"10";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"second";"catalogProductSimple::100_dollar_product,catalogProductSimple::40_dollar_product";"default";"-";"-";"-";"-";"assertProductSaveMessage" diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/EditBundleTest.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/EditBundleTest.php old mode 100644 new mode 100755 index 5626dee51a54ed0f38d5f811ae439e590c36a78e..ed3b6068a95831ccd77e503f8b966e71f700775f --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/EditBundleTest.php +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/EditBundleTest.php @@ -72,13 +72,11 @@ class EditBundleTest extends Functional $cachePage = Factory::getPageFactory()->getAdminCache(); $productGridPage->open(); - $gridBlock->searchAndOpen( - array( - 'sku' => $product->getProductSku(), - 'type' => 'Bundle Product' - ) - ); - $productForm->fillProduct($editProduct); + $gridBlock->searchAndOpen([ + 'sku' => $product->getProductSku(), + 'type' => 'Bundle Product' + ]); + $productForm->fill($editProduct); $editProductPage->getFormAction()->save(); //Verifying $editProductPage->getMessagesBlock()->assertSuccessMessage(); @@ -97,10 +95,10 @@ class EditBundleTest extends Functional */ public function createDataProvider() { - return array( - array('getMagentoBundleBundleFixed'), - array('getMagentoBundleBundleDynamic') - ); + return [ + ['getMagentoBundleBundleFixed'], + ['getMagentoBundleBundleDynamic'] + ]; } /** diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/UpdateBundleProductEntityTest.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/UpdateBundleProductEntityTest.php new file mode 100644 index 0000000000000000000000000000000000000000..9cbf6996f500b7848bbd9a15f1f20418072600f9 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/UpdateBundleProductEntityTest.php @@ -0,0 +1,100 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Bundle\Test\TestCase; + +use Mtf\TestCase\Injectable; +use Magento\Bundle\Test\Fixture\CatalogProductBundle; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductEdit; + +/** + * Test Creation for Update BundleProductEntity + * + * Test Flow: + * + * Precondition: + * 1. Category is created. + * 2. Bundle product is created. + * + * Steps + * 1. Login to backend. + * 2. Navigate to PRODUCTS > Catalog. + * 3. Select a product in the grid. + * 4. Edit test value(s) according to dataset. + * 5. Click "Save". + * 6. Perform asserts + * + * + * @group Bundle_Product_(MX) + * @ZephyrId MAGETWO-26195 + */ +class UpdateBundleProductEntityTest extends Injectable +{ + /** + * Page product on backend + * + * @var CatalogProductIndex + */ + protected $catalogProductIndex; + + /** + * Edit page on backend + * + * @var CatalogProductEdit + */ + protected $catalogProductEdit; + + /** + * Injection data + * + * @param CatalogProductIndex $catalogProductIndexNewPage + * @param CatalogProductEdit $catalogProductEditPage + * @return void + */ + public function __inject( + CatalogProductIndex $catalogProductIndexNewPage, + CatalogProductEdit $catalogProductEditPage + ) { + $this->catalogProductIndex = $catalogProductIndexNewPage; + $this->catalogProductEdit = $catalogProductEditPage; + } + + /** + * Test update bundle product + * + * @param CatalogProductBundle $product + * @param CatalogProductBundle $originalProduct + * @return void + */ + public function test(CatalogProductBundle $product, CatalogProductBundle $originalProduct) + { + $originalProduct->persist(); + $this->catalogProductIndex->open(); + $filter = ['sku' => $originalProduct->getSku()]; + $this->catalogProductIndex->getProductGrid()->searchAndOpen($filter); + $this->catalogProductEdit->getForm()->fill($product); + $this->catalogProductEdit->getFormAction()->save(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/UpdateBundleProductEntityTest/test.csv b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/UpdateBundleProductEntityTest/test.csv new file mode 100644 index 0000000000000000000000000000000000000000..440518b0e5a28b6bb3091b75096252385aaed8e5 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/UpdateBundleProductEntityTest/test.csv @@ -0,0 +1,3 @@ +"originalProduct/dataSet";"product/data/name";"product/data/sku_type";"product/data/sku";"product/data/price/preset";"product/data/weight_type";"product/data/weight";"product/data/category_ids/presets";"product/data/description";"product/data/bundle_shipment_type";"product/data/bundle_selections/preset";"product/data/checkout_data/preset";"product/data/visibility";"constraint" +"bundle_dynamic_product";"bundle_dynamic_%isolation%";"Fixed";"bundle_dynamic_%isolation%";"dynamic-100";"Fixed";"1";"-";"Bundle Product Fixed Required";"Together";"default_dynamic";"default";"-";"assertProductSaveMessage, assertProductInGrid, assertBundleItemsOnProductPage, assertBundleProductForm, assertBundleProductPage, assertProductInStock, assertBundlePriceView, assertBundlePriceType" +"bundle_fixed_product";"bundle_dynamic_%isolation%";"Dynamic";"bundle_sku_%isolation%";"fixed-756";"Dynamic";"-";"default_subcategory";"-";"Separately";"default_fixed";"default";"Catalog, Search";"assertProductSaveMessage, assertProductInGrid, assertBundleItemsOnProductPage, assertBundleProductForm, assertBundleProductPage, assertProductInStock, assertProductVisibleInCategory, assertBundlePriceView, assertBundlePriceType" diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/etc/global/constraint.xml b/dev/tests/functional/tests/app/Magento/Bundle/Test/etc/global/constraint.xml index 64b43a1d6aa70ce8ab7735d547f75b5eae91dc92..017c23441d638d0a28764d9745fa4bd2332bd4d9 100644 --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/etc/global/constraint.xml +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/etc/global/constraint.xml @@ -33,19 +33,25 @@ <category class="Magento\Catalog\Test\Fixture\Category" /> </require> </assertBundleInCategory> - <assertBundleView module="Magento_Bundle"> + <assertBundleItemsOnProductPage module="Magento_Bundle"> <severeness>low</severeness> - <require> - <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" /> - <product class="Magento\Bundle\Test\Fixture\CatalogProductBundle" /> - </require> - </assertBundleView> - <assertBundleInCart module="Magento_Bundle"> + </assertBundleItemsOnProductPage> + <assertBundlePriceView module="Magento_Bundle"> <severeness>low</severeness> - <require> - <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" /> - <product class="Magento\Bundle\Test\Fixture\CatalogProductBundle" /> - <checkoutCart class="Magento\Checkout\Test\Page\CheckoutCart" /> - </require> - </assertBundleInCart> + </assertBundlePriceView> + <assertBundlePriceType module="Magento_Bundle"> + <severeness>low</severeness> + </assertBundlePriceType> + <assertBundleProductForm module="Magento_Bundle"> + <severeness>low</severeness> + </assertBundleProductForm> + <assertTierPriceOnBundleProductPage module="Magento_Bundle"> + <severeness>low</severeness> + </assertTierPriceOnBundleProductPage> + <assertBundleProductPage module="Magento_Bundle"> + <severeness>low</severeness> + </assertBundleProductPage> + <assertGroupedPriceOnBundleProductPage module="Magento_Bundle"> + <severeness>low</severeness> + </assertGroupedPriceOnBundleProductPage> </constraint> diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/etc/global/fixture.xml b/dev/tests/functional/tests/app/Magento/Bundle/Test/etc/global/fixture.xml index dbeb096b70bab750886b4ac77ba72449eff9d1be..36e822cde00dba9e147f719d1370a964f0c14658 100644 --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/etc/global/fixture.xml +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/etc/global/fixture.xml @@ -40,7 +40,7 @@ <backend_type>virtual</backend_type> <is_required>1</is_required> <group>bundle</group> - <fixture>Magento\Bundle\Test\Fixture\Bundle\Selections</fixture> + <fixture>Magento\Bundle\Test\Fixture\Bundle\BundleSelections</fixture> </bundle_selections> </fields> <data_set> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Edit/CategoryForm.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Edit/CategoryForm.xml index 5db9812bcfe59206ff262f156d8c79d5a9e5c945..16a88a95a6893df51a5a398d4ed1a21c80b9752d 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Edit/CategoryForm.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Edit/CategoryForm.xml @@ -66,6 +66,15 @@ <default_sort_by> <input>select</input> </default_sort_by> + <display_mode> + <input>select</input> + </display_mode> + <landing_page> + <input>select</input> + </landing_page> + <is_anchor> + <input>select</input> + </is_anchor> </fields> </display_setting> <custom_design> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Widget/Chooser.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Widget/Chooser.php new file mode 100644 index 0000000000000000000000000000000000000000..ce943c65d2dfef5d0ed64ba2e72d0f73bfa996c6 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Widget/Chooser.php @@ -0,0 +1,53 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\Block\Adminhtml\Category\Widget; + +use Mtf\Block\Block; +use Mtf\Client\Element\Locator; + +/** + * Class CategoryChooser + * Backend Cms Page select category block + */ +class Chooser extends Block +{ + /** + * Category name selector + * + * @var string + */ + protected $categoryNameSelector = "//a/span[contains(text(),'%s')]"; + + /** + * Select category by name + * + * @param string $name + * @return void + */ + public function selectCategoryByName($name) + { + $this->_rootElement->find(sprintf($this->categoryNameSelector, $name), Locator::SELECTOR_XPATH)->click(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Attribute/Set/FormPageActions.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Attribute/Set/FormPageActions.php index a6a178968c474b17d6362e69f9b07f8cc5b1e8d5..3aaeb9b765da6ad8ef043a9ed6dec7bce67d1b90 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Attribute/Set/FormPageActions.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Attribute/Set/FormPageActions.php @@ -27,8 +27,8 @@ namespace Magento\Catalog\Test\Block\Adminhtml\Product\Attribute\Set; use Magento\Backend\Test\Block\FormPageActions as AbstractFormPageActions; /** - * Class Form - * Catalog Product Attribute form + * Class FormPageActions + * Form page actions in Attribute Set page */ class FormPageActions extends AbstractFormPageActions { @@ -38,4 +38,11 @@ class FormPageActions extends AbstractFormPageActions * @var string */ protected $saveButton = '.save-attribute-set'; + + /** + * "Delete" button + * + * @var string + */ + protected $deleteButton = '.delete'; } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Attribute/Set/Main.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Attribute/Set/Main.php index 627f5469f01d4ef986250ccd58bdfc45426b5211..fec00fd3d314902169768d4f0b3d22b1d9f49fda 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Attribute/Set/Main.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Attribute/Set/Main.php @@ -47,6 +47,20 @@ class Main extends Block */ protected $attribute = './/*[contains(@class,"x-tree-root-node")]//div/a/span[text()="%s"]'; + /** + * Attribute label locator + * + * @var string + */ + protected $attributeLabel = ".//*[contains(@id,'tree-div2')]//li[@class='x-tree-node']/div/a/span[text()='%s']"; + + /** + * Add group button locator + * + * @var string + */ + protected $addGroupButton = '[data-ui-id="adminhtml-catalog-product-set-edit-add-group-button"]'; + /** * Move Attribute to Attribute Group * @@ -54,7 +68,7 @@ class Main extends Block * @param string $attributeGroup * @return void */ - public function moveAttribute($attributeData, $attributeGroup) + public function moveAttribute(array $attributeData, $attributeGroup) { if (isset($attributeData['attribute_code'])) { $attribute = $attributeData['attribute_code']; @@ -82,16 +96,42 @@ class Main extends Block /** * Checks present Product Attribute on product_set Groups * - * @param $attributeLabel + * @param string $attributeLabel * @return bool */ public function checkProductAttribute($attributeLabel) { $attributeLabelLocator = sprintf( - ".//*[contains(@class,'x-tree-root-node')]//li[@class='x-tree-node']/div/a/span[text()='%s']", + ".//*[contains(@id,'tree-div1')]//li[@class='x-tree-node']/div/a/span[text()='%s']", $attributeLabel ); return $this->_rootElement->find($attributeLabelLocator, Locator::SELECTOR_XPATH)->isVisible(); } + + /** + * Checks present Unassigned Product Attribute + * + * @param string $attributeLabel + * @return bool + */ + public function checkUnassignedProductAttribute($attributeLabel) + { + $attributeLabelLocator = sprintf($this->attributeLabel, $attributeLabel); + + return $this->_rootElement->find($attributeLabelLocator, Locator::SELECTOR_XPATH)->isVisible(); + } + + /** + * Add attribute set group to Attribute Set + * + * @param string $groupName + * @return void + */ + public function addAttributeSetGroup($groupName) + { + $this->_rootElement->find($this->addGroupButton)->click(); + $this->_rootElement->setAlertText($groupName); + $this->_rootElement->acceptAlert(); + } } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Attribute/Set/Main/EditForm.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Attribute/Set/Main/EditForm.php new file mode 100644 index 0000000000000000000000000000000000000000..18607bb1587507573fde7f47f9e6aa112060da9a --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Attribute/Set/Main/EditForm.php @@ -0,0 +1,36 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\Block\Adminhtml\Product\Attribute\Set\Main; + +use Mtf\Block\Form as AbstractForm; + +/** + * Class EditForm + * Attribute Set form + */ +class EditForm extends AbstractForm +{ + // +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Attribute/Set/Main/EditForm.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Attribute/Set/Main/EditForm.xml new file mode 100644 index 0000000000000000000000000000000000000000..a17059154de6a53b8afcf021c1dc39775687536d --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Attribute/Set/Main/EditForm.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" ?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<mapping strict="0"> + <fields> + <attribute_set_name /> + </fields> +</mapping> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab.php old mode 100644 new mode 100755 index 192f4ea671de1f20458782de0b20ea119248890a..bdcbd5fa3022b5ef431254b884c7afc9a22ac8df --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab.php @@ -109,7 +109,7 @@ class AdvancedPricingTab extends Tab } } elseif (!empty($field['value'])) { $data = $this->dataMapping([$fieldName => $field]); - $formData[$fieldName] = $this->_getData($data, $this->_rootElement); + $formData += $this->_getData($data, $this->_rootElement); } } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab/OptionGroup.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab/OptionGroup.php index 9d98751f3928403d9ae0775a211ab46f93d74dd4..72a5d99b7f89600bb4ccb7ebd5afdbdea7e856ff 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab/OptionGroup.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab/OptionGroup.php @@ -25,13 +25,13 @@ namespace Magento\Catalog\Test\Block\Adminhtml\Product\Edit\AdvancedPricingTab; use Mtf\Client\Element; -use Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Options; +use Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Options\AbstractOptions; /** * Class OptionField * Form "Group prices" on the tab "Extended price" */ -class OptionGroup extends Options +class OptionGroup extends AbstractOptions { /** * 'Add Group Price' button selector diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab/OptionTier.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab/OptionTier.php index f62941712b8a126acc23c4a906e1beb15d1efa05..bafabe132a5ad6cfc8f2115763b6a17933a2f797 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab/OptionTier.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab/OptionTier.php @@ -25,13 +25,13 @@ namespace Magento\Catalog\Test\Block\Adminhtml\Product\Edit\AdvancedPricingTab; use Mtf\Client\Element; -use Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Options; +use Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Options\AbstractOptions; /** * Class OptionTier * Form 'Tier prices' on the 'Advanced Pricing' tab */ -class OptionTier extends Options +class OptionTier extends AbstractOptions { /** * 'Add Tier' button selector diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options.php similarity index 83% rename from dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab.php rename to dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options.php index 3238cb19301b619179fb609120a578b1e1a666e3..3b3056997e8ed85d8f7f472d312b6377ac864db5 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options.php @@ -22,17 +22,17 @@ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ -namespace Magento\Catalog\Test\Block\Adminhtml\Product\Edit; +namespace Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab; use Mtf\ObjectManager; use Mtf\Client\Element; use Magento\Backend\Test\Block\Widget\Tab; /** - * Class CustomOptionsTab + * Class Options * Product custom options tab */ -class CustomOptionsTab extends Tab +class Options extends Tab { /** * Custom option row CSS locator @@ -41,16 +41,6 @@ class CustomOptionsTab extends Tab */ protected $customOptionRow = '#product-custom-options-content .fieldset-wrapper:nth-child(%d)'; - /** - * Class name 'Subform' of the main tab form - * - * @var array - */ - protected $childrenForm = [ - 'Field' => 'CustomOptionsTab\OptionField', - 'Drop-down' => 'CustomOptionsTab\OptionDropDown' - ]; - /** * Add an option button * @@ -85,12 +75,10 @@ class CustomOptionsTab extends Tab $this->_fill($data, $rootElement); // Fill subform - if (isset($field['type']) && isset($this->childrenForm[$field['type']]) - && !empty($options) - ) { - /** @var \Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Options $optionsForm */ + if (isset($field['type']) && !empty($options)) { + /** @var \Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Options\OptionsAbstract $optionsForm */ $optionsForm = $this->blockFactory->create( - __NAMESPACE__ . '\\' . $this->childrenForm[$field['type']], + __NAMESPACE__ . '\Options\Type\\' . $this->optionNameConvert($field['type']), ['element' => $rootElement] ); @@ -137,12 +125,10 @@ class CustomOptionsTab extends Tab $formDataItem = $this->_getData($data, $rootElement); // Data collection subform - if (isset($field['type']) && isset($this->childrenForm[$field['type']]) - && !empty($options) - ) { - /** @var \Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Options $optionsForm */ + if (isset($field['type']) && !empty($options)) { + /** @var \Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Options\OptionsAbstract $optionsForm */ $optionsForm = $this->blockFactory->create( - __NAMESPACE__ . '\\' . $this->childrenForm[$field['type']], + __NAMESPACE__ . '\Options\Type\\' . $this->optionNameConvert($field['type']), ['element' => $rootElement] ); @@ -158,4 +144,19 @@ class CustomOptionsTab extends Tab return $formData; } + + /** + * Convert option name + * + * @param string $str + * @return string + */ + protected function optionNameConvert($str) + { + $str = str_replace([' ', '&'], "", $str); + if ($end = strpos($str, '-')) { + $str = substr($str, 0, $end) . ucfirst(substr($str, ($end + 1))); + } + return $str; + } } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Options.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/AbstractOptions.php similarity index 92% rename from dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Options.php rename to dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/AbstractOptions.php index f24a3a59eaa026c8f4d9f6c7c995f73bedefa9c6..7eb94ac733e38a1b50f6069e3bf69e0714edd893 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Options.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/AbstractOptions.php @@ -22,16 +22,16 @@ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ -namespace Magento\Catalog\Test\Block\Adminhtml\Product\Edit; +namespace Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Options; use Mtf\Client\Element; use Magento\Backend\Test\Block\Widget\Tab; /** - * Abstract class Options + * Abstract class AbstractOptions * Parent class for all forms of product options */ -abstract class Options extends Tab +abstract class AbstractOptions extends Tab { /** * Fills in the form of an array of input data diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/Area.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/Area.php new file mode 100644 index 0000000000000000000000000000000000000000..da9564cae1bcd312ad0b5ea2020fb026636146cb --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/Area.php @@ -0,0 +1,36 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Options\Type; + +use Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Options\AbstractOptions; + +/** + * Class Area + * Form "Text area" on tab product "Custom options" + */ +class Area extends AbstractOptions +{ + // Parent behavior +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab/OptionField.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/Area.xml similarity index 100% rename from dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab/OptionField.xml rename to dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/Area.xml diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/Checkbox.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/Checkbox.php new file mode 100644 index 0000000000000000000000000000000000000000..e1ff5cdc94970e397221a623086e364b23839b38 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/Checkbox.php @@ -0,0 +1,37 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Options\Type; + +use Mtf\Client\Element; +use Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Options\Type\DropDown as AbstractOptions; + +/** + * Class Checkbox + * Form "Option checkbox" on tab product "Custom options" + */ +class Checkbox extends AbstractOptions +{ + // Parent behavior +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab/OptionDropDown.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/Checkbox.xml similarity index 100% rename from dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab/OptionDropDown.xml rename to dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/Checkbox.xml diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/Date.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/Date.php new file mode 100644 index 0000000000000000000000000000000000000000..0d01fc2e08e6eb034128ddd522a5fd9df493ce0c --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/Date.php @@ -0,0 +1,36 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Options\Type; + +use Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Options\AbstractOptions; + +/** + * Class Date + * Form "Date" on tab product "Custom options" + */ +class Date extends AbstractOptions +{ + // Parent behavior +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/Date.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/Date.xml new file mode 100644 index 0000000000000000000000000000000000000000..d127f10cc56d9bfcf2cea32f9a0891c8cc539398 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/Date.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" ?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<mapping strict="0"> + <fields> + <price> + <selector>[id$='_price']</selector> + </price> + <price_type> + <selector>[id$='_price_type']</selector> + <input>select</input> + </price_type> + <sku> + <selector>[name$='[sku]']</selector> + </sku> + </fields> +</mapping> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/DateTime.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/DateTime.php new file mode 100644 index 0000000000000000000000000000000000000000..39ae959d3f89afa6a694d88b2fbd020953696323 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/DateTime.php @@ -0,0 +1,36 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Options\Type; + +use Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Options\AbstractOptions; + +/** + * Class DateTime + * Form "Date & Time" on tab product "Custom options" + */ +class DateTime extends AbstractOptions +{ + // Parent behavior +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/DateTime.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/DateTime.xml new file mode 100644 index 0000000000000000000000000000000000000000..d127f10cc56d9bfcf2cea32f9a0891c8cc539398 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/DateTime.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" ?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<mapping strict="0"> + <fields> + <price> + <selector>[id$='_price']</selector> + </price> + <price_type> + <selector>[id$='_price_type']</selector> + <input>select</input> + </price_type> + <sku> + <selector>[name$='[sku]']</selector> + </sku> + </fields> +</mapping> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab/OptionDropDown.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/DropDown.php similarity index 83% rename from dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab/OptionDropDown.php rename to dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/DropDown.php index 54a92ab01bd5cbd1e93207b6c244b22fd68dfbd2..c9a21a000810046a256e6f54a8b9be3ba1f56088 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab/OptionDropDown.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/DropDown.php @@ -22,23 +22,23 @@ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ -namespace Magento\Catalog\Test\Block\Adminhtml\Product\Edit\CustomOptionsTab; +namespace Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Options\Type; use Mtf\Client\Element; -use Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Options; +use Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Options\AbstractOptions; /** - * Class OptionDropDown + * Class DropDown * Form "Option dropdown" on tab product "Custom options" */ -class OptionDropDown extends Options +class DropDown extends AbstractOptions { /** * Add button css selector * * @var string */ - private $buttonAddLocator = '[id$="_add_select_row"]'; + protected $buttonAddLocator = '[id$="_add_select_row"]'; /** * Fill the form diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/DropDown.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/DropDown.xml new file mode 100644 index 0000000000000000000000000000000000000000..4dac6efd003d6b8f317418a7e16f3a8eafdec485 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/DropDown.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" ?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<mapping strict="0"> + <fields> + <title> + <selector>[id$="_title"]</selector> + </title> + <price> + <selector>[id$="_price"]</selector> + </price> + <price_type> + <selector>[id$="_price_type"]</selector> + <input>select</input> + </price_type> + <sku> + <selector>[name$='[sku]']</selector> + </sku> + </fields> +</mapping> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/Field.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/Field.php new file mode 100644 index 0000000000000000000000000000000000000000..87d0807614f6b42f1855dcb32e3d1f98bfc253e6 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/Field.php @@ -0,0 +1,36 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Options\Type; + +use Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Options\AbstractOptions; + +/** + * Class Field + * Form "Text field" on tab product "Custom options" + */ +class Field extends AbstractOptions +{ + // Parent behavior +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/Field.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/Field.xml new file mode 100644 index 0000000000000000000000000000000000000000..e5b42e7e52488ab41a91cd305821910f72738cbd --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/Field.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" ?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<mapping strict="0"> + <fields> + <price> + <selector>[id$='_price']</selector> + </price> + <price_type> + <selector>[id$='_price_type']</selector> + <input>select</input> + </price_type> + <sku> + <selector>[name$='[sku]']</selector> + </sku> + <max_characters> + <selector>[name$='[max_characters]']</selector> + </max_characters> + </fields> +</mapping> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/File.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/File.php new file mode 100644 index 0000000000000000000000000000000000000000..b2591e0af88ecd62e091e06b0f57ca9f32d36b9e --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/File.php @@ -0,0 +1,36 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Options\Type; + +use Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Options\AbstractOptions; + +/** + * Class File + * Form "Text file" on tab product "Custom options" + */ +class File extends AbstractOptions +{ + // Parent behavior +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/File.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/File.xml new file mode 100644 index 0000000000000000000000000000000000000000..46f641b1ef3b2ae983ae76d89db60e6e8b01f1f4 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/File.xml @@ -0,0 +1,48 @@ +<?xml version="1.0" ?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<mapping strict="0"> + <fields> + <price> + <selector>[name$='[price]']</selector> + </price> + <price_type> + <selector>[name$='[price_type]']</selector> + <input>select</input> + </price_type> + <sku> + <selector>[name$='[sku]']</selector> + </sku> + <file_extension> + <selector>[name$='[file_extension]']</selector> + </file_extension> + <image_size_x> + <selector>[name$='[image_size_x]']</selector> + </image_size_x> + <image_size_y> + <selector>[name$='[image_size_y]']</selector> + </image_size_y> + </fields> +</mapping> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/MultipleSelect.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/MultipleSelect.php new file mode 100644 index 0000000000000000000000000000000000000000..8523086ea1649d4a4569be1dfe96767618cf0e8e --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/MultipleSelect.php @@ -0,0 +1,37 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Options\Type; + +use Mtf\Client\Element; +use Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Options\Type\DropDown as AbstractOptions; + +/** + * Class MultipleSelect + * Form "Option multiple select" on tab product "Custom options" + */ +class MultipleSelect extends AbstractOptions +{ + // Parent behavior +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/MultipleSelect.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/MultipleSelect.xml new file mode 100644 index 0000000000000000000000000000000000000000..4dac6efd003d6b8f317418a7e16f3a8eafdec485 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/MultipleSelect.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" ?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<mapping strict="0"> + <fields> + <title> + <selector>[id$="_title"]</selector> + </title> + <price> + <selector>[id$="_price"]</selector> + </price> + <price_type> + <selector>[id$="_price_type"]</selector> + <input>select</input> + </price_type> + <sku> + <selector>[name$='[sku]']</selector> + </sku> + </fields> +</mapping> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/RadioButtons.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/RadioButtons.php new file mode 100644 index 0000000000000000000000000000000000000000..ca0a944d07c1b9297e6c92ae0b66456a60ed4c50 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/RadioButtons.php @@ -0,0 +1,37 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Options\Type; + +use Mtf\Client\Element; +use Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Options\Type\DropDown as AbstractOptions; + +/** + * Class RadioButtons + * Form "Option radio button" on tab product "Custom options" + */ +class RadioButtons extends AbstractOptions +{ + // Parent behavior +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/RadioButtons.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/RadioButtons.xml new file mode 100644 index 0000000000000000000000000000000000000000..4dac6efd003d6b8f317418a7e16f3a8eafdec485 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/RadioButtons.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" ?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<mapping strict="0"> + <fields> + <title> + <selector>[id$="_title"]</selector> + </title> + <price> + <selector>[id$="_price"]</selector> + </price> + <price_type> + <selector>[id$="_price_type"]</selector> + <input>select</input> + </price_type> + <sku> + <selector>[name$='[sku]']</selector> + </sku> + </fields> +</mapping> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/Time.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/Time.php new file mode 100644 index 0000000000000000000000000000000000000000..5307fb3ff3498668cf07d437d08ba218512fea06 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/Time.php @@ -0,0 +1,36 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Options\Type; + +use Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Options\AbstractOptions; + +/** + * Class Time + * Form "Date time" on tab product "Custom options" + */ +class Time extends AbstractOptions +{ + // Parent behavior +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/Time.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/Time.xml new file mode 100644 index 0000000000000000000000000000000000000000..d127f10cc56d9bfcf2cea32f9a0891c8cc539398 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Options/Type/Time.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" ?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<mapping strict="0"> + <fields> + <price> + <selector>[id$='_price']</selector> + </price> + <price_type> + <selector>[id$='_price_type']</selector> + <input>select</input> + </price_type> + <sku> + <selector>[name$='[sku]']</selector> + </sku> + </fields> +</mapping> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/ProductDetails/CategoryIds.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/ProductDetails/CategoryIds.php new file mode 100644 index 0000000000000000000000000000000000000000..2ffcee808d0468eb8aa5550edc85fcd44c3bc558 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/ProductDetails/CategoryIds.php @@ -0,0 +1,48 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\ProductDetails; + +use Mtf\Client\Driver\Selenium\Element\MultisuggestElement; + +/** + * Class CategoryIds + * Typified element class for category element + */ +class CategoryIds extends MultisuggestElement +{ + /** + * Selector suggest input + * + * @var string + */ + protected $suggest = '#category_ids-suggest'; + + /** + * Selector item of search result + * + * @var string + */ + protected $resultItem = './/li/a/span[@class="category-label"][text()="%s"]'; +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/ProductDetails/ProductOnlineSwitcher.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/ProductDetails/ProductOnlineSwitcher.php new file mode 100644 index 0000000000000000000000000000000000000000..c61f192582b14b3b013e72e19e2d884386cec5a7 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/ProductDetails/ProductOnlineSwitcher.php @@ -0,0 +1,79 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\ProductDetails; + +use Mtf\Client\Driver\Selenium\Element; + +/** + * Class ProductOnlineSwitcher + * Typified element class for product status element + */ +class ProductOnlineSwitcher extends Element +{ + /** + * CSS locator button status of the product + * + * @var string + */ + protected $onlineSwitcher = '#product-online-switcher%s + [for="product-online-switcher"]'; + + /** + * Set value + * + * @param string $value + * @return void + * @throws \Exception + */ + public function setValue($value) + { + if (!$this->find(sprintf($this->onlineSwitcher, ''))->isVisible()) { + throw new \Exception("Can't find product online switcher."); + } + if (($value === 'Product offline' && $this->find(sprintf($this->onlineSwitcher, ':checked'))->isVisible()) + || ($value === 'Product online' + && $this->find(sprintf($this->onlineSwitcher, ':not(:checked)'))->isVisible() + ) + ) { + $this->find(sprintf($this->onlineSwitcher, ''))->click(); + } + } + + /** + * Get value + * + * @return string + * @throws \Exception + */ + public function getValue() + { + if (!$this->find(sprintf($this->onlineSwitcher, ''))->isVisible()) { + throw new \Exception("Can't find product online switcher."); + } + if ($this->find(sprintf($this->onlineSwitcher, ':checked'))->isVisible()) { + return 'Product online'; + } + return 'Product offline'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Variations/Search.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Variations/Search.php new file mode 100644 index 0000000000000000000000000000000000000000..00a7d7297c521758210c1534713976fae99b5b03 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Variations/Search.php @@ -0,0 +1,100 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Variations; + +use Mtf\Client\Element; +use Mtf\Client\Driver\Selenium\Element\SuggestElement; +use Magento\Catalog\Test\Fixture\CatalogProductAttribute; + +/** + * Class FormAttributeSearch + * Form Attribute Search on Product page + */ +class Search extends SuggestElement +{ + /** + * Attribute Set locator + * + * @var string + */ + protected $value = '.action-toggle > span'; + + /** + * Attribute Set button + * + * @var string + */ + protected $actionToggle = '.action-toggle'; + + /** + * Search attribute result locator + * + * @var string + */ + protected $searchResult = '.mage-suggest-dropdown .ui-corner-all'; + + /** + * Set value + * + * @param string $value + * @return void + */ + public function setValue($value) + { + $this->find($this->actionToggle)->click(); + parent::setValue($value); + } + + /** + * Get value + * + * @return string + */ + public function getValue() + { + return $this->find($this->value)->getText(); + } + + /** + * Checking not exist configurable attribute in search result + * + * @param CatalogProductAttribute $productAttribute + * @return bool + */ + public function isExistAttributeInSearchResult(CatalogProductAttribute $productAttribute) + { + $attribute = $productAttribute->getFrontendLabel(); + $searchResult = $this->find($this->searchResult); + + $this->find($this->suggest)->setValue($attribute); + if (!$searchResult->isVisible()) { + return false; + } + if ($searchResult->getText() == $attribute) { + return true; + } + return false; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Websites/StoreTree.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Websites/StoreTree.php new file mode 100755 index 0000000000000000000000000000000000000000..1fbcd598a2ac08d2e30408a1f0c229cfcc9a256c --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Websites/StoreTree.php @@ -0,0 +1,89 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Websites; + +use Mtf\Client\Element\Locator; +use Mtf\Client\Driver\Selenium\Element; + +/** + * Class StoreTree + * Typified element class for store tree element + */ +class StoreTree extends Element +{ + /** + * Selector for website checkbox + * + * @var string + */ + protected $website = './/*[@class="website-name"]/label[contains(text(),"%s")]/../input'; + + /** + * Selector for selected website checkbox + * + * @var string + */ + protected $selectedWebsite = './/*[@class="website-name"]/input[@checked="checked"][%d]/../label'; + + /** + * Set value + * + * @param array|string $values + * @return void + * @throws \Exception + */ + public function setValue($values) + { + $values = is_array($values) ? $values : [$values]; + foreach ($values as $value) { + $website = $this->find(sprintf($this->website, $value), Locator::SELECTOR_XPATH); + if (!$website->isVisible()) { + throw new \Exception("Can't find website: \"{$value}\"."); + } + if (!$website->isSelected()) { + $website->click(); + } + } + } + + /** + * Get value + * + * @return array + */ + public function getValue() + { + $values = []; + + $count = 1; + $website = $this->find(sprintf($this->selectedWebsite, $count), Locator::SELECTOR_XPATH); + while ($website->isVisible()) { + $values[] = $website->getText(); + ++$count; + $website = $this->find(sprintf($this->selectedWebsite, $count), Locator::SELECTOR_XPATH); + } + return $values; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/FormPageActions.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/FormPageActions.php index 467ad465bc9552d906b53f9c4a98a8e5d0fe7126..b5fe622c14b4eba0372390a7201eeaeb5c5b65c0 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/FormPageActions.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/FormPageActions.php @@ -25,6 +25,7 @@ namespace Magento\Catalog\Test\Block\Adminhtml\Product; use Mtf\Page\BackendPage; +use Mtf\Client\Element\Locator; use Mtf\Fixture\FixtureInterface; use Magento\Backend\Test\Block\FormPageActions as ParentFormPageActions; @@ -34,6 +35,35 @@ use Magento\Backend\Test\Block\FormPageActions as ParentFormPageActions; */ class FormPageActions extends ParentFormPageActions { + /** + * Save and create new product - 'Save & New' + */ + const SAVE_NEW = 'new'; + + /** + * Save and create a duplicate product - 'Save & Duplicate' + */ + const SAVE_DUPLICATE = 'duplicate'; + + /** + * Save and close the product page - 'Save & Close' + */ + const SAVE_CLOSE = 'close'; + + /** + * CSS selector toggle "Save button" + * + * @var string + */ + protected $toggleButton = '[data-ui-id="page-actions-toolbar-save-split-button-dropdown"]'; + + /** + * Save type item + * + * @var string + */ + protected $saveTypeItem = '#save-split-button-%s-button'; + /** * "Save" button * @@ -55,4 +85,37 @@ class FormPageActions extends ParentFormPageActions $affectedAttributeSetForm = $page->getAffectedAttributeSetForm(); $affectedAttributeSetForm->fill($product)->confirm(); } + + /** + * Click save and duplicate action + * + * @return void + */ + public function saveAndDuplicate() + { + $this->_rootElement->find($this->toggleButton, Locator::SELECTOR_CSS)->click(); + $this->_rootElement->find(sprintf($this->saveTypeItem, static::SAVE_DUPLICATE), Locator::SELECTOR_CSS)->click(); + } + + /** + * Click save and new action + * + * @return void + */ + public function saveAndNew() + { + $this->_rootElement->find($this->toggleButton, Locator::SELECTOR_CSS)->click(); + $this->_rootElement->find(sprintf($this->saveTypeItem, static::SAVE_NEW), Locator::SELECTOR_CSS)->click(); + } + + /** + * Click save and new action + * + * @return void + */ + public function saveAndClose() + { + $this->_rootElement->find($this->toggleButton, Locator::SELECTOR_CSS)->click(); + $this->_rootElement->find(sprintf($this->saveTypeItem, static::SAVE_CLOSE), Locator::SELECTOR_CSS)->click(); + } } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Grid.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Grid.php index 316afd6e097f425dc4b73a7717dfb80322ab0fc3..4b628be44b590307fb82c8214b8a6714181da763 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Grid.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Grid.php @@ -34,6 +34,8 @@ class Grid extends ParentGrid { /** * Initialize block elements + * + * @var array */ protected $filters = [ 'name' => [ @@ -51,6 +53,20 @@ class Grid extends ParentGrid ], 'price_to' => [ 'selector' => '#productGrid_product_filter_price_to' + ], + 'qty_from' => [ + 'selector' => '#productGrid_product_filter_qty_from' + ], + 'qty_to' => [ + 'selector' => '#productGrid_product_filter_qty_to' + ], + 'visibility' => [ + 'selector' => '#productGrid_product_filter_visibility', + 'input' => 'select' + ], + 'status' => [ + 'selector' => '#productGrid_product_filter_status', + 'input' => 'select' ] ]; @@ -60,7 +76,7 @@ class Grid extends ParentGrid * @param array $items * @return void */ - public function updateAttributes(array $items = array()) + public function updateAttributes(array $items = []) { $this->massaction('Update Attributes', $items); } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/GridPageAction.php similarity index 88% rename from dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product.php rename to dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/GridPageAction.php index 611c058c430b746b066c880efb99184c0981f397..8ffaeae30cbe66610317f56b74cfd19123868ff9 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/GridPageAction.php @@ -22,17 +22,16 @@ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ -namespace Magento\Catalog\Test\Block\Adminhtml; +namespace Magento\Catalog\Test\Block\Adminhtml\Product; -use Mtf\Block\Block; +use Magento\Backend\Test\Block\GridPageActions as ParentGridPageActions; use Mtf\Client\Element\Locator; /** - * Class Product + * Class GridPageAction * Catalog manage products block - * */ -class Product extends Block +class GridPageAction extends ParentGridPageActions { /** * Product toggle button @@ -52,6 +51,7 @@ class Product extends Block * Add product using split button * * @param string $productType + * @return void */ public function addProduct($productType = 'simple') { diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/ProductForm.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/ProductForm.php index 5f54bf33a3f7093d04a56ceac5a4399183d75c18..f2ab98df6df055c71d864c3a6bcfd542068df5aa 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/ProductForm.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/ProductForm.php @@ -24,15 +24,12 @@ namespace Magento\Catalog\Test\Block\Adminhtml\Product; +use Magento\Backend\Test\Block\Widget\FormTabs; use Mtf\Client\Element; -use Mtf\Factory\Factory; -use Mtf\Client\Element\Locator; use Mtf\Fixture\FixtureInterface; use Mtf\Fixture\InjectableFixture; use Magento\Catalog\Test\Fixture\Product; -use Magento\Backend\Test\Block\Widget\Tab; -use Magento\Backend\Test\Block\Widget\FormTabs; -use Magento\Catalog\Test\Fixture\ConfigurableProduct; +use Mtf\Client\Element\Locator; use Magento\Catalog\Test\Fixture\CatalogCategory; use Magento\Catalog\Test\Fixture\CatalogProductAttribute; @@ -43,155 +40,101 @@ use Magento\Catalog\Test\Fixture\CatalogProductAttribute; class ProductForm extends FormTabs { /** - * New variation set button selector + * Attribute on the Product page * * @var string */ - protected $newVariationSet = '[data-ui-id="admin-product-edit-tab-super-config-grid-container-add-attribute"]'; + protected $attribute = './/*[contains(@class,"label")]/span[text()="%s"]'; /** - * Category name selector + * Attribute Search locator the Product page * * @var string */ - protected $categoryName = '//*[contains(@class, "mage-suggest-choice")]/*[text()="%categoryName%"]'; + protected $attributeSearch = '#product-attribute-search-container'; /** - * 'Advanced Settings' tab + * Selector for trigger(show/hide) of advanced setting content * * @var string */ - protected $advancedSettings = '#product_info_tabs-advanced [data-role="trigger"]'; + protected $advancedSettingTrigger = '#product_info_tabs-advanced [data-role="trigger"]'; /** - * Advanced tab list + * Selector for advanced setting content * * @var string */ - protected $advancedTabList = '#product_info_tabs-advanced[role="tablist"]'; - /** - * Advanced tab panel - * - * @var string - */ - protected $advancedTabPanel = './/*[role="tablist"]//ul[!contains(@style,"overflow")]'; + protected $advancedSettingContent = '#product_info_tabs-advanced [data-role="content"]'; /** - * CSS locator button status of the product + * Variations Attribute Search locator the Product page * * @var string */ - protected $onlineSwitcher = '#product-online-switcher%s + [for="product-online-switcher"]'; + protected $variationsAttributeSearch = '#variations-search-field'; /** - * Category fixture - * - * @var CatalogCategory - */ - protected $category; - - /** - * Attribute on the Product page + * Variations Tab locator the Product page * * @var string */ - protected $attribute = './/*[contains(@class,"label")]/span[text()="%s"]'; + protected $variationsTab = '#product_info_tabs_super_config_content .title'; /** - * Attribute Search locator the Product page + * Custom Tab locator * * @var string */ - protected $attributeSearch = '#product-attribute-search-container'; + protected $customTab = './/*/a[contains(@id,"product_info_tabs_%s")]'; /** * Fill the product form * - * @param FixtureInterface $fixture - * @param CatalogCategory $category - * @param Element $element - * @return $this + * @param FixtureInterface $product + * @param Element|null $element [optional] + * @param FixtureInterface|null $category [optional] + * @return FormTabs */ - public function fillProduct( - FixtureInterface $fixture, - CatalogCategory $category = null, - Element $element = null - ) { - $this->category = $category; - $this->fillCategory($fixture); + public function fill(FixtureInterface $product, Element $element = null, FixtureInterface $category = null) + { + $tabs = $this->getFieldsByTabs($product); - if ($fixture instanceof InjectableFixture) { - $status = $fixture->getStatus(); - if (($status === 'Product offline' - && $this->_rootElement->find(sprintf($this->onlineSwitcher, ':checked'))->isVisible()) - || ($status === 'Product online' - && $this->_rootElement->find(sprintf($this->onlineSwitcher, ':not(:checked)'))->isVisible()) - ) { - $this->_rootElement->find(sprintf($this->onlineSwitcher, ''))->click(); - } + if ($category) { + $tabs['product-details']['category_ids']['value'] = ($category instanceof InjectableFixture ) + ? $category->getName() + : $category->getCategoryName(); } - return parent::fill($fixture, $element); + $this->showAdvancedSettings(); + return parent::fillTabs($tabs, $element); } /** - * Select category + * Get data of the tabs * - * @param FixtureInterface $fixture - * @return void|null + * @param FixtureInterface|null $fixture + * @param Element|null $element + * @return array */ - protected function fillCategory(FixtureInterface $fixture) + public function getData(FixtureInterface $fixture = null, Element $element = null) { - // TODO should be removed after suggest widget implementation as typified element - $categoryName = null; - if (!empty($this->category)) { - $categoryName = $this->category->getName(); - } - if (empty($categoryName) && !($fixture instanceof InjectableFixture)) { - $categoryName = $fixture->getCategoryName(); - } - if (empty($categoryName)) { - return; - } - - $category = $this->_rootElement->find( - str_replace( - '%categoryName%', - $categoryName, - $this->categoryName - ), - Locator::SELECTOR_XPATH - ); - if (!$category->isVisible()) { - $this->fillCategoryField( - $categoryName, - 'category_ids-suggest', - '//*[@id="attribute-category_ids-container"]' - ); - } + $this->showAdvancedSettings(); + return parent::getData($fixture, $element); } /** - * Fills select category field + * Show Advanced Setting * - * @param string $name - * @param string $elementId - * @param string $parentLocation * @return void */ - protected function fillCategoryField($name, $elementId, $parentLocation) + protected function showAdvancedSettings() { - // TODO should be removed after suggest widget implementation as typified element - $this->_rootElement->find($elementId, Locator::SELECTOR_ID)->setValue($name); - $this->waitForElementVisible( - $parentLocation . '//div[@class="mage-suggest-dropdown"]', - Locator::SELECTOR_XPATH - ); - $this->_rootElement->find( - $parentLocation . '//li[contains(@data-suggest-option, \'"label":"' . $name . '",\')]//a', - Locator::SELECTOR_XPATH - )->click(); + if (!$this->_rootElement->find($this->advancedSettingContent)->isVisible()) { + $this->_rootElement->find($this->advancedSettingTrigger)->click(); + $this->waitForElementVisible($this->advancedSettingContent); + } } /** @@ -252,80 +195,6 @@ class ProductForm extends FormTabs $this->waitForElementVisible('input#new_category_name'); } - /** - * Open tab - * - * @param string $tabName - * @return Tab|bool - */ - public function openTab($tabName) - { - $rootElement = $this->_rootElement; - $selector = $this->tabs[$tabName]['selector']; - $strategy = isset($this->tabs[$tabName]['strategy']) - ? $this->tabs[$tabName]['strategy'] - : Locator::SELECTOR_CSS; - $tab = $this->_rootElement->find($selector, $strategy); - $advancedSettings = $this->_rootElement->find($this->advancedSettings); - - // Wait until all tabs will load - $advancedTabList = $this->advancedTabList; - $this->_rootElement->waitUntil( - function () use ($rootElement, $advancedTabList) { - return $rootElement->find($advancedTabList)->isVisible(); - } - ); - - if ($tab->isVisible()) { - $tab->click(); - } elseif ($advancedSettings->isVisible()) { - $advancedSettings->click(); - // Wait for open tab animation - $tabPanel = $this->advancedTabPanel; - $this->_rootElement->waitUntil( - function () use ($rootElement, $tabPanel) { - return $rootElement->find($tabPanel, Locator::SELECTOR_XPATH)->isVisible(); - } - ); - // Wait until needed tab will appear - $this->_rootElement->waitUntil( - function () use ($rootElement, $selector, $strategy, $tabPanel) { - $this->_rootElement->waitUntil( - function () use ($rootElement, $tabPanel) { - return $rootElement->find($tabPanel, Locator::SELECTOR_XPATH)->isVisible(); - } - ); - return $rootElement->find($selector, $strategy)->isVisible(); - } - ); - $tab->click(); - } else { - return false; - } - - return $this; - } - - /** - * Get data of the tabs - * - * @param FixtureInterface|null $fixture - * @param Element|null $element - * @return array - */ - public function getData(FixtureInterface $fixture = null, Element $element = null) - { - $data = parent::getData($fixture); - if ($fixture->hasData('status')) { - $data['status'] = 'Product offline'; - if ($this->_rootElement->find(sprintf($this->onlineSwitcher, ':checked'))->isVisible()) { - $data['status'] = 'Product online'; - } - } - - return $data; - } - /** * Check visibility of the attribute on the product page * @@ -348,7 +217,7 @@ class ProductForm extends FormTabs * @param CatalogProductAttribute $productAttribute * @return bool */ - public function checkAttributeInSearchAttributeForm($productAttribute) + public function checkAttributeInSearchAttributeForm(CatalogProductAttribute $productAttribute) { return $this->_rootElement->find( $this->attributeSearch, @@ -356,4 +225,56 @@ class ProductForm extends FormTabs 'Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Attributes\Search' )->isExistAttributeInSearchResult($productAttribute); } + + /** + * Call method that checking present attribute in search result + * + * @param CatalogProductAttribute $productAttribute + * @return bool + */ + public function checkAttributeInVariationsSearchAttributeForm(CatalogProductAttribute $productAttribute) + { + return $this->_rootElement->find( + $this->variationsAttributeSearch, + Locator::SELECTOR_CSS, + 'Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Variations\Search' + )->isExistAttributeInSearchResult($productAttribute); + } + + /** + * Open Variations tab on Product form + * + * @return void + */ + public function openVariationsTab() + { + if (!$this->_rootElement->find($this->variationsAttributeSearch, Locator::SELECTOR_CSS)->isVisible()) { + $this->_rootElement->find($this->variationsTab, Locator::SELECTOR_CSS)->click(); + } + } + + /** + * Check tab visibility on Product form + * + * @param string $tabName + * @return bool + */ + public function isTabVisible($tabName) + { + $tabName = strtolower($tabName); + + return $this->_rootElement->find(sprintf($this->customTab, $tabName), Locator::SELECTOR_XPATH)->isVisible(); + } + + /** + * Open custom tab on Product form + * + * @param string $tabName + * @return void + */ + public function openCustomTab($tabName) + { + $tabName = strtolower($tabName); + $this->_rootElement->find(sprintf($this->customTab, $tabName), Locator::SELECTOR_XPATH)->click(); + } } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/ProductForm.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/ProductForm.xml index 8e443f1eac124d5569eaa26a34c87aab6b3548a3..56f08f31376a55ae9506bfa17c54931e57cfdd3b 100755 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/ProductForm.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/ProductForm.xml @@ -29,35 +29,40 @@ <selector>#product_info_tabs_product-details</selector> <strategy>css selector</strategy> <wrapper>product</wrapper> - <fields> - <attribute_set_id> - <selector>#product-template-suggest-container</selector> - <class>Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\ProductDetails\AttributeSet</class> - </attribute_set_id> - <attribute_id> - <selector>#product-attribute-search-container</selector> - <class>Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Attributes\Search</class> - </attribute_id> - <tax_class_id> + <fields> + <status> + <selector>.product-actions .switcher</selector> + <class>Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\ProductDetails\ProductOnlineSwitcher</class> + </status> + <attribute_set_id> + <selector>#product-template-suggest-container</selector> + <class>Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\ProductDetails\AttributeSet</class> + </attribute_set_id> + <attribute_id> + <selector>#product-attribute-search-container</selector> + <class>Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Attributes\Search</class> + </attribute_id> + <tax_class_id> + <input>select</input> + </tax_class_id> + <is_virtual> + <input>checkbox</input> + </is_virtual> + <category_ids> + <selector>#attribute-category_ids-container</selector> + <class>Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\ProductDetails\CategoryIds</class> + </category_ids> + <quantity_and_stock_status composite="1"> + <qty> + <selector>[name="product[quantity_and_stock_status][qty]"]</selector> + </qty> + <is_in_stock> + <selector>[name="product[quantity_and_stock_status][is_in_stock]"]</selector> <input>select</input> - </tax_class_id> - <is_virtual> - <input>checkbox</input> - </is_virtual> - <quantity_and_stock_status composite="1"> - <qty> - <selector>#qty</selector> - </qty> - <is_in_stock> - <selector>#quantity_and_stock_status</selector> - <input>select</input> - </is_in_stock> - </quantity_and_stock_status> - <description> - <selector>#description</selector> - <input>textarea</input> - </description> - </fields> + </is_in_stock> + </quantity_and_stock_status> + <description /> + </fields> </product-details> <websites> <class>\Magento\Backend\Test\Block\Widget\Tab</class> @@ -66,8 +71,8 @@ <wrapper>product</wrapper> <fields> <website_ids> - <selector>[name='product[website_ids][]']</selector> - <input>checkbox</input> + <selector>#product_info_tabs_websites_content .store-tree</selector> + <class>\Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Websites\StoreTree</class> </website_ids> </fields> </websites> @@ -88,20 +93,25 @@ <strategy>css selector</strategy> <wrapper>product[stock_data]</wrapper> <fields> - <inventory_manage_stock> - <selector>[name='product[stock_data][manage_stock]']</selector> - <input>select</input> - </inventory_manage_stock> - <inventory_qty> - <selector>[name='product[stock_data][qty]']</selector> - </inventory_qty> - <stock_data_use_config_min_qty> - <selector>[name='product[stock_data][use_config_min_qty]']</selector> - <input>checkbox</input> - </stock_data_use_config_min_qty> - <stock_data_min_qty> - <selector>[name='product[stock_data][min_qty]']</selector> - </stock_data_min_qty> + <stock_data composite="1"> + <manage_stock> + <selector>[name='product[stock_data][manage_stock]']</selector> + <input>select</input> + </manage_stock> + <qty> + <selector>[name='product[stock_data][qty]']</selector> + </qty> + <use_config_min_qty> + <selector>[name='product[stock_data][use_config_min_qty]']</selector> + <input>checkbox</input> + </use_config_min_qty> + <min_qty> + <selector>[name='product[stock_data][min_qty]']</selector> + </min_qty> + <use_config_manage_stock> + <input>checkbox</input> + </use_config_manage_stock> + </stock_data> </fields> </advanced-inventory> <autosettings> @@ -117,7 +127,16 @@ <selector>#short_description</selector> <input>textarea</input> </short_description> - <url_key></url_key> + <is_returnable> + <input>select</input> + </is_returnable> + <url_key/> + <gift_message_available> + <input>select</input> + </gift_message_available> + <use_config_gift_message_available> + <input>checkbox</input> + </use_config_gift_message_available> </fields> </autosettings> <variations> @@ -131,7 +150,7 @@ <strategy>css selector</strategy> </grouped-product> <customer-options> - <class>\Magento\Catalog\Test\Block\Adminhtml\Product\Edit\CustomOptionsTab</class> + <class>\Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Options</class> <selector>#product_info_tabs_customer_options</selector> <strategy>css selector</strategy> <fields> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Widget/Chooser.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Widget/Chooser.php new file mode 100644 index 0000000000000000000000000000000000000000..1dbd80cdc3310625889e479421baaa6eed9a2ee4 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Widget/Chooser.php @@ -0,0 +1,52 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\Block\Adminhtml\Product\Widget; + +use Magento\Backend\Test\Block\Widget\Grid; + +/** + * Class Chooser + * Backend Cms Page select product grid + */ +class Chooser extends Grid +{ + /** + * Filters array mapping + * + * @var array + */ + protected $filters = [ + 'chooser_sku' => [ + 'selector' => 'input[name="chooser_sku"]' + ], + ]; + + /** + * Locator value for link in sku column + * + * @var string + */ + protected $editLink = 'td.col-sku'; +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Backend/ProductForm.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Backend/ProductForm.xml index 6de3916287afa53d7e5824ba16519d4efb46ed72..8e7c8113ab29e46632ec0e49dc909ee001958d91 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Backend/ProductForm.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Backend/ProductForm.xml @@ -111,7 +111,7 @@ <strategy>css selector</strategy> </grouped-product> <customer-options> - <class>\Magento\Catalog\Test\Block\Adminhtml\Product\Edit\CustomOptionsTab</class> + <class>\Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Options</class> <selector>#product_info_tabs_customer_options</selector> <strategy>css selector</strategy> <fields> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Category/View.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Category/View.php old mode 100644 new mode 100755 index 4b5a13b3108cd8580889792bef6c2ec751220969..b056a546fb3ca27d7c18243844391d7f8ac4c70d --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Category/View.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Category/View.php @@ -37,7 +37,7 @@ class View extends Block * * @var string */ - protected $description = '.category.description'; + protected $description = '.category-description'; /** * Get description @@ -48,4 +48,14 @@ class View extends Block { return $this->_rootElement->find($this->description)->getText(); } + + /** + * Get Category Content + * + * @return string + */ + public function getContent() + { + return $this->_rootElement->getText(); + } } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Compare/ListCompare.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Compare/ListCompare.php new file mode 100644 index 0000000000000000000000000000000000000000..98cfd200d72d1f45ba87d06e3c9d543cf9b7ba8b --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Compare/ListCompare.php @@ -0,0 +1,218 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\Block\Product\Compare; + +use Mtf\Block\Block; +use Mtf\Client\Element; +use Mtf\Client\Element\Locator; + +/** + * Class ListCompare + * Compare list product block + */ +class ListCompare extends Block +{ + /** + * Selector by product info + * + * @var string + */ + protected $productInfo = '//td[contains(@class, "cell product info")][%d]'; + + /** + * Selector by product attribute + * + * @var string + */ + protected $productAttribute = '//tr[th//*[normalize-space(text()) = "%s"]]'; + + /** + * Selector by name product + * + * @var string + */ + protected $nameSelector = './/*[contains(@class, "product name")]/a'; + + /** + * Selector for search product via name + * + * @var string + */ + protected $productName = '[normalize-space(text()) = "%s"]'; + + /** + * Selector by price product + * + * @var string + */ + protected $priceSelector = './/div[contains(@class,"price-box")]'; + + /** + * Selector by sku product + * + * @var string + */ + protected $attributeSelector = './td[%d]/div'; + + /** + * Remove button selector + * + * @var string + */ + protected $removeButton = './/thead//td[%d]//a[contains(@class,"action delete")]'; + + /** + * Selector for empty message + * + * @var string + */ + protected $isEmpty = 'p.empty'; + + /** + * Get product info + * + * @param int $index + * @param string $attributeKey + * @param string $currency + * @return string + */ + public function getProductInfo($index, $attributeKey, $currency = ' $') + { + $infoBlock = $this->getCompareProductInfo($index); + if ($attributeKey == 'price') { + $price = $infoBlock->find($this->priceSelector, Locator::SELECTOR_XPATH)->getText(); + preg_match_all('`([a-z]+).*?([\d\.]+)`i', $price, $prices); + if (!empty($prices[0])) { + $resultPrice = []; + foreach ($prices[1] as $key => $value) { + $resultPrice['price_' . lcfirst($value)] = $prices[2][$key]; + } + return $resultPrice; + } + return trim($price, $currency); + } else { + return $infoBlock->find($this->nameSelector, Locator::SELECTOR_XPATH)->getText(); + } + } + + /** + * Get item compare product info + * + * @param int $index + * @return Element + */ + protected function getCompareProductInfo($index) + { + return $this->_rootElement->find(sprintf($this->productInfo, $index), Locator::SELECTOR_XPATH); + } + + /** + * Get item compare product attribute + * + * @param string $key + * @return Element + */ + protected function getCompareProductAttribute($key) + { + return $this->_rootElement->find(sprintf($this->productAttribute, $key), Locator::SELECTOR_XPATH); + } + + /** + * Get item attribute + * + * @param int $indexProduct + * @param string $attributeKey + * @return string + */ + public function getProductAttribute($indexProduct, $attributeKey) + { + return trim( + $this->getCompareProductAttribute($attributeKey) + ->find(sprintf($this->attributeSelector, $indexProduct), Locator::SELECTOR_XPATH)->getText() + ); + } + + /** + * Remove product from compare product list + * + * @param int $index [optional] + * @return void + */ + public function removeProduct($index = 1) + { + $this->_rootElement->find(sprintf($this->removeButton, $index), Locator::SELECTOR_XPATH)->click(); + } + + /** + * Remove all products from compare product list + * + * @return void + */ + public function removeAllProducts() + { + while ($this->isProductVisible()) { + $this->removeProduct(); + $this->reinitRootElement(); + } + } + + /** + * Visible product in compare product list + * + * @param int $index [optional] + * @return bool + */ + public function isProductVisible($index = 1) + { + return $this->_rootElement->find(sprintf($this->removeButton, $index), Locator::SELECTOR_XPATH)->isVisible(); + } + + /** + * Verify product is visible in compare product block + * + * @param string $productName + * @return bool + */ + public function isProductVisibleInCompareBlock($productName = '') + { + $nameSelector = $this->nameSelector . sprintf($this->productName, $productName); + return $this->_rootElement->find($nameSelector, Locator::SELECTOR_XPATH)->isVisible(); + } + + /** + * Get empty message on compare product block + * Returns message absence of compared products or false, if the message isn't visible + * + * @return string|bool + */ + public function getEmptyMessage() + { + $isEmpty = $this->_rootElement->find($this->isEmpty); + if ($isEmpty->isVisible()) { + return $isEmpty->getText(); + } + return false; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Compare/Sidebar.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Compare/Sidebar.php new file mode 100644 index 0000000000000000000000000000000000000000..fc668a01879fd0e7433f0949aec5c100ada6ad00 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Compare/Sidebar.php @@ -0,0 +1,85 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\Block\Product\Compare; + +use Mtf\Client\Element; + +/** + * Class Sidebar + * Compare product block on cms page + */ +class Sidebar extends ListCompare +{ + /** + * Selector for empty message + * + * @var string + */ + protected $isEmpty = 'p.empty'; + + /** + * Product name selector + * + * @var string + */ + protected $productName = 'li.item.odd.last strong.name a'; + + /** + * Selector for "Clear All" button + * + * @var string + */ + protected $clearAll = '#compare-clear-all'; + + /** + * Get compare products block content + * + * @return array|string + */ + public function getProducts() + { + $result = []; + $isEmpty = $this->_rootElement->find($this->isEmpty); + if ($isEmpty->isVisible()) { + return $isEmpty->getText(); + } + $elements = $this->_rootElement->find($this->productName)->getElements(); + foreach ($elements as $element) { + $result[] = $element->getText(); + } + return $result; + } + + /** + * Click "Clear All" on "My Account" page + * + * @return void + */ + public function clickClearAll() + { + $this->_rootElement->find($this->clearAll)->click(); + $this->_rootElement->acceptAlert(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Price.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Price.php old mode 100644 new mode 100755 index 0b5c6aead82ba111c50544bdd989f7711f67bd25..726ec183155570c7b02cb80f0f011ca27272187e --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Price.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Price.php @@ -65,7 +65,7 @@ class Price extends Block * * @var string */ - protected $priceMap = '.old.price .price'; + protected $priceMap = '.old.price .price .price'; /** * Actual Price @@ -113,6 +113,7 @@ class Price extends Block //@TODO it have to rewrite when will be possibility to divide it to different blocks(by product type) $prices = explode("\n", trim($this->_rootElement->getText())); if (count($prices) === 1) { + $prices[0] = str_replace(',', '', $prices[0]); return ['price_regular_price' => trim($prices[0], $currency)]; } return $this->formatPricesData($prices, $currency); @@ -131,7 +132,7 @@ class Price extends Block foreach ($prices as $price) { list($name, $price) = explode($currency, $price); $name = str_replace(' ', '_', trim(preg_replace('#[^0-9a-z]+#i', ' ', strtolower($name)), ' ')); - $formatted['price_' . $name] = $price; + $formatted['price_' . $name] = str_replace(',', '', $price); } return $formatted; } @@ -259,20 +260,22 @@ class Price extends Block /** * Get price from * - * @return array|string + * @param string $currency + * @return string */ - public function getPriceFrom() + public function getPriceFrom($currency = '$') { - return $this->_rootElement->find($this->priceFromSelector)->getText(); + return trim($this->_rootElement->find($this->priceFromSelector)->getText(), $currency); } /** * Get price to * - * @return array|string + * @param string $currency + * @return string */ - public function getPriceTo() + public function getPriceTo($currency = '$') { - return $this->_rootElement->find($this->priceToSelector)->getText(); + return trim($this->_rootElement->find($this->priceToSelector)->getText(), $currency); } } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View.php index 627382ba707a7438fe2dcc516fd20b227f63cd71..6b984e17225a0c183e6a3366215f6e1f1832f37b 100755 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View.php @@ -34,9 +34,19 @@ use Magento\Catalog\Test\Fixture\ConfigurableProduct; /** * Class View * Product view block on the product page + * + * @SuppressWarnings(PHPMD.TooManyFields) + * @SuppressWarnings(PHPMD.ExcessivePublicCount) */ class View extends Block { + /** + * Custom options CSS selector + * + * @var string + */ + protected $customOptionsSelector = '.product-options-wrapper'; + /** * 'Add to Cart' button * @@ -70,7 +80,7 @@ class View extends Block * * @var string */ - protected $productName = '.page-title.product span'; + protected $productName = '.page-title.product h1.title .base'; /** * Product sku element @@ -142,6 +152,20 @@ class View extends Block */ protected $tierPricesSelector = "//ul[contains(@class,'tier')]//*[@class='item'][%line-number%]"; + /** + * Selector for price block + * + * @var string + */ + protected $priceBlock = '.product-info-main .price-box'; + + /** + * 'Add to Compare' button + * + * @var string + */ + protected $clickAddToCompare = '.action.tocompare'; + /** * Get bundle options block * @@ -161,9 +185,7 @@ class View extends Block */ protected function getPriceBlock() { - return Factory::getBlockFactory()->getMagentoCatalogProductPrice( - $this->_rootElement->find('.product-info-main .price-box') - ); + return Factory::getBlockFactory()->getMagentoCatalogProductPrice($this->_rootElement->find($this->priceBlock)); } /** @@ -263,6 +285,19 @@ class View extends Block ); } + /** + * This method returns the custom options block. + * + * @return \Magento\Catalog\Test\Block\Product\View\CustomOptions + */ + public function getCustomOptionsBlock() + { + return $this->blockFactory->create( + 'Magento\Catalog\Test\Block\Product\View\CustomOptions', + ['element' => $this->_rootElement->find($this->customOptionsSelector)] + ); + } + /** * Return product price displayed on page * @@ -358,14 +393,14 @@ class View extends Block } if ($configureSection->isVisible()) { $productOptions = $product->getProductOptions(); - $this->getBundleBlock()->fillProductOptions($productOptions); + $this->getCustomOptionsBlock()->fillProductOptions($productOptions); } } /** * This method return array tier prices * - * @param int $lineNumber + * @param int $lineNumber [optional] * @return array */ public function getTierPrices($lineNumber = 1) @@ -384,7 +419,7 @@ class View extends Block public function clickCustomize() { $this->_rootElement->find($this->customizeButton)->click(); - + $this->waitForElementVisible($this->addToCart); } /** @@ -445,6 +480,16 @@ class View extends Block */ public function stockAvailability() { - return $this->_rootElement->find($this->stockAvailability)->getText(); + return strtolower($this->_rootElement->find($this->stockAvailability)->getText()); + } + + /** + * Click "Add to Compare" button + * + * @return void + */ + public function clickAddToCompare() + { + $this->_rootElement->find($this->clickAddToCompare, Locator::SELECTOR_CSS)->click(); } } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View/CustomOptions.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View/CustomOptions.php old mode 100644 new mode 100755 index 3d80fabc9215167f0e1a7683a10513de386f90b3..af6f96cb6677275f238d29a78dac5ec439e07008 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View/CustomOptions.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View/CustomOptions.php @@ -24,73 +24,86 @@ namespace Magento\Catalog\Test\Block\Product\View; -use Mtf\Block\Block; +use Mtf\Block\Form; use Mtf\Client\Element; use Mtf\Client\Element\Locator; +use Mtf\Fixture\FixtureInterface; /** * Class Custom Options - * Block of custom options product - * - * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * Form of custom options product */ -class CustomOptions extends Block +class CustomOptions extends Form { /** - * Regexp price pattern + * Selector for options context + * + * @var string + */ + protected $optionsContext = '#product-options-wrapper > fieldset'; + + /** + * Selector for single option block + * + * @var string + */ + protected $optionElement = './div[contains(@class,"field")][%d]'; + + /** + * Selector for title of option * * @var string */ - protected $pricePattern = '#\$([\d,]+\.\d+)$#'; + protected $title = './label/span[1]'; /** - * Field set XPath locator + * Selector for required option * * @var string */ - protected $fieldsetLocator = '//*[@id="product-options-wrapper"]//*[@class="fieldset"]'; + protected $required = './self::*[contains(@class,"required")]'; /** - * Field XPath locator + * Selector for price notice of option * * @var string */ - protected $fieldLocator = '/div[not(contains(@class,"downloads")) and contains(@class,"field")%s][%d]'; + protected $priceNotice = './/*[@class="price-notice"]'; /** - * Required field XPath locator + * Selector for max characters of option * * @var string */ - protected $requiredLocator = ' and contains(@class,"required")'; + protected $maxCharacters = './/div[@class="control"]/p[@class="note"]/strong'; /** - * Select field XPath locator + * Selector for label of option value element * * @var string */ - protected $selectLocator = './div[contains(@class,"control")]//select'; + protected $optionLabel = './/div[@class="control"]//label[contains(@for, "options_")][%d]'; /** - * Title value CSS locator + * Select note of option by number * * @var string */ - protected $titleLocator = '.label span:not(.price-notice)'; + protected $noteByNumber = './/*[@class="note"][%d]/strong'; /** - * Price value CSS locator + * Selector for select element of option * * @var string */ - protected $priceLocator = '.label .price-notice'; + protected $selectOption = './/div[@class="control"]/select'; /** - * Option XPath locator + * Selector for option of select element * * @var string */ - protected $optionLocator = './option[%d]'; + protected $option = './/option[%d]'; /** * Option XPath locator by value @@ -107,68 +120,302 @@ class CustomOptions extends Block protected $selectByTitleLocator = '//*[*[@class="product-options-wrapper"]//span[text()="%s"]]//select'; /** - * Bundle field CSS locator + * Select XPath locator by option name * * @var string */ - protected $bundleFieldLocator = '#product-options-wrapper > .fieldset > .field'; + protected $optionByName = '//*[label//span[contains(.,"%s")]]'; /** * Get product options * + * @param FixtureInterface|null $product [optional] * @return array + * @throws \Exception */ - public function getOptions() + public function getOptions(FixtureInterface $product = null) { - $options = []; - $index = 1; + $dataOptions = ($product && $product->hasData('custom_options')) ? $product->getCustomOptions() : []; + $listCustomOptions = $this->getListCustomOptions(); + $readyOptions = []; + $result = []; - $fieldElement = $this->_rootElement->find( - $this->fieldsetLocator . sprintf($this->fieldLocator, '', $index), - Locator::SELECTOR_XPATH - ); - - while ($fieldElement && $fieldElement->isVisible()) { - $option = ['price' => []]; - $option['is_require'] = $this->_rootElement->find( - $this->fieldsetLocator . sprintf($this->fieldLocator, $this->requiredLocator, $index), - Locator::SELECTOR_XPATH - )->isVisible(); - $option['title'] = $fieldElement->find($this->titleLocator)->getText(); - - if (($price = $fieldElement->find($this->priceLocator)) - && $price->isVisible() - ) { - $matches = []; - $value = $price->getText(); - if (preg_match($this->pricePattern, $value, $matches)) { - $option['value'][] = $value; - $option['price'][] = $matches[1]; - } - } elseif (($prices = $fieldElement->find($this->selectLocator, Locator::SELECTOR_XPATH)) - && $prices->isVisible() - ) { - $priceIndex = 0; - while (($price = $prices->find(sprintf($this->optionLocator, ++$priceIndex), Locator::SELECTOR_XPATH)) - && $price->isVisible() - ) { - $matches = []; - $value = $price->getText(); - if (preg_match($this->pricePattern, $value, $matches)) { - $option['value'][] = $value; - $option['price'][] = $matches[1]; - } - } + foreach ($dataOptions as $option) { + $title = $option['title']; + if (!isset($listCustomOptions[$title])) { + throw new \Exception("Can't find option: \"{$title}\""); } - $options[$option['title']] = $option; - ++$index; - $fieldElement = $this->_rootElement->find( - $this->fieldsetLocator . sprintf($this->fieldLocator, '', $index), - Locator::SELECTOR_XPATH - ); + + /** @var Element $optionElement */ + $optionElement = $listCustomOptions[$title]; + $typeMethod = preg_replace('/[^a-zA-Z]/', '', $option['type']); + $getTypeData = 'get' . ucfirst(strtolower($typeMethod)) . 'Data'; + + $optionData = $this->$getTypeData($optionElement); + $optionData['title'] = $title; + $optionData['type'] = $option['type']; + $optionData['is_require'] = $optionElement->find($this->required, Locator::SELECTOR_XPATH)->isVisible() + ? 'Yes' + : 'No'; + + $readyOptions[] = $title; + $result[$title] = $optionData; + } + + $unreadyCustomOptions = array_diff_key($listCustomOptions, array_flip($readyOptions)); + foreach ($unreadyCustomOptions as $optionElement) { + $title = $optionElement->find($this->title, Locator::SELECTOR_XPATH)->getText(); + $result[$title] = ['title' => $title]; + } + + return $result; + } + + /** + * Get list custom options + * + * @return array + */ + protected function getListCustomOptions() + { + $customOptions = []; + $context = $this->_rootElement->find($this->optionsContext); + + $count = 1; + $optionElement = $context->find(sprintf($this->optionElement, $count), Locator::SELECTOR_XPATH); + while ($optionElement->isVisible()) { + $title = $optionElement->find($this->title, Locator::SELECTOR_XPATH)->getText(); + $customOptions[$title] = $optionElement; + ++$count; + $optionElement = $context->find(sprintf($this->optionElement, $count), Locator::SELECTOR_XPATH); + } + return $customOptions; + } + + /** + * Get data of "Field" custom option + * + * @param Element $option + * @return array + */ + protected function getFieldData(Element $option) + { + $price = $this->getOptionPriceNotice($option); + $maxCharacters = $option->find($this->maxCharacters, Locator::SELECTOR_XPATH); + + return [ + 'options' => [ + [ + 'price' => floatval($price), + 'max_characters' => $maxCharacters->isVisible() ? $maxCharacters->getText() : null, + ] + ] + ]; + } + + /** + * Get data of "Area" custom option + * + * @param Element $option + * @return array + */ + protected function getAreaData(Element $option) + { + return $this->getFieldData($option); + } + + /** + * Get data of "File" custom option + * + * @param Element $option + * @return array + */ + protected function getFileData(Element $option) + { + $price = $this->getOptionPriceNotice($option); + + return [ + 'options' => [ + [ + 'price' => floatval($price), + 'file_extension' => $this->getOptionNotice($option, 1), + 'image_size_x' => preg_replace('/[^0-9]/', '', $this->getOptionNotice($option, 2)), + 'image_size_y' => preg_replace('/[^0-9]/', '', $this->getOptionNotice($option, 3)), + ] + ] + ]; + } + + /** + * Get data of "Drop-down" custom option + * + * @param Element $option + * @return array + */ + protected function getDropdownData(Element $option) + { + $select = $option->find($this->selectOption, Locator::SELECTOR_XPATH, 'select'); + // Skip "Choose option ..."(option #1) + return $this->getSelectOptionsData($select, 2); + } + + /** + * Get data of "Multiple Select" custom option + * + * @param Element $option + * @return array + */ + protected function getMultipleSelectData(Element $option) + { + $multiselect = $option->find($this->selectOption, Locator::SELECTOR_XPATH, 'multiselect'); + return $this->getSelectOptionsData($multiselect, 1); + } + + /** + * Get data of "Radio Buttons" custom option + * + * @param Element $option + * @return array + */ + protected function getRadioButtonsData(Element $option) + { + $listOptions = []; + + $count = 1; + $option = $option->find(sprintf($this->optionLabel, $count), Locator::SELECTOR_XPATH); + while ($option->isVisible()) { + $listOptions[] = $this->parseOptionText($option->getText()); + ++$count; + $option = $option->find(sprintf($this->optionLabel, $count), Locator::SELECTOR_XPATH); + } + + return [ + 'options' => $listOptions + ]; + } + + /** + * Get data of "Checkbox" custom option + * + * @param Element $option + * @return array + */ + protected function getCheckboxData(Element $option) + { + return $this->getRadioButtonsData($option); + } + + /** + * Get data of "Date" custom option + * + * @param Element $option + * @return array + */ + protected function getDateData(Element $option) + { + $price = $this->getOptionPriceNotice($option); + + return [ + 'options' => [ + [ + 'price' => floatval($price) + ] + ] + ]; + } + + /** + * Get data of "Date & Time" custom option + * + * @param Element $option + * @return array + */ + protected function getDateTimeData(Element $option) + { + return $this->getDateData($option); + } + + /** + * Get data of "Time" custom option + * + * @param Element $option + * @return array + */ + protected function getTimeData(Element $option) + { + return $this->getDateData($option); + } + + /** + * Get data from option of select and multiselect + * + * @param Element $element + * @param int $firstOption + * @return array + */ + protected function getSelectOptionsData(Element $element, $firstOption = 1) + { + $listOptions = []; + + $count = $firstOption; + $selectOption = $element->find(sprintf($this->option, $count), Locator::SELECTOR_XPATH); + while ($selectOption->isVisible()) { + $listOptions[] = $this->parseOptionText($selectOption->getText()); + ++$count; + $selectOption = $element->find(sprintf($this->option, $count), Locator::SELECTOR_XPATH); } - return $options; + return [ + 'options' => $listOptions + ]; + } + + /** + * Get price from price-notice of custom option + * + * @param Element $option + * @return array + */ + protected function getOptionPriceNotice(Element $option) + { + $priceNotice = $option->find($this->priceNotice, Locator::SELECTOR_XPATH); + if (!$priceNotice->isVisible()) { + return null; + } + return preg_replace('/[^0-9\.]/', '', $priceNotice->getText()); + } + + /** + * Get notice of option by number + * + * @param Element $option + * @param int $number + * @return mixed + */ + protected function getOptionNotice(Element $option, $number) + { + $note = $option->find(sprintf($this->noteByNumber, $number), Locator::SELECTOR_XPATH); + return $note->isVisible() ? $note->getText() : null; + } + + /** + * Parse option text to title and price + * + * @param string $optionText + * @return array + */ + protected function parseOptionText($optionText) + { + preg_match('/\+?.([0-9.]+)$/', $optionText, $match); + $optionPrice = isset($match[1]) ? $match[1] : 0; + $optionTitle = isset($match[0]) + ? substr($optionText, 0, strlen($optionText) - strlen($match[0])) + : $optionText; + + return [ + 'title' => trim($optionTitle), + 'price' => $optionPrice + ]; } /** @@ -177,7 +424,7 @@ class CustomOptions extends Block * @param array $productOptions * @return void */ - public function fillProductOptions($productOptions) + public function fillProductOptions(array $productOptions) { foreach ($productOptions as $attributeLabel => $attributeValue) { $select = $this->_rootElement->find( @@ -189,19 +436,83 @@ class CustomOptions extends Block } } + /** + * Fill custom options + * + * @param array $customOptions + * @return void + */ + public function fillCustomOptions(array $customOptions) + { + $type = strtolower(preg_replace('/[^a-zA-Z]/', '', $customOptions['type'])); + $customOptions += $this->dataMapping([$type => []]); + + $isDate = $customOptions['type'] == 'Date' || + $customOptions['type'] == 'Time' || + $customOptions['type'] == 'Date & Time'; + $isChecked = $customOptions['type'] == 'Checkbox' || $customOptions['type'] == 'Radio Buttons'; + + if ($isDate) { + $customOptions['value'] = explode('/', $customOptions['value'][0]); + $customOptions['dateSelector'] = $this->setDateTypeSelector(count($customOptions['value'])); + } + + foreach ($customOptions['value'] as $key => $attributeValue) { + $selector = $customOptions[$type]['selector']; + if ($isDate) { + $selector .= $customOptions['dateSelector'][$key]; + } elseif ($isChecked) { + $selector = str_replace('%product_name%', $attributeValue, $selector); + $attributeValue = 'Yes'; + } + + $select = $this->_rootElement->find( + sprintf($this->optionByName, $customOptions['title']) . $selector, + Locator::SELECTOR_XPATH, + $customOptions[$type]['input'] + ); + $select->setValue($attributeValue); + } + } + + /** + * Set item data type selector + * + * @param int $count + * @return array + */ + protected function setDateTypeSelector($count) + { + $result = []; + $parent = ''; + for ($i = 0; $i < $count; $i++) { + if (!(($i + 1) % 4)) { + $parent = '//span'; + } + $result[$i] = $parent . '//select[' . ($i % 3 + 1) . ']'; + } + + return $result; + } + /** * Choose custom option in a drop down * - * @param string $productOption + * @param string $title + * @param string|null $value [optional] * @return void */ - public function selectProductCustomOption($productOption) + public function selectProductCustomOption($title, $value = null) { $select = $this->_rootElement->find( - sprintf($this->optionByValueLocator, $productOption), + sprintf($this->selectByTitleLocator, $title), Locator::SELECTOR_XPATH, 'select' ); - $select->setValue($productOption); + + if (null === $value) { + $value = $select->find('.//option[@value != ""][1]', Locator::SELECTOR_XPATH)->getText(); + } + $select->setValue($value); } } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View/CustomOptions.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View/CustomOptions.xml new file mode 100644 index 0000000000000000000000000000000000000000..44504ba1c175b32744a5ce008c4371775716c27c --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View/CustomOptions.xml @@ -0,0 +1,66 @@ +<?xml version="1.0" ?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<mapping strict="0"> + <fields> + <dropdown> + <selector>//select</selector> + <input>select</input> + </dropdown> + <multipleselect> + <selector>//select</selector> + <input>multiselect</input> + </multipleselect> + <checkbox> + <selector>//div[label[span[contains(text(), "%product_name%")]]]/input</selector> + <input>checkbox</input> + </checkbox> + <radiobuttons> + <selector>//div[label[span[contains(text(), "%product_name%")]]]/input</selector> + <input>checkbox</input> + </radiobuttons> + <date> + <selector /> + <input>select</input> + </date> + <datetime> + <selector /> + <input>select</input> + </datetime> + <time> + <selector /> + <input>select</input> + </time> + <area> + <selector>//textarea</selector> + </area> + <file> + <selector>//input</selector> + </file> + <field> + <selector>//input</selector> + </field> + </fields> +</mapping> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertAddToCartButtonAbsent.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertAddToCartButtonAbsent.php old mode 100644 new mode 100755 index 6b2726761fd164acded86da7fa844643f79c33d2..013910c651fb755a35a331656338ca8549949f73 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertAddToCartButtonAbsent.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertAddToCartButtonAbsent.php @@ -105,7 +105,7 @@ class AssertAddToCartButtonAbsent extends AbstractConstraint { $this->cmsIndex->open(); $this->cmsIndex->getTopmenu()->selectCategoryByName( - $this->product->getCategoryIds()[0]['name'] + $this->product->getCategoryIds()[0] ); \PHPUnit_Framework_Assert::assertFalse( $this->catalogCategoryView->getListProductBlock()->checkAddToCardButton(), @@ -122,7 +122,7 @@ class AssertAddToCartButtonAbsent extends AbstractConstraint { $this->cmsIndex->open(); $this->cmsIndex->getTopmenu()->selectCategoryByName( - $this->product->getCategoryIds()[0]['name'] + $this->product->getCategoryIds()[0] ); $this->catalogCategoryView->getListProductBlock()->openProductViewPage($this->product->getName()); \PHPUnit_Framework_Assert::assertFalse( diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertAddToCartButtonPresent.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertAddToCartButtonPresent.php old mode 100644 new mode 100755 index f4ac24bc1c39d48ee8ae343699a4fdd64d520110..120e528430c64e2bbe3cc64fe96266110ad651ad --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertAddToCartButtonPresent.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertAddToCartButtonPresent.php @@ -105,7 +105,7 @@ class AssertAddToCartButtonPresent extends AbstractConstraint { $this->cmsIndex->open(); $this->cmsIndex->getTopmenu()->selectCategoryByName( - $this->product->getCategoryIds()[0]['name'] + $this->product->getCategoryIds()[0] ); \PHPUnit_Framework_Assert::assertTrue( $this->catalogCategoryView->getListProductBlock()->checkAddToCardButton(), @@ -122,7 +122,7 @@ class AssertAddToCartButtonPresent extends AbstractConstraint { $this->cmsIndex->open(); $this->cmsIndex->getTopmenu()->selectCategoryByName( - $this->product->getCategoryIds()[0]['name'] + $this->product->getCategoryIds()[0] ); $this->catalogCategoryView->getListProductBlock()->openProductViewPage($this->product->getName()); \PHPUnit_Framework_Assert::assertTrue( diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertCrossSellsProductsSection.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertCrossSellsProductsSection.php old mode 100644 new mode 100755 index 98f6e122ad7b079788e3a8e5fd4596bda2a47a7d..fd2acc9b17c8774c757d74b36c734137b1ec1fad --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertCrossSellsProductsSection.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertCrossSellsProductsSection.php @@ -62,7 +62,7 @@ class AssertCrossSellsProductsSection extends AbstractConstraint CatalogProductView $catalogProductView, CheckoutCart $checkoutCart ) { - $categoryName = $product1->getCategoryIds()[0]['name']; + $categoryName = $product1->getCategoryIds()[0]; $checkoutCart->open(); $checkoutCart->getCartBlock()->clearShoppingCart(); $cmsIndex->getTopmenu()->selectCategoryByName($categoryName); diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertCustomOptionsOnProductPage.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertCustomOptionsOnProductPage.php deleted file mode 100644 index 95e1ef295df99e7d3e467ede042777b58d11947f..0000000000000000000000000000000000000000 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertCustomOptionsOnProductPage.php +++ /dev/null @@ -1,128 +0,0 @@ -<?php -/** - * Magento - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://opensource.org/licenses/osl-3.0.php - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@magentocommerce.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade Magento to newer - * versions in the future. If you wish to customize Magento for your - * needs please refer to http://www.magentocommerce.com for more information. - * - * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) - */ - -namespace Magento\Catalog\Test\Constraint; - -use Mtf\Fixture\FixtureInterface; -use Mtf\Constraint\AbstractConstraint; -use Magento\Catalog\Test\Page\Product\CatalogProductView; - -/** - * Class AssertCustomOptionsOnProductPage - */ -class AssertCustomOptionsOnProductPage extends AbstractConstraint -{ - /** - * Constraint severeness - * - * @var string - */ - protected $severeness = 'low'; - - /** - * Product fixture - * - * @var FixtureInterface - */ - protected $product; - - /** - * Assertion that commodity options are displayed correctly - * - * @param CatalogProductView $catalogProductView - * @param FixtureInterface $product - * @return void - */ - public function processAssert(CatalogProductView $catalogProductView, FixtureInterface $product) - { - $this->product = $product; - // TODO fix initialization url for frontend page - // Open product view page - $catalogProductView->init($this->product); - $catalogProductView->open(); - // Prepare data - $customOptions = $catalogProductView->getCustomOptionsBlock()->getOptions(); - foreach ($customOptions as &$option) { - unset($option['value']); - } - unset($option); - $compareOptions = $this->prepareOptionArray($this->product->getCustomOptions()); - $customOptions = $this->dataSortByKey($customOptions); - $compareOptions = $this->dataSortByKey($compareOptions); - - \PHPUnit_Framework_Assert::assertEquals( - $customOptions, - $compareOptions, - 'Incorrect display of custom product options on the product page.' - ); - } - - protected function dataSortByKey(array $data) - { - foreach ($data as &$item) { - ksort($item); - } - unset($item); - return $data; - } - - /** - * Preparation options before comparing - * - * @param array $options - * @return array - */ - protected function prepareOptionArray(array $options) - { - $result = []; - $productPrice = $this->product->hasData('group_price') - ? $this->product->getGroupPrice()[0]['price'] - : $this->product->getPrice(); - - $placeholder = ['Yes' => true, 'No' => false]; - foreach ($options as $option) { - $result[$option['title']]['is_require'] = $placeholder[$option['is_require']]; - $result[$option['title']]['title'] = $option['title']; - $result[$option['title']]['price'] = []; - foreach ($option['options'] as $optionValue) { - if ($optionValue['price_type'] === 'Percent') { - $optionValue['price'] = $productPrice / 100 * $optionValue['price']; - } - $result[$option['title']]['price'][] = number_format($optionValue['price'], 2); - } - } - - return $result; - } - - /** - * Returns a string representation of the object - * - * @return string - */ - public function toString() - { - return 'Value of custom option on the page is correct.'; - } -} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertNoCrossSellsProductsSection.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertNoCrossSellsProductsSection.php old mode 100644 new mode 100755 index f600e90898b9656a6482c5b4675f8fe4268d56e3..38a422f7f501fca09316224494e492cbb8933d9d --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertNoCrossSellsProductsSection.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertNoCrossSellsProductsSection.php @@ -62,7 +62,7 @@ class AssertNoCrossSellsProductsSection extends AbstractConstraint CatalogProductView $catalogProductView, CheckoutCart $checkoutCart ) { - $categoryName = $product1->getCategoryIds()[0]['name']; + $categoryName = $product1->getCategoryIds()[0]; $checkoutCart->open(); $checkoutCart->getCartBlock()->clearShoppingCart(); $cmsIndex->getTopmenu()->selectCategoryByName($categoryName); diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertNoRelatedProductsSection.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertNoRelatedProductsSection.php old mode 100644 new mode 100755 index c722951047db2b347a7abf482e5e23bec8b7dac5..0e53a68b1334ed5a8750c67ef00da4f233eb1e95 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertNoRelatedProductsSection.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertNoRelatedProductsSection.php @@ -59,7 +59,7 @@ class AssertNoRelatedProductsSection extends AbstractConstraint CatalogCategoryView $catalogCategoryView, CatalogProductView $catalogProductView ) { - $categoryName = $product1->getCategoryIds()[0]['name']; + $categoryName = $product1->getCategoryIds()[0]; $cmsIndex->open(); $cmsIndex->getTopmenu()->selectCategoryByName($categoryName); $catalogCategoryView->getListProductBlock()->openProductViewPage($product1->getName()); diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertNoUpSellsProductsSection.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertNoUpSellsProductsSection.php old mode 100644 new mode 100755 index 7aec1213cfe5a2803269d92ac82a90ca3cefc21f..8f8a952c590e7e46d68d0829319bc60e2338430f --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertNoUpSellsProductsSection.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertNoUpSellsProductsSection.php @@ -59,7 +59,7 @@ class AssertNoUpSellsProductsSection extends AbstractConstraint CatalogCategoryView $catalogCategoryView, CatalogProductView $catalogProductView ) { - $categoryName = $product1->getCategoryIds()[0]['name']; + $categoryName = $product1->getCategoryIds()[0]; $cmsIndex->open(); $cmsIndex->getTopmenu()->selectCategoryByName($categoryName); $catalogCategoryView->getListProductBlock()->openProductViewPage($product1->getName()); diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertPriceOnProductPageInterface.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertPriceOnProductPageInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..9447928dc4c586153ae87b70f9677ca130b72bbd --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertPriceOnProductPageInterface.php @@ -0,0 +1,53 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\Constraint; + +use Mtf\Fixture\FixtureInterface; +use Magento\Catalog\Test\Page\Product\CatalogProductView; + +/** + * Interface AssertPriceOnProductPageInterface + * Interface for Constraints price on product page classes + */ +interface AssertPriceOnProductPageInterface +{ + /** + * Verify product price on product view page + * + * @param FixtureInterface $product + * @param CatalogProductView $catalogProductView + * @param string $block + * @return void + */ + public function assertPrice(FixtureInterface $product, CatalogProductView $catalogProductView, $block); + + /** + * Set $errorMessage for constraint + * + * @param string $errorMessage + * @return void + */ + public function setErrorMessage($errorMessage); +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductAttributeAbsenceInSearchOnProductForm.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductAttributeAbsenceInSearchOnProductForm.php index f78a28f429825ba8f7e83693c1f84e421f7819f0..d7a7209b8e2ce384ed622aa3bbd2562e57ba5d7c 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductAttributeAbsenceInSearchOnProductForm.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductAttributeAbsenceInSearchOnProductForm.php @@ -58,7 +58,7 @@ class AssertProductAttributeAbsenceInSearchOnProductForm extends AbstractConstra CatalogProductNew $newProductPage ) { $productGrid->open(); - $productGrid->getProductBlock()->addProduct('simple'); + $productGrid->getGridPageActionBlock()->addProduct('simple'); \PHPUnit_Framework_Assert::assertFalse( $newProductPage->getForm()->checkAttributeInSearchAttributeForm($productAttribute), "Product attribute found in Attribute Search form." diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductAttributeAbsenceInTemplateGroups.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductAttributeAbsenceInTemplateGroups.php new file mode 100644 index 0000000000000000000000000000000000000000..43103300027100aed9bba1feed956717bc736616 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductAttributeAbsenceInTemplateGroups.php @@ -0,0 +1,82 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\Constraint; + +use Mtf\Constraint\AbstractConstraint; +use Magento\Catalog\Test\Fixture\CatalogAttributeSet; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductSetEdit; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductSetIndex; + +/** + * Class AssertProductAttributeAbsenceInTemplateGroups + * Checks that product attribute isn't displayed in Product template's Groups section + */ +class AssertProductAttributeAbsenceInTemplateGroups extends AbstractConstraint +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Assert that deleted attribute isn't displayed in Product template's Groups section + * + * @param CatalogAttributeSet $productTemplate + * @param CatalogProductSetIndex $productSetIndex + * @param CatalogProductSetEdit $productSetEdit + * @return void + */ + public function processAssert( + CatalogAttributeSet $productTemplate, + CatalogProductSetIndex $productSetIndex, + CatalogProductSetEdit $productSetEdit + ) { + $filter = ['set_name' => $productTemplate->getAttributeSetName()]; + $productSetIndex->open(); + $productSetIndex->getGrid()->searchAndOpen($filter); + + $attributeCode = $productTemplate + ->getDataFieldConfig('assigned_attributes')['source'] + ->getAttributes()[0] + ->getAttributeCode(); + + \PHPUnit_Framework_Assert::assertFalse( + $productSetEdit->getAttributeSetEditBlock()->checkProductAttribute($attributeCode), + "Attribute " . $attributeCode . " is present in Product template's Groups section." + ); + } + + /** + * Text absent Product Attribute in Product template's Groups section + * + * @return string + */ + public function toString() + { + return "Product Attribute is absent in Product template's Groups section."; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductAttributeAbsenceInUnassignedAttributes.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductAttributeAbsenceInUnassignedAttributes.php new file mode 100644 index 0000000000000000000000000000000000000000..e5b6f333d6de4cbd81801e5368adf6b0dcb112ca --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductAttributeAbsenceInUnassignedAttributes.php @@ -0,0 +1,82 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\Constraint; + +use Mtf\Constraint\AbstractConstraint; +use Magento\Catalog\Test\Fixture\CatalogAttributeSet; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductSetEdit; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductSetIndex; + +/** + * Class AssertProductAttributeAbsenceInUnassignedAttributes + * Checks that product attribute isn't displayed in Product template's Unassigned Attributes section + */ +class AssertProductAttributeAbsenceInUnassignedAttributes extends AbstractConstraint +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Assert that deleted attribute isn't displayed in Product template's Unassigned Attributes section + * + * @param CatalogAttributeSet $productTemplate + * @param CatalogProductSetIndex $productSetIndex + * @param CatalogProductSetEdit $productSetEdit + * @return void + */ + public function processAssert( + CatalogAttributeSet $productTemplate, + CatalogProductSetIndex $productSetIndex, + CatalogProductSetEdit $productSetEdit + ) { + $filter = ['set_name' => $productTemplate->getAttributeSetName()]; + $productSetIndex->open(); + $productSetIndex->getGrid()->searchAndOpen($filter); + + $attributeCode = $productTemplate + ->getDataFieldConfig('assigned_attributes')['source'] + ->getAttributes()[0] + ->getAttributeCode(); + + \PHPUnit_Framework_Assert::assertFalse( + $productSetEdit->getAttributeSetEditBlock()->checkUnassignedProductAttribute($attributeCode), + "Attribute " . $attributeCode . " is present in Unassigned Product template's section." + ); + } + + /** + * Text absent Product Attribute Unassigned Product template's section + * + * @return string + */ + public function toString() + { + return "Product Attribute is absent in Unassigned Product template's section."; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductAttributeAbsenceInVariationsSearch.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductAttributeAbsenceInVariationsSearch.php new file mode 100644 index 0000000000000000000000000000000000000000..c913d8fc6e602a82813a43d91ce7dd433e52dddd --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductAttributeAbsenceInVariationsSearch.php @@ -0,0 +1,80 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\Constraint; + +use Mtf\Constraint\AbstractConstraint; +use Magento\Catalog\Test\Fixture\CatalogProductAttribute; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductNew; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductEdit; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex; + +/** + * Class AssertProductAttributeAbsenceInVariationsSearch + * Check that deleted attribute can't be added to product template on Product Page via Add Attribute control + */ +class AssertProductAttributeAbsenceInVariationsSearch extends AbstractConstraint +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Assert that deleted attribute can't be added to product template on Product Page via Add Attribute control + * + * @param CatalogProductAttribute $productAttribute + * @param CatalogProductIndex $productGrid + * @param CatalogProductNew $newProductPage + * @param CatalogProductEdit $productEdit + * @return void + */ + public function processAssert + ( + CatalogProductAttribute $productAttribute, + CatalogProductIndex $productGrid, + CatalogProductEdit $productEdit, + CatalogProductNew $newProductPage + ) { + $productGrid->open(); + $productGrid->getGridPageActionBlock()->addProduct('simple'); + $productEdit->getForm()->openVariationsTab(); + \PHPUnit_Framework_Assert::assertFalse( + $newProductPage->getForm()->checkAttributeInVariationsSearchAttributeForm($productAttribute), + "Product attribute found in Attribute Search form." + ); + } + + /** + * Text absent Product Attribute in Attribute Search form + * + * @return string + */ + public function toString() + { + return "Product Attribute is absent in Attribute Search form."; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductCompareBlockOnCmsPage.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductCompareBlockOnCmsPage.php new file mode 100644 index 0000000000000000000000000000000000000000..1ac1b0e824639b5cedece22fea2dd41c1deef35d --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductCompareBlockOnCmsPage.php @@ -0,0 +1,78 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\Constraint; + +use Mtf\Client\Browser; +use Mtf\Fixture\FixtureFactory; +use Magento\Cms\Test\Page\CmsIndex; +use Mtf\Constraint\AbstractConstraint; + +/** + * Class AssertProductCompareBlockOnCmsPage + */ +class AssertProductCompareBlockOnCmsPage extends AbstractConstraint +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Assert that Compare Products block is presented on CMS pages. + * Block contains information about compared products + * + * @param array $products + * @param CmsIndex $cmsIndex + * @param FixtureFactory $fixtureFactory + * @param Browser $browser + * @return void + */ + public function processAssert(array $products, CmsIndex $cmsIndex, FixtureFactory $fixtureFactory, Browser $browser) + { + $newCmsPage = $fixtureFactory->createByCode('cmsPage', ['dataSet' => 'with_compare']); + $newCmsPage->persist(); + $browser->open($_ENV['app_frontend_url'] . $newCmsPage->getIdentifier()); + foreach ($products as &$product) { + $product = $product->getName(); + } + \PHPUnit_Framework_Assert::assertEquals( + $products, + $cmsIndex->getCompareProductsBlock()->getProducts(), + 'Compare product block contains NOT valid information about compared products.' + ); + } + + /** + * Returns a string representation of the object + * + * @return string + */ + public function toString() + { + return 'Compare product block contains valid information about compared products.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductCompareItemsLink.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductCompareItemsLink.php new file mode 100644 index 0000000000000000000000000000000000000000..0e6900da87a6d2fd35f17741db79b707398aad6b --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductCompareItemsLink.php @@ -0,0 +1,76 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\Constraint; + +use Mtf\Constraint\AbstractConstraint; +use Magento\Cms\Test\Page\CmsIndex; + +/** + * Class AssertProductCompareItemsLink + */ +class AssertProductCompareItemsLink extends AbstractConstraint +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Assert that link "Compare Products..." on top menu of page + * + * @param array $products + * @param CmsIndex $cmsIndex + * @return void + */ + public function processAssert(array $products, CmsIndex $cmsIndex) + { + $productQty = count($products); + $qtyOnPage = $cmsIndex->getLinksBlock()->getQtyInCompareList(); + + \PHPUnit_Framework_Assert::assertEquals( + $productQty, + $qtyOnPage, + 'Qty is not correct in "Compare Products" link.' + ); + + $compareProductUrl = '/catalog/product_compare/'; + \PHPUnit_Framework_Assert::assertTrue( + strpos($cmsIndex->getLinksBlock()->getLinkUrl('Compare Products'), $compareProductUrl) !== false, + 'Compare product link isn\'t lead to Compare Product Page.' + ); + } + + /** + * Returns a string representation of the object + * + * @return string + */ + public function toString() + { + return '"Compare Products..." link on top menu of page is correct.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductCompareItemsLinkIsAbsent.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductCompareItemsLinkIsAbsent.php new file mode 100644 index 0000000000000000000000000000000000000000..6cdcee88fe27aacfdd06334b2befbc57e3f50309 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductCompareItemsLinkIsAbsent.php @@ -0,0 +1,65 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\Constraint; + +use Magento\Cms\Test\Page\CmsIndex; +use Mtf\Constraint\AbstractConstraint; + +/** + * Class AssertProductCompareItemsLinkIsAbsent + */ +class AssertProductCompareItemsLinkIsAbsent extends AbstractConstraint +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Assert compare products link is NOT visible at the top of page. + * + * @param CmsIndex $cmsIndex + * @return void + */ + public function processAssert(CmsIndex $cmsIndex) + { + \PHPUnit_Framework_Assert::assertFalse( + $cmsIndex->getLinksBlock()->getQtyInCompareList(), + 'The link "Compare Products..." is visible at the top of page.' + ); + } + + /** + * Returns a string representation of the object. + * + * @return string + */ + public function toString() + { + return 'The link is NOT visible at the top of page.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductComparePage.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductComparePage.php new file mode 100644 index 0000000000000000000000000000000000000000..d28ecf697f4c48aa94591932e35a44d234315c53 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductComparePage.php @@ -0,0 +1,111 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\Constraint; + +use Mtf\Constraint\AbstractConstraint; +use Magento\Cms\Test\Page\CmsIndex; +use Magento\Catalog\Test\Page\Product\CatalogProductCompare; + +/** + * Class AssertProductComparePage + * Assert that "Compare Product" page contains product(s) that was added + */ +class AssertProductComparePage extends AbstractConstraint +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Product attribute on compare product page + * + * @var array + */ + protected $attributeProduct = [ + 'name', + 'price', + 'sku' => 'SKU', + 'description' => 'Description', + 'short_description' => 'Short Description' + ]; + + /** + * Assert that "Compare Product" page contains product(s) that was added + * - Product name + * - Price + * - SKU + * - Description (if exists, else text "No") + * - Short Description (if exists, else text "No") + * + * @param array $products + * @param CatalogProductCompare $comparePage + * @param CmsIndex $cmsIndex + * @return void + * + * @SuppressWarnings(PHPMD.NPathComplexity) + */ + public function processAssert( + array $products, + CatalogProductCompare $comparePage, + CmsIndex $cmsIndex + ) { + $cmsIndex->open(); + $cmsIndex->getLinksBlock()->openLink("Compare Products"); + foreach ($products as $key => $product) { + foreach ($this->attributeProduct as $attributeKey => $attribute) { + $value = $attribute; + $attribute = is_numeric($attributeKey) ? $attribute : $attributeKey; + + $attributeValue = $attribute != 'price' + ? ($product->hasData($attribute) + ? $product->getData($attribute) + : 'N/A') + : ($product->getDataFieldConfig('price')['source']->getPreset() !== null + ? $product->getDataFieldConfig('price')['source']->getPreset()['compare_price'] + : number_format($product->getPrice(), 2)); + + $attribute = is_numeric($attributeKey) ? 'info' : 'attribute'; + \PHPUnit_Framework_Assert::assertEquals( + $attributeValue, + $comparePage->getCompareProductsBlock()->{'getProduct' . ucfirst($attribute)}($key + 1, $value), + 'Product "' . $product->getName() . '" is\'n equals with data from fixture.' + ); + } + } + } + + /** + * Returns a string representation of the object + * + * @return string + */ + public function toString() + { + return '"Compare Product" page has valid data for all products.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductCompareRemoveLastProductMessage.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductCompareRemoveLastProductMessage.php new file mode 100644 index 0000000000000000000000000000000000000000..456c2075f8807fa6f5ae80c7d9bbd3216edbc89e --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductCompareRemoveLastProductMessage.php @@ -0,0 +1,73 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\Constraint; + +use Mtf\Constraint\AbstractConstraint; +use Magento\Catalog\Test\Page\Product\CatalogProductCompare; + +/** + * Class AssertProductCompareRemoveLastProductMessage + * Assert message on "Compare Products" page after removing product + */ +class AssertProductCompareRemoveLastProductMessage extends AbstractConstraint +{ + const SUCCESS_MESSAGE = 'You have no items to compare.'; + + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * After removing last product message is appeared on "Compare Products" page + * + * @param CatalogProductCompare $comparePage + * @return void + */ + public function processAssert(CatalogProductCompare $comparePage) + { + $comparePage->open(); + $actualMessage = $comparePage->getCompareProductsBlock()->getEmptyMessage(); + \PHPUnit_Framework_Assert::assertEquals( + self::SUCCESS_MESSAGE, + $actualMessage, + 'Wrong success message is displayed.' + . "\nExpected: " . self::SUCCESS_MESSAGE + . "\nActual: " . $actualMessage + ); + } + + /** + * Returns a string representation of the object. + * + * @return string + */ + public function toString() + { + return 'After removing last product the message appears on "Compare Products" page.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertGroupedPriceOnProductPage.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductCompareSuccessAddMessage.php similarity index 59% rename from dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertGroupedPriceOnProductPage.php rename to dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductCompareSuccessAddMessage.php index 0e364e2975f53b7a04153550b4974f2afbf98207..ec8e9aaa84bf82f9ae85455e3f2442a8c1dca437 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertGroupedPriceOnProductPage.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductCompareSuccessAddMessage.php @@ -24,24 +24,26 @@ namespace Magento\Catalog\Test\Constraint; -use Mtf\Fixture\FixtureInterface; use Mtf\Constraint\AbstractConstraint; use Magento\Catalog\Test\Page\Product\CatalogProductView; +use Mtf\Fixture\FixtureInterface; /** - * Class AssertGroupedPriceOnProductPage + * Class AssertProductCompareSuccessAddMessage */ -class AssertGroupedPriceOnProductPage extends AbstractConstraint +class AssertProductCompareSuccessAddMessage extends AbstractConstraint { + const SUCCESS_MESSAGE = 'You added product %s to the comparison list.'; + /** * Constraint severeness * * @var string */ - protected $severeness = 'low'; + protected $severeness = 'high'; /** - * Assert that displayed grouped price on product page equals passed from fixture + * Assert success message is presented on page * * @param CatalogProductView $catalogProductView * @param FixtureInterface $product @@ -49,22 +51,15 @@ class AssertGroupedPriceOnProductPage extends AbstractConstraint */ public function processAssert(CatalogProductView $catalogProductView, FixtureInterface $product) { - $catalogProductView->init($product); - $catalogProductView->open(); - $fields = $product->getData(); - $groupPrice = $catalogProductView->getViewBlock()->getProductPrice(); - $groupPrice = isset($groupPrice['price_special_price']) - ? $groupPrice['price_special_price'] - : null; - if (isset($fields['group_price'])) { - foreach ($fields['group_price'] as $itemGroupPrice) { - \PHPUnit_Framework_Assert::assertEquals( - $itemGroupPrice['price'], - $groupPrice, - 'Assert that displayed grouped price on product page NOT equals passed from fixture.' - ); - } - } + $successMessage = sprintf(self::SUCCESS_MESSAGE, $product->getName()); + $actualMessage = $catalogProductView->getMessagesBlock()->getSuccessMessages(); + \PHPUnit_Framework_Assert::assertEquals( + $successMessage, + $actualMessage, + 'Wrong success message is displayed.' + . "\nExpected: " . $successMessage + . "\nActual: " . $actualMessage + ); } /** @@ -74,6 +69,6 @@ class AssertGroupedPriceOnProductPage extends AbstractConstraint */ public function toString() { - return 'Assert that displayed grouped price on product page equals passed from fixture.'; + return 'Product has been added compare products list.'; } } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductCompareSuccessRemoveAllProductsMessage.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductCompareSuccessRemoveAllProductsMessage.php new file mode 100644 index 0000000000000000000000000000000000000000..a4ce76d407b1e3c7312dd8f19e07a6fd90583d45 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductCompareSuccessRemoveAllProductsMessage.php @@ -0,0 +1,71 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\Constraint; + +use Mtf\Constraint\AbstractConstraint; +use Magento\Catalog\Test\Page\Product\CatalogProductView; + +/** + * Class AssertProductCompareSuccessRemoveAllProductsMessage + */ +class AssertProductCompareSuccessRemoveAllProductsMessage extends AbstractConstraint +{ + const SUCCESS_MESSAGE = 'You cleared the comparison list.'; + + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'high'; + + /** + * Assert message is appeared on "Compare Products" page. + * + * @param CatalogProductView $catalogProductView + * @return void + */ + public function processAssert(CatalogProductView $catalogProductView) + { + $actualMessage = $catalogProductView->getMessagesBlock()->getSuccessMessages(); + \PHPUnit_Framework_Assert::assertEquals( + self::SUCCESS_MESSAGE, + $actualMessage, + 'Wrong success message is displayed.' + . "\nExpected: " . self::SUCCESS_MESSAGE + . "\nActual: " . $actualMessage + ); + } + + /** + * Returns a string representation of the object. + * + * @return string + */ + public function toString() + { + return 'Compare Product success message is present.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductCompareSuccessRemoveMessage.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductCompareSuccessRemoveMessage.php new file mode 100644 index 0000000000000000000000000000000000000000..2a210d9958e1cf5259ed8f8a30c1b6956b44b2a0 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductCompareSuccessRemoveMessage.php @@ -0,0 +1,69 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\Constraint; + +use Mtf\Fixture\FixtureInterface; +use Mtf\Constraint\AbstractConstraint; +use Magento\Catalog\Test\Page\Product\CatalogProductCompare; + +/** + * Class AssertProductCompareSuccessRemoveMessage + * Assert message is appeared on "Compare Products" block on myAccount page + */ +class AssertProductCompareSuccessRemoveMessage extends AbstractConstraint +{ + const SUCCESS_MESSAGE = 'You removed product %s from the comparison list.'; + + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Assert message is appeared on "Compare Products" block on myAccount page + * + * @param CatalogProductCompare $catalogProductCompare + * @param FixtureInterface $product + * @return void + */ + public function processAssert(CatalogProductCompare $catalogProductCompare, FixtureInterface $product) + { + $successMessage = sprintf(self::SUCCESS_MESSAGE, $product->getName()); + $actualMessage = $catalogProductCompare->getMessagesBlock()->getSuccessMessages(); + \PHPUnit_Framework_Assert::assertEquals($successMessage, $actualMessage, 'Wrong success message is displayed.'); + } + + /** + * Returns a string representation of the object + * + * @return string + */ + public function toString() + { + return 'Product has been removed from compare products list.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductCustomOptionsOnProductPage.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductCustomOptionsOnProductPage.php new file mode 100755 index 0000000000000000000000000000000000000000..2de9af98ded0acac2c3514680a3c1ea25cdad8f3 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductCustomOptionsOnProductPage.php @@ -0,0 +1,158 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\Constraint; + +use Mtf\Constraint\AbstractAssertForm; +use Mtf\Fixture\FixtureInterface; +use Magento\Catalog\Test\Page\Product\CatalogProductView; +use Magento\Catalog\Test\Fixture\CatalogProductSimple; + +/** + * Class AssertProductCustomOptionsOnProductPage + */ +class AssertProductCustomOptionsOnProductPage extends AbstractAssertForm +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Skipped field for custom options + * + * @var array + */ + protected $skippedFieldOptions = [ + 'Field' => [ + 'price_type', + 'sku', + ], + 'Area' => [ + 'price_type', + 'sku', + ], + 'Drop-down' => [ + 'price_type', + 'sku', + ], + 'File' => [ + 'price_type', + 'sku', + ], + 'Radio Buttons' => [ + 'price_type', + 'sku', + ], + 'Checkbox' => [ + 'price_type', + 'sku', + ], + 'Multiple Select' => [ + 'price_type', + 'sku', + ], + 'Date' => [ + 'price_type', + 'sku', + ], + 'Date & Time' => [ + 'price_type', + 'sku', + ], + 'Time' => [ + 'price_type', + 'sku', + ] + ]; + + /** + * Assertion that commodity options are displayed correctly + * + * @param CatalogProductView $catalogProductView + * @param FixtureInterface $product + * @return void + */ + public function processAssert(CatalogProductView $catalogProductView, FixtureInterface $product) + { + // TODO fix initialization url for frontend page + // Open product view page + $catalogProductView->init($product); + $catalogProductView->open(); + // Prepare data + $formCustomOptions = $catalogProductView->getCustomOptionsBlock()->getOptions($product); + $prices = $catalogProductView->getViewBlock()->getProductPriceBlock()->getPrice(); + $actualPrice = isset($prices['price_special_price']) + ? $prices['price_special_price'] + : $prices['price_regular_price']; + $fixtureCustomOptions = $this->prepareOptions($product, $actualPrice); + $error = $this->verifyData($fixtureCustomOptions, $formCustomOptions); + \PHPUnit_Framework_Assert::assertEmpty($error, $error); + } + + /** + * Preparation options before comparing + * + * @param FixtureInterface $product + * @param int|null $actualPrice + * @return array + */ + protected function prepareOptions(FixtureInterface $product, $actualPrice = null) + { + $customOptions = $product->getCustomOptions(); + $result = []; + + $actualPrice = $actualPrice ? $actualPrice : $product->getPrice(); + foreach ($customOptions as $customOption) { + $skippedField = isset($this->skippedFieldOptions[$customOption['type']]) + ? $this->skippedFieldOptions[$customOption['type']] + : []; + foreach ($customOption['options'] as &$option) { + // recalculate percent price + if ('Percent' == $option['price_type']) { + $option['price'] = ($actualPrice * $option['price']) / 100; + $option['price'] = round($option['price'], 2); + } + + $option = array_diff_key($option, array_flip($skippedField)); + } + + $result[$customOption['title']] = $customOption; + } + + return $result; + } + + /** + * Returns a string representation of the object + * + * @return string + */ + public function toString() + { + return 'Value of custom option on the page is correct.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductDuplicateForm.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductDuplicateForm.php new file mode 100644 index 0000000000000000000000000000000000000000..2fde4a0da852f217a420b93b919445f86b5151b8 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductDuplicateForm.php @@ -0,0 +1,140 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\Constraint; + +use Mtf\Fixture\FixtureInterface; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductEdit; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex; + +/** + * Class AssertProductDuplicateForm + */ +class AssertProductDuplicateForm extends AssertProductForm +{ + /** + * Formatting options for numeric values + * + * @var array + */ + protected $formattingOptions = [ + 'price' => [ + 'decimals' => 2, + 'dec_point' => '.', + 'thousands_sep' => '' + ], + 'qty' => [ + 'decimals' => 4, + 'dec_point' => '.', + 'thousands_sep' => '' + ], + 'weight' => [ + 'decimals' => 4, + 'dec_point' => '.', + 'thousands_sep' => '' + ] + ]; + + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Assert form data equals fixture data + * + * @param FixtureInterface $product + * @param CatalogProductIndex $productGrid + * @param CatalogProductEdit $productPage + * @return void + */ + public function processAssert( + FixtureInterface $product, + CatalogProductIndex $productGrid, + CatalogProductEdit $productPage + ) { + $filter = ['sku' => $product->getSku() . '-1']; + $productGrid->open()->getProductGrid()->searchAndOpen($filter); + + $formData = $productPage->getForm()->getData($product); + $fixtureData = $this->prepareFixtureData($product->getData()); + + $errors = $this->verifyData($fixtureData, $formData); + \PHPUnit_Framework_Assert::assertEmpty($errors, $errors); + } + + /** + * Prepares fixture data for comparison + * + * @param array $data + * @param array $sortFields [optional] + * @return array + */ + protected function prepareFixtureData(array $data, array $sortFields = []) + { + $compareData = array_filter($data); + + array_walk_recursive( + $compareData, + function (&$item, $key, $formattingOptions) { + if (isset($formattingOptions[$key])) { + $item = number_format( + $item, + $formattingOptions[$key]['decimals'], + $formattingOptions[$key]['dec_point'], + $formattingOptions[$key]['thousands_sep'] + ); + } + }, + $this->formattingOptions + ); + + if (isset($compareData['status'])) { + $compareData['status'] = 'Product offline'; + } + if (isset($compareData['quantity_and_stock_status']['qty'])) { + $compareData['quantity_and_stock_status']['qty'] = ''; + } + if (isset($compareData['special_price'])) { + $compareData['special_price'] = ['special_price' => $compareData['special_price']]; + } + $compareData['sku'] .= '-1'; + $compareData['quantity_and_stock_status']['is_in_stock'] = 'Out of Stock'; + unset($compareData['category_ids'], $compareData['id']); + + return $compareData; + } + + /** + * Returns a string representation of the object + * + * @return string + */ + public function toString() + { + return 'Form data equals to fixture data of duplicated product.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductDuplicateIsNotDisplayingOnFrontend.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductDuplicateIsNotDisplayingOnFrontend.php new file mode 100644 index 0000000000000000000000000000000000000000..35b0008b4909d062230b0077e974d3eb6bc8304a --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductDuplicateIsNotDisplayingOnFrontend.php @@ -0,0 +1,60 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\Constraint; + +use Mtf\Constraint\AbstractConstraint; + +/** + * Class AssertProductDuplicateIsNotDisplayingOnFrontend + */ +class AssertProductDuplicateIsNotDisplayingOnFrontend extends AbstractConstraint +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'high'; + + /** + * Assert that product duplicate is not displayed on front-end + * + * @return void + */ + public function processAssert() + { + // TODO mage to MAGETWO-25523 + } + + /** + * Returns a string representation of the object + * + * @return string + */ + public function toString() + { + return 'The product does not appear on the frontend.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductDuplicateMessage.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductDuplicateMessage.php new file mode 100644 index 0000000000000000000000000000000000000000..b01a1731bbf21dc3d84df9d86b60cbce8579ed2d --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductDuplicateMessage.php @@ -0,0 +1,75 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\Constraint; + +use Mtf\Constraint\AbstractConstraint; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductEdit; + +/** + * Class AssertProductDuplicateMessage + */ +class AssertProductDuplicateMessage extends AbstractConstraint +{ + /** + * Text value to be checked + */ + const DUPLICATE_MESSAGE = 'You duplicated the product.'; + + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'high'; + + /** + * Checking the output message successful product duplication + * + * @param CatalogProductEdit $productPage + * @return void + */ + public function processAssert(CatalogProductEdit $productPage) + { + $actualMessages = $productPage->getMessagesBlock()->getSuccessMessages(); + $actualMessages = is_array($actualMessages) ? $actualMessages : [$actualMessages]; + \PHPUnit_Framework_Assert::assertContains( + self::DUPLICATE_MESSAGE, + $actualMessages, + 'Wrong duplicated message is displayed.' + . "\nExpected: " . self::DUPLICATE_MESSAGE + . "\nActual:\n" . implode("\n - ", $actualMessages) + ); + } + + /** + * Returns a string representation of the object + * + * @return string + */ + public function toString() + { + return 'Product duplicated message is present.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductDuplicatedInGrid.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductDuplicatedInGrid.php new file mode 100644 index 0000000000000000000000000000000000000000..c3de80ebfb82cfe5a9cd085479fe99b530188c74 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductDuplicatedInGrid.php @@ -0,0 +1,83 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\Constraint; + +use Mtf\Fixture\FixtureInterface; +use Mtf\Constraint\AbstractConstraint; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex; + +/** + * Class AssertProductDuplicatedInGrid + */ +class AssertProductDuplicatedInGrid extends AbstractConstraint +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Assert that duplicated product is found by sku and has correct product type, product template, + * product status disabled and out of stock + * + * @param FixtureInterface $product + * @param CatalogProductIndex $productGrid + * @return void + */ + public function processAssert(FixtureInterface $product, CatalogProductIndex $productGrid) + { + $config = $product->getDataConfig(); + $filter = [ + 'name' => $product->getName(), + 'visibility' => $product->getVisibility(), + 'status' => 'Disabled', + 'sku' => $product->getSku() . '-1', + 'type' => ucfirst($config['create_url_params']['type']) . ' Product', + 'price_to' => number_format($product->getPrice(), 2) + ]; + + $productGrid->open() + ->getProductGrid() + ->search($filter); + + $filter['price_to'] = '$' . $filter['price_to']; + \PHPUnit_Framework_Assert::assertTrue( + $productGrid->getProductGrid()->isRowVisible($filter, false), + 'Product duplicate is absent in Products grid.' + ); + } + + /** + * Returns a string representation of the object + * + * @return string + */ + public function toString() + { + return 'The product has been successfully found, according to the filters.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductForm.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductForm.php old mode 100644 new mode 100755 index 267cfb97e52b725fafda50c94c09edb75632b554..b5ade64e7f27a5c7e485181a237e26a10a99df1f --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductForm.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductForm.php @@ -24,38 +24,22 @@ namespace Magento\Catalog\Test\Constraint; +use Mtf\Constraint\AbstractAssertForm; use Mtf\Fixture\FixtureInterface; -use Mtf\Constraint\AbstractConstraint; -use Magento\Catalog\Test\Page\Adminhtml\CatalogProductEdit; use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductEdit; /** * Class AssertProductForm */ -class AssertProductForm extends AbstractConstraint +class AssertProductForm extends AbstractAssertForm { /** - * Formatting options for numeric values + * Sort fields for fixture and form data * * @var array */ - protected $formattingOptions = [ - 'price' => [ - 'decimals' => 2, - 'dec_point' => '.', - 'thousands_sep' => '' - ], - 'qty' => [ - 'decimals' => 4, - 'dec_point' => '.', - 'thousands_sep' => '' - ], - 'weight' => [ - 'decimals' => 4, - 'dec_point' => '.', - 'thousands_sep' => '' - ] - ]; + protected $sortFields = []; /** * Constraint severeness @@ -78,86 +62,47 @@ class AssertProductForm extends AbstractConstraint CatalogProductEdit $productPage ) { $filter = ['sku' => $product->getSku()]; - $productGrid->open()->getProductGrid()->searchAndOpen($filter); - - $formData = $productPage->getForm()->getData($product); - $fixtureData = $this->prepareFixtureData($product); + $productGrid->open(); + $productGrid->getProductGrid()->searchAndOpen($filter); - $errors = $this->compareArray($fixtureData, $formData); - \PHPUnit_Framework_Assert::assertTrue( - empty($errors), - "These data must be equal to each other:\n" . implode("\n", $errors) - ); + $fixtureData = $this->prepareFixtureData($product->getData(), $this->sortFields); + $formData = $this->prepareFormData($productPage->getForm()->getData($product), $this->sortFields); + $error = $this->verifyData($fixtureData, $formData); + \PHPUnit_Framework_Assert::assertTrue(empty($error), $error); } /** - * Prepares and returns data to the fixture, ready for comparison + * Prepares fixture data for comparison * - * @param FixtureInterface $product + * @param array $data + * @param array $sortFields [optional] * @return array */ - protected function prepareFixtureData(FixtureInterface $product) + protected function prepareFixtureData(array $data, array $sortFields = []) { - $compareData = $product->getData(); - $compareData = array_filter($compareData); - - array_walk_recursive( - $compareData, - function (&$item, $key, $formattingOptions) { - if (isset($formattingOptions[$key])) { - $item = number_format( - $item, - $formattingOptions[$key]['decimals'], - $formattingOptions[$key]['dec_point'], - $formattingOptions[$key]['thousands_sep'] - ); - } - }, - $this->formattingOptions - ); - - if (isset($compareData['special_price'])) { - $compareData['special_price'] = ['special_price' => $compareData['special_price']]; + if (isset($data['website_ids']) && !is_array($data['website_ids'])) { + $data['website_ids'] = [$data['website_ids']]; } - return $compareData; + foreach ($sortFields as $path) { + $data = $this->sortDataByPath($data, $path); + } + return $data; } /** - * Comparison of multidimensional arrays + * Prepares form data for comparison * - * @param array $fixtureData - * @param array $formData + * @param array $data + * @param array $sortFields [optional] * @return array - * - * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ - protected function compareArray(array $fixtureData, array $formData) + protected function prepareFormData(array $data, array $sortFields = []) { - $errors = []; - $keysDiff = array_diff(array_keys($formData), array_keys($fixtureData)); - if (!empty($keysDiff)) { - return ['- fixture data do not correspond to form data in composition.']; + foreach ($sortFields as $path) { + $data = $this->sortDataByPath($data, $path); } - - foreach ($fixtureData as $key => $value) { - if (is_array($value) && is_array($formData[$key]) - && ($innerErrors = $this->compareArray($value, $formData[$key])) && !empty($innerErrors) - ) { - $errors = array_merge($errors, $innerErrors); - } elseif ($value != $formData[$key]) { - $fixtureValue = empty($value) ? '<empty-value>' : $value; - $formValue = empty($formData[$key]) ? '<empty-value>' : $formData[$key]; - $errors = array_merge( - $errors, - [ - "error key -> '{$key}' : error value -> '{$fixtureValue}' does not equal -> '{$formValue}'" - ] - ); - } - } - - return $errors; + return $data; } /** diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductGroupedPriceOnProductPage.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductGroupedPriceOnProductPage.php new file mode 100644 index 0000000000000000000000000000000000000000..05902a4b452a47c38a696f6441bec7df632a57a7 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductGroupedPriceOnProductPage.php @@ -0,0 +1,136 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\Constraint; + +use Mtf\Fixture\FixtureInterface; +use Mtf\Constraint\AbstractConstraint; +use Magento\Catalog\Test\Block\Product\View; +use Magento\Catalog\Test\Page\Product\CatalogProductView; + +/** + * Class AssertProductGroupedPriceOnProductPage + */ +class AssertProductGroupedPriceOnProductPage extends AbstractConstraint implements AssertPriceOnProductPageInterface +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Error message + * + * @var string + */ + protected $errorMessage = 'That displayed grouped price on product page is NOT equal to one, passed from fixture.'; + + /** + * Customer group + * + * @var string + */ + protected $customerGroup; + + /** + * Assert that displayed grouped price on product page equals passed from fixture + * + * @param CatalogProductView $catalogProductView + * @param FixtureInterface $product + * @return void + */ + public function processAssert(CatalogProductView $catalogProductView, FixtureInterface $product) + { + $catalogProductView->init($product); + $catalogProductView->open(); + + //Process assertions + $this->assertPrice($product, $catalogProductView); + } + + /** + * Set $errorMessage for grouped price assert + * + * @param string $errorMessage + * @return void + */ + public function setErrorMessage($errorMessage) + { + $this->errorMessage = $errorMessage; + } + + /** + * Verify product special price on product view page + * + * @param FixtureInterface $product + * @param CatalogProductView $catalogProductView + * @param string $block [optional] + * @param string $customerGroup [optional] + * @return void + */ + public function assertPrice( + FixtureInterface $product, + CatalogProductView $catalogProductView, + $block = '', + $customerGroup = 'NOT LOGGED IN' + ) { + $this->customerGroup = $customerGroup; + $groupPrice = $this->getGroupedPrice($catalogProductView->{'get' . $block . 'ViewBlock'}(), $product); + \PHPUnit_Framework_Assert::assertEquals($groupPrice['fixture'], $groupPrice['onPage'], $this->errorMessage); + } + + /** + * Get grouped price with fixture product and product page + * + * @param View $view + * @param FixtureInterface $product + * @return array + */ + protected function getGroupedPrice(View $view, FixtureInterface $product) + { + $fields = $product->getData(); + $groupPrice['onPage'] = $view->getProductPrice(); + $groupPrice['onPage'] = isset($groupPrice['onPage']['price_special_price']) + ? $groupPrice['onPage']['price_special_price'] + : null; + $groupPrice['fixture'] = number_format( + $fields['group_price'][array_search($this->customerGroup, $fields['group_price'])]['price'], + 2 + ); + + return $groupPrice; + } + + /** + * Returns a string representation of the object + * + * @return string + */ + public function toString() + { + return 'Assert that displayed grouped price on product page equals passed from fixture.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductInCart.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductInCart.php old mode 100644 new mode 100755 index 83987d7abd5524e702d421c7268a945bab99f450..7b03df6af3cec7f4cab312b8d3353aa4cc2f121d --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductInCart.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductInCart.php @@ -62,7 +62,7 @@ class AssertProductInCart extends AbstractConstraint $customOption = $catalogProductView->getCustomOptionsBlock(); $options = $customOption->getOptions(); $key = $productOptions[0]['title']; - $customOption->selectProductCustomOption(reset($options[$key]['value'])); + $customOption->selectProductCustomOption($options[$key]['title']); } $catalogProductView->getViewBlock()->clickAddToCart(); diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductInCategory.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductInCategory.php index 164eafe6024a2d1312495248c763cdf63427d8e2..4490968398655e8019f8c8634cb5aca2ba87bab8 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductInCategory.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductInCategory.php @@ -58,8 +58,13 @@ class AssertProductInCategory extends AbstractConstraint CatalogCategory $category ) { // Open category view page and check visible product + $categoryName = $category->getName(); + if ($product->hasData('category_ids')) { + $categoryIds = $product->getCategoryIds(); + $categoryName = is_array($categoryIds) ? reset($categoryIds) : $categoryName; + } $cmsIndex->open(); - $cmsIndex->getTopmenu()->selectCategoryByName($category->getName()); + $cmsIndex->getTopmenu()->selectCategoryByName($categoryName); $isProductVisible = $catalogCategoryView->getListProductBlock()->isProductVisible($product->getName()); while (!$isProductVisible && $catalogCategoryView->getToolbar()->nextPage()) { diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductInStock.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductInStock.php old mode 100644 new mode 100755 index 88af87b1409a5472d81a1832f7330bb4ff731029..134d826fd58bd854895b0e1d794bd54cd467ee97 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductInStock.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductInStock.php @@ -43,7 +43,7 @@ class AssertProductInStock extends AbstractConstraint /** * Text value for checking Stock Availability */ - const STOCK_AVAILABILITY = 'In stock'; + const STOCK_AVAILABILITY = 'in stock'; /** * Assert that In Stock status is displayed on product page diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductIsNotDisplayingOnFrontend.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductIsNotDisplayingOnFrontend.php old mode 100644 new mode 100755 index 97378c339816e27f7aa5323c131c79e1576f414e..399df64eae5297f7fe1792fe99138c1ef1bd18b2 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductIsNotDisplayingOnFrontend.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductIsNotDisplayingOnFrontend.php @@ -92,7 +92,7 @@ class AssertProductIsNotDisplayingOnFrontend extends AbstractConstraint * @param CatalogCategoryView $catalogCategoryView * @param CmsIndex $cmsIndex * @param FixtureInterface|FixtureInterface[] $product - * @param CatalogCategory $category + * @param CatalogCategory|null $category */ public function processAssert( CatalogProductView $catalogProductView, @@ -100,7 +100,7 @@ class AssertProductIsNotDisplayingOnFrontend extends AbstractConstraint CatalogCategoryView $catalogCategoryView, CmsIndex $cmsIndex, $product, - CatalogCategory $category + CatalogCategory $category = null ) { $this->catalogProductView = $catalogProductView; $this->catalogSearchResult = $catalogSearchResult; @@ -112,8 +112,8 @@ class AssertProductIsNotDisplayingOnFrontend extends AbstractConstraint foreach ($products as $product) { $errors = array_merge($errors, $this->isNotDisplayingOnFrontendAssert($product)); } - \PHPUnit_Framework_Assert::assertTrue( - empty($errors), + \PHPUnit_Framework_Assert::assertEmpty( + $errors, "In the process of checking product availability on the frontend, found the following errors:\n" . implode("\n", $errors) ); @@ -147,7 +147,7 @@ class AssertProductIsNotDisplayingOnFrontend extends AbstractConstraint } $categoryName = ($product->hasData('category_ids')) - ? $product->getCategoryIds()[0]['name'] + ? $product->getCategoryIds()[0] : $this->category->getName(); $this->cmsIndex->open(); $this->cmsIndex->getTopmenu()->selectCategoryByName($categoryName); diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductIsNotVisibleInCompareBlock.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductIsNotVisibleInCompareBlock.php new file mode 100644 index 0000000000000000000000000000000000000000..b158dc7eb74ad116c1c8a15b0bec12c764ec4daf --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductIsNotVisibleInCompareBlock.php @@ -0,0 +1,89 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\Constraint; + +use Mtf\Fixture\FixtureInterface; +use Magento\Cms\Test\Page\CmsIndex; +use Mtf\Constraint\AbstractConstraint; +use Magento\Customer\Test\Page\CustomerAccountIndex; + +/** + * Class AssertProductIsNotVisibleInCompareBlock + * Assert the product is not displayed on Compare Products block on my account page + */ +class AssertProductIsNotVisibleInCompareBlock extends AbstractConstraint +{ + const SUCCESS_MESSAGE = 'You have no items to compare.'; + + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Assert the product is not displayed on Compare Products block on my account page + * + * @param CmsIndex $cmsIndex + * @param CustomerAccountIndex $customerAccountIndex + * @param int $countProducts [optional] + * @param FixtureInterface $product [optional] + * @return void + */ + public function processAssert( + CmsIndex $cmsIndex, + CustomerAccountIndex $customerAccountIndex, + $countProducts = 0, + FixtureInterface $product = null + ) { + $cmsIndex->open(); + $cmsIndex->getLinksBlock()->openLink("My Account"); + $compareBlock = $customerAccountIndex->getCompareProductsBlock(); + + if (($countProducts > 1) && ($product !== null)) { + \PHPUnit_Framework_Assert::assertFalse( + $compareBlock->isProductVisibleInCompareBlock($product->getName()), + 'The product displays on Compare Products block on my account page.' + ); + } else { + \PHPUnit_Framework_Assert::assertEquals( + self::SUCCESS_MESSAGE, + $compareBlock->getEmptyMessage(), + 'The product displays on Compare Products block on my account page.' + ); + } + } + + /** + * Returns a string representation of the object + * + * @return string + */ + public function toString() + { + return 'The message appears on Compare Products block on my account page.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductIsNotVisibleInComparePage.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductIsNotVisibleInComparePage.php new file mode 100644 index 0000000000000000000000000000000000000000..922188213d892c181fdf41e73324dc75e0609b18 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductIsNotVisibleInComparePage.php @@ -0,0 +1,82 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\Constraint; + +use Mtf\Fixture\FixtureInterface; +use Mtf\Constraint\AbstractConstraint; +use Magento\Catalog\Test\Page\Product\CatalogProductCompare; + +/** + * Class AssertProductIsNotVisibleInComparePage + * Assert the product is not displayed on Compare Products page + */ +class AssertProductIsNotVisibleInComparePage extends AbstractConstraint +{ + const SUCCESS_MESSAGE = 'You have no items to compare.'; + + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Assert the product is not displayed on Compare Products page + * + * @param CatalogProductCompare $comparePage + * @param FixtureInterface $product + * @param int $countProducts [optional] + * @return void + */ + public function processAssert(CatalogProductCompare $comparePage, FixtureInterface $product, $countProducts = 0) + { + $comparePage->open(); + $compareBlock = $comparePage->getCompareProductsBlock(); + + if ($countProducts > 1) { + \PHPUnit_Framework_Assert::assertFalse( + $compareBlock->isProductVisibleInCompareBlock($product->getName()), + 'The product displays on Compare Products page.' + ); + } else { + \PHPUnit_Framework_Assert::assertEquals( + self::SUCCESS_MESSAGE, + $compareBlock->getEmptyMessage(), + 'The product displays on Compare Products page.' + ); + } + } + + /** + * Returns a string representation of the object + * + * @return string + */ + public function toString() + { + return 'Products is not displayed on Compare Products page.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductNotInGrid.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductNotInGrid.php index a1811ddfa2231a4204db69b231e988e252187612..ad5dcd417cdbf0c9514d6e754f687dbadba11b97 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductNotInGrid.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductNotInGrid.php @@ -30,6 +30,7 @@ use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex; /** * Class AssertProductNotInGrid + * Assert that Product absence on grid */ class AssertProductNotInGrid extends AbstractConstraint { @@ -41,7 +42,7 @@ class AssertProductNotInGrid extends AbstractConstraint protected $severeness = 'low'; /** - * Assert that product cannot be found by name and sku. + * Assert that product cannot be found by name and sku * * @param FixtureInterface|FixtureInterface[] $product * @param CatalogProductIndex $productGrid @@ -61,7 +62,7 @@ class AssertProductNotInGrid extends AbstractConstraint } /** - * Returns a string representation of the object. + * Returns a string representation of the object * * @return string */ diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductNotSearchableBySku.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductNotSearchableBySku.php new file mode 100644 index 0000000000000000000000000000000000000000..4a97fa372299cc8548bc23579079d5d732459404 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductNotSearchableBySku.php @@ -0,0 +1,75 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\Constraint; + +use Mtf\Fixture\FixtureInterface; +use Magento\Cms\Test\Page\CmsIndex; +use Mtf\Constraint\AbstractConstraint; +use Magento\CatalogSearch\Test\Page\CatalogsearchResult; + +/** + * Class AssertProductNotSearchableBySku + * Assert that product cannot be found via Quick Search using searchable product attributes. + */ +class AssertProductNotSearchableBySku extends AbstractConstraint +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Assert that product cannot be found via Quick Search using searchable product attributes. + * + * @param CatalogsearchResult $catalogSearchResult + * @param CmsIndex $cmsIndex + * @param FixtureInterface $product + * @return void + */ + public function processAssert( + CatalogsearchResult $catalogSearchResult, + CmsIndex $cmsIndex, + FixtureInterface $product + ) { + $cmsIndex->open(); + $cmsIndex->getSearchBlock()->search($product->getSku()); + \PHPUnit_Framework_Assert::assertFalse( + $catalogSearchResult->getListProductBlock()->isProductVisible($product->getName()), + 'Product was found by SKU.' + ); + } + + /** + * Returns a string representation of the object. + * + * @return string + */ + public function toString() + { + return "Product is not searchable by SKU."; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductNotVisibleInCategory.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductNotVisibleInCategory.php new file mode 100755 index 0000000000000000000000000000000000000000..e8a88c5ae6b75e55f0bbef75c60bf5781f5e3e2f --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductNotVisibleInCategory.php @@ -0,0 +1,85 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\Constraint; + +use Mtf\Fixture\FixtureInterface; +use Magento\Cms\Test\Page\CmsIndex; +use Mtf\Constraint\AbstractConstraint; +use Magento\Catalog\Test\Fixture\CatalogCategory; +use Magento\Catalog\Test\Page\Category\CatalogCategoryView; + +/** + * Class AssertProductNotVisibleInCategory + */ +class AssertProductNotVisibleInCategory extends AbstractConstraint +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Assert that product is not visible in the assigned category + * + * @param CatalogCategoryView $catalogCategoryView + * @param CmsIndex $cmsIndex + * @param FixtureInterface $product + * @param CatalogCategory|null $category + * @return void + */ + public function processAssert( + CatalogCategoryView $catalogCategoryView, + CmsIndex $cmsIndex, + FixtureInterface $product, + CatalogCategory $category = null + ) { + $categoryName = $category + ? $category->getName() + : $product->getCategoryIds()[0]; + $cmsIndex->open(); + $cmsIndex->getTopmenu()->selectCategoryByName($categoryName); + + $isProductVisible = $catalogCategoryView->getListProductBlock()->isProductVisible($product->getName()); + while (!$isProductVisible && $catalogCategoryView->getToolbar()->nextPage()) { + $isProductVisible = $catalogCategoryView->getListProductBlock()->isProductVisible($product->getName()); + } + \PHPUnit_Framework_Assert::assertFalse( + $isProductVisible, + 'Product is exist on category page.' + ); + } + + /** + * Returns a string representation of the object + * + * @return string + */ + public function toString() + { + return 'Product is absent in the assigned category.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductOutOfStock.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductOutOfStock.php old mode 100644 new mode 100755 index 7d340ceddbce8c86d3c1660b1a1da49da816235c..c4e35745f3ea5ef93a9033de17e1a88a431b8417 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductOutOfStock.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductOutOfStock.php @@ -43,7 +43,7 @@ class AssertProductOutOfStock extends AbstractConstraint /** * Text value for checking Stock Availability */ - const STOCK_AVAILABILITY = 'Out of stock'; + const STOCK_AVAILABILITY = 'out of stock'; /** * Assert that Out of Stock status is displayed on product page diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductPage.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductPage.php old mode 100644 new mode 100755 index 52f18eade7d156322bfce35e6c581ffa7288c7b7..3dd53067ba8fbd91f77502bb726160d3e284bd6d --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductPage.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductPage.php @@ -47,6 +47,19 @@ class AssertProductPage extends AbstractConstraint */ protected $severeness = 'low'; + /** + * Error messages + * + * @var array + */ + protected $errorsMessages = [ + 'name' => '- product name on product view page is not correct.', + 'sku' => '- product sku on product view page is not correct.', + 'regular_price' => '- product regular price on product view page is not correct.', + 'short_description' => '- product short description on product view page is not correct.', + 'description' => '- product description on product view page is not correct.' + ]; + /** * Assertion that the product page is displayed correctly * @@ -62,70 +75,79 @@ class AssertProductPage extends AbstractConstraint $catalogProductView->init($product); $catalogProductView->open(); - //Process assertions - $this->assertOnProductView($catalogProductView); + $data = $this->prepareData($catalogProductView); + $badValues = array_diff($data['onPage'], $data['fixture']); + $errors = array_intersect_key($this->errorsMessages, array_keys($badValues)); + $errors += $this->verifySpecialPrice($catalogProductView); + \PHPUnit_Framework_Assert::assertEmpty( + $errors, + PHP_EOL . 'Found the following errors:' . PHP_EOL . implode(' ' . PHP_EOL, $this->errorsMessages) + ); } /** - * Assert prices on the product view page + * Prepare array for assert * * @param CatalogProductView $catalogProductView - * @return void + * @return array */ - protected function assertOnProductView(CatalogProductView $catalogProductView) + protected function prepareData(CatalogProductView $catalogProductView) { $viewBlock = $catalogProductView->getViewBlock(); $price = $viewBlock->getProductPriceBlock()->getPrice(); - $errorsMessages = [ - 'name' => '- product name on product view page is not correct.', - 'sku' => '- product sku on product view page is not correct.', - 'regular_price' => '- product regular price on product view page is not correct.', - 'short_description' => '- product short description on product view page is not correct.', - 'description' => '- product description on product view page is not correct.' - ]; - $dataOnPage = [ - 'name' => $viewBlock->getProductName(), - 'sku' => $viewBlock->getProductSku(), - 'regular_price' => $price['price_regular_price'] + $data = [ + 'onPage' => [ + 'name' => $viewBlock->getProductName(), + 'sku' => $viewBlock->getProductSku(), + ], + 'fixture' => [ + 'name' => $this->product->getName(), + 'sku' => $this->product->getSku(), + ] ]; - $compareData = [ - 'name' => $this->product->getName(), - 'sku' => $this->product->getSku(), - 'regular_price' => number_format($this->product->getPrice(), 2), - ]; + list($priceOnPage, $priceFixture) = $this->preparePrice($price); + $data['onPage'] += $priceOnPage; + $data['fixture'] += $priceFixture; if ($productShortDescription = $this->product->getShortDescription()) { - $compareData['short_description'] = $productShortDescription; - $dataOnPage['short_description'] = $viewBlock->getProductShortDescription(); + $data['fixture']['short_description'] = $productShortDescription; + $data['onPage']['short_description'] = $viewBlock->getProductShortDescription(); } if ($productDescription = $this->product->getDescription()) { - $compareData['description'] = $productDescription; - $dataOnPage['description'] = $viewBlock->getProductDescription(); + $data['fixture']['description'] = $productDescription; + $data['onPage']['description'] = $viewBlock->getProductDescription(); } - $badValues = array_diff($dataOnPage, $compareData); - $errorsMessages = array_merge( - $this->assertSpecialPrice($price), - array_intersect_key($errorsMessages, array_keys($badValues)) - ); + return $data; + } - \PHPUnit_Framework_Assert::assertTrue( - empty($errorsMessages), - PHP_EOL . 'Found the following errors:' . PHP_EOL - . implode(' ' . PHP_EOL, $errorsMessages) - ); + /** + * Prepare Price data + * + * @param array $price + * @return array + */ + protected function preparePrice($price) + { + return [ + ['regular_price' => $price['price_regular_price']], + ['regular_price' => number_format($this->product->getPrice(), 2)] + ]; } /** * Checking the special product price * - * @param array $price + * @param CatalogProductView $catalogProductView * @return array */ - protected function assertSpecialPrice(array $price) + protected function verifySpecialPrice(CatalogProductView $catalogProductView) { + $priceBlock = $catalogProductView->getViewBlock()->getProductPriceBlock(); + $price = $priceBlock->isVisible() ? $priceBlock->getPrice() : ['price_special_price' => null]; $priceComparing = false; + if ($specialPrice = $this->product->getSpecialPrice()) { $priceComparing = $specialPrice; } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductSaveMessage.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductSaveMessage.php index 0c0795556a4689a9d383aaaf59e39206e8a12ac2..8af6a38dad20e853f615b11282116b7324259fea 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductSaveMessage.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductSaveMessage.php @@ -52,18 +52,19 @@ class AssertProductSaveMessage extends AbstractConstraint */ public function processAssert(CatalogProductEdit $productPage) { - $actualMessage = $productPage->getMessagesBlock()->getSuccessMessages(); - \PHPUnit_Framework_Assert::assertEquals( + $actualMessages = $productPage->getMessagesBlock()->getSuccessMessages(); + $actualMessages = is_array($actualMessages) ? $actualMessages : [$actualMessages]; + \PHPUnit_Framework_Assert::assertContains( self::SUCCESS_MESSAGE, - $actualMessage, + $actualMessages, 'Wrong success message is displayed.' . "\nExpected: " . self::SUCCESS_MESSAGE - . "\nActual: " . $actualMessage + . "\nActual:\n" . implode("\n - ", $actualMessages) ); } /** - * Returns a string representation of the object. + * Returns a string representation of the object * * @return string */ diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductSearchableBySku.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductSearchableBySku.php index ffd5b5de0a9e36ca4cc085ffaf67dfd7255b62b9..db48a737ccb5304039e03ac5201328fc3d4b061c 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductSearchableBySku.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductSearchableBySku.php @@ -62,6 +62,8 @@ class AssertProductSearchableBySku extends AbstractConstraint * @param CmsIndex $cmsIndex * @param FixtureInterface $product * @return void + * + * @SuppressWarnings(PHPMD.NPathComplexity) */ public function processAssert( CatalogsearchResult $catalogSearchResult, @@ -69,19 +71,24 @@ class AssertProductSearchableBySku extends AbstractConstraint FixtureInterface $product ) { $cmsIndex->open(); - $cmsIndex->getSearchBlock()->search($product->getSku()); + $sku = ($product->hasData('sku') !== false) ? $product->getSku() : $product->getName(); + $cmsIndex->getSearchBlock()->search($sku); + + $quantityAndStockStatus = $product->getQuantityAndStockStatus(); + $stockStatus = isset($quantityAndStockStatus['is_in_stock']) + ? $quantityAndStockStatus['is_in_stock'] + : null; - $isInStock = $product->getQuantityAndStockStatus(); - if ($product->getVisibility() === 'Catalog' - || (isset($isInStock['is_in_stock']) && $isInStock['is_in_stock'] === 'Out of Stock') - ) { - $isVisible = !($catalogSearchResult->getListProductBlock()->isProductVisible($product->getName())); - $this->errorMessage = 'Product successfully found by SKU.'; - $this->successfulMessage = 'The product has not been found by SKU.'; - } else { + $isVisible = $catalogSearchResult->getListProductBlock()->isProductVisible($product->getName()); + while (!$isVisible && $catalogSearchResult->getToolbar()->nextPage()) { $isVisible = $catalogSearchResult->getListProductBlock()->isProductVisible($product->getName()); } + if ($product->getVisibility() === 'Catalog' || $stockStatus === 'Out of Stock') { + $isVisible = !$isVisible; + list($this->errorMessage, $this->successfulMessage) = [$this->successfulMessage, $this->errorMessage]; + } + \PHPUnit_Framework_Assert::assertTrue( $isVisible, $this->errorMessage diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductSimpleDuplicateForm.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductSimpleDuplicateForm.php new file mode 100644 index 0000000000000000000000000000000000000000..b0975294e6d1a56631974f5241c828d1c363e652 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductSimpleDuplicateForm.php @@ -0,0 +1,39 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\Constraint; + +/** + * Class AssertProductSimpleDuplicateForm + * Assert form data equals duplicate simple product data + */ +class AssertProductSimpleDuplicateForm extends AssertProductDuplicateForm +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertSpecialPriceOnProductPage.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductSpecialPriceOnProductPage.php old mode 100644 new mode 100755 similarity index 63% rename from dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertSpecialPriceOnProductPage.php rename to dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductSpecialPriceOnProductPage.php index aa17ed49c67a0efc500eac2e9e2e31805e54a29d..39561809d3dd2fb91d5bcb0fff0555e0f9cbbb7b --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertSpecialPriceOnProductPage.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductSpecialPriceOnProductPage.php @@ -29,9 +29,9 @@ use Mtf\Constraint\AbstractConstraint; use Magento\Catalog\Test\Page\Product\CatalogProductView; /** - * Class AssertSpecialPriceOnProductPage + * Class AssertProductSpecialPriceOnProductPage */ -class AssertSpecialPriceOnProductPage extends AbstractConstraint +class AssertProductSpecialPriceOnProductPage extends AbstractConstraint implements AssertPriceOnProductPageInterface { /** * Constraint severeness @@ -40,6 +40,13 @@ class AssertSpecialPriceOnProductPage extends AbstractConstraint */ protected $severeness = 'low'; + /** + * Error message + * + * @var string + */ + protected $errorMessage = 'Assert that displayed special price on product page NOT equals to passed from fixture.'; + /** * Assert that displayed special price on product page equals passed from fixture * @@ -51,16 +58,45 @@ class AssertSpecialPriceOnProductPage extends AbstractConstraint { $catalogProductView->init($product); $catalogProductView->open(); + + //Process assertions + $this->assertPrice($product, $catalogProductView); + } + + /** + * Set $errorMessage for special price assert + * + * @param string $errorMessage + * @return void + */ + public function setErrorMessage($errorMessage) + { + $this->errorMessage = $errorMessage; + } + + /** + * Verify product special price on product view page + * + * @param CatalogProductView $catalogProductView + * @param FixtureInterface $product + * @param string $block [optional] + * @return void + */ + public function assertPrice( + FixtureInterface $product, + CatalogProductView $catalogProductView, + $block = '' + ) { $fields = $product->getData(); - $specialPrice = $catalogProductView->getViewBlock()->getProductPrice(); + $specialPrice = $catalogProductView->{'get' . $block . 'ViewBlock'}()->getProductPrice(); $specialPrice = (isset($specialPrice['price_special_price'])) ? $specialPrice['price_special_price'] : null; if (isset($fields['special_price'])) { \PHPUnit_Framework_Assert::assertEquals( - $fields['special_price'], + number_format($fields['special_price'], 2), $specialPrice, - 'Assert that displayed special price on product page NOT equals passed from fixture.' + $this->errorMessage ); } } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductTemplateGroupOnProductForm.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductTemplateGroupOnProductForm.php new file mode 100644 index 0000000000000000000000000000000000000000..492294e88edf27cb4b8ed7106fa138b355cb0e4b --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductTemplateGroupOnProductForm.php @@ -0,0 +1,110 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\Constraint; + +use Mtf\Fixture\FixtureFactory; +use Mtf\Constraint\AbstractConstraint; +use Magento\Catalog\Test\Fixture\CatalogAttributeSet; +use Magento\Catalog\Test\Fixture\CatalogProductSimple; +use Magento\Catalog\Test\Fixture\CatalogProductAttribute; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductNew; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductEdit; + +/** + * Class AssertProductTemplateGroupOnProductForm + * Check that created product template displays in product template suggest container dropdown and + * can be used for new created product + */ +class AssertProductTemplateGroupOnProductForm extends AbstractConstraint +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'high'; + + /** + * Assert that created product template: + * 1. Displays in product template suggest container dropdown + * 2. Can be used for new created product. + * + * @param FixtureFactory $fixtureFactory + * @param CatalogProductEdit $productEdit + * @param CatalogProductIndex $productGrid + * @param CatalogAttributeSet $attributeSet + * @param CatalogProductNew $newProductPage + * @param CatalogProductAttribute $productAttributeOriginal + * @return void + */ + public function processAssert + ( + FixtureFactory $fixtureFactory, + CatalogProductEdit $productEdit, + CatalogProductIndex $productGrid, + CatalogAttributeSet $attributeSet, + CatalogProductNew $newProductPage, + CatalogProductAttribute $productAttributeOriginal + ) { + + $productGrid->open(); + $productGrid->getGridPageActionBlock()->addProduct('simple'); + $productBlockForm = $newProductPage->getForm(); + + /**@var CatalogProductSimple $catalogProductSimple */ + $productSimple = $fixtureFactory->createByCode( + 'catalogProductSimple', + [ + 'dataSet' => 'default', + 'data' => [ + 'attribute_set_id' => ['attribute_set' => $attributeSet], + ], + ] + ); + $productBlockForm->fill($productSimple); + + \PHPUnit_Framework_Assert::assertTrue( + $productEdit->getForm()->isTabVisible($attributeSet->getGroup()), + "Product Group is absent on Product form tabs." + ); + + $productEdit->getForm()->openCustomTab($attributeSet->getGroup()); + \PHPUnit_Framework_Assert::assertTrue( + $productEdit->getForm()->checkAttributeLabel($productAttributeOriginal), + "Product Attribute is absent on Product form." + ); + } + + /** + * Returns a string representation of the object + * + * @return string + */ + public function toString() + { + return 'Product Group and Product Attribute are present on the Product form.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductTemplateNotInGrid.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductTemplateNotInGrid.php new file mode 100644 index 0000000000000000000000000000000000000000..36a9580890c8a7638abe7f007bd3608fb536089b --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductTemplateNotInGrid.php @@ -0,0 +1,73 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\Constraint; + +use Mtf\Constraint\AbstractConstraint; +use Magento\Catalog\Test\Fixture\CatalogAttributeSet; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductSetIndex; + +/** + * Class AssertProductTemplateNotInGrid + * Assert that Product Template absence on grid + */ +class AssertProductTemplateNotInGrid extends AbstractConstraint +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Assert that product template is not displayed in Product Templates grid + * + * @param CatalogProductSetIndex $productSetPage + * @param CatalogAttributeSet $productTemplate + * @return void + */ + public function processAssert(CatalogProductSetIndex $productSetPage, CatalogAttributeSet $productTemplate) + { + $filterAttributeSet = [ + 'set_name' => $productTemplate->getAttributeSetName(), + ]; + + $productSetPage->open(); + \PHPUnit_Framework_Assert::assertFalse( + $productSetPage->getGrid()->isRowVisible($filterAttributeSet), + 'Attribute Set with name "' . $filterAttributeSet['set_name'] . '" is present in Product Template grid.' + ); + } + + /** + * Text absent new product template in grid + * + * @return string + */ + public function toString() + { + return 'Product template is absent in Product Templates grid'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductTemplateOnProductForm.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductTemplateOnProductForm.php old mode 100644 new mode 100755 index 3d7b29e55d6d797283d8cc9fb16b1dad7a7e954c..c0b365a1e1f37069ca6d93c4523cc086d5f134f8 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductTemplateOnProductForm.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductTemplateOnProductForm.php @@ -55,6 +55,7 @@ class AssertProductTemplateOnProductForm extends AbstractConstraint * @param CatalogProductEdit $productEdit * @param CatalogProductIndex $productGrid * @param CatalogAttributeSet $attributeSet + * @param CatalogAttributeSet $attributeSetOriginal * @param CatalogProductNew $newProductPage * @param CatalogProductAttribute $productAttribute * @return void @@ -66,11 +67,12 @@ class AssertProductTemplateOnProductForm extends AbstractConstraint CatalogProductIndex $productGrid, CatalogAttributeSet $attributeSet, CatalogProductNew $newProductPage, - CatalogProductAttribute $productAttribute + CatalogProductAttribute $productAttribute, + CatalogAttributeSet $attributeSetOriginal = null ) { $productGrid->open(); - $productGrid->getProductBlock()->addProduct('simple'); + $productGrid->getGridPageActionBlock()->addProduct('simple'); $productBlockForm = $newProductPage->getForm(); /**@var CatalogProductSimple $catalogProductSimple */ @@ -83,7 +85,7 @@ class AssertProductTemplateOnProductForm extends AbstractConstraint ], ] ); - $productBlockForm->fillProduct($productSimple); + $productBlockForm->fill($productSimple); $newProductPage->getFormAction()->save(); $formData = $productEdit->getForm()->getData($productSimple); @@ -96,11 +98,14 @@ class AssertProductTemplateOnProductForm extends AbstractConstraint . "\nActual: " . $formAttributeSet ); - $productEdit->getForm()->openTab('product-details'); - \PHPUnit_Framework_Assert::assertTrue( - $productEdit->getForm()->checkAttributeLabel($productAttribute), - "Product Attribute is absent on Product form." - ); + if ($attributeSetOriginal === null) { + $productEdit->getForm()->openTab('product-details'); + + \PHPUnit_Framework_Assert::assertTrue( + $productEdit->getForm()->checkAttributeLabel($productAttribute), + "Product Attribute is absent on Product form." + ); + } } /** diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductTemplateSuccessDeleteMessage.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductTemplateSuccessDeleteMessage.php new file mode 100644 index 0000000000000000000000000000000000000000..d794de682bbe29151d54e70974e4905d53f378e0 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductTemplateSuccessDeleteMessage.php @@ -0,0 +1,75 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\Constraint; + +use Mtf\Constraint\AbstractConstraint; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductSetIndex; + +/** + * Class AssertProductTemplateSuccessDeleteMessage + * Check Product Templates success delete message + */ +class AssertProductTemplateSuccessDeleteMessage extends AbstractConstraint +{ + /** + * Text value to be checked + */ + const SUCCESS_DELETE_MESSAGE = 'The attribute set has been removed.'; + + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'high'; + + /** + * Assert that after deleting product template success delete message appears + * + * @param CatalogProductSetIndex $productSetIndex + * @return void + */ + public function processAssert(CatalogProductSetIndex $productSetIndex) + { + $actualMessage = $productSetIndex->getMessagesBlock()->getSuccessMessages(); + \PHPUnit_Framework_Assert::assertEquals( + self::SUCCESS_DELETE_MESSAGE, + $actualMessage, + 'Wrong success message is displayed.' + . "\nExpected: " . self::SUCCESS_DELETE_MESSAGE + . "\nActual: " . $actualMessage + ); + } + + /** + * Returns a string representation of the object. + * + * @return string + */ + public function toString() + { + return 'Product Templates success delete message is present.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertTierPriceOnProductPage.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductTierPriceOnProductPage.php old mode 100644 new mode 100755 similarity index 71% rename from dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertTierPriceOnProductPage.php rename to dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductTierPriceOnProductPage.php index d2cf9dfba5c80ba8c7429f6c51e2ac1d827f4cb1..da02ab532058870322ac3a40292862923726fd36 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertTierPriceOnProductPage.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductTierPriceOnProductPage.php @@ -27,11 +27,12 @@ namespace Magento\Catalog\Test\Constraint; use Mtf\Fixture\FixtureInterface; use Mtf\Constraint\AbstractConstraint; use Magento\Catalog\Test\Page\Product\CatalogProductView; +use Magento\Catalog\Test\Block\Product\View; /** - * Class AssertTierPriceOnProductPage + * Class AssertProductTierPriceOnProductPage */ -class AssertTierPriceOnProductPage extends AbstractConstraint +class AssertProductTierPriceOnProductPage extends AbstractConstraint implements AssertPriceOnProductPageInterface { /** * Constraint severeness @@ -40,6 +41,20 @@ class AssertTierPriceOnProductPage extends AbstractConstraint */ protected $severeness = 'low'; + /** + * Error message + * + * @var string + */ + protected $errorMessage = 'Product tier price on product page is not correct.'; + + /** + * Format price + * + * @var int + */ + protected $priceFormat = 2; + /** * Assertion that tier prices are displayed correctly * @@ -57,7 +72,18 @@ class AssertTierPriceOnProductPage extends AbstractConstraint $catalogProductView->open(); //Process assertions - $this->assertTierPrice($product, $catalogProductView); + $this->assertPrice($product, $catalogProductView); + } + + /** + * Set $errorMessage for tier price assert + * + * @param string $errorMessage + * @return void + */ + public function setErrorMessage($errorMessage) + { + $this->errorMessage = $errorMessage; } /** @@ -65,14 +91,16 @@ class AssertTierPriceOnProductPage extends AbstractConstraint * * @param FixtureInterface $product * @param CatalogProductView $catalogProductView + * @param string $block [optional] * @return void */ - protected function assertTierPrice(FixtureInterface $product, CatalogProductView $catalogProductView) + public function assertPrice(FixtureInterface $product, CatalogProductView $catalogProductView, $block = '') { $noError = true; $match = []; $index = 1; - $viewBlock = $catalogProductView->getViewBlock(); + /** @var View $viewBlock */ + $viewBlock = $catalogProductView->{'get' . $block . 'ViewBlock'}(); $tierPrices = $product->getTierPrice(); foreach ($tierPrices as $tierPrice) { @@ -83,14 +111,14 @@ class AssertTierPriceOnProductPage extends AbstractConstraint } if (count($match) < 2 && $match[1] != $tierPrice['price_qty'] - || $match[2] !== number_format($tierPrice['price'], 2) + || $match[2] !== number_format($tierPrice['price'], $this->priceFormat) ) { $noError = false; break; } } - \PHPUnit_Framework_Assert::assertTrue($noError, 'Product tier price on product page is not correct.'); + \PHPUnit_Framework_Assert::assertTrue($noError, $this->errorMessage); } /** diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductVisibleInCategory.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductVisibleInCategory.php index 04e4727a32ffc6be3c8e3dc718234470c1622e93..da0b9f38421d5ba5bd128b865cb63868f9c89fb0 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductVisibleInCategory.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductVisibleInCategory.php @@ -42,7 +42,6 @@ class AssertProductVisibleInCategory extends AbstractConstraint */ protected $severeness = 'low'; - /** * Displays an error message * @@ -63,27 +62,27 @@ class AssertProductVisibleInCategory extends AbstractConstraint * @param CatalogCategoryView $catalogCategoryView * @param CmsIndex $cmsIndex * @param FixtureInterface $product - * @param CatalogCategory $category + * @param CatalogCategory|null $category * @return void + * + * @SuppressWarnings(PHPMD.NPathComplexity) */ public function processAssert( CatalogCategoryView $catalogCategoryView, CmsIndex $cmsIndex, FixtureInterface $product, - CatalogCategory $category + CatalogCategory $category = null ) { + $categoryName = $product->hasData('category_ids') ? $product->getCategoryIds()[0] : $category->getName(); $cmsIndex->open(); - $cmsIndex->getTopmenu()->selectCategoryByName($category->getName()); + $cmsIndex->getTopmenu()->selectCategoryByName($categoryName); $isProductVisible = $catalogCategoryView->getListProductBlock()->isProductVisible($product->getName()); while (!$isProductVisible && $catalogCategoryView->getToolbar()->nextPage()) { $isProductVisible = $catalogCategoryView->getListProductBlock()->isProductVisible($product->getName()); } - $isInStock = $product->getQuantityAndStockStatus(); - if ($product->getVisibility() === 'Search' - || (isset($isInStock['is_in_stock']) && $isInStock['is_in_stock'] === 'Out of Stock') - ) { + if (($product->getVisibility() === 'Search') || ($this->getStockStatus($product) === 'Out of Stock')) { $isProductVisible = !$isProductVisible; $this->errorMessage = 'Product found in this category.'; $this->successfulMessage = 'Asserts that the product could not be found in this category.'; @@ -95,6 +94,18 @@ class AssertProductVisibleInCategory extends AbstractConstraint ); } + /** + * Getting is in stock status + * + * @param FixtureInterface $product + * @return string|null + */ + protected function getStockStatus(FixtureInterface $product) + { + $quantityAndStockStatus = $product->getQuantityAndStockStatus(); + return isset($quantityAndStockStatus['is_in_stock']) ? $quantityAndStockStatus['is_in_stock'] : null; + } + /** * Returns a string representation of the object * diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertRelatedProductsSection.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertRelatedProductsSection.php old mode 100644 new mode 100755 index 99cb9c60ebbf578a90a72d9c0def7d26407f49be..5448c74e9a5167efa265b09c9a4c56de946025d9 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertRelatedProductsSection.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertRelatedProductsSection.php @@ -59,7 +59,7 @@ class AssertRelatedProductsSection extends AbstractConstraint CatalogCategoryView $catalogCategoryView, CatalogProductView $catalogProductView ) { - $categoryName = $product1->getCategoryIds()[0]['name']; + $categoryName = $product1->getCategoryIds()[0]; $cmsIndex->open(); $cmsIndex->getTopmenu()->selectCategoryByName($categoryName); $catalogCategoryView->getListProductBlock()->openProductViewPage($product1->getName()); diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertUpSellsProductsSection.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertUpSellsProductsSection.php old mode 100644 new mode 100755 index 9a90a23493e32967856e059417a2af23e906286f..bc6d87abcce1be69c1eeacaa7bec5ddca87b2c95 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertUpSellsProductsSection.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertUpSellsProductsSection.php @@ -59,7 +59,7 @@ class AssertUpSellsProductsSection extends AbstractConstraint CatalogCategoryView $catalogCategoryView, CatalogProductView $catalogProductView ) { - $categoryName = $product1->getCategoryIds()[0]['name']; + $categoryName = $product1->getCategoryIds()[0]; $cmsIndex->open(); $cmsIndex->getTopmenu()->selectCategoryByName($categoryName); $catalogCategoryView->getListProductBlock()->openProductViewPage($product1->getName()); diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogAttributeSet.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogAttributeSet.php index 85942bbc2a98021925cd40747d542838ba108324..e5ed3b548087a977907e3344f4f70f0215e31d5a 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogAttributeSet.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogAttributeSet.php @@ -27,8 +27,8 @@ namespace Magento\Catalog\Test\Fixture; use Mtf\Fixture\InjectableFixture; /** - * Class CatalogProductTemplate - * Product Template fixture + * Class CatalogAttributeSet + * Catalog Attribute Set fixture */ class CatalogAttributeSet extends InjectableFixture { @@ -88,6 +88,17 @@ class CatalogAttributeSet extends InjectableFixture 'source' => 'Magento\Catalog\Test\Fixture\CatalogAttributeSet\SkeletonSet', ]; + protected $assigned_attributes = [ + 'attribute_code' => 'assigned_attributes', + 'backend_type' => 'virtual', + 'source' => 'Magento\Catalog\Test\Fixture\CatalogAttributeSet\AssignedAttributes', + ]; + + protected $group = [ + 'attribute_code' => 'group', + 'backend_type' => 'virtual', + ]; + public function getAttributeSetId() { return $this->getData('attribute_set_id'); @@ -112,4 +123,14 @@ class CatalogAttributeSet extends InjectableFixture { return $this->getData('skeleton_set'); } + + public function getAssignedAttributes() + { + return $this->getData('assigned_attributes'); + } + + public function getGroup() + { + return $this->getData('group'); + } } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogAttributeSet.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogAttributeSet.xml index 9d89dbd3824e0585791ecfa3894204d56f4b51db..5cdb82ee1414c1e11cfe4608aae2e5f3921c807a 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogAttributeSet.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogAttributeSet.xml @@ -61,6 +61,15 @@ <attribute_code>skeleton_set</attribute_code> <backend_type>virtual</backend_type> </skeleton_set> + <assigned_attributes> + <attribute_code>assigned_attributes</attribute_code> + <backend_type>virtual</backend_type> + <source>Magento\Catalog\Test\Fixture\CatalogAttributeSet\AssignedAttributes</source> + </assigned_attributes> + <group> + <attribute_code>group</attribute_code> + <backend_type>virtual</backend_type> + </group> </fields> <repository_class>Magento\Catalog\Test\Repository\CatalogAttributeSet</repository_class> <handler_interface>Magento\Catalog\Test\Handler\CatalogAttributeSet\CatalogAttributeSetInterface</handler_interface> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogAttributeSet/AssignedAttributes.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogAttributeSet/AssignedAttributes.php new file mode 100644 index 0000000000000000000000000000000000000000..49576b99733f8c4fa70549d36c255d4e5a7e2899 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogAttributeSet/AssignedAttributes.php @@ -0,0 +1,126 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\Fixture\CatalogAttributeSet; + +use Mtf\Fixture\FixtureFactory; +use Mtf\Fixture\FixtureInterface; +use Magento\Catalog\Test\Fixture\CatalogProductAttribute; + +/** + * Class AssignedAttributes + * + * Data keys: + * - presets + */ +class AssignedAttributes implements FixtureInterface +{ + /** + * Data set configuration settings + * + * @var array + */ + protected $params = []; + + /** + * Names of assigned attributes + * + * @var array + */ + protected $data = []; + + /** + * Assigned attributes + * + * @var array + */ + protected $attributes = []; + + /** + * @constructor + * @param FixtureFactory $fixtureFactory + * @param array $params + * @param array $data [optional] + */ + public function __construct(FixtureFactory $fixtureFactory, array $params, array $data = []) + { + $this->params = $params; + if (isset($data['presets']) && $data['presets'] !== '-') { + $presets = explode(',', $data['presets']); + foreach ($presets as $preset) { + /** @var CatalogProductAttribute $attribute */ + $attribute = $fixtureFactory->createByCode('catalogProductAttribute', ['dataSet' => $preset]); + $attribute->persist(); + + $this->data[] = $attribute->getAttributeCode(); + $this->attributes[] = $attribute; + } + } else { + $this->data = $data; + } + } + + /** + * Persist attribute + * + * @return void + */ + public function persist() + { + // + } + + /** + * Return data set configuration settings + * + * @return array + */ + public function getDataConfig() + { + return $this->params; + } + + /** + * Return prepared data set + * + * @param string|null $key + * @return array + * + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function getData($key = null) + { + return $this->data; + } + + /** + * Get Attributes + * + * @return array + */ + public function getAttributes() + { + return $this->attributes; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogCategory.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogCategory.php index dff2a59d98b510f5edd81bcf26f30c21cb592d4c..29ec7ec1e25293b34ce4572b360437f3a16fac7c 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogCategory.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogCategory.php @@ -197,21 +197,39 @@ class CatalogCategory extends InjectableFixture protected $name = [ 'attribute_code' => 'name', 'backend_type' => 'virtual', + 'group' => 'general_information', ]; protected $is_active = [ 'attribute_code' => 'is_active', 'backend_type' => 'virtual', + 'group' => 'general_information', ]; protected $url_key = [ 'attribute_code' => 'url_key', 'backend_type' => 'virtual', + 'group' => 'general_information', ]; protected $include_in_menu = [ 'attribute_code' => 'include_in_menu', 'backend_type' => 'virtual', + 'group' => 'general_information', + ]; + + protected $landing_page = [ + 'attribute_code' => 'landing_page', + 'backend_type' => 'virtual', + 'input' => 'select', + 'group' => 'display_setting', + ]; + + protected $display_mode = [ + 'attribute_code' => 'display_mode', + 'backend_type' => 'virtual', + 'input' => 'select', + 'group' => 'display_setting', ]; protected $category_products = [ @@ -326,8 +344,23 @@ class CatalogCategory extends InjectableFixture return $this->getData('include_in_menu'); } + public function getLandingPage() + { + return $this->getData('landing_page'); + } + + public function getDisplayMode() + { + return $this->getData('display_mode'); + } + public function getCategoryProducts() { return $this->getData('category_products'); } + + public function getBlockId() + { + return $this->getData('block_id'); + } } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogCategory.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogCategory.xml index ab2369fc54af0e76b01621345ca730fc3fe90525..ef393c01c95bfc650cee70128569d88b7d7d7c33 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogCategory.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogCategory.xml @@ -149,19 +149,35 @@ <name> <attribute_code>name</attribute_code> <backend_type>virtual</backend_type> + <group>general_information</group> </name> <is_active> <attribute_code>is_active</attribute_code> <backend_type>virtual</backend_type> + <group>general_information</group> </is_active> <url_key> <attribute_code>url_key</attribute_code> <backend_type>virtual</backend_type> + <group>general_information</group> </url_key> <include_in_menu> <attribute_code>include_in_menu</attribute_code> <backend_type>virtual</backend_type> + <group>general_information</group> </include_in_menu> + <landing_page> + <attribute_code>landing_page</attribute_code> + <backend_type>virtual</backend_type> + <input>select</input> + <group>display_setting</group> + </landing_page> + <display_mode> + <attribute_code>display_mode</attribute_code> + <backend_type>virtual</backend_type> + <input>select</input> + <group>display_setting</group> + </display_mode> <category_products> <attribute_code>category_products</attribute_code> <backend_type>virtual</backend_type> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.php old mode 100644 new mode 100755 index 67590d6d8dc3cf08678141cc7f9795ed16ad152c..d34ea99c6890949d5783cada18d268ebab3ae4ed --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.php @@ -106,6 +106,7 @@ class CatalogProductSimple extends InjectableFixture 'qty' => 10.0000, 'is_in_stock' => 'In Stock', ], + 'website_ids' => ['Main Website'], ]; protected $category_ids = [ @@ -114,6 +115,7 @@ class CatalogProductSimple extends InjectableFixture 'is_required' => '0', 'default_value' => '', 'input' => 'text', + 'group' => 'product-details', 'source' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\CategoryIds', ]; @@ -324,22 +326,6 @@ class CatalogProductSimple extends InjectableFixture 'group' => 'product-details', ]; - protected $news_from_date = [ - 'attribute_code' => 'news_from_date', - 'backend_type' => 'datetime', - 'is_required' => '0', - 'default_value' => '', - 'input' => 'date', - ]; - - protected $news_to_date = [ - 'attribute_code' => 'news_to_date', - 'backend_type' => 'datetime', - 'is_required' => '0', - 'default_value' => '', - 'input' => 'date', - ]; - protected $old_id = [ 'attribute_code' => 'old_id', 'backend_type' => 'int', @@ -376,10 +362,10 @@ class CatalogProductSimple extends InjectableFixture protected $quantity_and_stock_status = [ 'attribute_code' => 'quantity_and_stock_status', - 'backend_type' => 'int', + 'backend_type' => 'array', 'is_required' => '0', - 'default_value' => 'In Stock', - 'input' => 'select', + 'default_value' => '', + 'input' => '', 'group' => 'product-details', ]; @@ -574,10 +560,37 @@ class CatalogProductSimple extends InjectableFixture protected $website_ids = [ 'attribute_code' => 'website_ids', 'backend_type' => 'virtual', - 'default_value' => ['Main Website'], + 'default_value' => 'Main Website', 'group' => 'websites', ]; + protected $is_returnable = [ + 'attribute_code' => 'is_returnable', + 'backend_type' => 'varchar', + 'is_required' => '0', + 'default_value' => '2', + 'input' => 'select', + 'group' => 'autosettings', + ]; + + protected $news_from_date = [ + 'attribute_code' => 'news_from_date', + 'backend_type' => 'datetime', + 'is_required' => '0', + 'default_value' => '', + 'input' => 'date', + 'source' => 'Magento\Backend\Test\Fixture\Date', + ]; + + protected $news_to_date = [ + 'attribute_code' => 'news_to_date', + 'backend_type' => 'datetime', + 'is_required' => '0', + 'default_value' => '', + 'input' => 'date', + 'source' => 'Magento\Backend\Test\Fixture\Date', + ]; + public function getCategoryIds() { return $this->getData('category_ids'); @@ -708,16 +721,6 @@ class CatalogProductSimple extends InjectableFixture return $this->getData('name'); } - public function getNewsFromDate() - { - return $this->getData('news_from_date'); - } - - public function getNewsToDate() - { - return $this->getData('news_to_date'); - } - public function getOldId() { return $this->getData('old_id'); @@ -862,4 +865,19 @@ class CatalogProductSimple extends InjectableFixture { return $this->getData('website_ids'); } + + public function getIsReturnable() + { + return $this->getData('is_returnable'); + } + + public function getNewsFromDate() + { + return $this->getData('news_from_date'); + } + + public function getNewsToDate() + { + return $this->getData('news_to_date'); + } } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.xml old mode 100644 new mode 100755 index feccbc686956427730064ba45598084b355eea1f..52b9547ef7ff82391d79a5c3d2b3473d520eb9ef --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.xml @@ -37,7 +37,8 @@ <is_required>0</is_required> <default_value></default_value> <input>text</input> - <fixture>Magento\Catalog\Test\Fixture\CatalogProductSimple\CategoryIds</fixture> + <group>product-details</group> + <source>Magento\Catalog\Test\Fixture\CatalogProductSimple\CategoryIds</source> </category_ids> <color> <attribute_code>color</attribute_code> @@ -445,6 +446,14 @@ <default_value>Main Website</default_value> <group>websites</group> </website_ids> + <is_returnable> + <attribute_code>is_returnable</attribute_code> + <backend_type>varchar</backend_type> + <is_required>0</is_required> + <default_value>2</default_value> + <input>select</input> + <group>autosettings</group> + </is_returnable> </fields> <data_set> <sku></sku> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/CategoryIds.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/CategoryIds.php old mode 100644 new mode 100755 index a8b463e1fdf4cca4a4a8d1af724f0157de4110a3..ec2f5b38f454b0418d95599ab2ddb8f784f9d115 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/CategoryIds.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/CategoryIds.php @@ -42,13 +42,14 @@ class CategoryIds implements FixtureInterface protected $data; /** - * New categories + * Fixtures of category * * @var array */ - protected $category; + protected $categories; /** + * @constructor * @param FixtureFactory $fixtureFactory * @param array $params * @param array $data @@ -66,24 +67,20 @@ class CategoryIds implements FixtureInterface ) { /** @var CatalogCategory $category */ $category = $data['category']; - $this->data[] = [ - 'id' => $category->getId(), - 'name' => $category->getName(), - ]; - $this->category[] = $category; - } elseif (isset($data['presets']) && $data['presets'] !== '-') { - + if (!$category->hasData('id')) { + $category->persist(); + } + $this->data[] = $category->getName(); + $this->categories[] = $category; + } elseif (isset($data['presets'])) { $presets = explode(',', $data['presets']); foreach ($presets as $preset) { $category = $fixtureFactory->createByCode('catalogCategory', ['dataSet' => $preset]); $category->persist(); /** @var CatalogCategory $category */ - $this->data[] = [ - 'id' => $category->getId(), - 'name' => $category->getName(), - ]; - $this->category[] = $category; + $this->data[] = $category->getName(); + $this->categories[] = $category; } } } @@ -101,8 +98,8 @@ class CategoryIds implements FixtureInterface /** * Return prepared data set * - * @param $key [optional] - * @return mixed + * @param string|null $key + * @return array * * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ @@ -126,8 +123,23 @@ class CategoryIds implements FixtureInterface * * @return array */ - public function getCategory() + public function getCategories() { - return $this->category; + return $this->categories; + } + + /** + * Get id of categories + * + * @return array + */ + public function getIds() + { + $ids = []; + foreach ($this->categories as $category) { + $ids[] = $category->getId(); + } + + return $ids; } } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/CheckoutData.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/CheckoutData.php new file mode 100644 index 0000000000000000000000000000000000000000..884b098f388339b01048445c9194face0437b60d --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/CheckoutData.php @@ -0,0 +1,103 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\Fixture\CatalogProductSimple; + +use Mtf\Fixture\FixtureInterface; + +/** + * Class CheckoutData + * Data keys: + * - preset (Checkout data verification preset name) + */ +class CheckoutData implements FixtureInterface +{ + /** + * Current preset + * + * @var string + */ + protected $currentPreset; + + /** + * @constructor + * @param array $params + * @param array $data + */ + public function __construct(array $params, array $data = []) + { + $this->params = $params; + $this->data = (isset($data['value']) && $data['value'] != '-') ? $data['value'] : null; + if (isset($data['preset'])) { + $this->currentPreset = $data['preset']; + } + } + + /** + * Persist custom selections products + * + * @return void + */ + public function persist() + { + // + } + + /** + * Return prepared data set + * + * @param int $key [optional] + * @return mixed + * + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function getData($key = null) + { + return $this->data; + } + + /** + * Return data set configuration settings + * + * @return string + */ + public function getDataConfig() + { + return $this->params; + } + + /** + * Return array preset + * + * @return array|null + */ + public function getPreset() + { + $presets = []; + if (!isset($presets[$this->currentPreset])) { + return null; + } + return $presets[$this->currentPreset]; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/CustomOptions.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/CustomOptions.php old mode 100644 new mode 100755 index b5b1a060b1b0ca866cba632dee4b166c4df91e39..ae564f6f61f72de0f354e040ae0cacdd01f91b5c --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/CustomOptions.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/CustomOptions.php @@ -276,6 +276,150 @@ class CustomOptions implements FixtureInterface ] ] ] + ], + 'all_types' => [ + [ + 'title' => 'custom option field %isolation%', + 'type' => 'Field', + 'is_require' => 'Yes', + 'options' => [ + [ + 'price' => 10, + 'price_type' => 'Fixed', + 'sku' => 'sku_field_option_%isolation%', + 'max_characters' => 1024 + ] + ] + ], + [ + 'title' => 'custom option Area %isolation%', + 'is_require' => 'Yes', + 'type' => 'Area', + 'options' => [ + [ + 'price' => 10, + 'price_type' => 'Fixed', + 'sku' => 'sku_area_row_%isolation%', + 'max_characters' => '10' + ] + ] + ], + [ + 'title' => 'custom option File %isolation%', + 'is_require' => 'No', + 'type' => 'File', + 'options' => [ + [ + 'price' => 10, + 'price_type' => 'Fixed', + 'sku' => 'sku_file_row_%isolation%', + 'file_extension' => 'jpg', + 'image_size_x' => '100', + 'image_size_y' => '100' + ] + ] + ], + [ + 'title' => 'custom option drop down %isolation%', + 'is_require' => 'Yes', + 'type' => 'Drop-down', + 'options' => [ + [ + 'title' => '10 percent', + 'price' => 10, + 'price_type' => 'Percent', + 'sku' => 'sku_drop_down_row_1_%isolation%' + ], + [ + 'title' => '20 percent', + 'price' => 20, + 'price_type' => 'Percent', + 'sku' => 'sku_drop_down_row_2_%isolation%' + ], + [ + 'title' => '30 fixed', + 'price' => 30, + 'price_type' => 'Fixed', + 'sku' => 'sku_drop_down_row_3_%isolation%' + ] + ] + ], + [ + 'title' => 'custom option Radio Buttons %isolation%', + 'is_require' => 'Yes', + 'type' => 'Radio Buttons', + 'options' => [ + [ + 'title' => '20 percent', + 'price' => 20, + 'price_type' => 'Fixed', + 'sku' => 'sku_radio_buttons_row%isolation%' + ] + ] + ], + [ + 'title' => 'custom option Checkbox %isolation%', + 'is_require' => 'Yes', + 'type' => 'Checkbox', + 'options' => [ + [ + 'title' => '20 percent', + 'price' => 20, + 'price_type' => 'Fixed', + 'sku' => 'sku_checkbox_row%isolation%' + ] + ] + ], + [ + 'title' => 'custom option Multiple Select %isolation%', + 'is_require' => 'Yes', + 'type' => 'Multiple Select', + 'options' => [ + [ + 'title' => '20 percent', + 'price' => 20, + 'price_type' => 'Fixed', + 'sku' => 'sku_multiple_select_row%isolation%' + ] + ] + ], + [ + 'title' => 'custom option Date %isolation%', + 'is_require' => 'Yes', + 'type' => 'Date', + 'options' => [ + [ + 'price' => 20, + 'price_type' => 'Fixed', + 'sku' => 'sku_date_row%isolation%' + ] + ] + ], + [ + 'title' => 'custom option Date & Time %isolation%', + 'is_require' => 'Yes', + 'type' => 'Date & Time', + 'options' => [ + [ + 'price' => 20, + 'price_type' => 'Fixed', + 'sku' => 'sku_date_and_time_row%isolation%' + ] + ] + ], + [ + //TODO fixed setValue() for select type (contains => "=") + 'title' => 'custom option Time %isolation%', + 'is_require' => 'Yes', + 'type' => 'Date & Time', + 'options' => [ + [ + 'price' => 20, + 'price_type' => 'Fixed', + 'sku' => 'sku_time_row%isolation%' + ] + ] + ] ] ]; if (!isset($presets[$name])) { diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/GroupPriceOptions.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/GroupPriceOptions.php index 361228f31e6bc2dd2cb7b9012e38667aa8408b53..f1c1639040e7bbe204dbec6badd47d0accf3b55d 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/GroupPriceOptions.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/GroupPriceOptions.php @@ -33,7 +33,6 @@ use Mtf\Fixture\FixtureInterface; * Data keys: * - preset (Price options preset name) * - products (comma separated sku identifiers) - * */ class GroupPriceOptions implements FixtureInterface { @@ -114,7 +113,7 @@ class GroupPriceOptions implements FixtureInterface 'website' => 'All Websites [USD]', 'customer_group' => 'NOT LOGGED IN' ] - ] + ], ]; if (!isset($presets[$name])) { return null; diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/Price.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/Price.php index aef5c617c10f5c0e7ab967cb4a7ad37eb69c9237..7b9ddfe6c723fdb4ee72dd09f176173e14e112f2 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/Price.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/Price.php @@ -36,6 +36,20 @@ use Mtf\Fixture\FixtureInterface; */ class Price implements FixtureInterface { + /** + * Prepared dataSet data + * + * @var array + */ + protected $data; + + /** + * Data set configuration settings + * + * @var array + */ + protected $params; + /** * @var \Mtf\Fixture\FixtureFactory */ @@ -138,7 +152,7 @@ class Price implements FixtureInterface 'product_price' => '100.00', 'product_special_price' => '90.00', 'cart_price' => '90.00' - ] + ], ]; if (!isset($presets[$this->currentPreset])) { return null; diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/TierPriceOptions.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/TierPriceOptions.php index f0e1d290c2e181b4a786170a06457ae42f107d7e..645eac17d343e6941792885a7eac5fe883f4836f 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/TierPriceOptions.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/TierPriceOptions.php @@ -32,7 +32,6 @@ use Mtf\Fixture\FixtureInterface; * Data keys: * - preset (Price options preset name) * - products (comma separated sku identifiers) - * */ class TierPriceOptions implements FixtureInterface { @@ -89,13 +88,13 @@ class TierPriceOptions implements FixtureInterface { $presets = [ 'default' => [ - 0 => [ - 'price' => 150, + [ + 'price' => 15, 'website' => 'All Websites [USD]', 'price_qty' => 3, 'customer_group' => 'ALL GROUPS' ], - 1 => [ + [ 'price' => 24, 'website' => 'All Websites [USD]', 'price_qty' => 15, @@ -103,13 +102,13 @@ class TierPriceOptions implements FixtureInterface ] ], 'MAGETWO-23002' => [ - 0 => [ + [ 'price' => 90, 'website' => 'All Websites [USD]', 'price_qty' => 2, 'customer_group' => 'ALL GROUPS' ] - ] + ], ]; if (!isset($presets[$name])) { diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductVirtual.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductVirtual.php index 9022128f7bca18a2c81451c8549009a8ab7cb096..44b724c213585652e6bd59073c4e0dfb5674260d 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductVirtual.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductVirtual.php @@ -120,6 +120,7 @@ class CatalogProductVirtual extends InjectableFixture 'default_value' => '', 'input' => 'text', 'source' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\CategoryIds', + 'group' => 'product-details', ]; protected $color = [ @@ -579,7 +580,8 @@ class CatalogProductVirtual extends InjectableFixture protected $website_ids = [ 'attribute_code' => 'website_ids', 'backend_type' => 'virtual', - 'default_value' => 'Main Website', + 'default_value' => ['Main Website'], + 'group' => 'websites', ]; public function getCategoryIds() diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductVirtual.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductVirtual.xml index fee9f0037b27f1d9aa2e994fa81d94d76fb24238..37fb96f32497fba8bb270ecc678eb82123a00984 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductVirtual.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductVirtual.xml @@ -38,6 +38,7 @@ <default_value></default_value> <input>text</input> <fixture>Magento\Catalog\Test\Fixture\CatalogProductSimple\CategoryIds</fixture> + <group>product-details</group> </category_ids> <color> <attribute_code>color</attribute_code> @@ -442,6 +443,12 @@ <group>customer-options</group> <fixture>Magento\Catalog\Test\Fixture\CatalogProductSimple\CustomOptions</fixture> </custom_options> + <website_ids> + <attribute_code>website_ids</attribute_code> + <backend_type>virtual</backend_type> + <default_value>Main Website</default_value> + <group>websites</group> + </website_ids> </fields> <data_set> <sku></sku> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/ConfigurableProduct.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/ConfigurableProduct.php index 7a0b52477633bf319c57d79d74c042c0e9ffeaea..344edc124ad91ff3ec4bad4064aac4edee0a1c79 100755 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/ConfigurableProduct.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/ConfigurableProduct.php @@ -243,40 +243,40 @@ class ConfigurableProduct extends Product ), 'configurable_attributes_data' => array( 'value' => array( + '0' => array( + 'label' => array( + 'value' => '%attribute_label_1%' + ), '0' => array( - 'label' => array( - 'value' => '%attribute_label_1%' + 'option_label' => array( + 'value' => '%attribute_1_option_label_1%' ), - '0' => array( - 'option_label' => array( - 'value' => '%attribute_1_option_label_1%' - ), - 'pricing_value' => array( - 'value' => '1' - ), - 'is_percent' => array( - 'value' => 'No' - ), - 'include' => array( - 'value' => 'Yes' - ), + 'pricing_value' => array( + 'value' => '1' + ), + 'is_percent' => array( + 'value' => 'No' + ), + 'include' => array( + 'value' => 'Yes' + ), + ), + '1' => array( + 'option_label' => array( + 'value' => '%attribute_1_option_label_2%' + ), + 'pricing_value' => array( + 'value' => '2' + ), + 'is_percent' => array( + 'value' => 'No' + ), + 'include' => array( + 'value' => 'Yes' ), - '1' => array( - 'option_label' => array( - 'value' => '%attribute_1_option_label_2%' - ), - 'pricing_value' => array( - 'value' => '2' - ), - 'is_percent' => array( - 'value' => 'No' - ), - 'include' => array( - 'value' => 'Yes' - ), - ) ) - ), + ) + ), 'group' => static::GROUP ), 'variations-matrix' => array( diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogAttributeSet/Curl.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogAttributeSet/Curl.php index dc4c1f9b6c37920e13267668ae468f7a9f6bcf87..86fa3f55a7f0cfc94c1f510e5a981dc5fffd18c0 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogAttributeSet/Curl.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogAttributeSet/Curl.php @@ -30,6 +30,7 @@ use Mtf\Util\Protocol\CurlInterface; use Mtf\Util\Protocol\CurlTransport; use Mtf\Handler\Curl as AbstractCurl; use Mtf\Util\Protocol\CurlTransport\BackendDecorator; +use Magento\Catalog\Test\Fixture\CatalogAttributeSet; /** * Class Curl @@ -37,41 +38,175 @@ use Mtf\Util\Protocol\CurlTransport\BackendDecorator; */ class Curl extends AbstractCurl implements CatalogAttributeSetInterface { + /** + * Regex for finding attribute set id + * + * @var string + */ + protected $attributeSetId = '`http.*?product_set\/delete\/id\/(\d*?)\/`'; + + /** + * Regex for finding attributes + * + * @var string + */ + protected $attributes = '#buildCategoryTree\(this.root,.*?(\[.*\}\]\}\])\);#s'; + + /** + * Regex for finding attribute set name + * + * @var string + */ + protected $attributeSetName = '#id="attribute_set_name".*?value="([\w\d]+)"#s'; + /** * Post request for creating Attribute Set * - * @param FixtureInterface $fixture + * @param FixtureInterface|null $fixture * @return array - * @throws \Exception + * + * @SuppressWarnings(PHPMD.NPathComplexity) + * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ public function persist(FixtureInterface $fixture = null) + { + /** @var CatalogAttributeSet $fixture */ + $response = $fixture->hasData('attribute_set_id') + ? $this->getDefaultAttributeSet($fixture) + : $this->createAttributeSet($fixture); + + $attributeSetId = ($fixture->hasData('attribute_set_id')) + ? $fixture->getAttributeSetId() + : $this->getData($this->attributeSetId, $response); + + $assignedAttributes = $fixture->hasData('assigned_attributes') + ? $fixture->getDataFieldConfig('assigned_attributes')['source']->getAttributes() + : []; + $dataAttribute = $this->getDataAttributes($response); + + $lastAttribute = array_pop($dataAttribute['attributes']); + + foreach ($assignedAttributes as $key => $assignedAttribute) { + $dataAttribute['attributes'][] = [ + $assignedAttribute->getAttributeId(), + $dataAttribute['groups'][0][0], + ($lastAttribute[2] + ($key + 1)), + null, + ]; + } + + $this->updateAttributeSet($attributeSetId, $dataAttribute); + + return ['attribute_set_id' => $attributeSetId]; + } + + /** + * Create Attribute Set + * + * @param CatalogAttributeSet $fixture + * @return string + */ + protected function createAttributeSet(CatalogAttributeSet $fixture) { $data = $fixture->getData(); if (!isset($data['gotoEdit'])) { $data['gotoEdit'] = 1; } - $data['skeleton_set'] = $fixture - ->getDataFieldConfig('skeleton_set')['source'] - ->getAttributeSet() + + $data['skeleton_set'] = $fixture->getDataFieldConfig('skeleton_set')['source']->getAttributeSet() ->getAttributeSetId(); $url = $_ENV['app_backend_url'] . 'catalog/product_set/save/'; $curl = new BackendDecorator(new CurlTransport(), new Config); - $curl->write(CurlInterface::POST, $url, '1.0', array(), $data); + $curl->addOption(CURLOPT_HEADER, 1); + $curl->write(CurlInterface::POST, $url, '1.0', [], $data); + $response = $curl->read(); + $curl->close(); + + return $response; + } + + /** + * Get Default Attribute Set page with curl + * + * @param CatalogAttributeSet $fixture + * @return string + */ + protected function getDefaultAttributeSet(CatalogAttributeSet $fixture) + { + $url = $_ENV['app_backend_url'] . 'catalog/product_set/edit/id/' . $fixture->getAttributeSetId() . '/'; + $curl = new BackendDecorator(new CurlTransport(), new Config); + $curl->write(CurlInterface::POST, $url, '1.0'); $response = $curl->read(); $curl->close(); - preg_match( - '`http.*?id\/(\d*?)\/.*?data-ui-id=\"page-actions-toolbar-delete-button\".*`', - $response, - $matches - ); - $id = isset($matches[1]) ? $matches[1] : null; + return $response; + } + + /** + * Update Attribute Set + * + * @param int $attributeSetId + * @param array $dataAttribute + * @return void + */ + protected function updateAttributeSet($attributeSetId, array $dataAttribute) + { + $data = ['data' => json_encode($dataAttribute)]; + $url = $_ENV['app_backend_url'] . 'catalog/product_set/save/id/' . $attributeSetId . '/'; + $curl = new BackendDecorator(new CurlTransport(), new Config); + $curl->write(CurlInterface::POST, $url, '1.0', [], $data); + $curl->read(); + $curl->close(); + } - if (!strpos($response, 'data-ui-id="messages-message-success"')) { - throw new \Exception("Attribute Set creating by curl handler was not successful!"); + /** + * Get data attributes for curl + * + * @param string $response + * @return array + */ + protected function getDataAttributes($response) + { + $attributes = $this->getData($this->attributes, $response, true); + $dataAttribute = []; + + $index = 1; + foreach ($attributes as $key => $parentAttributes) { + $dataAttribute['groups'][$key][] = $parentAttributes['id']; + $dataAttribute['groups'][$key][] = $parentAttributes['text']; + $dataAttribute['groups'][$key][] = $key + 1; + foreach ($parentAttributes['children'] as $attribute) { + $dataAttribute['attributes'][$index][] = $attribute['id']; + $dataAttribute['attributes'][$index][] = $parentAttributes['id']; + $dataAttribute['attributes'][$index][] = $index; + $dataAttribute['attributes'][$index][] = $attribute['entity_id']; + $index++; + } + } + $dataAttribute['not_attributes'] = []; + $dataAttribute['removeGroups'] = []; + $dataAttribute['attribute_set_name'] = $this->getData($this->attributeSetName, $response); + + return $dataAttribute; + } + + /** + * Select data from response by regular expression + * + * @param string $regularExpression + * @param string $response + * @param bool $isJson + * @return mixed + * @throws \Exception + */ + protected function getData($regularExpression, $response, $isJson = false) + { + preg_match($regularExpression, $response, $matches); + if (!isset($matches[1])) { + throw new \Exception("Can't find data in response by regular expression \"{$regularExpression}\"."); } - return ['attribute_set_id' => $id]; + return $isJson ? json_decode($matches[1], true) : $matches[1]; } } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogCategory/Curl.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogCategory/Curl.php old mode 100644 new mode 100755 index 9333090e28c49a892154e5e0a6ec7aa089370b4f..7f3ec0347d1ba65fe32069b007677a0b32cde874 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogCategory/Curl.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogCategory/Curl.php @@ -48,22 +48,38 @@ class Curl extends AbstractCurl implements CatalogCategoryInterface 'filter_price_range', ]; + /** + * Mapping values for data. + * + * @var array + */ + protected $mappingData = [ + 'is_active' => [ + 'Yes' => 1, + 'No' => 0, + ], + 'include_in_menu' => [ + 'Yes' => 1, + 'No' => 0, + ], + 'display_mode' => [ + 'Static block and products' => 'PRODUCTS_AND_PAGE', + 'Static block only' => 'PAGE', + 'Products only' => 'PRODUCTS', + ], + ]; + /** * Post request for creating Subcategory * - * @param FixtureInterface $fixture [optional] - * @return mixed|string + * @param FixtureInterface|null $fixture [optional] + * @return array */ public function persist(FixtureInterface $fixture = null) { - $data['general'] = $fixture->getData(); - foreach ($data['general'] as $key => $value) { - if ($value == 'Yes') { - $data['general'][$key] = 1; - } - if ($value == 'No') { - $data['general'][$key] = 0; - } + $data['general'] = $this->replaceMappingData($fixture->getData()); + if ($fixture->hasData('landing_page')) { + $data['general']['landing_page'] = $this->getBlockId($fixture->getLandingPage()); } $diff = array_diff($this->dataUseConfig, array_keys($data['general'])); @@ -79,7 +95,27 @@ class Curl extends AbstractCurl implements CatalogCategoryInterface $curl->close(); preg_match('#http://.+/id/(\d+).+store/#m', $response, $matches); - $id = isset($matches[1]) ? $matches[1] : null; + $id = isset($matches[1]) ? (int)$matches[1] : null; + return ['id' => $id]; } + + /** + * Getting block id by name + * + * @param string $landingName + * @return int|null + */ + public function getBlockId($landingName) + { + $url = $_ENV['app_backend_url'] . 'catalog/category'; + $curl = new BackendDecorator(new CurlTransport(), new Config); + $curl->write(CurlInterface::POST, $url, '1.0', [], []); + $response = $curl->read(); + $curl->close(); + preg_match('~<option.*value="(\d+)".*>' . preg_quote($landingName) . '</option>~', $response, $matches); + $id = isset($matches[1]) ? (int)$matches[1] : null; + + return $id; + } } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Curl.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Curl.php index 0c754bc08144e6e08a2317cf12ae8f9ab31077f5..f63463d550d29b3bb38d290fe3b75ccf24a4655f 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Curl.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Curl.php @@ -90,12 +90,32 @@ class Curl extends AbstractCurl implements CatalogProductSimpleInterface ] ]; + /** + * Placeholder for price data sent Curl + * + * @var array + */ + protected $priceData = [ + 'website' => [ + 'name' => 'website_id', + 'data' => [ + 'All Websites [USD]' => 0 + ] + ], + 'customer_group' => [ + 'name' => 'cust_group', + 'data' => [ + 'ALL GROUPS' => 32000, + 'NOT LOGGED IN' => 0 + ] + ] + ]; + /** * Post request for creating simple product * * @param FixtureInterface|null $fixture [optional] * @return array - * @throws \Exception * * @SuppressWarnings(PHPMD.NPathComplexity) * @SuppressWarnings(PHPMD.CyclomaticComplexity) @@ -105,34 +125,9 @@ class Curl extends AbstractCurl implements CatalogProductSimpleInterface $config = $fixture->getDataConfig(); $prefix = isset($config['input_prefix']) ? $config['input_prefix'] : null; $data = $this->prepareData($fixture, $prefix); - return ['id' => $this->createProduct($data, $config)]; } - /** - * Getting tax class id from tax rule page - * - * @param string $taxClassName - * @return int - * @throws \Exception - */ - protected function getTaxClassId($taxClassName) - { - $url = $_ENV['app_backend_url'] . 'tax/rule/new/'; - $curl = new BackendDecorator(new CurlTransport(), new Config); - $curl->addOption(CURLOPT_HEADER, 1); - $curl->write(CurlInterface::POST, $url, '1.0', array(), array()); - $response = $curl->read(); - $curl->close(); - - preg_match('~<option value="(\d+)".*>' . $taxClassName . '</option>~', $response, $matches); - if (!isset($matches[1]) || empty($matches[1])) { - throw new \Exception('Product tax class id ' . $taxClassName . ' undefined!'); - } - - return (int)$matches[1]; - } - /** * Prepare POST data for creating product request * @@ -140,28 +135,34 @@ class Curl extends AbstractCurl implements CatalogProductSimpleInterface * @param string|null $prefix [optional] * @return array * - * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) + * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ protected function prepareData(FixtureInterface $fixture, $prefix = null) { $fields = $this->replaceMappingData($fixture->getData()); // Getting Tax class id if ($fixture->hasData('tax_class_id')) { - $taxClassId = $fixture->getDataFieldConfig('tax_class_id')['source']->getTaxClass()->getId(); - $fields['tax_class_id'] = ($taxClassId === null) - ? $this->getTaxClassId($fields['tax_class_id']) - : $taxClassId; + $fields['tax_class_id'] = $fixture->getDataFieldConfig('tax_class_id')['source']->getTaxClass()->getId(); } if (!empty($fields['category_ids'])) { $categoryIds = []; - foreach ($fields['category_ids'] as $categoryData) { - $categoryIds[] = $categoryData['id']; + /** @var InjectableFixture $fixture */ + foreach ($fixture->getDataFieldConfig('category_ids')['source']->getCategories() as $category) { + /** @var CatalogCategory $category */ + $categoryIds[] = $category->getId(); } $fields['category_ids'] = $categoryIds; } - + + if (isset($fields['tier_price'])) { + $fields['tier_price'] = $this->preparePriceData($fields['tier_price']); + } + if (isset($fields['group_price'])) { + $fields['group_price'] = $this->preparePriceData($fields['group_price']); + } + if (!empty($fields['website_ids'])) { foreach ($fields['website_ids'] as &$value) { $value = isset($this->mappingData['website_ids'][$value]) @@ -179,13 +180,11 @@ class Curl extends AbstractCurl implements CatalogProductSimpleInterface $fields['attribute_set_id'] = $attributeSetId; } - $fields = $this->prepareStockData($fields); - return $prefix ? [$prefix => $fields] : $fields; } /** - * Preparation of stock data + * Preparation of tier price data * * @param array $fields * @return array @@ -193,32 +192,16 @@ class Curl extends AbstractCurl implements CatalogProductSimpleInterface * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) */ - protected function prepareStockData(array $fields) + protected function preparePriceData(array $fields) { - if (isset($fields['quantity_and_stock_status']) && !is_array($fields['quantity_and_stock_status'])) { - $fields['quantity_and_stock_status'] = [ - 'qty' => $fields['qty'], - 'is_in_stock' => $fields['quantity_and_stock_status'] - ]; - } - - if (!isset($fields['stock_data']['is_in_stock'])) { - $fields['stock_data']['is_in_stock'] = isset($fields['quantity_and_stock_status']['is_in_stock']) - ? $fields['quantity_and_stock_status']['is_in_stock'] - : (isset($fields['inventory_manage_stock']) ? $fields['inventory_manage_stock'] : null); - } - if (!isset($fields['stock_data']['qty'])) { - $fields['stock_data']['qty'] = isset($fields['quantity_and_stock_status']['qty']) - ? $fields['quantity_and_stock_status']['qty'] - : null; - } - - if (!isset($fields['stock_data']['manage_stock'])) { - $fields['stock_data']['manage_stock'] = (int)(!empty($fields['stock_data']['qty']) - || !empty($fields['stock_data']['is_in_stock'])); + foreach ($fields as &$field) { + foreach ($this->priceData as $key => $data) { + $field[$data['name']] = $this->priceData[$key]['data'][$field[$key]]; + unset($field[$key]); + } + $field['delete'] = ''; } - - return $this->filter($fields); + return $fields; } /** diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductIndex.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductIndex.php index 29af1a20c5f4972715005a39a750132988607e51..8913ed7440b8286a65940d57e5a1e89b85231b7d 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductIndex.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductIndex.php @@ -47,9 +47,9 @@ class CatalogProductIndex extends BackendPage 'locator' => '#messages', 'strategy' => 'css selector', ], - 'productBlock' => [ - 'name' => 'productBlock', - 'class' => 'Magento\Catalog\Test\Block\Adminhtml\Product', + 'gridPageActionBlock' => [ + 'name' => 'gridPageActionBlock', + 'class' => 'Magento\Catalog\Test\Block\Adminhtml\Product\GridPageAction', 'locator' => '#add_new_product', 'strategy' => 'css selector', ], @@ -59,12 +59,6 @@ class CatalogProductIndex extends BackendPage 'locator' => '[id="page:main-container"]', 'strategy' => 'css selector', ], - 'FormPageActions' => [ - 'name' => 'GridPageActions', - 'class' => 'Magento\Catalog\Test\Block\Adminhtml\Product\FormPageActions', - 'locator' => '#add_new_product', - 'strategy' => 'css selector', - ], ]; /** @@ -84,11 +78,11 @@ class CatalogProductIndex extends BackendPage } /** - * @return \Magento\Catalog\Test\Block\Adminhtml\Product + * @return \Magento\Catalog\Test\Block\Adminhtml\Product\GridPageAction */ - public function getProductBlock() + public function getGridPageActionBlock() { - return $this->getBlockInstance('productBlock'); + return $this->getBlockInstance('gridPageActionBlock'); } /** diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductIndex.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductIndex.xml index 0f7cb2b405b8fe9e550032f7753a91d73be4b63f..86115986f042ac02bbcb09aee18151aa56bfa91f 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductIndex.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductIndex.xml @@ -37,8 +37,8 @@ <strategy>css selector</strategy> </block> <block> - <name>productBlock</name> - <class>Magento\Catalog\Test\Block\Adminhtml\Product</class> + <name>gridPageActionBlock</name> + <class>Magento\Catalog\Test\Block\Adminhtml\Product\GridPageAction</class> <locator>#add_new_product</locator> <strategy>css selector</strategy> </block> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductSetEdit.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductSetEdit.php index 0b39dcd231e974ea6063aa9037d3937c42a2e536..cdcfaebf1a9023bc4f2767a0fea2650d2fc29016 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductSetEdit.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductSetEdit.php @@ -47,6 +47,12 @@ class CatalogProductSetEdit extends BackendPage 'locator' => '.attribute-set', 'strategy' => 'css selector', ], + 'attributeSetEditForm' => [ + 'name' => 'attributeSetEditForm', + 'class' => 'Magento\Catalog\Test\Block\Adminhtml\Product\Attribute\Set\Main\EditForm', + 'locator' => '#set_name', + 'strategy' => 'css selector', + ], ]; /** @@ -64,4 +70,11 @@ class CatalogProductSetEdit extends BackendPage { return $this->getBlockInstance('attributeSetEditBlock'); } + /** + * @return \Magento\Catalog\Test\Block\Adminhtml\Product\Attribute\Set\Main\EditForm + */ + public function getAttributeSetEditForm() + { + return $this->getBlockInstance('attributeSetEditForm'); + } } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductSetEdit.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductSetEdit.xml index bcdc08250cf4055019f883a47117d1e2b3f2bfb0..e5e219884e5c4dd0415b6464437b9cbf294c84a3 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductSetEdit.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductSetEdit.xml @@ -36,4 +36,10 @@ <locator>#tree-div2</locator> <strategy>css selector</strategy> </block> + <block> + <name>attributeSetEditForm</name> + <class>Magento\Catalog\Test\Block\Adminhtml\Product\Attribute\Set\Main\EditForm</class> + <locator>#set_name</locator> + <strategy>css selector</strategy> + </block> </page> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Category/CatalogCategoryView.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Category/CatalogCategoryView.php index 72129db92426ac6c07975bf8ee24d9f04b288e48..75699ca9cc2bac42cd3c0385d8f91ebc090bea51 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Category/CatalogCategoryView.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Category/CatalogCategoryView.php @@ -62,13 +62,13 @@ class CatalogCategoryView extends FrontendPage 'titleBlock' => [ 'name' => 'titleBlock', 'class' => 'Magento\Theme\Test\Block\Html\Title', - 'locator' => '.page.title h1.title', + 'locator' => '.page-title h1.title .base', 'strategy' => 'css selector', ], 'viewBlock' => [ 'name' => 'viewBlock', 'class' => 'Magento\Catalog\Test\Block\Category\View', - 'locator' => '.category.view', + 'locator' => '.column.main', 'strategy' => 'css selector', ], ]; diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Category/CatalogCategoryView.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Category/CatalogCategoryView.xml index 179054d44fc1f1f0aa573160650694de5a2be0bb..7f643881091d79c91626ab87bfd22f6ad7e5c91b 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Category/CatalogCategoryView.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Category/CatalogCategoryView.xml @@ -51,13 +51,13 @@ <block> <name>titleBlock</name> <class>Magento\Theme\Test\Block\Html\Title</class> - <locator>.page.title h1.title</locator> + <locator>.page-title h1.title .base</locator> <strategy>css selector</strategy> </block> <block> <name>viewBlock</name> <class>Magento\Catalog\Test\Block\Category\View</class> - <locator>.category.view</locator> + <locator>.column.main</locator> <strategy>css selector</strategy> </block> </page> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductCompare.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductCompare.php new file mode 100644 index 0000000000000000000000000000000000000000..dd1b9857e6aedaa652f1b4fe7ca234f9eec363cf --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductCompare.php @@ -0,0 +1,71 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\Page\Product; + +use Mtf\Page\FrontendPage; + +/** + * Class CatalogProductCompare + * Frontend product compare page + */ +class CatalogProductCompare extends FrontendPage +{ + const MCA = 'catalog/product_compare/index'; + + protected $_blocks = [ + 'compareProductsBlock' => [ + 'name' => 'compareProductsBlock', + 'class' => 'Magento\Catalog\Test\Block\Product\Compare\ListCompare', + 'locator' => '.column.main', + 'strategy' => 'css selector', + ], + 'messagesBlock' => [ + 'name' => 'messagesBlock', + 'class' => 'Magento\Core\Test\Block\Messages', + 'locator' => '.page.messages .messages', + 'strategy' => 'css selector', + ], + ]; + + /** + * Get compare products block + * + * @return \Magento\Catalog\Test\Block\Product\Compare\ListCompare + */ + public function getCompareProductsBlock() + { + return $this->getBlockInstance('compareProductsBlock'); + } + + /** + * Get message block + * + * @return \Magento\Core\Test\Block\Messages + */ + public function getMessagesBlock() + { + return $this->getBlockInstance('messagesBlock'); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductCompare.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductCompare.xml new file mode 100644 index 0000000000000000000000000000000000000000..e1eec834eaacdad45f8e91d243091155bef2058a --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductCompare.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" ?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<page mca="catalog/product_compare/index" > + <block> + <name>compareProductsBlock</name> + <class>Magento\Catalog\Test\Block\Product\Compare\ListCompare</class> + <locator>.column.main</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>messagesBlock</name> + <class>Magento\Core\Test\Block\Messages</class> + <locator>.page.messages .messages</locator> + <strategy>css selector</strategy> + </block> +</page> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductView.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductView.php index 8e0b3d43f38f94de3fb6b4c8347648fc5155a350..80446b453125edb32b8e9dccdb12184eb7a1a1c2 100755 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductView.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductView.php @@ -79,7 +79,7 @@ class CatalogProductView extends FrontendPage 'reviewSummary' => [ 'name' => 'reviewSummary', 'class' => 'Magento\Review\Test\Block\Product\View\Summary', - 'locator' => '.product.reviews.summary', + 'locator' => '.product-reviews-summary', 'strategy' => 'css selector', ], 'reviewFormBlock' => [ @@ -103,7 +103,7 @@ class CatalogProductView extends FrontendPage 'titleBlock' => [ 'name' => 'titleBlock', 'class' => 'Magento\Theme\Test\Block\Html\Title', - 'locator' => '.page.title', + 'locator' => '.page-title h1.title .base', 'strategy' => 'css selector', ] ]; diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductView.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductView.xml index e6301cff8ef22c11b40027dc40f3270fac1e79e7..79c874d2bc7b3beebac595a3526825c803232151 100755 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductView.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductView.xml @@ -75,7 +75,7 @@ <block> <name>reviewSummary</name> <class>Magento\Review\Test\Block\Product\View\Summary</class> - <locator>.product.reviews.summary</locator> + <locator>.product-reviews-summary</locator> <strategy>css selector</strategy> </block> <block> @@ -93,7 +93,7 @@ <block> <name>titleBlock</name> <class>Magento\Theme\Test\Block\Html\Title</class> - <locator>.page.title h1.title</locator> + <locator>.page-title h1.title .base</locator> <strategy>css selector</strategy> </block> </page> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogCategory.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogCategory.php index 00e5f45899fa1940fbbf5adb30152e219a764537..2303a597c96929f7bdbe1865eb5442c3d237b1b5 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogCategory.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogCategory.php @@ -33,6 +33,7 @@ use Mtf\Repository\AbstractRepository; class CatalogCategory extends AbstractRepository { /** + * @constructor * @param array $defaultConfig * @param array $defaultData * diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.php old mode 100644 new mode 100755 index c908338c2edbe89daf7d33ec13a27f13795f63c3..8062fd7ff4b169640fa1d16b12f472c32d9ef777 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.php @@ -55,6 +55,7 @@ class CatalogProductSimple extends AbstractRepository 'price' => ['value' => 560.00, 'preset' => '-'], 'tax_class_id' => ['dataSet' => 'Taxable Goods'], 'website_ids' => ['Main Website'], + 'visibility' => 'Catalog, Search', ]; $this->_data['100_dollar_product'] = [ @@ -71,8 +72,8 @@ class CatalogProductSimple extends AbstractRepository ]; $this->_data['40_dollar_product'] = [ - 'sku' => '40_dollar_product', - 'name' => '40_dollar_product', + 'sku' => '40_dollar_product%isolation%', + 'name' => '40_dollar_product%isolation%', 'type_id' => 'simple', 'quantity_and_stock_status' => [ 'qty' => 666.0000, @@ -128,6 +129,28 @@ class CatalogProductSimple extends AbstractRepository 'category_ids' => ['presets' => 'default_subcategory'] ]; + $this->_data['simple_for_composite_products'] = [ + 'name' => 'simple_for_composite_products%isolation%', + 'sku' => 'simple_for_composite_products%isolation%', + 'price' => ['value' => 560, 'preset' => '-'], + 'attribute_set_id' => ['dataSet' => 'default'], + 'tax_class_id' => ['dataSet' => 'Taxable Goods'], + 'quantity_and_stock_status' => [ + 'qty' => 111, + 'is_in_stock' => 'In Stock', + ], + 'weight' => '1', + 'status' => '1', + 'website_ids' => ['Main Website'], + 'stock_data' => [ + 'manage_stock' => 'Yes', + 'qty' => '111', + 'is_in_stock' => 'In Stock' + ], + 'url_key' => 'simple-for-composite-products%isolation%', + 'visibility' => 'Catalog, Search' + ]; + $this->_data['simple_for_salesrule_2'] = [ 'attribute_set_id' => ['dataSet' => 'default'], 'name' => 'Simple Product %isolation%', @@ -193,5 +216,35 @@ class CatalogProductSimple extends AbstractRepository 'price' => ['value' => 100, 'preset' => '-'], 'website_ids' => ['Main Website'], ]; + + $this->_data['withSpecialPrice'] = [ + 'type_id' => 'simple', + 'attribute_set_id' => ['dataSet' => 'default'], + 'name' => 'Simple Product %isolation%', + 'sku' => 'sku_simple_product_%isolation%', + 'price' => ['value' => 100, 'preset' => '-'], + 'weight' => 1, + 'special_price' => 9 + ]; + + $this->_data['simple_with_group_price'] = [ + 'type_id' => 'simple', + 'attribute_set_id' => ['dataSet' => 'default'], + 'name' => 'Simple Product %isolation%', + 'sku' => 'sku_simple_product_%isolation%', + 'price' => ['value' => 100, 'preset' => '-'], + 'weight' => 1, + 'group_price' => ['preset' => 'default'], + ]; + + $this->_data['simple_with_tier_price'] = [ + 'type_id' => 'simple', + 'attribute_set_id' => ['dataSet' => 'default'], + 'name' => 'Simple Product %isolation%', + 'sku' => 'sku_simple_product_%isolation%', + 'price' => ['value' => 300, 'preset' => '-'], + 'weight' => 1, + 'tier_price' => ['preset' => 'default'], + ]; } } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductVirtual.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductVirtual.php index db7579fae10b2944e74b8724c614d5faa37653f2..7c43610b0d73dd3e31e08a6c22128f98a3a62d4b 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductVirtual.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductVirtual.php @@ -58,5 +58,22 @@ class CatalogProductVirtual extends AbstractRepository ], 'price' => ['value' => 10.00, 'preset' => '-'] ]; + + $this->_data['50_dollar_product'] = [ + 'name' => '50_dollar_product %isolation%', + 'sku' => '50_dollar_product_%isolation%', + 'tax_class_id' => ['dataSet' => 'Taxable Goods'], + 'status' => 'Product online', + 'website_ids' => ['Main Website'], + 'is_virtual' => 'Yes', + 'url_key' => 'virtual-product%isolation%', + 'visibility' => 'Catalog, Search', + 'attribute_set_id' => ['dataSet' => 'default'], + 'quantity_and_stock_status' => [ + 'qty' => 111.0000, + 'is_in_stock' => 'In Stock', + ], + 'price' => ['value' => 50.00, 'preset' => '-'] + ]; } } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/VirtualProduct.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/VirtualProduct.php index ff5aafe8c101827226ffe75e233d21b4bffadfea..cd86c8a2069afffddf98677f7a28102b041d0cd2 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/VirtualProduct.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/VirtualProduct.php @@ -24,6 +24,11 @@ namespace Magento\Catalog\Test\Repository; +/** + * Class VirtualProduct + * Virtual product repository + */ class VirtualProduct extends Product { + // } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AbstractCompareProductsTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AbstractCompareProductsTest.php new file mode 100644 index 0000000000000000000000000000000000000000..4e2cb37e5b30d9bc8da6af78fe421e013c554d30 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AbstractCompareProductsTest.php @@ -0,0 +1,189 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\TestCase\Product; + +use Mtf\TestCase\Injectable; +use Mtf\Fixture\FixtureFactory; +use Mtf\Fixture\InjectableFixture; +use Magento\Cms\Test\Page\CmsIndex; +use Mtf\Constraint\AbstractConstraint; +use Magento\Customer\Test\Page\CustomerAccountLogin; +use Magento\Customer\Test\Fixture\CustomerInjectable; +use Magento\Catalog\Test\Page\Product\CatalogProductView; +use Magento\Catalog\Test\Page\Product\CatalogProductCompare; + +/** + * Class AbstractCompareProductsTest + * Abstract class for compare products class + */ +abstract class AbstractCompareProductsTest extends Injectable +{ + /** + * Array products + * + * @var array + */ + protected $products; + + /** + * Cms index page + * + * @var CmsIndex + */ + protected $cmsIndex; + + /** + * Catalog product compare page + * + * @var CatalogProductCompare + */ + protected $catalogProductCompare; + + /** + * Catalog product page + * + * @var CatalogProductView + */ + protected $catalogProductView; + + /** + * Customer login page + * + * @var CustomerAccountLogin + */ + protected $customerAccountLogin; + + /** + * Fixture factory + * + * @var FixtureFactory + */ + protected $fixtureFactory; + + /** + * Fixture customer + * + * @var CustomerInjectable + */ + protected $customer; + + /** + * Prepare data + * + * @param FixtureFactory $fixtureFactory + * @param CustomerInjectable $customer + * @return void + */ + public function __prepare(FixtureFactory $fixtureFactory, CustomerInjectable $customer) + { + $this->fixtureFactory = $fixtureFactory; + $customer->persist(); + $this->customer = $customer; + } + + /** + * Injection data + * + * @param CmsIndex $cmsIndex + * @param CatalogProductView $catalogProductView + * @param CustomerAccountLogin $customerAccountLogin + * @return void + */ + public function __inject( + CmsIndex $cmsIndex, + CatalogProductView $catalogProductView, + CustomerAccountLogin $customerAccountLogin + ) { + $this->cmsIndex = $cmsIndex; + $this->catalogProductView = $catalogProductView; + $this->customerAccountLogin = $customerAccountLogin; + } + + /** + * Login customer + * + * @return void + */ + protected function loginCustomer() + { + if (!$this->cmsIndex->getLinksBlock()->isLinkVisible('Log Out')) { + $this->cmsIndex->getLinksBlock()->openLink("Log In"); + $this->customerAccountLogin->getLoginBlock()->login($this->customer); + } + } + + /** + * Create products + * + * @param string $products + * @return array + */ + protected function createProducts($products) + { + $products = explode(',', $products); + foreach ($products as $key => $product) { + list($fixture, $dataSet) = explode('::', $product); + $product = $this->fixtureFactory->createByCode($fixture, ['dataSet' => $dataSet]); + $product->persist(); + $products[$key] = $product; + } + return $products; + } + + /** + * Add products to compare list + * + * @param array $products + * @param AbstractConstraint $assert + * @return void + */ + protected function addProducts(array $products, AbstractConstraint $assert = null) + { + foreach ($products as $itemProduct) { + $this->catalogProductView->init($itemProduct); + $this->catalogProductView->open(); + $this->catalogProductView->getViewBlock()->clickAddToCompare(); + if ($assert !== null) { + $this->productCompareAssert($assert, $itemProduct); + } + } + } + + /** + * Perform assert + * + * @param AbstractConstraint $assert + * @param InjectableFixture $product + * @return void + */ + protected function productCompareAssert(AbstractConstraint $assert, InjectableFixture $product) + { + $assert->configure( + $this, + ['catalogProductView' => $this->catalogProductView, 'product' => $product] + ); + \PHPUnit_Framework_Assert::assertThat($this->getName(), $assert); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/Configurable/CreateWithAttributeTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/Configurable/CreateWithAttributeTest.php index cb6a5950987240c09af7d7f6d1491a0f6aa332a9..1e06b8d5b5f67ab7bad3d0c82b802d90a0c66fde 100755 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/Configurable/CreateWithAttributeTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/Configurable/CreateWithAttributeTest.php @@ -91,7 +91,7 @@ class CreateWithAttributeTest extends Functional //Steps $manageProductsGrid->open(); - $manageProductsGrid->getProductBlock()->addProduct(); + $manageProductsGrid->getGridPageActionBlock()->addProduct(); $productForm->fill($product); $productForm->openTab(Product::GROUP_PRODUCT_DETAILS); $productForm->addNewCategory($product); diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateConfigurableTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateConfigurableTest.php index 6deb176332e5abac044ec1fb6ac78f2c2bd27709..1bc8c880df2a7aa09854bff0bd3cb54b69103238 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateConfigurableTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateConfigurableTest.php @@ -60,7 +60,7 @@ class CreateConfigurableTest extends Functional $createProductPage = Factory::getPageFactory()->getCatalogProductNew(); //Steps $manageProductsGrid->open(); - $manageProductsGrid->getProductBlock()->addProduct('configurable'); + $manageProductsGrid->getGridPageActionBlock()->addProduct('configurable'); $productForm = $createProductPage->getProductForm(); $productForm->fill($product); $createProductPage->getFormAction()->saveProduct($createProductPage, $product); diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateGroupedTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateGroupedTest.php index 7ff383d0040103f81b63f395e3d6d8e59b00c297..668f68ed663598e8329aba985780146f39bc70de 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateGroupedTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateGroupedTest.php @@ -62,7 +62,7 @@ class CreateGroupedTest extends Functional $productForm = $createProductPage->getProductForm(); //Steps $manageProductsGrid->open(); - $manageProductsGrid->getProductBlock()->addProduct('grouped'); + $manageProductsGrid->getGridPageActionBlock()->addProduct('grouped'); $productForm->fill($product); $createProductPage->getFormAction()->save(); //Verifying diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleProductEntityTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleProductEntityTest.php new file mode 100755 index 0000000000000000000000000000000000000000..5e9f56d36349a0e07b03852b8ee67d18cbed852a --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleProductEntityTest.php @@ -0,0 +1,119 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\TestCase\Product; + +use Mtf\TestCase\Injectable; +use Magento\Catalog\Test\Fixture\CatalogProductSimple; +use Magento\Catalog\Test\Fixture\CatalogCategory; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductNew; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex; + +/** + * Test Creation for CreateSimpleProductEntity + * + * Test Flow: + * 1. Login to the backend. + * 2. Navigate to Products > Catalog. + * 3. Start to create simple product. + * 4. Fill in data according to data set. + * 5. Save Product. + * 6. Perform appropriate assertions. + * + * @group Products_(CS) + * @ZephyrId MAGETWO-23414 + */ +class CreateSimpleProductEntityTest extends Injectable +{ + /** + * Category fixture + * + * @var CatalogCategory + */ + protected $category; + + /** + * Product page with a grid + * + * @var CatalogProductIndex + */ + protected $productGrid; + + /** + * Page to create a product + * + * @var CatalogProductNew + */ + protected $newProductPage; + + /** + * Prepare data + * + * @param CatalogCategory $category + * @return array + */ + public function __prepare(CatalogCategory $category) + { + $category->persist(); + + return [ + 'category' => $category + ]; + } + + /** + * Injection data + * + * @param CatalogCategory $category + * @param CatalogProductIndex $productGrid + * @param CatalogProductNew $newProductPage + * @return void + */ + public function __inject( + CatalogCategory $category, + CatalogProductIndex $productGrid, + CatalogProductNew $newProductPage + ) { + $this->category = $category; + $this->productGrid = $productGrid; + $this->newProductPage = $newProductPage; + } + + /** + * Run create product simple entity test + * + * @param CatalogProductSimple $product + * @param CatalogCategory $category + * @return void + */ + public function testCreate(CatalogProductSimple $product, CatalogCategory $category) + { + // Steps + $this->productGrid->open(); + $this->productGrid->getGridPageActionBlock()->addProduct('simple'); + $productBlockForm = $this->newProductPage->getForm(); + $productBlockForm->fill($product, null, $category); + $this->newProductPage->getFormAction()->save(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleProductEntityTest/testCreate.csv b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleProductEntityTest/testCreate.csv new file mode 100644 index 0000000000000000000000000000000000000000..3fdd14092f40ecdac812115e979275b306efd906 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleProductEntityTest/testCreate.csv @@ -0,0 +1,19 @@ +"product/data/name";"product/data/sku";"product/data/tax_class_id/dataSet";"product/data/price/value";"product/data/special_price";"product/data/short_description";"product/data/description";"product/data/weight";"product/data/quantity_and_stock_status/qty";"product/data/quantity_and_stock_status/is_in_stock";"product/data/visibility";"constraint";"product/data/custom_options/preset";"product/data/price/preset";"product/data/group_price/preset";"product/data/tier_price/preset" +"Simple Product %isolation%";"simple_sku_%isolation%";"-";"10000";"-";"Simple Product short_description %isolation%";"Simple Product description %isolation%";"50";"657";"-";"-";"assertProductSaveMessage, assertProductInGrid, assertProductInCategory, assertProductPage, assertProductInCart";"MAGETWO-23062";"MAGETWO-23062";"-";"-" +"Simple Product %isolation%";"simple_sku_%isolation%";"-";"10001";"-";"Simple Product short_description %isolation%";"Simple Product description %isolation%";"51";"658";"-";"-";"assertProductSaveMessage, assertProductInGrid, assertProductInCategory, assertProductPage, assertProductInCart";"MAGETWO-23063";"MAGETWO-23063";"-";"-" +"Simple Product %isolation%";"simple_sku_%isolation%";"-";"10002";"90";"Simple Product short_description %isolation%";"Simple Product description %isolation%";"52";"659";"-";"-";"assertProductSaveMessage, assertProductInGrid, assertProductInCategory, assertProductPage, assertProductInCart";"MAGETWO-23062";"MAGETWO-23029";"-";"-" +"Simple Product %isolation%";"simple_sku_%isolation%";"-";"10003";"90";"Simple Product short_description %isolation%";"Simple Product description %isolation%";"53";"660";"-";"-";"assertProductSaveMessage, assertProductInGrid, assertProductInCategory, assertProductPage, assertProductInCart";"MAGETWO-23063";"MAGETWO-23030";"-";"-" +"Simple Product %isolation%";"simple_sku_%isolation%";"-";"10004";"-";"Simple Product short_description %isolation%";"Simple Product description %isolation%";"54";"661";"-";"-";"assertProductSaveMessage, assertProductInGrid, assertProductInCategory, assertProductPage, assertProductInCart";"MAGETWO-23063";"MAGETWO-23030";"MAGETWO-23055";"-" +"Simple Product %isolation%";"simple_sku_%isolation%";"-";"10005";"-";"Simple Product short_description %isolation%";"Simple Product description %isolation%";"55";"662";"-";"-";"assertProductSaveMessage, assertProductInGrid, assertProductInCategory, assertProductPage, assertProductInCart";"MAGETWO-23062";"MAGETWO-23029";"MAGETWO-23055";"-" +"Simple Product %isolation%";"simple_sku_%isolation%";"-";"10006";"-";"Simple Product short_description %isolation%";"Simple Product description %isolation%";"56";"663";"-";"-";"assertProductSaveMessage, assertProductInGrid, assertProductInCategory, assertProductPage, assertProductInCart";"MAGETWO-23063";"MAGETWO-23030";"-";"MAGETWO-23002" +"Simple Product %isolation%";"simple_sku_%isolation%";"-";"10007";"-";"Simple Product short_description %isolation%";"Simple Product description %isolation%";"57";"664";"-";"-";"assertProductSaveMessage, assertProductInGrid, assertProductInCategory, assertProductPage, assertProductInCart";"MAGETWO-23062";"MAGETWO-23029";"-";"MAGETWO-23002" +"Simple Product %isolation%";"simple_sku_%isolation%";"-";"10008";"-";"Simple Product short_description %isolation%";"Simple Product description %isolation%";"58";"665";"-";"-";"assertProductSaveMessage, assertProductInGrid, assertProductVisibleInCategory, assertProductPage";"-";"-";"-";"-" +"Simple Product %isolation%";"simple_sku_%isolation%";"-";"10009";"-";"Simple Product short_description %isolation%";"Simple Product description %isolation%";"59";"75";"In Stock";"-";"assertProductSaveMessage, assertProductInStock";"-";"-";"-";"-" +"Simple Product %isolation%";"simple_sku_%isolation%";"-";"10010";"-";"Simple Product short_description %isolation%";"Simple Product description %isolation%";"60";"0";"Out of Stock";"-";"assertProductSaveMessage, assertProductOutOfStock";"-";"-";"-";"-" +"Simple Product %isolation%";"simple_sku_%isolation%";"-";"10011";"-";"Simple Product short_description %isolation%";"Simple Product description %isolation%";"61";"138";"-";"Search";"assertProductSaveMessage, assertProductSearchableBySku";"-";"-";"-";"-" +"Simple Product %isolation%";"simple_sku_%isolation%";"-";"10012";"-";"Simple Product short_description %isolation%";"Simple Product description %isolation%";"62";"139";"-";"-";"assertProductSaveMessage, assertProductInGrid, assertProductForm, assertProductInStock, assertProductSearchableBySku, assertProductPage";"-";"-";"-";"-" +"Simple Product %isolation%";"simple_sku_%isolation%";"-";"10013";"-";"Simple Product short_description %isolation%";"Simple Product description %isolation%";"63";"140";"-";"-";"assertProductSaveMessage, assertProductInGrid, assertProductForm, assertProductInStock, assertProductVisibleInCategory, assertProductPage";"-";"-";"-";"-" +"Simple Product %isolation%";"simple_sku_%isolation%";"Taxable Goods";"10014";"-";"Simple Product short_description %isolation%";"Simple Product description %isolation%";"64";"141";"-";"-";"assertProductSaveMessage, assertProductInGrid, assertProductForm, assertProductInStock, assertProductVisibleInCategory, assertProductPage, assertProductGroupedPriceOnProductPage";"-";"-";"default";"-" +"Simple Product %isolation%";"simple_sku_%isolation%";"Taxable Goods";"10015";"-";"Simple Product short_description %isolation%";"Simple Product description %isolation%";"65";"142";"-";"-";"assertProductSaveMessage, assertProductInGrid, assertProductForm, assertProductInStock, assertProductVisibleInCategory, assertProductPage, assertProductSpecialPriceOnProductPage";"-";"-";"-";"-" +"Simple Product %isolation%";"simple_sku_%isolation%";"None";"10016";"-";"Simple Product short_description %isolation%";"Simple Product description %isolation%";"66";"143";"-";"-";"assertProductSaveMessage, assertProductInGrid, assertProductForm, assertProductInStock, assertProductVisibleInCategory, assertProductPage, assertProductTierPriceOnProductPage";"-";"-";"-";"default" +"Simple Product %isolation%";"simple_sku_%isolation%";"-";"10017";"-";"Simple Product short_description %isolation%";"Simple Product description %isolation%";"67";"144";"-";"-";"assertProductSaveMessage, assertProductInGrid, assertProductForm, assertProductInStock, assertProductVisibleInCategory, assertProductPage, assertProductCustomOptionsOnProductPage";"options-suite";"-";"-";"-" diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleWithCategoryTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleWithCategoryTest.php index 4a4e413458ce8915ef6f2b2a988f8fb5896458f6..6b011703794e1f68ced48372dc5b8ea28dc1ec6d 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleWithCategoryTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleWithCategoryTest.php @@ -59,7 +59,7 @@ class CreateSimpleWithCategoryTest extends Functional //Page & Blocks $productListPage = Factory::getPageFactory()->getCatalogProductIndex(); $createProductPage = Factory::getPageFactory()->getCatalogProductNew(); - $addProductBlock = $productListPage->getProductBlock(); + $addProductBlock = $productListPage->getGridPageActionBlock(); $productForm = $createProductPage->getProductForm(); //Steps diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleWithCustomOptionsAndCategoryTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleWithCustomOptionsAndCategoryTest.php old mode 100644 new mode 100755 index 3226fb642ccf2b7c0a13f88bee295fe6a38157b7..272ec07ac31176cae095c06fd4105f3332f790f3 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleWithCustomOptionsAndCategoryTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleWithCustomOptionsAndCategoryTest.php @@ -60,7 +60,8 @@ class CreateSimpleWithCustomOptionsAndCategoryTest extends Functional $productForm = $createProductPage->getForm(); //Steps $createProductPage->open(); - $productForm->fillProduct($product); + $category = $product->getCategories()['category']; + $productForm->fill($product, null, $category); $createProductPage->getFormAction()->save(); //Verifying $createProductPage->getMessagesBlock()->assertSuccessMessage(); diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateVirtualProductEntityTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateVirtualProductEntityTest.php old mode 100644 new mode 100755 index 939f39a411a85d840f43393c1a2453235ee94085..74c3de8495496efa10b70991194314a3be334aeb --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateVirtualProductEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateVirtualProductEntityTest.php @@ -105,9 +105,9 @@ class CreateVirtualProductEntityTest extends Injectable { // Steps $this->productGrid->open(); - $this->productGrid->getProductBlock()->addProduct('virtual'); + $this->productGrid->getGridPageActionBlock()->addProduct('virtual'); $productBlockForm = $this->newProductPage->getForm(); - $productBlockForm->fillProduct($product, $category); + $productBlockForm->fill($product, null, $category); $this->newProductPage->getFormAction()->save(); } } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateVirtualProductEntityTest/testCreate.csv b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateVirtualProductEntityTest/testCreate.csv index de3705644ba17a842ade495d66b0c068da297133..204ed2c43a4a96f7b539b4b0f2bce8248a26626c 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateVirtualProductEntityTest/testCreate.csv +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateVirtualProductEntityTest/testCreate.csv @@ -3,6 +3,6 @@ "VirtualProduct %isolation%";"virtual_sku_%isolation%";"10";"None";"999";"Yes";"category_%isolation%";"-";"-";"MAGETWO-23002";"Yes";"In Stock";"-";"Catalog, Search";"assertProductSaveMessage, assertProductVisibleInCategory, assertProductForm, assertProductSearchableBySku" "VirtualProduct %isolation%";"-";"10";"Taxable Goods";"999";"Yes";"-";"-";"MAGETWO-23030";"-";"-";"Out of Stock";"-";"Search";"assertProductSaveMessage, assertProductForm, assertProductSkuAutoGenerated, assertProductSearchableBySku" "VirtualProduct %isolation%";"virtual_sku_%isolation%";"10";"-";"-";"Yes";"category_%isolation%";"MAGETWO-23055";"-";"-";"-";"-";"-";"Catalog";"assertProductSaveMessage, assertProductForm, assertProductVisibleInCategory" -"VirtualProduct %isolation%";"virtual_sku_%isolation%";"9000";"-";"-";"Yes";"-";"MAGETWO-23055";"-";"-";"-";"-";"options-suite";"-";"assertProductSaveMessage, assertProductSearchableBySku, assertProductPage, assertGroupedPriceOnProductPage, assertCustomOptionsOnProductPage" -"VirtualProduct %isolation%";"virtual_sku_%isolation%";"10";"-";"999";"Yes";"-";"-";"MAGETWO-23030";"-";"No";"In Stock";"-";"-";"assertProductSaveMessage, assertProductPage, assertSpecialPriceOnProductPage, assertProductInStock" -"VirtualProduct %isolation%";"virtual_sku_%isolation%";"9000";"-";"999";"Yes";"-";"-";"-";"default";"-";"Out of Stock";"-";"-";"assertProductSaveMessage, assertProductPage, assertTierPriceOnProductPage, assertProductOutOfStock" +"VirtualProduct %isolation%";"virtual_sku_%isolation%";"9000";"-";"-";"Yes";"-";"MAGETWO-23055";"-";"-";"-";"-";"options-suite";"-";"assertProductSaveMessage, assertProductSearchableBySku, assertProductPage, assertProductGroupedPriceOnProductPage, assertProductCustomOptionsOnProductPage" +"VirtualProduct %isolation%";"virtual_sku_%isolation%";"10";"-";"999";"Yes";"-";"-";"MAGETWO-23030";"-";"No";"In Stock";"-";"-";"assertProductSaveMessage, assertProductPage, assertProductSpecialPriceOnProductPage, assertProductInStock" +"VirtualProduct %isolation%";"virtual_sku_%isolation%";"9000";"-";"999";"Yes";"-";"-";"-";"default";"-";"Out of Stock";"-";"-";"assertProductSaveMessage, assertProductPage, assertProductTierPriceOnProductPage, assertProductOutOfStock" diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateSimpleProductEntityTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateSimpleProductEntityTest.php old mode 100644 new mode 100755 index 2b63d75ec3f356b175970f155dcb2d4d9169fcb3..2bf01a6dd0ec276adc58d0326695ba986199cd30 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateSimpleProductEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateSimpleProductEntityTest.php @@ -95,7 +95,7 @@ class UpdateSimpleProductEntityTest extends Injectable * @param CatalogProductEdit $editProductPage * @param CatalogCategory $category * @param FixtureFactory $fixtureFactory - * @return array + * @return void */ public function __inject( CatalogProductIndex $productGrid, @@ -131,7 +131,7 @@ class UpdateSimpleProductEntityTest extends Injectable $filter = ['sku' => $this->product->getSku()]; $this->productGrid->open()->getProductGrid()->searchAndOpen($filter); $productBlockForm = $this->editProductPage->getForm(); - $productBlockForm->fillProduct($product); + $productBlockForm->fill($product); $this->editProductPage->getFormAction()->save(); } } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateVirtualProductEntityTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateVirtualProductEntityTest.php new file mode 100644 index 0000000000000000000000000000000000000000..1d3781e35c6d6800bbe96bdad3bff939ef76acec --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateVirtualProductEntityTest.php @@ -0,0 +1,137 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\TestCase\Product; + +use Mtf\TestCase\Injectable; +use Mtf\Fixture\FixtureFactory; +use Magento\Catalog\Test\Fixture\CatalogCategory; +use Magento\Catalog\Test\Fixture\CatalogProductVirtual; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductEdit; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex; + +/** + * Test Creation for UpdateVirtualProductEntity + * + * Test Flow: + * + * Precondition: + * 1. Category is created. + * 2. Virtual product is created and assigned to created category. + * + * Steps: + * 1. Login to backend. + * 2. Navigate to PRODUCTS -> Catalog. + * 3. Select a product in the grid. + * 4. Edit test value(s) according to dataset. + * 5. Click "Save". + * 6. Perform asserts. + * + * @group Products_(CS) + * @ZephyrId MAGETWO-26204 + */ +class UpdateVirtualProductEntityTest extends Injectable +{ + /** + * Virtual product fixture + * + * @var CatalogProductVirtual + */ + protected $product; + + /** + * Product page with a grid + * + * @var CatalogProductIndex + */ + protected $productGrid; + + /** + * Page to update a product + * + * @var CatalogProductEdit + */ + protected $editProductPage; + + /** + * Prepare data + * + * @param CatalogCategory $category + * @return array + */ + public function __prepare(CatalogCategory $category) + { + $category->persist(); + return [ + 'category' => $category + ]; + } + + /** + * Injection data + * + * @param CatalogProductIndex $productGrid + * @param CatalogProductEdit $editProductPage + * @param CatalogCategory $category + * @param FixtureFactory $fixtureFactory + * @return void + */ + public function __inject( + CatalogProductIndex $productGrid, + CatalogProductEdit $editProductPage, + CatalogCategory $category, + FixtureFactory $fixtureFactory + ) { + $this->product = $fixtureFactory->createByCode( + 'catalogProductVirtual', + [ + 'dataSet' => 'default', + 'data' => [ + 'category_ids' => [ + 'category' => $category + ] + ] + ] + ); + $this->product->persist(); + + $this->productGrid = $productGrid; + $this->editProductPage = $editProductPage; + } + + /** + * Run update product virtual entity test + * + * @param CatalogProductVirtual $product + * @return void + */ + public function test(CatalogProductVirtual $product) + { + // Steps + $this->productGrid->open(); + $this->productGrid->getProductGrid()->searchAndOpen(['sku' => $this->product->getSku()]); + $this->editProductPage->getForm()->fill($product); + $this->editProductPage->getFormAction()->save(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateVirtualProductEntityTest/test.csv b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateVirtualProductEntityTest/test.csv new file mode 100644 index 0000000000000000000000000000000000000000..8c4e634beabb14bdab9c845d812aad6d944e8a24 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateVirtualProductEntityTest/test.csv @@ -0,0 +1,12 @@ +"product/data/name";"product/data/sku";"product/data/price/value";"product/data/tax_class_id/dataSet";"product/data/quantity_and_stock_status/qty";"product/data/is_virtual";"product/data/category_ids/presets";"product/data/group_price/preset";"product/data/special_price";"product/data/tier_price/preset";"product/data/quantity_and_stock_status/is_in_stock";"product/data/custom_options/preset";"product/data/visibility";"constraint" +"VirtualProduct %isolation%";"virtual_sku_%isolation%";"99.99";"None";"999";"Yes";"default_subcategory";"-";"-";"MAGETWO-23002";"In Stock";"-";"Catalog";"assertProductSaveMessage, assertProductInGrid, assertProductForm, assertProductPage, assertProductVisibleInCategory, assertProductInCategory, assertProductTierPriceOnProductPage, assertProductSearchableBySku " +"virtual_product_%isolation%";"virtual_sku_%isolation%";"120.00";"Taxable Goods";"999";"Yes";"-";"-";"45";"-";"In Stock";"-";"Catalog, Search";"assertProductSaveMessage, assertProductInGrid, assertProductForm, assertProductPage, assertProductVisibleInCategory, assertProductInCategory, assertProductPage, assertProductSpecialPriceOnProductPage, assertProductSearchableBySku" +"VirtualProduct %isolation%";"virtual_sku_%isolation%";"185.00";"None";"999";"Yes";"default_subcategory";"-";"-";"MAGETWO-23002";"Out of Stock";"-";"Catalog, Search";"assertProductSaveMessage, assertProductInGrid, assertProductForm, assertProductPage, assertProductVisibleInCategory, assertProductPage, assertProductOutOfStock, assertProductTierPriceOnProductPage, assertProductSearchableBySku" +"virtual_product_%isolation%";"virtual_sku_%isolation%";"99.99";"Taxable Goods";"-";"Yes";"-";"-";"-";"-";"Out of Stock";"-";"Search";"assertProductSaveMessage, assertProductInGrid, assertProductForm, assertProductPage, assertProductOutOfStock, assertProductSearchableBySku" +"VirtualProduct %isolation%";"virtual_sku_%isolation%";"5.00";"None";"-";"Yes";"-";"-";"-";"-";"Out of Stock";"-";"Catalog";"assertProductSaveMessage, assertProductInGrid, assertProductForm, assertProductPage, assertProductOutOfStock, assertProductSearchableBySku" +"virtual_product_%isolation%";"virtual_sku_%isolation%";"145.00";"Taxable Goods";"999";"Yes";"default_subcategory";"MAGETWO-23055";"-";"MAGETWO-23002";"In Stock";"-";"Catalog, Search";"assertProductSaveMessage, assertProductInGrid, assertProductForm, assertProductPage, assertProductVisibleInCategory, assertProductGroupedPriceOnProductPage, assertProductTierPriceOnProductPage, assertProductSearchableBySku" +"VirtualProduct %isolation%";"virtual_sku_%isolation%";"99.99";"None";"-";"Yes";"default_subcategory";"-";"45";"-";"Out of Stock";"-";"Catalog, Search";"assertProductSaveMessage, assertProductInGrid, assertProductForm, assertProductPage, assertProductOutOfStock, assertProductSearchableBySku" +"virtual_product_%isolation%";"virtual_sku_%isolation%";"5.00";"Taxable Goods";"-";"Yes";"-";"MAGETWO-23055";"-";"-";"Out of Stock";"-";"Search";"assertProductSaveMessage, assertProductInGrid, assertProductForm, assertProductPage, assertProductOutOfStock, assertProductSearchableBySku" +"VirtualProduct %isolation%";"virtual_sku_%isolation%";"120.00";"None";"999";"Yes";"default_subcategory";"-";"-";"-";"In Stock";"options-suite";"Search";"assertProductSaveMessage, assertProductInGrid, assertProductForm, assertProductPage, assertProductSpecialPriceOnProductPage, assertProductCustomOptionsOnProductPage, assertProductSearchableBySku" +"VirtualProduct %isolation%";"virtual_sku_%isolation%";"99.99";"Taxable Goods";"-";"Yes";"-";"MAGETWO-23055";"-";"-";"Out of Stock";"-";"Catalog, Search";"assertProductSaveMessage, assertProductInGrid, assertProductForm, assertProductPage, assertProductOutOfStock, assertProductSearchableBySku" +"VirtualProduct %isolation%";"virtual_sku_%isolation%";"99.99";"None";"999";"Yes";"default_subcategory";"MAGETWO-23055";"-";"MAGETWO-23002";"In Stock";"-";"Catalog";"assertProductSaveMessage, assertProductInGrid, assertProductForm, assertProductPage, assertProductVisibleInCategory, assertProductSpecialPriceOnProductPage, assertProductPage, assertProductGroupedPriceOnProductPage, assertProductTierPriceOnProductPage, assertProductInCategory, assertProductSearchableBySku" diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/CreateProductAttributeEntityTest/testCreateProductAttribute.csv b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/CreateProductAttributeEntityTest/testCreateProductAttribute.csv old mode 100644 new mode 100755 diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteAssignedToTemplateProductAttributeTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteAssignedToTemplateProductAttributeTest.php new file mode 100644 index 0000000000000000000000000000000000000000..7d47022330a61f4502840a637f827d5f29ab5738 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteAssignedToTemplateProductAttributeTest.php @@ -0,0 +1,105 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\TestCase\ProductAttribute; + +use Mtf\TestCase\Injectable; +use Magento\Catalog\Test\Fixture\CatalogAttributeSet; +use Magento\Catalog\Test\Fixture\CatalogProductAttribute; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductAttributeIndex; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductAttributeNew; + +/** + * Test Creation for Delete Attribute Set (Product Template) + * + * Preconditions: + * 1. Create Product template, based on Default + * 2. Create product attribute and add to created template + * + * Test Flow: + * 1. Log in to Backend. + * 2. Go to Stores > Attributes > Product + * 3. Search product attribute in grid by given data + * 4. Open this attribute by clicking + * 5. Click on the "Delete Attribute" button + * 6. Perform all assertions. + * + * @group Product_Attributes_(MX) + * @ZephyrId MAGETWO-26011 + */ +class DeleteAssignedToTemplateProductAttributeTest extends Injectable +{ + /** + * Catalog Product Attribute index page + * + * @var CatalogProductAttributeIndex + */ + protected $attributeIndex; + + /** + * Catalog Product Attribute new page + * + * @var CatalogProductAttributeNew + */ + protected $attributeNew; + + /** + * Inject pages + * + * @param CatalogProductAttributeIndex $attributeIndex + * @param CatalogProductAttributeNew $attributeNew + * @return void + */ + public function __inject(CatalogProductAttributeIndex $attributeIndex, CatalogProductAttributeNew $attributeNew) + { + $this->attributeIndex = $attributeIndex; + $this->attributeNew = $attributeNew; + } + + /** + * Run DeleteAssignedToTemplateProductAttribute test + * + * @param CatalogAttributeSet $productTemplate + * @return array + */ + public function test(CatalogAttributeSet $productTemplate) + { + // Precondition + $productTemplate->persist(); + + // Steps + $filter = [ + 'attribute_code' => $productTemplate + ->getDataFieldConfig('assigned_attributes')['source'] + ->getAttributes()[0] + ->getAttributeCode() + ]; + + $this->attributeIndex->open(); + $this->attributeIndex->getGrid()->searchAndOpen($filter); + $this->attributeNew->getPageActions()->delete(); + + return ['productTemplate' => $productTemplate]; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteAssignedToTemplateProductAttributeTest/test.csv b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteAssignedToTemplateProductAttributeTest/test.csv new file mode 100644 index 0000000000000000000000000000000000000000..8633f468c2410d59e05fbbbef1c2adf6b8c26289 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteAssignedToTemplateProductAttributeTest/test.csv @@ -0,0 +1,3 @@ +"productTemplate/dataSet";"productTemplate/data/assigned_attributes/presets";"constraint" +"custom_attribute_set";"attribute_type_dropdown";"assertProductAttributeSuccessDeleteMessage, assertProductAttributeAbsenceInGrid, assertProductAttributeAbsenceForAttributeMapping, assertProductAttributeAbsenceInTemplateGroups, assertProductAttributeAbsenceInUnassignedAttributes" +"default";"attribute_type_text_field";"assertProductAttributeSuccessDeleteMessage, assertProductAttributeAbsenceInGrid, assertProductAttributeAbsenceInVariationsSearch" diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteAttributeSetTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteAttributeSetTest.php new file mode 100644 index 0000000000000000000000000000000000000000..cf7ae657609bb3554648cf470c4ccabfe2600d30 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteAttributeSetTest.php @@ -0,0 +1,112 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\TestCase\ProductAttribute; + +use Mtf\Fixture\FixtureFactory; +use Mtf\TestCase\Injectable; +use Magento\Catalog\Test\Fixture\CatalogAttributeSet; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductSetEdit; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductSetIndex; + +/** + * Test Creation for Delete Attribute Set (Product Template) + * + * Preconditions: + * 1. An attribute is created. + * 2. An attribute template is created. + * 3. A simple product is created with this attribute and template + * + * Test Flow: + * 1. Log in to Backend. + * 2. Navigate to Stores > Attributes > Product Template. + * 3. Open created Product Template. + * 4. Click 'Delete Attribute Set' button. + * 5. Perform all assertions. + * + * @group Product_Attributes_(MX) + * @ZephyrId MAGETWO-25473 + */ +class DeleteAttributeSetTest extends Injectable +{ + /** + * Catalog Product Set index page + * + * @var CatalogProductSetIndex + */ + protected $productSetIndex; + + /** + * Catalog Product Set edit page + * + * @var CatalogProductSetEdit + */ + protected $productSetEdit; + + /** + * Inject data + * + * @param CatalogProductSetIndex $productSetIndex + * @param CatalogProductSetEdit $productSetEdit + * @return void + */ + public function __inject( + CatalogProductSetIndex $productSetIndex, + CatalogProductSetEdit $productSetEdit + ) { + $this->productSetIndex = $productSetIndex; + $this->productSetEdit = $productSetEdit; + } + + /** + * Run DeleteAttributeSet test + * + * @param FixtureFactory $fixtureFactory + * @param CatalogAttributeSet $productTemplate + * @return array + */ + public function test(FixtureFactory $fixtureFactory, CatalogAttributeSet $productTemplate) + { + // Precondition + $productTemplate->persist(); + $product = $fixtureFactory->createByCode( + 'catalogProductSimple', + [ + 'dataSet' => 'default', + 'data' => [ + 'attribute_set_id' => ['attribute_set' => $productTemplate], + ], + ] + ); + $product->persist(); + + // Steps + $filter = ['set_name' => $productTemplate->getAttributeSetName()]; + $this->productSetIndex->open(); + $this->productSetIndex->getGrid()->searchAndOpen($filter); + $this->productSetEdit->getPageActions()->delete(); + + return ['product' => $product]; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteAttributeSetTest/test.csv b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteAttributeSetTest/test.csv new file mode 100644 index 0000000000000000000000000000000000000000..362d06693eaeb77517b2197d03d233746fa5d2e6 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteAttributeSetTest/test.csv @@ -0,0 +1,2 @@ +"productTemplate/dataSet";"productTemplate/data/assigned_attributes/presets";"product/dataSet";"constraint" +"custom_attribute_set";"default";"default";"assertProductTemplateSuccessDeleteMessage, assertProductTemplateNotInGrid, assertProductNotInGrid" \ No newline at end of file diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/UpdateAttributeSetTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/UpdateAttributeSetTest.php new file mode 100644 index 0000000000000000000000000000000000000000..cd73dba5a491894f38974fec7a79aba61795107d --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/UpdateAttributeSetTest.php @@ -0,0 +1,111 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Test\TestCase\ProductAttribute; + +use Mtf\TestCase\Injectable; +use Magento\Catalog\Test\Fixture\CatalogAttributeSet; +use Magento\Catalog\Test\Fixture\CatalogProductAttribute; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductSetEdit; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductSetIndex; + +/** + * Test Creation for UpdateAttributeSetTest + * + * Preconditions: + * 1. An attribute is created + * 2. An attribute template is created + * + * Test Flow: + * 1. Log in to Backend. + * 2. Navigate to Stores > Attributes > Product Template. + * 3. Open created Product Template. + * 4. Click 'Add New' button to create new group + * 5. Add created Product Attribute to created group. + * 6. Fill out other fields data according to data set. + * 7. Save Product Template. + * 8. Preform all assertions. + * + * @group Product_Attributes_(CS) + * @ZephyrId MAGETWO-26251 + */ +class UpdateAttributeSetTest extends Injectable +{ + /** + * Catalog Product Set page + * + * @var CatalogProductSetIndex + */ + protected $productSetIndex; + + /** + * Catalog Product Set edit page + * + * @var CatalogProductSetEdit + */ + protected $productSetEdit; + + /** + * Inject data + * + * @param CatalogProductSetIndex $productSetIndex + * @param CatalogProductSetEdit $productSetEdit + * @return void + */ + public function __inject( + CatalogProductSetIndex $productSetIndex, + CatalogProductSetEdit $productSetEdit + ) { + $this->productSetIndex = $productSetIndex; + $this->productSetEdit = $productSetEdit; + } + + /** + * Run UpdateProductTemplate test + * + * @param CatalogAttributeSet $attributeSet + * @param CatalogAttributeSet $attributeSetOriginal + * @param CatalogProductAttribute $productAttributeOriginal + * @return void + */ + public function test( + CatalogAttributeSet $attributeSet, + CatalogAttributeSet $attributeSetOriginal, + CatalogProductAttribute $productAttributeOriginal + ) { + // Precondition + $attributeSetOriginal->persist(); + $productAttributeOriginal->persist(); + // Steps + $filter = ['set_name' => $attributeSetOriginal->getAttributeSetName()]; + $this->productSetIndex->open(); + $this->productSetIndex->getGrid()->searchAndOpen($filter); + $groupName = $attributeSet->getGroup(); + $this->productSetEdit->getAttributeSetEditBlock()->addAttributeSetGroup($groupName); + $this->productSetEdit->getAttributeSetEditBlock() + ->moveAttribute($productAttributeOriginal->getData(), $groupName); + $this->productSetEdit->getAttributeSetEditForm()->fill($attributeSet); + $this->productSetEdit->getPageActions()->save(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/UpdateAttributeSetTest/test.csv b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/UpdateAttributeSetTest/test.csv new file mode 100644 index 0000000000000000000000000000000000000000..c7edd39778f676936296aebf77b2f0e27069f087 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/UpdateAttributeSetTest/test.csv @@ -0,0 +1,2 @@ +"attributeSet/data/attribute_set_name";"attributeSet/data/group";"attributeSetOriginal/dataSet";"productAttributeOriginal/dataSet";"constraint" +"ProductTemplateEdit1%isolation%";"Custom-group%isolation%";"custom_attribute_set";"attribute_type_text_field";"assertProductTemplateSuccessSaveMessage, assertProductTemplateForm, assertProductTemplateInGrid, assertProductTemplateOnProductForm, assertProductTemplateGroupOnProductForm" diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/global/constraint.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/global/constraint.xml old mode 100644 new mode 100755 index e3c25a122c8d7b76398b5f690509065a17a70239..f4694337a906207d69b6a175435dd881e57c0f36 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/global/constraint.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/global/constraint.xml @@ -27,104 +27,113 @@ <assertProductInGrid module="Magento_Catalog"> <severeness>high</severeness> <require> - <productGrid class="Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex"/> - <product class="Mtf\Fixture\FixtureInterface"/> + <productGrid class="Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex" /> + <product class="Mtf\Fixture\FixtureInterface" /> </require> </assertProductInGrid> <assertProductSaveMessage module="Magento_Catalog"> <severeness>low</severeness> <require> - <productPage class="Magento\Catalog\Test\Page\Adminhtml\CatalogProductEdit"/> + <productPage class="Magento\Catalog\Test\Page\Adminhtml\CatalogProductEdit" /> </require> </assertProductSaveMessage> <assertProductOutOfStock module="Magento_Catalog"> <severeness>low</severeness> <require> - <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView"/> - <product class="Mtf\Fixture\FixtureInterface"/> + <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" /> + <product class="Mtf\Fixture\FixtureInterface" /> </require> </assertProductOutOfStock> <assertProductInStock module="Magento_Catalog"> <severeness>low</severeness> <require> - <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView"/> - <product class="Mtf\Fixture\FixtureInterface"/> + <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" /> + <product class="Mtf\Fixture\FixtureInterface" /> </require> </assertProductInStock> <assertProductVisibleInCategory module="Magento_Catalog"> <severeness>low</severeness> <require> - <catalogCategoryView class="Magento\Catalog\Test\Page\Category\CatalogCategoryView"/> - <cmsIndex class="Magento\Cms\Test\Page\CmsIndex"/> - <category class="Magento\Catalog\Test\Fixture\CatalogCategory"/> - <product class="Mtf\Fixture\FixtureInterface"/> + <catalogCategoryView class="Magento\Catalog\Test\Page\Category\CatalogCategoryView" /> + <cmsIndex class="Magento\Cms\Test\Page\CmsIndex" /> + <category class="Magento\Catalog\Test\Fixture\CatalogCategory" /> + <product class="Mtf\Fixture\FixtureInterface" /> </require> </assertProductVisibleInCategory> + <assertProductNotVisibleInCategory module="Magento_Catalog"> + <severeness>low</severeness> + <require> + <catalogCategoryView class="Magento\Catalog\Test\Page\Category\CatalogCategoryView" /> + <cmsIndex class="Magento\Cms\Test\Page\CmsIndex" /> + <category class="Magento\Catalog\Test\Fixture\CatalogCategory" /> + <product class="Mtf\Fixture\FixtureInterface" /> + </require> + </assertProductNotVisibleInCategory> <assertProductSearchableBySku module="Magento_Catalog"> <severeness>low</severeness> <require> - <catalogSearchResult class="Magento\CatalogSearch\Test\Page\CatalogsearchResult"/> - <cmsIndex class="Magento\Cms\Test\Page\CmsIndex"/> - <product class="Mtf\Fixture\FixtureInterface"/> + <catalogSearchResult class="Magento\CatalogSearch\Test\Page\CatalogsearchResult" /> + <cmsIndex class="Magento\Cms\Test\Page\CmsIndex" /> + <product class="Mtf\Fixture\FixtureInterface" /> </require> </assertProductSearchableBySku> <assertProductInCategory module="Magento_Catalog"> <severeness>low</severeness> <require> - <catalogCategoryView class="Magento\Catalog\Test\Page\Category\CatalogCategoryView"/> - <cmsIndex class="Magento\Cms\Test\Page\CmsIndex"/> - <product class="Mtf\Fixture\FixtureInterface"/> - <category class="Magento\Catalog\Test\Fixture\CatalogCategory"/> + <catalogCategoryView class="Magento\Catalog\Test\Page\Category\CatalogCategoryView" /> + <cmsIndex class="Magento\Cms\Test\Page\CmsIndex" /> + <product class="Mtf\Fixture\FixtureInterface" /> + <category class="Magento\Catalog\Test\Fixture\CatalogCategory" /> </require> </assertProductInCategory> <assertProductInCart module="Magento_Catalog"> <severeness>low</severeness> <require> - <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView"/> - <product class="Mtf\Fixture\FixtureInterface"/> - <checkoutCart class="Magento\Checkout\Test\Page\CheckoutCart"/> + <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" /> + <product class="Mtf\Fixture\FixtureInterface" /> + <checkoutCart class="Magento\Checkout\Test\Page\CheckoutCart" /> </require> </assertProductInCart> <assertProductPage module="Magento_Catalog"> <severeness>low</severeness> <require> - <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView"/> - <product class="Mtf\Fixture\FixtureInterface"/> + <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" /> + <product class="Mtf\Fixture\FixtureInterface" /> </require> </assertProductPage> - <assertGroupedPriceOnProductPage module="Magento_Catalog"> + <assertProductGroupedPriceOnProductPage module="Magento_Catalog"> <severeness>low</severeness> <require> - <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView"/> - <product class="Mtf\Fixture\FixtureInterface"/> + <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" /> + <product class="Mtf\Fixture\FixtureInterface" /> </require> - </assertGroupedPriceOnProductPage> - <assertSpecialPriceOnProductPage module="Magento_Catalog"> + </assertProductGroupedPriceOnProductPage> + <assertProductSpecialPriceOnProductPage module="Magento_Catalog"> <severeness>low</severeness> <require> - <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView"/> - <product class="Mtf\Fixture\FixtureInterface"/> + <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" /> + <product class="Mtf\Fixture\FixtureInterface" /> </require> - </assertSpecialPriceOnProductPage> - <assertTierPriceOnProductPage module="Magento_Catalog"> + </assertProductSpecialPriceOnProductPage> + <assertProductTierPriceOnProductPage module="Magento_Catalog"> <severeness>low</severeness> <require> - <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView"/> - <product class="Mtf\Fixture\FixtureInterface"/> + <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" /> + <product class="Mtf\Fixture\FixtureInterface" /> </require> - </assertTierPriceOnProductPage> - <assertCustomOptionsOnProductPage module="Magento_Catalog"> + </assertProductTierPriceOnProductPage> + <assertProductCustomOptionsOnProductPage module="Magento_Catalog"> <severeness>low</severeness> <require> - <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView"/> - <product class="Mtf\Fixture\FixtureInterface"/> + <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" /> + <product class="Mtf\Fixture\FixtureInterface" /> </require> - </assertCustomOptionsOnProductPage> + </assertProductCustomOptionsOnProductPage> <assertProductForm module="Magento_Catalog"> <severeness>low</severeness> <require> - <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView"/> - <product class="Mtf\Fixture\FixtureInterface"/> + <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" /> + <product class="Mtf\Fixture\FixtureInterface" /> </require> </assertProductForm> <assertAddToCartButtonAbsent module="Magento_Catalog"> @@ -136,32 +145,32 @@ <assertProductIsNotDisplayingOnFrontend module="Magento_Catalog"> <severeness>high</severeness> <require> - <catalogCategoryView class="Magento\Catalog\Test\Page\Category\CatalogCategoryView"/> - <cmsIndex class="Magento\Cms\Test\Page\CmsIndex"/> - <product class="Mtf\Fixture\FixtureInterface"/> - <category class="Magento\Catalog\Test\Fixture\CatalogCategory"/> - <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView"/> - <catalogSearchResult class="Magento\CatalogSearch\Test\Page\CatalogsearchResult"/> + <catalogCategoryView class="Magento\Catalog\Test\Page\Category\CatalogCategoryView" /> + <cmsIndex class="Magento\Cms\Test\Page\CmsIndex" /> + <product class="Mtf\Fixture\FixtureInterface" /> + <category class="Magento\Catalog\Test\Fixture\CatalogCategory" /> + <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" /> + <catalogSearchResult class="Magento\CatalogSearch\Test\Page\CatalogsearchResult" /> </require> </assertProductIsNotDisplayingOnFrontend> <assertProductSkuAutoGenerated module="Magento_Catalog"> <severeness>low</severeness> <require> - <productGrid class="Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex"/> - <product class="Mtf\Fixture\FixtureInterface"/> + <productGrid class="Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex" /> + <product class="Mtf\Fixture\FixtureInterface" /> </require> </assertProductSkuAutoGenerated> - <assertGroupedPriceOnProductPage module="Magento_Catalog"> + <assertProductGroupedPriceOnProductPage module="Magento_Catalog"> <severeness>low</severeness> <require> - <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView"/> - <product class="Mtf\Fixture\FixtureInterface"/> + <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" /> + <product class="Mtf\Fixture\FixtureInterface" /> </require> - </assertGroupedPriceOnProductPage> + </assertProductGroupedPriceOnProductPage> <assertProductAttributeSaveMessage module="Magento_Catalog"> <severeness>high</severeness> <require> - <attributeIndex class="Magento\Catalog\Test\Page\Adminhtml\CatalogProductAttributeIndex"/> + <attributeIndex class="Magento\Catalog\Test\Page\Adminhtml\CatalogProductAttributeIndex" /> </require> </assertProductAttributeSaveMessage> <assertProductAttributeInGrid module="Magento_Catalog"> @@ -225,12 +234,12 @@ <assertCrossSellsProductsSection module="Magento_Catalog"> <severeness>middle</severeness> <require> - <product1 class="Magento\Catalog\Test\Fixture\CatalogProductSimple"/> - <product2 class="Magento\Catalog\Test\Fixture\CatalogProductSimple"/> - <cmsIndex class="Magento\Cms\Test\Page\CmsIndex"/> - <catalogCategoryView class="Magento\Catalog\Test\Page\Category\CatalogCategoryView"/> - <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView"/> - <checkoutCart class="Magento\Checkout\Test\Page\CheckoutCart"/> + <product1 class="Magento\Catalog\Test\Fixture\CatalogProductSimple" /> + <product2 class="Magento\Catalog\Test\Fixture\CatalogProductSimple" /> + <cmsIndex class="Magento\Cms\Test\Page\CmsIndex" /> + <catalogCategoryView class="Magento\Catalog\Test\Page\Category\CatalogCategoryView" /> + <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" /> + <checkoutCart class="Magento\Checkout\Test\Page\CheckoutCart" /> </require> </assertCrossSellsProductsSection> <assertProductAttributeSuccessDeleteMessage module="Magento_Catalog"> @@ -242,11 +251,11 @@ <assertRelatedProductsSection module="Magento_Catalog"> <severeness>middle</severeness> <require> - <product1 class="Magento\Catalog\Test\Fixture\CatalogProductSimple"/> - <product2 class="Magento\Catalog\Test\Fixture\CatalogProductSimple"/> - <cmsIndex class="Magento\Cms\Test\Page\CmsIndex"/> - <catalogCategoryView class="Magento\Catalog\Test\Page\Category\CatalogCategoryView"/> - <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView"/> + <product1 class="Magento\Catalog\Test\Fixture\CatalogProductSimple" /> + <product2 class="Magento\Catalog\Test\Fixture\CatalogProductSimple" /> + <cmsIndex class="Magento\Cms\Test\Page\CmsIndex" /> + <catalogCategoryView class="Magento\Catalog\Test\Page\Category\CatalogCategoryView" /> + <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" /> </require> </assertRelatedProductsSection> <assertProductAttributeAbsenceInGrid module="Magento_Catalog"> @@ -258,11 +267,11 @@ <assertUpSellsProductsSection module="Magento_Catalog"> <severeness>middle</severeness> <require> - <product1 class="Magento\Catalog\Test\Fixture\CatalogProductSimple"/> - <product2 class="Magento\Catalog\Test\Fixture\CatalogProductSimple"/> - <cmsIndex class="Magento\Cms\Test\Page\CmsIndex"/> - <catalogCategoryView class="Magento\Catalog\Test\Page\Category\CatalogCategoryView"/> - <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView"/> + <product1 class="Magento\Catalog\Test\Fixture\CatalogProductSimple" /> + <product2 class="Magento\Catalog\Test\Fixture\CatalogProductSimple" /> + <cmsIndex class="Magento\Cms\Test\Page\CmsIndex" /> + <catalogCategoryView class="Magento\Catalog\Test\Page\Category\CatalogCategoryView" /> + <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" /> </require> </assertUpSellsProductsSection> <assertProductAttributeAbsenceInSearchOnProductForm module="Magento_Catalog"> @@ -312,33 +321,41 @@ </assertCategoryAbsenceOnBackend> <assertProductTemplateSuccessSaveMessage module="Magento_Catalog"> <severeness>high</severeness> - <productSetIndex class="Magento\Catalog\Test\Page\Adminhtml\CatalogProductSetIndex" /> + <require> + <productSetIndex class="Magento\Catalog\Test\Page\Adminhtml\CatalogProductSetIndex" /> + </require> </assertProductTemplateSuccessSaveMessage> <assertProductTemplateForm module="Magento_Catalog"> <severeness>high</severeness> - <productSet class="Magento\Catalog\Test\Page\Adminhtml\CatalogProductSetIndex" /> - <productSetEdit class="Magento\Catalog\Test\Page\Adminhtml\CatalogProductSetEdit" /> - <attributeSet class="Magento\Catalog\Test\Fixture\CatalogAttributeSet" /> - <productAttribute class="Magento\Catalog\Test\Fixture\CatalogProductAttribute" /> + <require> + <productSet class="Magento\Catalog\Test\Page\Adminhtml\CatalogProductSetIndex" /> + <productSetEdit class="Magento\Catalog\Test\Page\Adminhtml\CatalogProductSetEdit" /> + <attributeSet class="Magento\Catalog\Test\Fixture\CatalogAttributeSet" /> + <productAttribute class="Magento\Catalog\Test\Fixture\CatalogProductAttribute" /> + </require> </assertProductTemplateForm> <assertProductTemplateInGrid module="Magento_Catalog"> <severeness>high</severeness> - <productSet class="Magento\Catalog\Test\Page\Adminhtml\CatalogProductSetIndex" /> - <attributeSet class="Magento\Catalog\Test\Fixture\CatalogAttributeSet" /> + <require> + <productSet class="Magento\Catalog\Test\Page\Adminhtml\CatalogProductSetIndex" /> + <attributeSet class="Magento\Catalog\Test\Fixture\CatalogAttributeSet" /> + </require> </assertProductTemplateInGrid> <assertProductTemplateOnProductForm module="Magento_Catalog"> <severeness>high</severeness> - <fixtureFactory class="Mtf\Fixture\FixtureFactory" /> - <attributeSet class="Magento\Catalog\Test\Fixture\CatalogAttributeSet" /> - <productEdit class="Magento\Catalog\Test\Page\Adminhtml\CatalogProductEdit" /> - <productGrid class="Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex" /> - <newProductPage class="Magento\Catalog\Test\Page\Adminhtml\CatalogProductNew" /> - <productAttribute class="Magento\Catalog\Test\Fixture\CatalogProductAttribute" /> + <require> + <fixtureFactory class="Mtf\Fixture\FixtureFactory" /> + <attributeSet class="Magento\Catalog\Test\Fixture\CatalogAttributeSet" /> + <productEdit class="Magento\Catalog\Test\Page\Adminhtml\CatalogProductEdit" /> + <productGrid class="Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex" /> + <newProductPage class="Magento\Catalog\Test\Page\Adminhtml\CatalogProductNew" /> + <productAttribute class="Magento\Catalog\Test\Fixture\CatalogProductAttribute" /> + </require> </assertProductTemplateOnProductForm> <assertAbsenceDeleteAttributeButton module="Magento_Catalog"> <severeness>high</severeness> <require> - <attributeNew class="Magento\Catalog\Test\Page\Adminhtml\CatalogProductAttributeNew"/> + <attributeNew class="Magento\Catalog\Test\Page\Adminhtml\CatalogProductAttributeNew" /> </require> </assertAbsenceDeleteAttributeButton> <assertProductSuccessDeleteMessage module="Magento_Catalog"> @@ -347,4 +364,95 @@ <assertProductNotInGrid module="Magento_Catalog"> <severeness>low</severeness> </assertProductNotInGrid> + <assertProductTemplateSuccessDeleteMessage module="Magento_Catalog"> + <severeness>high</severeness> + </assertProductTemplateSuccessDeleteMessage> + <assertProductTemplateNotInGrid module="Magento_Catalog"> + <severeness>low</severeness> + </assertProductTemplateNotInGrid> + <assertProductNotInGrid module="Magento_Catalog"> + <severeness>low</severeness> + </assertProductNotInGrid> + <assertProductNotSearchableBySku module="Magento_Catalog"> + <severeness>low</severeness> + </assertProductNotSearchableBySku> + <assertProductCompareItemsLink module="Magento_Catalog"> + <severeness>low</severeness> + </assertProductCompareItemsLink> + <assertProductComparePage module="Magento_Catalog"> + <severeness>low</severeness> + </assertProductComparePage> + <assertProductCompareBlockOnCmsPage module="Magento_Catalog"> + <severeness>low</severeness> + </assertProductCompareBlockOnCmsPage> + <assertProductCompareSuccessAddMessage module="Magento_Catalog"> + <severeness>high</severeness> + </assertProductCompareSuccessAddMessage> + <assertProductCompareSuccessRemoveMessage module="Magento_Catalog"> + <severeness>high</severeness> + </assertProductCompareSuccessRemoveMessage> + <assertProductCompareSuccessRemoveAllProductsMessage module="Magento_Catalog"> + <severeness>high</severeness> + </assertProductCompareSuccessRemoveAllProductsMessage> + <assertProductCompareItemsLinkIsAbsent module="Magento_Catalog"> + <severeness>low</severeness> + </assertProductCompareItemsLinkIsAbsent> + <assertProductCompareRemoveLastProductMessage module="Magento_Catalog"> + <severeness>low</severeness> + </assertProductCompareRemoveLastProductMessage> + <assertProductIsNotVisibleInCompareBlock module="Magento_Catalog"> + <severeness>low</severeness> + </assertProductIsNotVisibleInCompareBlock> + <assertProductCompareSuccessRemoveMessage module="Magento_Catalog"> + <severeness>low</severeness> + </assertProductCompareSuccessRemoveMessage> + <assertProductIsNotVisibleInComparePage module="Magento_Catalog"> + <severeness>low</severeness> + </assertProductIsNotVisibleInComparePage> + <assertProductAttributeAbsenceInTemplateGroups module="Magento_Catalog"> + <severeness>low</severeness> + </assertProductAttributeAbsenceInTemplateGroups> + <assertProductAttributeAbsenceInUnassignedAttributes module="Magento_Catalog"> + <severeness>low</severeness> + </assertProductAttributeAbsenceInUnassignedAttributes> + <assertProductAttributeAbsenceInVariationsSearch module="Magento_Catalog"> + <severeness>low</severeness> + </assertProductAttributeAbsenceInVariationsSearch> + <assertProductDuplicateMessage module="Magento_Catalog"> + <severeness>high</severeness> + <require> + <productPage class="Magento\Catalog\Test\Page\Adminhtml\CatalogProductEdit" /> + </require> + </assertProductDuplicateMessage> + <assertProductDuplicatedInGrid module="Magento_Catalog"> + <severeness>low</severeness> + <require> + <product class="Mtf\Fixture\FixtureInterface" /> + <productGrid class="Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex" /> + </require> + </assertProductDuplicatedInGrid> + <assertProductDuplicateIsNotDisplayingOnFrontend module="Magento_Catalog"> + <severeness>high</severeness> + </assertProductDuplicateIsNotDisplayingOnFrontend> + <assertProductDuplicateForm module="Magento_Catalog"> + <severeness>high</severeness> + </assertProductDuplicateForm> + <assertProductForm module="Magento_Catalog"> + <severeness>high</severeness> + </assertProductForm> + <assertProductTemplateGroupOnProductForm module="Magento_Catalog"> + <severeness>high</severeness> + </assertProductTemplateGroupOnProductForm> + <assertProductCompareSuccessRemoveAllProductsMessage module="Magento_Catalog"> + <severeness>high</severeness> + </assertProductCompareSuccessRemoveAllProductsMessage> + <assertProductCompareItemsLinkIsAbsent module="Magento_Catalog"> + <severeness>low</severeness> + </assertProductCompareItemsLinkIsAbsent> + <assertProductCompareRemoveLastProductMessage module="Magento_Catalog"> + <severeness>low</severeness> + </assertProductCompareRemoveLastProductMessage> + <assertProductIsNotVisibleInCompareBlock module="Magento_Catalog"> + <severeness>low</severeness> + </assertProductIsNotVisibleInCompareBlock> </constraint> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/global/fixture.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/global/fixture.xml index e9a13691255236a1840bdf51410a1cf23b3e581b..5a98b6e360203f9043e20308a8d3158c8afd922c 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/global/fixture.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/global/fixture.xml @@ -216,5 +216,15 @@ <type>flat</type> <entity_type>eav_attribute_set</entity_type> <collection>Magento\Catalog\Model\Resource\Product\Link\Product\Collection</collection> + <fields> + <skeleton_set> + <attribute_code>skeleton_set</attribute_code> + <backend_type>virtual</backend_type> + </skeleton_set> + <assigned_attributes> + <attribute_code>assigned_attributes</attribute_code> + <backend_type>virtual</backend_type> + </assigned_attributes> + </fields> </catalogAttributeSet> </fixture> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/global/page.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/global/page.xml index 5fd15786ae5d72f18767ea11a426f6e065a1f0cc..41de6c334f1105ad9160b617827fcf08144cce83 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/global/page.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/global/page.xml @@ -84,4 +84,9 @@ <area>adminhtml</area> <class>Magento\Catalog\Test\Page\Adminhtml\CatalogProductSetAdd</class> </catalogProductSetAdd> + <catalogProductCompare> + <mca>catalog/product_compare/index</mca> + <area>product</area> + <class>Magento\Catalog\Test\Page\Product\CatalogProductCompare</class> + </catalogProductCompare> </page> diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Block/Adminhtml/Edit/SearchTermForm.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Block/Adminhtml/Edit/SearchTermForm.php new file mode 100644 index 0000000000000000000000000000000000000000..8a4d0067e358f3c12fc3fe1f40c231fddba45f57 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Block/Adminhtml/Edit/SearchTermForm.php @@ -0,0 +1,36 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\CatalogSearch\Test\Block\Adminhtml\Edit; + +use Magento\Backend\Test\Block\Widget\Form as WidgetForm; + +/** + * Class Form + * Form for search term + */ +class SearchTermForm extends WidgetForm +{ + // +} diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Block/Adminhtml/Edit/SearchTermForm.xml b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Block/Adminhtml/Edit/SearchTermForm.xml new file mode 100644 index 0000000000000000000000000000000000000000..69a93cd6406d90d8c22f4e408f19d3123ddaf5d7 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Block/Adminhtml/Edit/SearchTermForm.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" ?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<mapping strict="0"> + <fields> + <query_text /> + <store_id> + <input>selectstore</input> + </store_id> + <num_results /> + <popularity /> + <synonym_for /> + <redirect /> + <display_in_terms> + <input>select</input> + </display_in_terms> + </fields> +</mapping> diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Block/Adminhtml/Grid.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Block/Adminhtml/Grid.php new file mode 100644 index 0000000000000000000000000000000000000000..f81b4f5ac9734ddd6ad12ed2d3b091ee7dcdcef6 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Block/Adminhtml/Grid.php @@ -0,0 +1,65 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\CatalogSearch\Test\Block\Adminhtml; + +use Magento\Backend\Test\Block\Widget\Grid as WidgetGrid; + +/** + * Class Grid + * Backend search terms grid + */ +class Grid extends WidgetGrid +{ + /** + * Initialize block elements + * + * @var array + */ + protected $filters = [ + 'search_query' => [ + 'selector' => 'input[name="search_query"]' + ], + 'store_id' => [ + 'selector' => 'select[name="store_id"]', + 'input' => 'selectstore' + ], + 'results_from' => [ + 'selector' => 'input[name="num_results[from]"]' + ], + 'popularity_from' => [ + 'selector' => 'input[name="popularity[from]"]' + ], + 'synonym_for' => [ + 'selector' => 'input[name="synonym_for"]' + ], + 'redirect' => [ + 'selector' => 'input[name="redirect"]' + ], + 'display_in_terms' => [ + 'selector' => 'select[name="display_in_terms"]', + 'input' => 'select' + ] + ]; +} diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Constraint/AssertSearchTermForm.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Constraint/AssertSearchTermForm.php new file mode 100644 index 0000000000000000000000000000000000000000..6fdc76c4e09de8db6f6ca3a441fb3e32b89fdcab --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Constraint/AssertSearchTermForm.php @@ -0,0 +1,85 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\CatalogSearch\Test\Constraint; + +use Mtf\Constraint\AbstractConstraint; +use Magento\CatalogSearch\Test\Fixture\CatalogSearchQuery; +use Magento\CatalogSearch\Test\Page\Adminhtml\CatalogSearchEdit; +use Magento\CatalogSearch\Test\Page\Adminhtml\CatalogSearchIndex; + +/** + * Class AssertSearchTermForm + * Assert that after save a search term on edit term search page displays + */ +class AssertSearchTermForm extends AbstractConstraint +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'high'; + + /** + * Assert that after save a search term on edit term search page displays: + * - correct Search Query field passed from fixture + * - correct Store + * - correct Number of results + * - correct Number of Uses + * - correct Synonym For + * - correct Redirect URL + * - correct Display in Suggested Terms + * + * @param CatalogSearchIndex $indexPage + * @param CatalogSearchEdit $editPage + * @param CatalogSearchQuery $searchTerm + * @return void + */ + public function processAssert( + CatalogSearchIndex $indexPage, + CatalogSearchEdit $editPage, + CatalogSearchQuery $searchTerm + ) { + $indexPage->open()->getGrid()->searchAndOpen(['search_query' => $searchTerm->getQueryText()]); + $formData = $editPage->getForm()->getData($searchTerm); + $fixtureData = $searchTerm->getData(); + + \PHPUnit_Framework_Assert::assertEquals( + $formData, + $fixtureData, + 'This form "Search Term" does not match the fixture data.' + ); + } + + /** + * Returns a string representation of the object + * + * @return string + */ + public function toString() + { + return 'These form "Search Term" correspond to the fixture data.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Constraint/AssertSearchTermInGrid.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Constraint/AssertSearchTermInGrid.php new file mode 100644 index 0000000000000000000000000000000000000000..51950166cb8e3bb982a46c328ddf0134adf10875 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Constraint/AssertSearchTermInGrid.php @@ -0,0 +1,88 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\CatalogSearch\Test\Constraint; + +use Mtf\Constraint\AbstractConstraint; +use Magento\CatalogSearch\Test\Fixture\CatalogSearchQuery; +use Magento\CatalogSearch\Test\Page\Adminhtml\CatalogSearchIndex; + +/** + * Class AssertSearchTermInGrid + * Assert that after save a term search on edit term search page displays + */ +class AssertSearchTermInGrid extends AbstractConstraint +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'high'; + + /** + * Assert that after save a term search on edit term search page displays: + * - correct Search Query field passed from fixture + * - correct Store + * - correct Results + * - correct Uses + * - correct Synonym + * - correct Redirect URL + * - correct Suggested Terms + * + * @param CatalogSearchIndex $indexPage + * @param CatalogSearchQuery $searchTerm + * @return void + */ + public function processAssert(CatalogSearchIndex $indexPage, CatalogSearchQuery $searchTerm) + { + $grid = $indexPage->open()->getGrid(); + $filters = [ + 'search_query' => $searchTerm->getQueryText(), + 'store_id' => $searchTerm->getStoreId(), + 'results_from' => $searchTerm->getNumResults(), + 'popularity_from' => $searchTerm->getPopularity(), + 'synonym_for' => $searchTerm->getSynonymFor(), + 'redirect' => $searchTerm->getRedirect(), + 'display_in_terms' => strtolower($searchTerm->getDisplayInTerms()) + ]; + + $grid->search($filters); + unset($filters['store_id']); + \PHPUnit_Framework_Assert::assertTrue( + $grid->isRowVisible($filters), + 'Row terms according to the filters is not found.' + ); + } + + /** + * Returns a string representation of the object + * + * @return string + */ + public function toString() + { + return 'Row term according to the filters is not found.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Constraint/AssertSearchTermOnFrontend.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Constraint/AssertSearchTermOnFrontend.php new file mode 100644 index 0000000000000000000000000000000000000000..2cf3f0dc73368f6aec5e8f7eaa06c350d99b2d1c --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Constraint/AssertSearchTermOnFrontend.php @@ -0,0 +1,118 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\CatalogSearch\Test\Constraint; + +use Mtf\Client\Browser; +use Magento\Cms\Test\Page\CmsIndex; +use Mtf\Constraint\AbstractConstraint; +use Magento\Catalog\Test\Block\Search; +use Magento\CatalogSearch\Test\Fixture\CatalogSearchQuery; + +/** + * Class AssertSearchTermOnFrontend + * Assert that after save a search term + */ +class AssertSearchTermOnFrontend extends AbstractConstraint +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'high'; + + /** + * Search block on CMS index page + * + * @var Search + */ + protected $searchBlock; + + /** + * Assert that after save a search term: + * - it displays in the Search field at the top of the page if type set of characters passed from fixture + * - after click 'Go' of Search field opens a results page if it was not specified Redirect URL + * - after click 'Go' of Search field a customer search redirects to a specific page (passed from fixture) + * if it was specified Redirect URL + * + * @param CmsIndex $cmsIndex + * @param CatalogSearchQuery $searchTerm + * @param Browser $browser + * @return void + */ + public function processAssert(CmsIndex $cmsIndex, CatalogSearchQuery $searchTerm, Browser $browser) + { + $errors = []; + $this->searchBlock = $cmsIndex->open()->getSearchBlock(); + + if ($searchTerm->hasData('display_in_terms') && $searchTerm->getDisplayInTerms() === 'Yes') { + $errors = $this->checkSuggestSearch($searchTerm); + } + + $this->searchBlock->search($searchTerm->getQueryText()); + $windowUrl = $browser->getUrl(); + $redirectUrl = $searchTerm->getRedirect(); + if ($windowUrl !== $redirectUrl) { + $errors[] = '- url window (' . $windowUrl . ') does not match the url redirect(' . $redirectUrl . ')'; + } + + \PHPUnit_Framework_Assert::assertEmpty( + $errors, + 'When checking on the frontend "Search terms" arose following errors:' . PHP_EOL . implode(PHP_EOL, $errors) + ); + } + + /** + * Check suggest block visibility + * + * @param CatalogSearchQuery $searchTerm + * @return array + */ + protected function checkSuggestSearch(CatalogSearchQuery $searchTerm) + { + $queryText = $searchTerm->getQueryText(); + $this->searchBlock->fillSearch($queryText); + if ($searchTerm->hasData('num_results')) { + $isVisible = $this->searchBlock->isSuggestSearchVisible( + $queryText, + $searchTerm->getNumResults() + ); + } else { + $isVisible = $this->searchBlock->isSuggestSearchVisible($queryText); + } + + return $isVisible ? [] : ['- block "Suggest Search" when searching was not found']; + } + + /** + * Returns a string representation of the object + * + * @return string + */ + public function toString() + { + return 'Checking "Search terms" on frontend successful.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Constraint/AssertSearchTermSuccessSaveMessage.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Constraint/AssertSearchTermSuccessSaveMessage.php new file mode 100644 index 0000000000000000000000000000000000000000..4e68188532eaaba4a47a8d2f1ce54ca08dab7d76 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Constraint/AssertSearchTermSuccessSaveMessage.php @@ -0,0 +1,75 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\CatalogSearch\Test\Constraint; + +use Mtf\Constraint\AbstractConstraint; +use Magento\CatalogSearch\Test\Page\Adminhtml\CatalogSearchIndex; + +/** + * Class AssertSearchTermSuccessSaveMessage + * Assert that success message is displayed after search term save + */ +class AssertSearchTermSuccessSaveMessage extends AbstractConstraint +{ + /** + * Text value to be checked + */ + const SUCCESS_MESSAGE = 'You saved the search term.'; + + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'high'; + + /** + * Assert that success message is displayed after search term save + * + * @param CatalogSearchIndex $indexPage + * @return void + */ + public function processAssert(CatalogSearchIndex $indexPage) + { + $actualMessage = $indexPage->getMessagesBlock()->getSuccessMessages(); + \PHPUnit_Framework_Assert::assertEquals( + self::SUCCESS_MESSAGE, + $actualMessage, + 'Wrong success message is displayed.' + . PHP_EOL . "Expected: " . self::SUCCESS_MESSAGE + . PHP_EOL . "Actual: " . $actualMessage + ); + } + + /** + * Returns a string representation of the object + * + * @return string + */ + public function toString() + { + return 'Search term success save message is present.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Constraint/AssertSearchTermSynonymOnFrontend.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Constraint/AssertSearchTermSynonymOnFrontend.php new file mode 100644 index 0000000000000000000000000000000000000000..9734bb43e33e80962b0a214e58741a12abc16572 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Constraint/AssertSearchTermSynonymOnFrontend.php @@ -0,0 +1,76 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\CatalogSearch\Test\Constraint; + +use Mtf\Client\Browser; +use Magento\Cms\Test\Page\CmsIndex; +use Mtf\Constraint\AbstractConstraint; +use Magento\CatalogSearch\Test\Fixture\CatalogSearchQuery; + +/** + * Class AssertSearchTermSynonymOnFrontend + * Assert that you will be redirected to url from dataset + */ +class AssertSearchTermSynonymOnFrontend extends AbstractConstraint +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'high'; + + /** + * Assert that you will be redirected to url from dataset + * + * @param CmsIndex $cmsIndex + * @param Browser $browser + * @param CatalogSearchQuery $searchTerm + * @return void + */ + public function processAssert(CmsIndex $cmsIndex, Browser $browser, CatalogSearchQuery $searchTerm) + { + $cmsIndex->open()->getSearchBlock()->search($searchTerm->getSynonymFor()); + $windowUrl = $browser->getUrl(); + $redirectUrl = $searchTerm->getRedirect(); + \PHPUnit_Framework_Assert::assertEquals( + $windowUrl, + $redirectUrl, + 'Redirect by synonym was not executed.' + . PHP_EOL . "Expected: " . $redirectUrl + . PHP_EOL . "Actual: " . $windowUrl + ); + } + + /** + * Returns a string representation of the object + * + * @return string + */ + public function toString() + { + return 'Redirect by synonym executed successfully.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Page/Adminhtml/CatalogSearchEdit.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Page/Adminhtml/CatalogSearchEdit.php new file mode 100644 index 0000000000000000000000000000000000000000..a0fb893070741b6d86ce549b2ab4c44ab2245275 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Page/Adminhtml/CatalogSearchEdit.php @@ -0,0 +1,66 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\CatalogSearch\Test\Page\Adminhtml; + +use Mtf\Page\BackendPage; + +/** + * Class CatalogSearchEdit + */ +class CatalogSearchEdit extends BackendPage +{ + const MCA = 'catalog/search/edit'; + + protected $_blocks = [ + 'form' => [ + 'name' => 'form', + 'class' => 'Magento\CatalogSearch\Test\Block\Adminhtml\Edit\SearchTermForm', + 'locator' => '#edit_form', + 'strategy' => 'css selector', + ], + 'formPageActions' => [ + 'name' => 'formPageActions', + 'class' => 'Magento\Backend\Test\Block\FormPageActions', + 'locator' => '.page-main-actions', + 'strategy' => 'css selector', + ], + ]; + + /** + * @return \Magento\CatalogSearch\Test\Block\Adminhtml\Edit\SearchTermForm + */ + public function getForm() + { + return $this->getBlockInstance('form'); + } + + /** + * @return \Magento\Backend\Test\Block\FormPageActions + */ + public function getFormPageActions() + { + return $this->getBlockInstance('formPageActions'); + } +} diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Page/Adminhtml/CatalogSearchEdit.xml b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Page/Adminhtml/CatalogSearchEdit.xml new file mode 100644 index 0000000000000000000000000000000000000000..6cd1827cc54cb57e0853bb7be077ffa9e0a297e9 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Page/Adminhtml/CatalogSearchEdit.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" ?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<page mca="catalog/search/edit" > + <block> + <name>form</name> + <class>Magento\CatalogSearch\Test\Block\Adminhtml\Edit\SearchTermForm</class> + <locator>#edit_form</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>formPageActions</name> + <class>Magento\Backend\Test\Block\FormPageActions</class> + <locator>.page-main-actions</locator> + <strategy>css selector</strategy> + </block> +</page> diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Page/Adminhtml/CatalogSearchIndex.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Page/Adminhtml/CatalogSearchIndex.php new file mode 100644 index 0000000000000000000000000000000000000000..65382917327be175741e637deb0c818b35447a84 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Page/Adminhtml/CatalogSearchIndex.php @@ -0,0 +1,80 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\CatalogSearch\Test\Page\Adminhtml; + +use Mtf\Page\BackendPage; + +/** + * Class CatalogSearchIndex + */ +class CatalogSearchIndex extends BackendPage +{ + const MCA = 'catalog/search/index'; + + protected $_blocks = [ + 'grid' => [ + 'name' => 'grid', + 'class' => 'Magento\CatalogSearch\Test\Block\Adminhtml\Grid', + 'locator' => '#catalog_search_grid', + 'strategy' => 'css selector', + ], + 'gridPageActions' => [ + 'name' => 'gridPageActions', + 'class' => 'Magento\Backend\Test\Block\GridPageActions', + 'locator' => '.page-main-actions', + 'strategy' => 'css selector', + ], + 'messagesBlock' => [ + 'name' => 'messagesBlock', + 'class' => 'Magento\Core\Test\Block\Messages', + 'locator' => '.page-main-actions', + 'strategy' => 'css selector', + ], + ]; + + /** + * @return \Magento\CatalogSearch\Test\Block\Adminhtml\Grid + */ + public function getGrid() + { + return $this->getBlockInstance('grid'); + } + + /** + * @return \Magento\Backend\Test\Block\GridPageActions + */ + public function getGridPageActions() + { + return $this->getBlockInstance('gridPageActions'); + } + + /** + * @return \Magento\Core\Test\Block\Messages + */ + public function getMessagesBlock() + { + return $this->getBlockInstance('messagesBlock'); + } +} diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Page/Adminhtml/CatalogSearchIndex.xml b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Page/Adminhtml/CatalogSearchIndex.xml new file mode 100644 index 0000000000000000000000000000000000000000..a1edd489ab49dc4f94eec0cdf921014d85c96a9e --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Page/Adminhtml/CatalogSearchIndex.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" ?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<page mca="catalog/search/index" > + <block> + <name>grid</name> + <class>Magento\CatalogSearch\Test\Block\Adminhtml\Grid</class> + <locator>#catalog_search_grid</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>gridPageActions</name> + <class>Magento\Backend\Test\Block\GridPageActions</class> + <locator>.page-main-actions</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>messagesBlock</name> + <class>Magento\Core\Test\Block\Messages</class> + <locator>.page-main-actions</locator> + <strategy>css selector</strategy> + </block> +</page> diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Page/CatalogsearchResult.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Page/CatalogsearchResult.php index d6f4bcd3b7f273ea7691932fd6a0158db5b860e9..5bbd6b735ec1265323e508415b8c259f076b6ca5 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Page/CatalogsearchResult.php +++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Page/CatalogsearchResult.php @@ -40,6 +40,12 @@ class CatalogsearchResult extends FrontendPage 'locator' => '.search.results', 'strategy' => 'css selector', ], + 'toolbar' => [ + 'name' => 'toolbar', + 'class' => 'Magento\Catalog\Test\Block\Product\ProductList\Toolbar', + 'locator' => '.toolbar.products', + 'strategy' => 'css selector', + ], ]; /** @@ -49,4 +55,12 @@ class CatalogsearchResult extends FrontendPage { return $this->getBlockInstance('listProductBlock'); } + + /** + * @return \Magento\Catalog\Test\Block\Product\ProductList\Toolbar + */ + public function getToolbar() + { + return $this->getBlockInstance('toolbar'); + } } diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Page/CatalogsearchResult.xml b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Page/CatalogsearchResult.xml index 3ed22b1488a608cd722183e01014f94b154f24ff..dbaf99afe1bad4d10253df277c4d84c88bd99422 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Page/CatalogsearchResult.xml +++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Page/CatalogsearchResult.xml @@ -30,4 +30,10 @@ <locator>.search.results</locator> <strategy>css selector</strategy> </block> + <block> + <name>toolbar</name> + <class>Magento\Catalog\Test\Block\Product\ProductList\Toolbar</class> + <locator>.toolbar.products</locator> + <strategy>css selector</strategy> + </block> </page> diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/CreateSearchTermEntityTest.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/CreateSearchTermEntityTest.php new file mode 100644 index 0000000000000000000000000000000000000000..bf3c3b0703beab9a11ad727ecd363dce0a8d5d80 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/CreateSearchTermEntityTest.php @@ -0,0 +1,95 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\CatalogSearch\Test\TestCase; + +use Mtf\TestCase\Injectable; +use Magento\CatalogSearch\Test\Fixture\CatalogSearchQuery; +use Magento\CatalogSearch\Test\Page\Adminhtml\CatalogSearchEdit; +use Magento\CatalogSearch\Test\Page\Adminhtml\CatalogSearchIndex; + +/** + * Test Creation for CreateSearchTermEntity + * + * Test Flow: + * + * Preconditions: + * 1. Product is created + * + * Steps: + * 1. Go to backend as admin user + * 4. Navigate to Marketing->SEO&Search->Search Terms + * 5. Click "Add New Search Term" button + * 6. Fill out all data according to dataset + * 7. Save the Search Term + * 8. Perform all assertions + * + * @group Search Terms (MX) + * @ZephyrId MAGETWO-26165 + */ +class CreateSearchTermEntityTest extends Injectable +{ + /** + * Search term page + * + * @var CatalogSearchIndex + */ + protected $indexPage; + + /** + * Search term edit page + * + * @var CatalogSearchEdit + */ + protected $editPage; + + /** + * Inject pages + * + * @param CatalogSearchIndex $indexPage + * @param CatalogSearchEdit $editPage + * @return void + */ + public function __inject(CatalogSearchIndex $indexPage, CatalogSearchEdit $editPage) + { + $this->indexPage = $indexPage; + $this->editPage = $editPage; + } + + /** + * Run create search term test + * + * @param CatalogSearchQuery $searchTerm + * @return void + */ + public function test(CatalogSearchQuery $searchTerm) + { + $this->markTestIncomplete('MAGETWO-26170'); + // Steps + $this->indexPage->open(); + $this->indexPage->getGridPageActions()->addNew(); + $this->editPage->getForm()->fill($searchTerm); + $this->editPage->getFormPageActions()->save(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/CreateSearchTermEntityTest/test.csv b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/CreateSearchTermEntityTest/test.csv new file mode 100644 index 0000000000000000000000000000000000000000..124f69344b39ade304e3ca3e188eb713caba2d52 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/CreateSearchTermEntityTest/test.csv @@ -0,0 +1,2 @@ +"searchTerm/data/query_text/value";"searchTerm/data/store_id";"searchTerm/data/synonym_for";"searchTerm/data/redirect";"searchTerm/data/display_in_terms";"constraint" +"catalogProductSimple::getSku";"Main Website/Main Website Store/Default Store View";"Search Term Synonym %isolation%";"http://example.com/";"No";"assertSearchTermSuccessSaveMessage, assertSearchTermInGrid, assertSearchTermForm, assertSearchTermOnFrontend, assertSearchTermSynonymOnFrontend" diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/EditSearchTermEntityTest.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/EditSearchTermEntityTest.php new file mode 100644 index 0000000000000000000000000000000000000000..e7beddab532a7574f8d873943c42157e235cfce7 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/EditSearchTermEntityTest.php @@ -0,0 +1,111 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\CatalogSearch\Test\TestCase; + +use Mtf\TestCase\Injectable; +use Magento\Cms\Test\Page\CmsIndex; +use Magento\CatalogSearch\Test\Fixture\CatalogSearchQuery; +use Magento\CatalogSearch\Test\Page\Adminhtml\CatalogSearchEdit; +use Magento\CatalogSearch\Test\Page\Adminhtml\CatalogSearchIndex; + +/** + * Test Creation for EditSearchTermEntity + * + * Test Flow: + * + * Preconditions: + * 1. Product is created + * + * Steps: + * 1. Go to frontend + * 2. Test word into the Search field at the top of the page and click Go + * 3. Go to backend as admin user + * 4. Navigate to Marketing->SEO&Search->Search Terms + * 5. Click "Edit" link of just added test word search term + * 6. Fill out all data according to dataset + * 7. Save the Search Term + * 8. Perform all assertions + * + * @group Search Terms (MX) + * @ZephyrId MAGETWO-26100 + */ +class EditSearchTermEntityTest extends Injectable +{ + /** + * CMS index page + * + * @var CmsIndex + */ + protected $cmsIndex; + + /** + * Search term page + * + * @var CatalogSearchIndex + */ + protected $indexPage; + + /** + * Search term edit page + * + * @var CatalogSearchEdit + */ + protected $editPage; + + /** + * Inject pages + * + * @param CmsIndex $cmsIndex + * @param CatalogSearchIndex $indexPage + * @param CatalogSearchEdit $editPage + * @return void + */ + public function __inject( + CmsIndex $cmsIndex, + CatalogSearchIndex $indexPage, + CatalogSearchEdit $editPage + ) { + $this->cmsIndex = $cmsIndex; + $this->indexPage = $indexPage; + $this->editPage = $editPage; + } + + /** + * Run edit search term test + * + * @param CatalogSearchQuery $searchTerm + * @return void + */ + public function test(CatalogSearchQuery $searchTerm) + { + // Preconditions + $searchText = $searchTerm->getQueryText(); + // Steps + $this->cmsIndex->open()->getSearchBlock()->search($searchText); + $this->indexPage->open()->getGrid()->searchAndOpen(['search_query' => $searchText]); + $this->editPage->getForm()->fill($searchTerm); + $this->editPage->getFormPageActions()->save(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/EditSearchTermEntityTest/test.csv b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/EditSearchTermEntityTest/test.csv new file mode 100644 index 0000000000000000000000000000000000000000..c6941e465c76df0ca1bbebdf41f6eb5910c7fddc --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/EditSearchTermEntityTest/test.csv @@ -0,0 +1,2 @@ +"searchTerm/data/query_text/value";"searchTerm/data/store_id";"searchTerm/data/num_results";"searchTerm/data/popularity";"searchTerm/data/synonym_for";"searchTerm/data/redirect";"searchTerm/data/display_in_terms";"constraint" +"catalogProductSimple::getSku";"Main Website/Main Website Store/Default Store View";1;20;"simple";"http://example.com/";"No";"assertSearchTermForm, assertSearchTermInGrid, assertSearchTermOnFrontend" diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/etc/global/constraint.xml b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/etc/global/constraint.xml index 7f383cc9f8b9b3af2a8cec41e68b9dad537ebeb9..dbe33dd650d840b1b547d5e3cddb6cecf31910c0 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/etc/global/constraint.xml +++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/etc/global/constraint.xml @@ -43,6 +43,45 @@ <require> <cmsIndex class="Magento\Cms\Test\Page\CmsIndex" /> <catalogSearch class="Magento\CatalogSearch\Test\Fixture\CatalogSearchQuery" /> + <editPage class="Magento\CatalogSearch\Test\Page\Adminhtml\CatalogSearchEdit" /> </require> </assertCatalogSearchResult> + <assertSearchTermForm module="Magento_CatalogSearch"> + <severeness>high</severeness> + <require> + <cmsIndex class="Magento\Cms\Test\Page\CmsIndex" /> + <searchTerm class="Magento\CatalogSearch\Test\Fixture\CatalogSearchQuery" /> + <editPage class="Magento\CatalogSearch\Test\Page\Adminhtml\CatalogSearchEdit" /> + </require> + </assertSearchTermForm> + <assertSearchTermInGrid module="Magento_CatalogSearch"> + <severeness>high</severeness> + <require> + <indexPage class="Magento\CatalogSearch\Test\Page\Adminhtml\CatalogSearchIndex" /> + <editPage class="Magento\CatalogSearch\Test\Page\Adminhtml\CatalogSearchEdit" /> + <searchTerm class="Magento\CatalogSearch\Test\Fixture\CatalogSearchQuery" /> + </require> + </assertSearchTermInGrid> + <assertSearchTermOnFrontend module="Magento_CatalogSearch"> + <severeness>high</severeness> + <require> + <searchTerm class="Magento\CatalogSearch\Test\Fixture\CatalogSearchQuery" /> + <cmsIndex class="Magento\Cms\Test\Page\CmsIndex" /> + <browser class="Mtf\Client\Browser" /> + </require> + </assertSearchTermOnFrontend> + <assertSearchTermSuccessSaveMessage module="Magento_CatalogSearch"> + <severeness>high</severeness> + <require> + <indexPage class="Magento\CatalogSearch\Test\Page\Adminhtml\CatalogSearchIndex" /> + </require> + </assertSearchTermSuccessSaveMessage> + <assertSearchTermSynonymOnFrontend module="Magento_CatalogSearch"> + <severeness>high</severeness> + <require> + <searchTerm class="Magento\CatalogSearch\Test\Fixture\CatalogSearchQuery" /> + <cmsIndex class="Magento\Cms\Test\Page\CmsIndex" /> + <browser class="Mtf\Client\Browser" /> + </require> + </assertSearchTermSynonymOnFrontend> </constraint> diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/etc/global/page.xml b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/etc/global/page.xml index 5c581d37d87fefd8f3cb0b2a72e18308966d2b90..ba505ac72d4a2a33d9d364ddd13a8b12b47d3d78 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/etc/global/page.xml +++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/etc/global/page.xml @@ -28,13 +28,14 @@ <mca>catalogsearch/result</mca> <class>Magento\CatalogSearch\Test\Page\CatalogsearchResult</class> </catalogsearchResult> - <advanced> - <mca>catalogsearch/advanced</mca> - <class>Magento\CatalogSearch\Test\Page\Advanced</class> - </advanced> - <result> - <mca>catalogsearch/advanced/result</mca> - <area>advanced</area> - <class>Magento\CatalogSearch\Test\Page\Advanced\Result</class> - </result> + <catalogSearchIndex> + <area>adminhtml</area> + <mca>catalog/search/index</mca> + <class>Magento\CatalogSearch\Test\Page\Adminhtml\CatalogSearchIndex</class> + </catalogSearchIndex> + <catalogSearchEdit> + <area>adminhtml</area> + <mca>catalog/search/edit</mca> + <class>Magento\CatalogSearch\Test\Page\Adminhtml\CatalogSearchEdit</class> + </catalogSearchEdit> </page> diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart.php index 6518de4138b921f9c5b5c93207ef1f193307c7dd..fc3b9146b1c8d16c1a5b329cceacf0f61fb1b249 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart.php @@ -58,21 +58,21 @@ class Cart extends Block * * @var string */ - protected $itemSubTotalSelector = '//td[@class="col subtotal excl tax"]//span[@class="price"]'; + protected $itemSubTotalSelector = '//td[@class="col subtotal"]//*[@class="excl tax"]//span[@class="price"]'; /** * Cart item unit price xpath selector * * @var string */ - protected $itemUnitPriceSelector = '//td[@class="col price excl tax"]//span[@class="price"]'; + protected $itemUnitPriceSelector = '//td[@class="col price"]//*[@class="excl tax"]//span[@class="price"]'; /** * Unit Price value * * @var string */ - protected $cartProductPrice = '//tr[string(td/div/strong/a)="%s"]/td[@class="col price excl tax"]/span/span'; + protected $cartProductPrice = '//tr[string(td/div/strong/a)="%s"]/td[@class="col price"]/*[@class="excl tax"]/span'; /** * 'Update Shopping Cart' button @@ -86,14 +86,21 @@ class Cart extends Block * * @var string */ - protected $productQty = '//input[@type="number" and @title="Qty"]'; + protected $productQty = './/input[@type="number" and @title="Qty"]'; /** * Cart item selector * * @var string */ - protected $cartItem = '//tr[normalize-space(td)="%s"]'; + protected $cartItem = './/tr[td//*[contains(.,"%s")]]'; + + /** + * Get bundle options + * + * @var string + */ + protected $bundleOptions = './/dl[contains(@class, "cart-item-options")]/dd[%d]/span[@class="price"][%d]'; /** * Get sub-total for the specified item in the cart @@ -268,7 +275,7 @@ class Cart extends Block if ($product instanceof ConfigurableProduct) { $productOptions = $product->getProductOptions(); if (!empty($productOptions)) { - $productName = $productName . ' ' . key($productOptions) . ' ' . current($productOptions); + $productName = $productName . '")] and *[contains(.,"' . current($productOptions); } } return $productName; @@ -333,4 +340,18 @@ class Cart extends Block preg_match("/^\\D*\\s*([\\d,\\.]+)\\s*\\D*$/", $price, $matches); return (isset($matches[1])) ? $matches[1] : null; } + + /** + * Get item Bundle options + * + * @param int $index + * @param int $itemIndex + * @param string $currency + * @return string + */ + public function getPriceBundleOptions($index, $itemIndex = 1, $currency = '$') + { + $formatPrice = sprintf($this->bundleOptions, $index, $itemIndex); + return trim($this->_rootElement->find($formatPrice, Locator::SELECTOR_XPATH)->getText(), $currency); + } } diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/Handler/CmsBlock/CmsBlockInterface.php b/dev/tests/functional/tests/app/Magento/Cms/Test/Handler/CmsBlock/CmsBlockInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..e4ae992c791b484a375648851cf577c713ad1ecc --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Cms/Test/Handler/CmsBlock/CmsBlockInterface.php @@ -0,0 +1,35 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Cms\Test\Handler\CmsBlock; + +use Mtf\Handler\HandlerInterface; + +/** + * Interface CmsBlockInterface + */ +interface CmsBlockInterface extends HandlerInterface +{ + // +} diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/Handler/CmsBlock/Curl.php b/dev/tests/functional/tests/app/Magento/Cms/Test/Handler/CmsBlock/Curl.php new file mode 100644 index 0000000000000000000000000000000000000000..54bb378e9ac1f2681d1058edadea9c1b13a91e5c --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Cms/Test/Handler/CmsBlock/Curl.php @@ -0,0 +1,114 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Cms\Test\Handler\CmsBlock; + +use Mtf\System\Config; +use Mtf\Fixture\FixtureInterface; +use Mtf\Util\Protocol\CurlInterface; +use Mtf\Util\Protocol\CurlTransport; +use Magento\Backend\Test\Handler\Extractor; +use Mtf\Util\Protocol\CurlTransport\BackendDecorator; +use Mtf\Handler\Curl as AbstractCurl; + +/** + * Class Curl + * Curl handler for creating CMS Block + */ +class Curl extends AbstractCurl implements CmsBlockInterface +{ + /** + * Url for saving data + * + * @var string + */ + protected $saveUrl = 'cms/block/save'; + + /** + * Mapping values for data + * + * @var array + */ + protected $mappingData = [ + 'is_active' => [ + 'Enabled' => 1, + 'Disabled' => 0, + ], + ]; + + /** + * Mapping values for Stores + * + * @var array + */ + protected $stores = [ + 'All Store Views' => 0 + ]; + + /** + * POST request for creating CMS Block + * + * @param FixtureInterface|null $fixture [optional] + * @return array + * @throws \Exception + */ + public function persist(FixtureInterface $fixture = null) + { + $data = $this->prepareData($fixture); + $url = $_ENV['app_backend_url'] . $this->saveUrl; + $curl = new BackendDecorator(new CurlTransport(), new Config()); + $curl->write(CurlInterface::POST, $url, '1.0', [], $data); + $response = $curl->read(); + $curl->close(); + if (!strpos($response, 'data-ui-id="messages-message-success"')) { + throw new \Exception("CMS Block entity creating by curl handler was not successful! Response: $response"); + } + + $url = 'cms/block/index/sort/creation_time/dir/desc'; + $regExpPattern = '@^.*block_id\/(\d+)\/.*' . $fixture->getTitle() . '@ms'; + $extractor = new Extractor($url, $regExpPattern); + + return ['block_id' => $extractor->getData()[1]]; + } + + /** + * Prepare data from text to values + * + * @param FixtureInterface $fixture + * @return array + */ + protected function prepareData($fixture) + { + $data = $this->replaceMappingData($fixture->getData()); + if (isset($data['stores'])) { + $stores = []; + foreach ($data['stores'] as $store) { + $stores[] = isset($this->stores[$store]) ? $this->stores[$store] : $store; + } + $data['stores'] = $stores; + } + + return $data; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/Page/CmsIndex.php b/dev/tests/functional/tests/app/Magento/Cms/Test/Page/CmsIndex.php index 0fd1481fc81776aa7040dae449455169abb20c31..934ef479b7109f8213fb4344305de916c962be02 100644 --- a/dev/tests/functional/tests/app/Magento/Cms/Test/Page/CmsIndex.php +++ b/dev/tests/functional/tests/app/Magento/Cms/Test/Page/CmsIndex.php @@ -76,6 +76,18 @@ class CmsIndex extends FrontendPage 'locator' => '[data-block="minicart"]', 'strategy' => 'css selector', ], + 'compareProductsBlock' => [ + 'name' => 'compareProductsBlock', + 'class' => 'Magento\Catalog\Test\Block\Product\Compare\Sidebar', + 'locator' => '.sidebar.sidebar-additional', + 'strategy' => 'css selector', + ], + 'mainContentBlock' => [ + 'name' => 'mainContentBlock', + 'class' => 'Magento\Cms\Test\Block\Page', + 'locator' => '#maincontent', + 'strategy' => 'css selector', + ], ]; /** @@ -133,4 +145,19 @@ class CmsIndex extends FrontendPage { return $this->getBlockInstance('cartSidebarBlock'); } + + /** + * @return \Magento\Catalog\Test\Block\Product\Compare\Sidebar + */ + public function getCompareProductsBlock() + { + return $this->getBlockInstance('compareProductsBlock'); + } + /** + * @return \Magento\Cms\Test\Block\Page + */ + public function getMainContentBlock() + { + return $this->getBlockInstance('mainContentBlock'); + } } diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/Page/CmsIndex.xml b/dev/tests/functional/tests/app/Magento/Cms/Test/Page/CmsIndex.xml index f2c089e48bf893f443ee99601e3ed4b78603500e..57462d1fde391df156ce03d5929ed350c928481a 100644 --- a/dev/tests/functional/tests/app/Magento/Cms/Test/Page/CmsIndex.xml +++ b/dev/tests/functional/tests/app/Magento/Cms/Test/Page/CmsIndex.xml @@ -33,7 +33,7 @@ <block> <name>topmenu</name> <class>Magento\Theme\Test\Block\Html\Topmenu</class> - <locator>[role=navigation]</locator> + <locator>[role="navigation"]</locator> <strategy>css selector</strategy> </block> <block> @@ -45,7 +45,7 @@ <block> <name>footerBlock</name> <class>Magento\Theme\Test\Block\Html\Footer</class> - <locator>footer.page-footer</locator> + <locator>footer.page.footer</locator> <strategy>css selector</strategy> </block> <block> @@ -66,4 +66,10 @@ <locator>[data-block="minicart"]</locator> <strategy>css selector</strategy> </block> + <block> + <name>compareProductsBlock</name> + <class>Magento\Catalog\Test\Block\Product\Compare\Sidebar</class> + <locator>.sidebar.sidebar-additional</locator> + <strategy>css selector</strategy> + </block> </page> diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/Page/CmsPage.xml b/dev/tests/functional/tests/app/Magento/Cms/Test/Page/CmsPage.xml new file mode 100644 index 0000000000000000000000000000000000000000..682a389cc83a21130158a8dfcfaf53b15efff5e8 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Cms/Test/Page/CmsPage.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" ?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<page mca="cms/page" > + <block> + <name>cmsPageBlock</name> + <class>Magento\Cms\Test\Block\Page</class> + <locator>.page.main</locator> + <strategy>css selector</strategy> + </block> +</page> diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Super/Config.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Super/Config.php index e33f17145d58b7082ba9d56371a70326879cfd3b..ebf6a8a5209755a01d1d2b1d4056049a356d2ad0 100644 --- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Super/Config.php +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Super/Config.php @@ -77,6 +77,41 @@ class Config extends Tab */ protected $attributeTab = './/*[@data-role="configurable-attribute"]//*[text()="%attributeTab%"]'; + /** + * XPath Selector attribute variations row content + * + * @var string + */ + protected $activeButtonSelector = '//*[contains(@class,"fieldset-wrapper-title")]//*[@class="title"]'; + + /** + * XPath Selector attribute variations row + * + * @var string + */ + protected $rowSelector = '//div[contains(@data-role,"configurable-attribute") and position()=%d]'; + + /** + * XPath Selector attribute options row + * + * @var string + */ + protected $rowOptions = './/tbody/tr[contains(@data-role,"option-container") and position()=%d]'; + + /** + * XPath Selector attribute options row + * + * @var string + */ + protected $rowMatrix = './/tbody/tr[contains(@data-role,"row") and position()=%d]'; + + /** + * CSS selector variations label + * + * @var string + */ + protected $labelSelector = '.store-label'; + /** * Get attribute block * @@ -197,4 +232,73 @@ class Config extends Tab $attribute->click(); } } + + /** + * Get data of tab + * + * @param array|null $fields [optional] + * @param Element|null $element [optional] + * @return array + */ + public function getDataFormTab($fields = null, Element $element = null) + { + $dataResult = []; + if (isset($fields['configurable_attributes_data']['value']['attributes_data'])) { + $field['attributes_data']['value'] = $fields['configurable_attributes_data']['value']['attributes_data']; + $data = $this->dataMapping($field)['attributes_data']; + $variationsBlock = $this->_rootElement->find($data['selector']); + + foreach ($data['value'] as $key => $value) { + ++$key; + $this->openVariation($key, $variationsBlock); + $row = $variationsBlock->find(sprintf($this->rowSelector, $key), Locator::SELECTOR_XPATH); + --$key; + $dataResult['attributes_data'][$key]['title'] = $row->find($this->labelSelector)->getValue(); + $dataResult['attributes_data'][$key]['options'] = []; + foreach ($value['options'] as $optionKey => $option) { + ++$optionKey; + $optionsForm = $this->blockFactory->create( + 'Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\Edit\Tab\Super\Options', + ['element' => $row->find(sprintf($this->rowOptions, $optionKey), Locator::SELECTOR_XPATH)] + ); + $dataResult['attributes_data'][$key]['options'][] = $optionsForm->getDataOptions($option); + } + } + } + if (isset($fields['configurable_attributes_data']['value']['matrix'])) { + $field['matrix']['value'] = $fields['configurable_attributes_data']['value']['matrix']; + $data = $this->dataMapping($field)['matrix']; + $matrixBlock = $this->_rootElement->find($data['selector']); + + $index = 1; + foreach ($data['value'] as $key => $value) { + $matrixCell = $this->blockFactory->create( + 'Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\Edit\Tab\Super\Matrix', + ['element' => $matrixBlock->find(sprintf($this->rowMatrix, $index), Locator::SELECTOR_XPATH)] + ); + $dataResult['matrix'][$key] = $matrixCell->getDataOptions(); + ++$index; + } + } + + return ['configurable_attributes_data' => $dataResult]; + } + + /** + * Active variation tab + * + * @param int $row + * @param Element $variationsBlock + * @return void + */ + protected function openVariation($row, Element $variationsBlock) + { + $element = $variationsBlock->find( + sprintf($this->rowSelector, $row) . $this->activeButtonSelector, + Locator::SELECTOR_XPATH + ); + if ($element->isVisible()) { + $element->click(); + } + } } diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Super/Matrix.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Super/Matrix.php new file mode 100644 index 0000000000000000000000000000000000000000..c0aecc288f0885727a0d27d2c829f57085326cbc --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Super/Matrix.php @@ -0,0 +1,83 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\Edit\Tab\Super; + +use Mtf\Client\Element; +use Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Options as CatalogOptions; + +/** + * Class Matrix + * Matrix row form + */ +class Matrix extends CatalogOptions +{ + /** + * CSS selector data cell + * + * @var string + */ + protected $cellSelector = 'td:nth-child(%d)'; + + /** + * Field name mapping + * + * @var array + */ + protected $fieldNameMapping = [ + 3 => 'name', + 4 => 'sku', + 5 => 'price', + 6 => 'qty', + 7 => 'weight' + ]; + + /** + * Getting product matrix data form on the product form + * + * @param array|null $fields [optional] + * @param Element|null $element [optional] + * @return array + */ + public function getDataOptions(array $fields = null, Element $element = null) + { + $element = $element === null ? $this->_rootElement : $element; + $mapping = $this->dataMapping($fields); + $data = $this->_getData($mapping, $element); + + $column = 3; + $cell = $element->find(sprintf($this->cellSelector, $column)); + $data['options_names'] = []; + while ($cell->isVisible()) { + if (isset($this->fieldNameMapping[$column])) { + $data[$this->fieldNameMapping[$column]] = $cell->getText(); + } else { + $data['options_names'][] = $cell->getText(); + } + $cell = $element->find(sprintf($this->cellSelector, ++$column)); + } + + return $data; + } +} diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Super/Matrix.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Super/Matrix.xml new file mode 100644 index 0000000000000000000000000000000000000000..211a7cc5252b6f14a319caf84ed0ea00f0ad9764 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Super/Matrix.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" ?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<mapping strict="0"> + <fields> + <display> + <selector>td [name$='associated_product_ids[]']</selector> + <input>checkbox</input> + </display> + </fields> +</mapping> diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Super/Options.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Super/Options.php new file mode 100644 index 0000000000000000000000000000000000000000..3749a1d246b9d071bc2f11b338f78f63786607b1 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Super/Options.php @@ -0,0 +1,77 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\Edit\Tab\Super; + +use Mtf\Client\Element; +use Mtf\Client\Element\Locator; +use Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Options as CatalogOptions; + +/** + * Class Options + * Attribute options row form + */ +class Options extends CatalogOptions +{ + /** + * CSS selector name item + * + * @var string + */ + protected $nameSelector = 'td[data-column="name"]'; + + /** + * XPath selector percent label + * + * @var string + */ + protected $percentSelector = '//button[span[contains(text(),"%")]]'; + + /** + * Getting options data form on the product form + * + * @param array|null $fields [optional] + * @param Element|null $element [optional] + * @return array + */ + public function getDataOptions(array $fields = null, Element $element = null) + { + $element = $element === null ? $this->_rootElement : $element; + $mapping = $this->dataMapping($fields); + $data = $this->_getData($mapping, $element); + + $data['is_percent'] = 'No'; + $percentElement = $element->find($this->percentSelector, Locator::SELECTOR_XPATH); + if ($percentElement->isVisible()) { + $data['is_percent'] = 'Yes'; + } + + $nameElement = $element->find($this->nameSelector); + if ($nameElement->isVisible()) { + $data['name'] = $nameElement->getText(); + } + + return $data; + } +} diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Super/Options.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Super/Options.xml new file mode 100644 index 0000000000000000000000000000000000000000..05c31e62d000cfcd3014e7097e8086b1b2509d66 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Super/Options.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" ?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<mapping strict="0"> + <fields> + <pricing_value> + <selector>[name$='[pricing_value]']</selector> + </pricing_value> + <include> + <selector>[name$='[include]']</selector> + <input>checkbox</input> + </include> + </fields> +</mapping> diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/ProductForm.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/ProductForm.php old mode 100644 new mode 100755 index 2cc1ac02d41fe3c805a36f6d8410d0b0ae396b41..98922c8272ffb128a2b202bbb444d8bf821ff3b0 --- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/ProductForm.php +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/ProductForm.php @@ -28,6 +28,7 @@ use Mtf\Block\Mapper; use Mtf\Client\Element; use Mtf\Client\Browser; use Mtf\Factory\Factory; +use Mtf\Fixture\FixtureInterface; use Mtf\Util\XmlConverter; use Mtf\Block\BlockFactory; use Mtf\Client\Element\Locator; @@ -54,6 +55,13 @@ class ProductForm extends ParentForm */ protected $newAttributeFrame = '#create_new_attribute_container'; + /** + * New variation set button selector + * + * @var string + */ + protected $newVariationSet = '[data-ui-id="admin-product-edit-tab-super-config-grid-container-add-attribute"]'; + /** * Variations tab selector * @@ -126,14 +134,17 @@ class ProductForm extends ParentForm } /** - * Initialization categories before use in the form of + * Save product * - * @param CatalogCategory $category - * @return void + * @param FixtureInterface $fixture + * @return \Magento\Backend\Test\Block\Widget\Form|void */ - public function setCategory(CatalogCategory $category) + public function save(FixtureInterface $fixture = null) { - $this->category = $category; + parent::save($fixture); + if ($this->getAffectedAttributeSetBlock()->isVisible()) { + $this->getAffectedAttributeSetBlock()->chooseAttributeSet($fixture); + } } /** diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/ProductForm.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/ProductForm.xml index eb831ebbe03b82b7cf434bc33769c103411ba5b6..68c9e8a73eb224bf7b1a9c92747e05252d04b0d6 100644 --- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/ProductForm.xml +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/ProductForm.xml @@ -68,5 +68,13 @@ <class>\Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\Edit\Tab\Super\Config</class> <selector>#product_info_tabs_product-details</selector> <strategy>css selector</strategy> + <fields> + <attributes_data> + <selector>#super_config-wrapper</selector> + </attributes_data> + <matrix> + <selector>#product-variations-matrix</selector> + </matrix> + </fields> </variations> </tabs> diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableInCart.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableInCart.php old mode 100644 new mode 100755 index b4f2372942cd3a830170a8db95fcf40b991a494c..5e9e9c0ed584cc247c1f0e1072bdbe830531a7e9 --- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableInCart.php +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableInCart.php @@ -30,7 +30,7 @@ use Magento\Catalog\Test\Page\Product\CatalogProductView; use Magento\ConfigurableProduct\Test\Fixture\CatalogProductConfigurable; /** - * Class AssertProductInCart + * Class AssertConfigurableInCart */ class AssertConfigurableInCart extends AbstractConstraint { @@ -61,7 +61,7 @@ class AssertConfigurableInCart extends AbstractConstraint if (!empty($configurableData)) { $configurableOption = $catalogProductView->getCustomOptionsBlock(); foreach ($configurableData['attributes_data'] as $attribute) { - $configurableOption->selectProductCustomOption(reset($attribute['options'])['name']); + $configurableOption->selectProductCustomOption($attribute['title']); } } $catalogProductView->getViewBlock()->clickAddToCart(); diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertProductAttributeIsConfigurable.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertProductAttributeIsConfigurable.php old mode 100644 new mode 100755 index ec83346fc0876233cbcc69aadcb1c292faebc9af..db8340d3116829bba22fa20da4d28c28e506174a --- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertProductAttributeIsConfigurable.php +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertProductAttributeIsConfigurable.php @@ -69,7 +69,7 @@ class AssertProductAttributeIsConfigurable extends AbstractConstraint ) { $this->attribute = !is_null($productAttribute) ? $productAttribute : $attribute; $productGrid->open(); - $productGrid->getProductBlock()->addProduct('configurable'); + $productGrid->getGridPageActionBlock()->addProduct('configurable'); $productConfigurable = $fixtureFactory->createByCode( 'catalogProductConfigurable', @@ -87,7 +87,7 @@ class AssertProductAttributeIsConfigurable extends AbstractConstraint ); $productBlockForm = $newProductPage->getForm(); - $productBlockForm->fillProduct($productConfigurable); + $productBlockForm->fill($productConfigurable); \PHPUnit_Framework_Assert::assertTrue( $newProductPage->getForm()->findAttribute($this->attribute->getFrontendLabel()), diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertProductConfigurableDuplicateForm.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertProductConfigurableDuplicateForm.php new file mode 100644 index 0000000000000000000000000000000000000000..d66d28b2156a1c93ff501eef8332a80e5c5dd672 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertProductConfigurableDuplicateForm.php @@ -0,0 +1,112 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\ConfigurableProduct\Test\Constraint; + +use Mtf\Fixture\FixtureInterface; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex; +use Magento\Catalog\Test\Constraint\AssertProductDuplicateForm; +use Magento\ConfigurableProduct\Test\Page\Adminhtml\CatalogProductEdit; + +/** + * Class AssertProductConfigurableDuplicateForm + */ +class AssertProductConfigurableDuplicateForm extends AssertProductDuplicateForm +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Assert form data equals duplicate product configurable data + * + * @param FixtureInterface $product + * @param CatalogProductIndex $productGrid + * @param CatalogProductEdit $productPage + * @return void + */ + public function processAssert( + FixtureInterface $product, + CatalogProductIndex $productGrid, + CatalogProductEdit $productPage + ) { + $filter = ['sku' => $product->getSku() . '-1']; + $productGrid->open()->getProductGrid()->searchAndOpen($filter); + + $form = $productPage->getForm(); + $formData = $form->getData($product); + foreach (array_keys($formData['configurable_attributes_data']['matrix']) as $key) { + unset($formData['configurable_attributes_data']['matrix'][$key]['price']); + } + + $fixtureData = $this->prepareFixtureData($product->getData()); + $attributes = $fixtureData['configurable_attributes_data']['attributes_data']; + $matrix = $fixtureData['configurable_attributes_data']['matrix']; + unset($fixtureData['configurable_attributes_data']); + + $fixtureData['configurable_attributes_data']['attributes_data'] = $this->prepareAttributes($attributes); + $fixtureData['configurable_attributes_data']['matrix'] = $this->prepareMatrix($matrix); + + $errors = $this->verifyData($fixtureData, $formData); + \PHPUnit_Framework_Assert::assertEmpty($errors, $errors); + } + + /** + * Preparing data attributes fixture + * + * @param array $fixtureAttribute + * @return array + */ + protected function prepareAttributes(array $fixtureAttribute) + { + foreach ($fixtureAttribute as &$attribute) { + unset($attribute['id'], $attribute['label'], $attribute['code']); + foreach ($attribute['options'] as &$option) { + $option['pricing_value'] = number_format($option['pricing_value'], 4); + unset($option['id']); + } + } + + return $fixtureAttribute; + } + + /** + * Preparing data matrix fixture + * + * @param array $fixtureMatrix + * @return array + */ + protected function prepareMatrix(array $fixtureMatrix) + { + foreach ($fixtureMatrix as &$matrix) { + $matrix['display'] = 'Yes'; + unset($matrix['configurable_attribute'], $matrix['associated_product_ids']); + } + + return $fixtureMatrix; + } +} diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/CatalogProductConfigurable.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/CatalogProductConfigurable.php index f985d2fe282702e26467e3a880c56b70e604a434..927a42c2111f2aa1709c0087ddff2598fc8ea2f7 100644 --- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/CatalogProductConfigurable.php +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/CatalogProductConfigurable.php @@ -591,7 +591,8 @@ class CatalogProductConfigurable extends InjectableFixture protected $website_ids = [ 'attribute_code' => 'website_ids', 'backend_type' => 'virtual', - 'default_value' => 'Main Website', + 'default_value' => ['Main Website'], + 'group' => 'websites', ]; public function getCategoryIds() diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/CatalogProductConfigurable.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/CatalogProductConfigurable.xml index b37c96cd976cc7c19d1068794eac7499806f5bad..8fcbbdc441bacdff88b78a43f3f23b2ed290443e 100644 --- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/CatalogProductConfigurable.xml +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/CatalogProductConfigurable.xml @@ -452,6 +452,7 @@ <attribute_code>website_ids</attribute_code> <backend_type>virtual</backend_type> <default_value>Main Website</default_value> + <group>websites</group> </website_ids> </fields> <data_set> diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/CatalogProductConfigurable/ConfigurableAttributesData.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/CatalogProductConfigurable/ConfigurableAttributesData.php index 0e9beb70f817bd6b82c13757d07c9ab61e5b49ba..bbcc25bee46541bc73b0d382e1cd78693d7591a6 100644 --- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/CatalogProductConfigurable/ConfigurableAttributesData.php +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/CatalogProductConfigurable/ConfigurableAttributesData.php @@ -444,7 +444,8 @@ class ConfigurableAttributesData implements FixtureInterface 'name' => 'In configurable %isolation% %attribute_0-option_0_name% %attribute_1-option_1_name%', 'sku' => 'sku_configurable_%isolation%_%attribute_0-option_0_id%_%attribute_1-option_1_id%', 'qty' => 10, - 'weight' => 1 + 'weight' => 1, + 'options_names' => [] ], '%attribute_0-option_0%-%attribute_1-option_2%' => [ 'configurable_attribute' => [ @@ -455,7 +456,8 @@ class ConfigurableAttributesData implements FixtureInterface 'name' => 'In configurable %isolation% %attribute_0-option_0_name% %attribute_1-option_2_name%', 'sku' => 'sku_configurable_%isolation%_%attribute_0-option_0_id%_%attribute_1-option_2_id%', 'qty' => 10, - 'weight' => 1 + 'weight' => 1, + 'options_names' => [] ], '%attribute_0-option_1%-%attribute_1-option_0%' => [ 'configurable_attribute' => [ @@ -466,7 +468,8 @@ class ConfigurableAttributesData implements FixtureInterface 'name' => 'In configurable %isolation% %attribute_0-option_1_name% %attribute_1-option_0_name%', 'sku' => 'sku_configurable_%isolation%_%attribute_0-option_1_id%_%attribute_1-option_0_id%', 'qty' => 10, - 'weight' => 1 + 'weight' => 1, + 'options_names' => [] ], '%attribute_0-option_1%-%attribute_1-option_1%' => [ 'configurable_attribute' => [ @@ -477,7 +480,8 @@ class ConfigurableAttributesData implements FixtureInterface 'name' => 'In configurable %isolation% %attribute_0-option_1_name% %attribute_1-option_1_name%', 'sku' => 'sku_configurable_%isolation%_%attribute_0-option_1_id%_%attribute_1-option_1_id%', 'qty' => 10, - 'weight' => 1 + 'weight' => 1, + 'options_names' => [] ], '%attribute_0-option_1%-%attribute_1-option_2%' => [ 'configurable_attribute' => [ @@ -488,7 +492,8 @@ class ConfigurableAttributesData implements FixtureInterface 'name' => 'In configurable %isolation% %attribute_0-option_1_name% %attribute_1-option_2_name%', 'sku' => 'sku_configurable_%isolation%_%attribute_0-option_1_id%_%attribute_1-option_2_id%', 'qty' => 10, - 'weight' => 1 + 'weight' => 1, + 'options_names' => [] ], '%attribute_0-option_2%-%attribute_1-option_0%' => [ 'configurable_attribute' => [ @@ -499,7 +504,8 @@ class ConfigurableAttributesData implements FixtureInterface 'name' => 'In configurable %isolation% %attribute_0-option_2_name% %attribute_1-option_0_name%', 'sku' => 'sku_configurable_%isolation%_%attribute_0-option_2_id%_%attribute_1-option_0_id%', 'qty' => 10, - 'weight' => 1 + 'weight' => 1, + 'options_names' => [] ], '%attribute_0-option_2%-%attribute_1-option_1%' => [ 'configurable_attribute' => [ @@ -510,7 +516,8 @@ class ConfigurableAttributesData implements FixtureInterface 'name' => 'In configurable %isolation% %attribute_0-option_2_name% %attribute_1-option_1_name%', 'sku' => 'sku_configurable_%isolation%_%attribute_0-option_2_id%_%attribute_1-option_1_id%', 'qty' => 10, - 'weight' => 1 + 'weight' => 1, + 'options_names' => [] ], '%attribute_0-option_2%-%attribute_1-option_2%' => [ 'configurable_attribute' => [ @@ -521,7 +528,8 @@ class ConfigurableAttributesData implements FixtureInterface 'name' => 'In configurable %isolation% %attribute_0-option_2_name% %attribute_1-option_2_name%', 'sku' => 'sku_configurable_%isolation%_%attribute_0-option_2_id%_%attribute_1-option_2_id%', 'qty' => 10, - 'weight' => 1 + 'weight' => 1, + 'options_names' => [] ] ] ], @@ -557,7 +565,8 @@ class ConfigurableAttributesData implements FixtureInterface 'name' => 'In configurable %isolation% %attribute_0-option_0_name%', 'sku' => 'sku_configurable_%isolation%_%attribute_0-option_0_id%', 'qty' => 10, - 'weight' => 1 + 'weight' => 1, + 'options_names' => [] ] ] ] diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Page/Adminhtml/CatalogProductEdit.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Page/Adminhtml/CatalogProductEdit.php new file mode 100644 index 0000000000000000000000000000000000000000..2ae766e3884c949848d0e293ce0ffe7f7af6439e --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Page/Adminhtml/CatalogProductEdit.php @@ -0,0 +1,56 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\ConfigurableProduct\Test\Page\Adminhtml; + +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductEdit as ParentCatalogProductEdit; + +/** + * Class CatalogProductEdit + */ +class CatalogProductEdit extends ParentCatalogProductEdit +{ + const MCA = 'configurable/catalog/product/edit'; + + /** + * Custom constructor + */ + protected function _init() + { + $this->_blocks['form'] = [ + 'name' => 'form', + 'class' => 'Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\ProductForm', + 'locator' => '[id="page:main-container"]', + 'strategy' => 'css selector', + ]; + } + + /** + * @return \Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\ProductForm + */ + public function getForm() + { + return $this->getBlockInstance('form'); + } +} diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Page/Adminhtml/CatalogProductEdit.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Page/Adminhtml/CatalogProductEdit.xml new file mode 100644 index 0000000000000000000000000000000000000000..833ae1e11ce3056af7ff0e06afeacb9fcc723db8 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Page/Adminhtml/CatalogProductEdit.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" ?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<page mca="configurable/catalog/product/edit" > + <block> + <name>form</name> + <class>Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\ProductForm</class> + <locator>[id="page:main-container"]</locator> + <strategy>css selector</strategy> + </block> +</page> diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Page/Adminhtml/CatalogProductNew.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Page/Adminhtml/CatalogProductNew.php index 42e4d61f36090653918feafbb746faf7981fd803..d07ee53638df4624af6cbad3bc99a76ad32fb051 100644 --- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Page/Adminhtml/CatalogProductNew.php +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Page/Adminhtml/CatalogProductNew.php @@ -32,7 +32,8 @@ use Magento\Catalog\Test\Page\Adminhtml\CatalogProductNew as ParentCatalogProduc */ class CatalogProductNew extends ParentCatalogProductNew { - const MCA = 'catalog/product_configurable/new'; + const MCA = 'configurable/catalog/product/new'; + /** * Custom constructor */ @@ -44,7 +45,6 @@ class CatalogProductNew extends ParentCatalogProductNew 'locator' => '[id="page:main-container"]', 'strategy' => 'css selector', ]; - $this->_url = $_ENV['app_backend_url'] . static::MCA; } /** diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Page/Adminhtml/CatalogProductNew.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Page/Adminhtml/CatalogProductNew.xml index f15ec3f97606bfc89b73e7e46503462674159edf..eccfc8eebdaa50d198f4714613f9a30f3aa23927 100644 --- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Page/Adminhtml/CatalogProductNew.xml +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Page/Adminhtml/CatalogProductNew.xml @@ -23,7 +23,7 @@ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) */ --> -<page mca="catalog/product_configurable/new"> +<page mca="configurable/catalog/product/new"> <block> <name>form</name> <class>Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\ProductForm</class> diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/Product/CreateConfigurableEntityTest.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/Product/CreateConfigurableEntityTest.php old mode 100644 new mode 100755 index dc214e17b828d97b06fef6ee9213a3c15bd66698..05581120708e14808d0983bc37d42f4d019fa09b --- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/Product/CreateConfigurableEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/Product/CreateConfigurableEntityTest.php @@ -109,10 +109,10 @@ class CreateConfigurableEntityTest extends Injectable { // Steps $this->productPageGrid->open(); - $this->productPageGrid->getProductBlock()->addProduct('configurable'); + $this->productPageGrid->getGridPageActionBlock()->addProduct('configurable'); // Fill form $productBlockForm = $this->newProductPage->getConfigurableProductForm(); - $productBlockForm->fillProduct($configurable, $category); + $productBlockForm->fill($configurable, null, $category); $this->newProductPage->getFormAction()->saveProduct($this->newProductPage, $configurable); } } diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/Product/CreateConfigurableEntityTest/testCreate.csv b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/Product/CreateConfigurableEntityTest/testCreate.csv old mode 100644 new mode 100755 diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/etc/global/constraint.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/etc/global/constraint.xml index a377726694e2e22cb6e8c3cd335f0ef683daa758..c480d4f9194f825ee349754c8601fff750b633ba 100644 --- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/etc/global/constraint.xml +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/etc/global/constraint.xml @@ -63,4 +63,12 @@ <newProductPage class="Magento\Catalog\Test\Page\Adminhtml\CatalogProductNew" /> </require> </assertProductAttributeIsConfigurable> + <assertProductConfigurableDuplicateForm module="Magento_ConfigurableProduct"> + <severeness>high</severeness> + <require> + <productGrid class="Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex" /> + <productPage class="Magento\ConfigurableProduct\Test\Page\Adminhtml\CatalogProductEdit" /> + <product class="Mtf\Fixture\FixtureInterface" /> + </require> + </assertProductConfigurableDuplicateForm> </constraint> diff --git a/dev/tests/functional/tests/app/Magento/Core/Test/Block/Adminhtml/System/Variable/FormPageActions.php b/dev/tests/functional/tests/app/Magento/Core/Test/Block/Adminhtml/System/Variable/FormPageActions.php new file mode 100644 index 0000000000000000000000000000000000000000..9386d490f9c66b1918d6848e81b80aa04cff8646 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Core/Test/Block/Adminhtml/System/Variable/FormPageActions.php @@ -0,0 +1,75 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Core\Test\Block\Adminhtml\System\Variable; + +use Magento\Backend\Test\Block\FormPageActions as AbstractFormPageActions; +use Mtf\Client\Element\Locator; + +/** + * Class FormPageActions + * Page Actions for Custom Variable + */ +class FormPageActions extends AbstractFormPageActions +{ + /** + * "Save and Continue Edit" button + * + * @var string + */ + protected $saveAndContinueButton = '#save_and_edit'; + + /** + * Store View button + * + * @var string + */ + protected $storeViewButton = '.store-switcher [data-toggle="dropdown"]'; + + /** + * Store View locator + * + * @var string + */ + protected $storeView = './/*/a[contains(text(),"%s")]'; + + /** + * Select Store View + * + * @param string $storeName + * @throws \Exception + * @return void + */ + public function selectStoreView($storeName) + { + $this->_rootElement->find($this->storeViewButton)->click(); + $selector = sprintf($this->storeView, $storeName); + if ($this->_rootElement->find($selector, Locator::SELECTOR_XPATH)->isVisible()) { + $this->_rootElement->find($selector, Locator::SELECTOR_XPATH)->click(); + } else { + throw new \Exception('Store View with name \'' . $storeName . '\' is not visible!'); + } + $this->_rootElement->acceptAlert(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Core/Test/Constraint/AssertCustomVariableForm.php b/dev/tests/functional/tests/app/Magento/Core/Test/Constraint/AssertCustomVariableForm.php new file mode 100644 index 0000000000000000000000000000000000000000..be548d5a94520ba8087057a90c6e6b626d39ea4c --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Core/Test/Constraint/AssertCustomVariableForm.php @@ -0,0 +1,115 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Core\Test\Constraint; + +use Magento\Store\Test\Fixture\Store; +use Mtf\Constraint\AbstractAssertForm; +use Magento\Core\Test\Fixture\SystemVariable; +use Magento\Core\Test\Page\Adminhtml\SystemVariableIndex; +use Magento\Core\Test\Page\Adminhtml\SystemVariableNew; + +/** + * Class AssertCustomVariableForm + * Check that data at the form corresponds to the fixture data + */ +class AssertCustomVariableForm extends AbstractAssertForm +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Skipped fields for verify data + * + * @var array + */ + protected $skippedFields = ['use_default_value', 'variable_id']; + + /** + * Assert that data at the form corresponds to the fixture data + * + * @param SystemVariable $customVariable + * @param SystemVariableIndex $systemVariableIndex + * @param SystemVariableNew $systemVariableNew + * @param Store $storeOrigin + * @param SystemVariable $customVariableOrigin + * @return void + * + * @SuppressWarnings(PHPMD.NPathComplexity) + */ + public function processAssert( + SystemVariable $customVariable, + SystemVariableIndex $systemVariableIndex, + SystemVariableNew $systemVariableNew, + Store $storeOrigin = null, + SystemVariable $customVariableOrigin = null + ) { + // Prepare data + $data = ($customVariableOrigin === null) + ? $customVariable->getData() + : array_merge($customVariableOrigin->getData(), $customVariable->getData()); + if ($customVariableOrigin !== null) { + $dataOrigin = $data; + $dataOrigin['html_value'] = $customVariableOrigin->getHtmlValue(); + $dataOrigin['plain_value'] = $customVariableOrigin->getPlainValue(); + } else { + $dataOrigin = $data; + } + if ($data['html_value'] == '') { + $data['html_value'] = $customVariableOrigin->getHtmlValue(); + $data['use_default_value'] = 'Yes'; + } + $data['plain_value'] = ($data['plain_value'] == '') + ? $customVariableOrigin->getPlainValue() + : $data['plain_value']; + // Perform assert + $systemVariableIndex->open(); + $systemVariableIndex->getSystemVariableGrid()->searchAndOpen(['code' => $data['code']]); + + $formData = $systemVariableNew->getSystemVariableForm()->getData($customVariable); + $errors = $this->verifyData($dataOrigin, $formData); + \PHPUnit_Framework_Assert::assertEmpty($errors, $errors); + + if ($storeOrigin !== null) { + $systemVariableNew->getFormPageActions()->selectStoreView($storeOrigin->getName()); + $formData = $systemVariableNew->getSystemVariableForm()->getData($customVariable); + $errors = $this->verifyData($data, $formData); + \PHPUnit_Framework_Assert::assertEmpty($errors, $errors); + } + } + + /** + * Text success verify Custom Variable + * + * @return string + */ + public function toString() + { + return 'Displayed Custom Variable data on edit page(backend) equals to passed from fixture.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Core/Test/Constraint/AssertCustomVariableInGrid.php b/dev/tests/functional/tests/app/Magento/Core/Test/Constraint/AssertCustomVariableInGrid.php new file mode 100644 index 0000000000000000000000000000000000000000..07feab08926c6974372fe25cfd52c9078aae8a4c --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Core/Test/Constraint/AssertCustomVariableInGrid.php @@ -0,0 +1,77 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Core\Test\Constraint; + +use Magento\Core\Test\Fixture\SystemVariable; +use Magento\Core\Test\Page\Adminhtml\SystemVariableIndex; +use Mtf\Constraint\AbstractConstraint; + +/** + * Class AssertCustomVariableInGrid + * Check that created custom variable is displayed on backend in custom variable grid and has correct data + * according to dataset + */ +class AssertCustomVariableInGrid extends AbstractConstraint +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Assert custom variable is displayed on backend in custom variable grid + * + * @param SystemVariableIndex $systemVariableIndexNew + * @param SystemVariable $customVariable + * @return void + */ + public function processAssert( + SystemVariableIndex $systemVariableIndexNew, + SystemVariable $customVariable + ) { + $filter = [ + 'code' => $customVariable->getCode(), + 'name' => $customVariable->getName(), + ]; + + $systemVariableIndexNew->open(); + \PHPUnit_Framework_Assert::assertTrue( + $systemVariableIndexNew->getSystemVariableGrid()->isRowVisible($filter), + 'Custom Variable with code \'' . $filter['code'] . '\' is absent in Custom Variable grid.' + ); + } + + /** + * Returns a string representation of successful assertion + * + * @return string + */ + public function toString() + { + return 'Custom System Variable is present in grid.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Core/Test/Constraint/AssertCustomVariableInPage.php b/dev/tests/functional/tests/app/Magento/Core/Test/Constraint/AssertCustomVariableInPage.php new file mode 100644 index 0000000000000000000000000000000000000000..e844c3e1d1c6cac66cf5932adb4d325d0380c1d4 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Core/Test/Constraint/AssertCustomVariableInPage.php @@ -0,0 +1,149 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Core\Test\Constraint; + +use Mtf\Client\Browser; +use Mtf\Fixture\FixtureFactory; +use Magento\Cms\Test\Page\CmsIndex; +use Magento\Store\Test\Fixture\Store; +use Mtf\Constraint\AbstractConstraint; +use Magento\Core\Test\Fixture\SystemVariable; + +/** + * Class AssertCustomVariableInPage + */ +class AssertCustomVariableInPage extends AbstractConstraint +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Add created variable to page and assert that Custom Variable is displayed on frontend page and has + * correct data according to dataset. + * + * @param SystemVariable $customVariable + * @param CmsIndex $cmsIndex + * @param SystemVariable $variable + * @param FixtureFactory $fixtureFactory + * @param Browser $browser + * @param Store $storeOrigin + * @param SystemVariable $customVariableOrigin + * @return void + */ + public function processAssert( + SystemVariable $customVariable, + CmsIndex $cmsIndex, + SystemVariable $variable, + FixtureFactory $fixtureFactory, + Browser $browser, + Store $storeOrigin = null, + SystemVariable $customVariableOrigin = null + ) { + $cmsPage = $fixtureFactory->createByCode( + 'cmsPage', + [ + 'dataSet' => 'default', + 'data' => ['content' => '{{customVar code=' . $customVariable->getCode() . '}}'], + ] + ); + $cmsPage->persist(); + $url = $_ENV['app_frontend_url'] . $cmsPage->getIdentifier(); + $browser->open($url); + + $cmsIndex->getStoreSwitcherBlock()->selectStoreView('Default Store View'); + + $htmlValue = ($customVariableOrigin !== null) + ? $this->getHtmlValue($customVariable, $customVariableOrigin) + : strip_tags($customVariable->getHtmlValue()); + $pageContent = $cmsIndex->getMainContentBlock()->getPageContent(); + $this->checkVariable($htmlValue, $pageContent); + + if ($storeOrigin !== null) { + $cmsIndex->getStoreSwitcherBlock()->selectStoreView($storeOrigin->getName()); + $htmlValue = strip_tags($customVariable->getHtmlValue()); + if ($htmlValue === '') { + $htmlValue = strip_tags($variable->getHtmlValue()); + } + $pageContent = $cmsIndex->getMainContentBlock()->getPageContent(); + $this->checkVariable($htmlValue, $pageContent); + } + } + + /** + * Get html value + * + * @param SystemVariable $customVariable + * @param SystemVariable $customVariableOrigin + * @return string + */ + protected function getHtmlValue(SystemVariable $customVariable, SystemVariable $customVariableOrigin) + { + $data = array_merge($customVariableOrigin->getData(), $customVariable->getData()); + if ($customVariable->getHtmlValue() == "" && $customVariableOrigin->getHtmlValue() == "") { + $htmlValue = ($data['plain_value'] == "") + ? $customVariableOrigin->getPlainValue() + : $data['plain_value']; + } else { + $htmlValue = ($customVariableOrigin == null) + ? $customVariable->getHtmlValue() + : $customVariableOrigin->getHtmlValue(); + $htmlValue = strip_tags($htmlValue); + } + return $htmlValue; + } + + /** + * Check Variable on frontend page + * + * @param string $htmlValue + * @param string $pageContent + * @return void + */ + protected function checkVariable($htmlValue, $pageContent) + { + \PHPUnit_Framework_Assert::assertEquals( + $htmlValue, + $pageContent, + 'Wrong content is displayed on frontend page' + . "\nExpected: " . $htmlValue + . "\nActual: " . $pageContent + ); + + } + + /** + * Returns a string representation of successful assertion + * + * @return string + */ + public function toString() + { + return 'Custom Variable is displayed on frontend page'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Core/Test/Constraint/AssertSystemVariableNotInCmsPageForm.php b/dev/tests/functional/tests/app/Magento/Core/Test/Constraint/AssertCustomVariableNotInCmsPageForm.php similarity index 95% rename from dev/tests/functional/tests/app/Magento/Core/Test/Constraint/AssertSystemVariableNotInCmsPageForm.php rename to dev/tests/functional/tests/app/Magento/Core/Test/Constraint/AssertCustomVariableNotInCmsPageForm.php index 85ffc1b1ff4ebc6c8396f50dd2a05686bb53e646..f85e03689ad66f9882ffce00aae76ef19276ab69 100644 --- a/dev/tests/functional/tests/app/Magento/Core/Test/Constraint/AssertSystemVariableNotInCmsPageForm.php +++ b/dev/tests/functional/tests/app/Magento/Core/Test/Constraint/AssertCustomVariableNotInCmsPageForm.php @@ -29,9 +29,9 @@ use Magento\Core\Test\Fixture\SystemVariable; use Mtf\Constraint\AbstractConstraint; /** - * Class AssertSystemVariableNotInCmsPageForm + * Class AssertCustomVariableNotInCmsPageForm */ -class AssertSystemVariableNotInCmsPageForm extends AbstractConstraint +class AssertCustomVariableNotInCmsPageForm extends AbstractConstraint { /** * Constraint severeness diff --git a/dev/tests/functional/tests/app/Magento/Core/Test/Constraint/AssertSystemVariableNotInGrid.php b/dev/tests/functional/tests/app/Magento/Core/Test/Constraint/AssertCustomVariableNotInGrid.php similarity index 95% rename from dev/tests/functional/tests/app/Magento/Core/Test/Constraint/AssertSystemVariableNotInGrid.php rename to dev/tests/functional/tests/app/Magento/Core/Test/Constraint/AssertCustomVariableNotInGrid.php index a8f89116f609881c56a297c335afabef573b3c4c..98d4de322b17c6cd07ea67e00f59efa9c0ff7700 100644 --- a/dev/tests/functional/tests/app/Magento/Core/Test/Constraint/AssertSystemVariableNotInGrid.php +++ b/dev/tests/functional/tests/app/Magento/Core/Test/Constraint/AssertCustomVariableNotInGrid.php @@ -29,9 +29,9 @@ use Magento\Core\Test\Page\Adminhtml\SystemVariableIndex; use Mtf\Constraint\AbstractConstraint; /** - * Class AssertSystemVariableNotInGrid + * Class AssertCustomVariableNotInGrid */ -class AssertSystemVariableNotInGrid extends AbstractConstraint +class AssertCustomVariableNotInGrid extends AbstractConstraint { /** * Constraint severeness diff --git a/dev/tests/functional/tests/app/Magento/Core/Test/Constraint/AssertSystemVariableSuccessDeleteMessage.php b/dev/tests/functional/tests/app/Magento/Core/Test/Constraint/AssertCustomVariableSuccessDeleteMessage.php similarity index 94% rename from dev/tests/functional/tests/app/Magento/Core/Test/Constraint/AssertSystemVariableSuccessDeleteMessage.php rename to dev/tests/functional/tests/app/Magento/Core/Test/Constraint/AssertCustomVariableSuccessDeleteMessage.php index 3c5d294676d44294ec5d27dff6848864c3a43623..bc0c05a0eeba3f084801e1bf38feaf6789587877 100644 --- a/dev/tests/functional/tests/app/Magento/Core/Test/Constraint/AssertSystemVariableSuccessDeleteMessage.php +++ b/dev/tests/functional/tests/app/Magento/Core/Test/Constraint/AssertCustomVariableSuccessDeleteMessage.php @@ -28,9 +28,9 @@ use Magento\Core\Test\Page\Adminhtml\SystemVariableIndex; use Mtf\Constraint\AbstractConstraint; /** - * Class AssertSystemVariableSuccessDeleteMessage + * Class AssertCustomVariableSuccessDeleteMessage */ -class AssertSystemVariableSuccessDeleteMessage extends AbstractConstraint +class AssertCustomVariableSuccessDeleteMessage extends AbstractConstraint { const SUCCESS_DELETE_MESSAGE = 'You deleted the custom variable.'; diff --git a/dev/tests/functional/tests/app/Magento/Core/Test/Constraint/AssertCustomVariableSuccessSaveMessage.php b/dev/tests/functional/tests/app/Magento/Core/Test/Constraint/AssertCustomVariableSuccessSaveMessage.php new file mode 100644 index 0000000000000000000000000000000000000000..33e535e26d55c1b4cfd338d9cbff33a5754a3608 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Core/Test/Constraint/AssertCustomVariableSuccessSaveMessage.php @@ -0,0 +1,72 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Core\Test\Constraint; + +use Mtf\Constraint\AbstractConstraint; +use Magento\Core\Test\Page\Adminhtml\SystemVariableIndex; + +/** + * Class AssertCustomVariableSuccessSaveMessage + * Check success delete message is correct after Custom System Variable deleted + */ +class AssertCustomVariableSuccessSaveMessage extends AbstractConstraint +{ + const SUCCESS_SAVE_MESSAGE = 'You saved the custom variable.'; + + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Assert that success delete message is correct after Custom System Variable deleted + * + * @param SystemVariableIndex $systemVariableIndexPage + * @return void + */ + public function processAssert(SystemVariableIndex $systemVariableIndexPage) + { + $actualMessage = $systemVariableIndexPage->getMessagesBlock()->getSuccessMessages(); + \PHPUnit_Framework_Assert::assertEquals( + self::SUCCESS_SAVE_MESSAGE, + $actualMessage, + 'Wrong success message is displayed.' + . "\nExpected: " . self::SUCCESS_SAVE_MESSAGE + . "\nActual: " . $actualMessage + ); + } + + /** + * Returns a string representation of successful assertion + * + * @return string + */ + public function toString() + { + return 'Custom Variable success save message is correct.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Core/Test/Page/Adminhtml/SystemVariableNew.php b/dev/tests/functional/tests/app/Magento/Core/Test/Page/Adminhtml/SystemVariableNew.php index df051f7158a5f6af7e98427913c3f9229b4d3078..3dfcc11c43dfc28493a3ba5222035d72bc21f79c 100644 --- a/dev/tests/functional/tests/app/Magento/Core/Test/Page/Adminhtml/SystemVariableNew.php +++ b/dev/tests/functional/tests/app/Magento/Core/Test/Page/Adminhtml/SystemVariableNew.php @@ -36,7 +36,7 @@ class SystemVariableNew extends BackendPage protected $_blocks = [ 'formPageActions' => [ 'name' => 'formPageActions', - 'class' => 'Magento\Backend\Test\Block\FormPageActions', + 'class' => 'Magento\Core\Test\Block\Adminhtml\System\Variable\FormPageActions', 'locator' => '.page-main-actions', 'strategy' => 'css selector', ], @@ -49,7 +49,7 @@ class SystemVariableNew extends BackendPage ]; /** - * @return \Magento\Backend\Test\Block\FormPageActions + * @return \Magento\Core\Test\Block\Adminhtml\System\Variable\FormPageActions */ public function getFormPageActions() { diff --git a/dev/tests/functional/tests/app/Magento/Core/Test/Page/Adminhtml/SystemVariableNew.xml b/dev/tests/functional/tests/app/Magento/Core/Test/Page/Adminhtml/SystemVariableNew.xml index a2dac6b6b79862c0016b634971b5f56acbe310c9..014bcf2f2dedb57881398364ffe3d68620aeee38 100644 --- a/dev/tests/functional/tests/app/Magento/Core/Test/Page/Adminhtml/SystemVariableNew.xml +++ b/dev/tests/functional/tests/app/Magento/Core/Test/Page/Adminhtml/SystemVariableNew.xml @@ -26,7 +26,7 @@ <page mca="admin/system_variable/new" > <block> <name>formPageActions</name> - <class>Magento\Backend\Test\Block\FormPageActions</class> + <class>Magento\Core\Test\Block\Adminhtml\System\Variable\FormPageActions</class> <locator>.page-main-actions</locator> <strategy>css selector</strategy> </block> diff --git a/dev/tests/functional/tests/app/Magento/Core/Test/TestCase/CreateCustomVariableEntityTest.php b/dev/tests/functional/tests/app/Magento/Core/Test/TestCase/CreateCustomVariableEntityTest.php new file mode 100644 index 0000000000000000000000000000000000000000..7f70a832a6f887fde4c7d26e898952e019847739 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Core/Test/TestCase/CreateCustomVariableEntityTest.php @@ -0,0 +1,92 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Core\Test\TestCase; + +use Mtf\TestCase\Injectable; +use Magento\Core\Test\Fixture\SystemVariable; +use Magento\Core\Test\Page\Adminhtml\SystemVariableIndex; +use Magento\Core\Test\Page\Adminhtml\SystemVariableNew; + +/** + * Test Creation for CreateCustomVariableEntity + * + * Test Flow: + * Steps: + * 1. Login to backend. + * 2. Navigate to System->Other Settings->Custom Variables. + * 3. Click on 'Add new variable' button. + * 4. Fill in all data according to data set. + * 5. Click 'Save' button. + * 6. Perform all asserts. + * + * @group Variables_(PS) + * @ZephyrId MAGETWO-23293 + */ +class CreateCustomVariableEntityTest extends Injectable +{ + /** + * Custom System Variable grid page + * + * @var SystemVariableIndex + */ + protected $systemVariableIndexPage; + + /** + * Custom System Variable new and edit page + * + * @var SystemVariableNew + */ + protected $systemVariableNewPage; + + /** + * Injection data + * + * @param SystemVariableIndex $systemVariableIndex + * @param SystemVariableNew $systemVariableNew + * @return void + */ + public function __inject( + SystemVariableIndex $systemVariableIndex, + SystemVariableNew $systemVariableNew + ) { + $this->systemVariableIndexPage = $systemVariableIndex; + $this->systemVariableNewPage = $systemVariableNew; + } + + /** + * Delete Custom System Variable Entity test + * + * @param SystemVariable $customVariable + * @return void + */ + public function test(SystemVariable $customVariable) + { + // Steps + $this->systemVariableIndexPage->open(); + $this->systemVariableIndexPage->getGridPageActions()->addNew(); + $this->systemVariableNewPage->getSystemVariableForm()->fill($customVariable); + $this->systemVariableNewPage->getFormPageActions()->save(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Core/Test/TestCase/CreateCustomVariableEntityTest/test.csv b/dev/tests/functional/tests/app/Magento/Core/Test/TestCase/CreateCustomVariableEntityTest/test.csv new file mode 100644 index 0000000000000000000000000000000000000000..6808d297faf51ee134f04cea89b2684e071d1314 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Core/Test/TestCase/CreateCustomVariableEntityTest/test.csv @@ -0,0 +1,3 @@ +"customVariable/data/code";"customVariable/data/name";"customVariable/data/html_value";"customVariable/data/plain_value";"constraint" +"variableCode%isolation%";"variableName%isolation%";"<h1>variableName%isolation%</h1>";"<p>variablePlainText%isolation%</p>";"assertCustomVariableSuccessSaveMessage, assertCustomVariableInGrid, assertCustomVariableForm, assertCustomVariableInPage" +"variableCode%isolation%";"variableName%isolation%";"<p>variableName%isolation%</p>";"variablePlainText%isolation%";"assertCustomVariableSuccessSaveMessage, assertCustomVariableInGrid, assertCustomVariableForm, assertCustomVariableInPage" \ No newline at end of file diff --git a/dev/tests/functional/tests/app/Magento/Core/Test/TestCase/DeleteSystemVariableEntityTest.php b/dev/tests/functional/tests/app/Magento/Core/Test/TestCase/DeleteCustomVariableEntityTest.php similarity index 96% rename from dev/tests/functional/tests/app/Magento/Core/Test/TestCase/DeleteSystemVariableEntityTest.php rename to dev/tests/functional/tests/app/Magento/Core/Test/TestCase/DeleteCustomVariableEntityTest.php index 45623cb81a7258a5a750ee0a18649f48f825baa4..5688063bbb5b660d16609885020b4516dedb1ca7 100644 --- a/dev/tests/functional/tests/app/Magento/Core/Test/TestCase/DeleteSystemVariableEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Core/Test/TestCase/DeleteCustomVariableEntityTest.php @@ -31,7 +31,7 @@ use Mtf\Fixture\FixtureFactory; use Mtf\TestCase\Injectable; /** - * Test Creation for DeleteSystemVariableEntity + * Test Creation for DeleteCustomVariableEntityTest * * Test Flow: * Preconditions: @@ -47,7 +47,7 @@ use Mtf\TestCase\Injectable; * @group Variables_(PS) * @ZephyrId MAGETWO-25535 */ -class DeleteSystemVariableEntityTest extends Injectable +class DeleteCustomVariableEntityTest extends Injectable { /** * Custom System Variable grid page diff --git a/dev/tests/functional/tests/app/Magento/Core/Test/TestCase/DeleteCustomVariableEntityTest/test.csv b/dev/tests/functional/tests/app/Magento/Core/Test/TestCase/DeleteCustomVariableEntityTest/test.csv new file mode 100644 index 0000000000000000000000000000000000000000..250384c701b4c52ae0ded9209d77e3103d58d8bb --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Core/Test/TestCase/DeleteCustomVariableEntityTest/test.csv @@ -0,0 +1,2 @@ +"constraint" +"assertCustomVariableSuccessDeleteMessage, assertCustomVariableNotInGrid, assertCustomVariableNotInCmsPageForm" \ No newline at end of file diff --git a/dev/tests/functional/tests/app/Magento/Core/Test/TestCase/DeleteSystemVariableEntityTest/test.csv b/dev/tests/functional/tests/app/Magento/Core/Test/TestCase/DeleteSystemVariableEntityTest/test.csv deleted file mode 100644 index ec58eb1c03c37c8e376808908bf5a05ddc013dad..0000000000000000000000000000000000000000 --- a/dev/tests/functional/tests/app/Magento/Core/Test/TestCase/DeleteSystemVariableEntityTest/test.csv +++ /dev/null @@ -1,2 +0,0 @@ -"constraint" -"assertSystemVariableSuccessDeleteMessage, assertSystemVariableNotInGrid, assertSystemVariableNotInCmsPageForm" \ No newline at end of file diff --git a/dev/tests/functional/tests/app/Magento/Core/Test/TestCase/UpdateCustomVariableEntityTest.php b/dev/tests/functional/tests/app/Magento/Core/Test/TestCase/UpdateCustomVariableEntityTest.php new file mode 100644 index 0000000000000000000000000000000000000000..1dc357b9fa9fd8d869f1325ea6e723c985b5ea8d --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Core/Test/TestCase/UpdateCustomVariableEntityTest.php @@ -0,0 +1,158 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Core\Test\TestCase; + +use Mtf\ObjectManager; +use Mtf\TestCase\Injectable; +use Magento\Store\Test\Fixture\Store; +use Magento\Core\Test\Fixture\SystemVariable; +use Magento\Core\Test\Page\Adminhtml\SystemVariableNew; +use Magento\Core\Test\Page\Adminhtml\SystemVariableIndex; + +/** + * Test Creation for CreateCustomVariableEntity + * + * Test Flow: + * Preconditions: + * 1. Custom system variable is created. + * 2. Additional Non Default Storeview is created. + * + * Steps: + * 1. Login to backend. + * 2. Navigate to System->Other Settings->Custom Variables. + * 3. Open from grid created custom system variable. + * 4. Navigate to the Store Switcher. + * 5. Choose Appropriate Storeview (non default). + * 6. Set Use Default Variable Values. + * 7. Edit necessary fields. + * 8. Save Custom variable using correspond saveActions. + * 9. Perform all assertions. + * + * @group Variables_(PS) + * @ZephyrId MAGETWO-26241 + */ +class UpdateCustomVariableEntityTest extends Injectable +{ + /** + * Custom System Variable grid page + * + * @var SystemVariableIndex + */ + protected $systemVariableIndexPage; + + /** + * Custom System Variable new and edit page + * + * @var SystemVariableNew + */ + protected $systemVariableNewPage; + + /** + * Store Name + * + * @var array + */ + public static $storeName; + + /** + * Prepare data + * + * @param Store $storeOrigin + * @return array + */ + public function __prepare(Store $storeOrigin) + { + $storeOrigin->persist(); + self::$storeName = $storeOrigin->getName(); + + return ['storeOrigin' => $storeOrigin]; + } + + /** + * Injection data + * + * @param SystemVariableIndex $systemVariableIndex + * @param SystemVariableNew $systemVariableNew + * @param SystemVariable $customVariableOrigin + * @return array + */ + public function __inject( + SystemVariableIndex $systemVariableIndex, + SystemVariableNew $systemVariableNew, + SystemVariable $customVariableOrigin + ) { + $this->systemVariableIndexPage = $systemVariableIndex; + $this->systemVariableNewPage = $systemVariableNew; + + $customVariableOrigin->persist(); + + return ['customVariableOrigin' => $customVariableOrigin]; + } + + /** + * Update Custom System Variable Entity test + * + * @param SystemVariable $customVariable + * @param SystemVariable $customVariableOrigin + * @param Store $storeOrigin + * @param $saveAction + * @return void + */ + public function test( + SystemVariable $customVariable, + SystemVariable $customVariableOrigin, + Store $storeOrigin, + $saveAction + ) { + $filter = [ + 'code' => $customVariableOrigin->getCode(), + ]; + + // Steps + $this->systemVariableIndexPage->open(); + $this->systemVariableIndexPage->getSystemVariableGrid()->searchAndOpen($filter); + $this->systemVariableNewPage->getFormPageActions()->selectStoreView($storeOrigin->getData('name')); + $this->systemVariableNewPage->getSystemVariableForm()->fill($customVariable); + $this->systemVariableNewPage->getFormPageActions()->$saveAction(); + } + + /** + * Delete Store after test + * + * @return void + */ + public static function tearDownAfterClass() + { + $filter['store_title'] = self::$storeName; + $storeIndex = ObjectManager::getInstance()->create('Magento\Backend\Test\Page\Adminhtml\StoreIndex'); + $storeIndex->open(); + $storeIndex->getStoreGrid()->searchAndOpen($filter); + $storeNew = ObjectManager::getInstance()->create('Magento\Backend\Test\Page\Adminhtml\StoreNew'); + $storeNew->getFormPageActions()->delete(); + $storeDelete = ObjectManager::getInstance()->create('Magento\Backend\Test\Page\Adminhtml\StoreDelete'); + $storeDelete->getStoreForm()->fillForm(['create_backup' => 'No']); + $storeDelete->getFormPageActions()->delete(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Core/Test/TestCase/UpdateCustomVariableEntityTest/test.csv b/dev/tests/functional/tests/app/Magento/Core/Test/TestCase/UpdateCustomVariableEntityTest/test.csv new file mode 100644 index 0000000000000000000000000000000000000000..da2cd79dfef66bad7b9d2cadbe90feb83558f664 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Core/Test/TestCase/UpdateCustomVariableEntityTest/test.csv @@ -0,0 +1,5 @@ +"customVariable/data/code";"customVariable/data/name";"customVariable/data/use_default_value";"customVariable/data/html_value";"customVariable/data/plain_value";"saveAction";"constraint" +"variableCode%isolation%";"variableName%isolation%";"No";"<h1>variableName%isolation%</h1>";"";"save";"assertCustomVariableSuccessSaveMessage, assertCustomVariableInGrid, assertCustomVariableForm, assertCustomVariableInPage" +"variableCode%isolation%";"variableName%isolation%";"No";"";"<p>variablePlainText%isolation%</p>";"saveAndContinue";"assertCustomVariableSuccessSaveMessage, assertCustomVariableInGrid, assertCustomVariableForm, assertCustomVariableInPage" +"variableCode%isolation%";"variableName%isolation%";"No";"<h1>variableName%isolation%</h1>";"<p>variablePlainText%isolation%</p>";"saveAndContinue";"assertCustomVariableSuccessSaveMessage, assertCustomVariableInGrid, assertCustomVariableForm, assertCustomVariableInPage" +"variableCode%isolation%";"variableName%isolation%";"No";"<h1>variableName%isolation%</h1>";"<p>variablePlainText%isolation%</p>";"save";"assertCustomVariableSuccessSaveMessage, assertCustomVariableInGrid, assertCustomVariableInPage" diff --git a/dev/tests/functional/tests/app/Magento/Core/Test/etc/curl/di.xml b/dev/tests/functional/tests/app/Magento/Core/Test/etc/curl/di.xml index 7fb1490cff2005d37ea423e31772c710f5898827..654b1969a56b935ca901a6d084a7a7271c0c7c66 100644 --- a/dev/tests/functional/tests/app/Magento/Core/Test/etc/curl/di.xml +++ b/dev/tests/functional/tests/app/Magento/Core/Test/etc/curl/di.xml @@ -25,4 +25,5 @@ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd"> <preference for="\Magento\Core\Test\Handler\SystemVariable\SystemVariableInterface" type="\Magento\Core\Test\Handler\SystemVariable\Curl" /> + <preference for="\Magento\Core\Test\Handler\ConfigData\ConfigDataInterface" type="\Magento\Core\Test\Handler\ConfigData\Curl" /> </config> diff --git a/dev/tests/functional/tests/app/Magento/Core/Test/etc/global/constraint.xml b/dev/tests/functional/tests/app/Magento/Core/Test/etc/global/constraint.xml index ff54ee59660a7f033945d96293f1ba66138f6047..723b85002f691a2e16af3d56dfe863bee6fca1f9 100644 --- a/dev/tests/functional/tests/app/Magento/Core/Test/etc/global/constraint.xml +++ b/dev/tests/functional/tests/app/Magento/Core/Test/etc/global/constraint.xml @@ -24,13 +24,31 @@ */ --> <constraint> - <assertSystemVariableSuccessDeleteMessage module="Magento_Core"> + <assertCustomVariableSuccessDeleteMessage module="Magento_Core"> <severeness>low</severeness> - </assertSystemVariableSuccessDeleteMessage> - <assertSystemVariableNotInGrid module="Magento_Core"> + </assertCustomVariableSuccessDeleteMessage> + <assertCustomVariableNotInGrid module="Magento_Core"> <severeness>low</severeness> - </assertSystemVariableNotInGrid> - <assertSystemVariableNotInCmsPageForm module="Magento_Core"> + </assertCustomVariableNotInGrid> + <assertCustomVariableNotInCmsPageForm module="Magento_Core"> <severeness>low</severeness> - </assertSystemVariableNotInCmsPageForm> + </assertCustomVariableNotInCmsPageForm> + <assertCustomVariableSuccessSaveMessage module="Magento_Core"> + <severeness>low</severeness> + </assertCustomVariableSuccessSaveMessage> + <assertCustomVariableInGrid module="Magento_Core"> + <severeness>low</severeness> + </assertCustomVariableInGrid> + <assertCustomVariableInPageStoreview module="Magento_Core"> + <severeness>low</severeness> + </assertCustomVariableInPageStoreview> + <assertCustomVariableNotInCmsPageForm module="Magento_Core"> + <severeness>low</severeness> + </assertCustomVariableNotInCmsPageForm> + <assertCustomVariableForm module="Magento_Core"> + <severeness>low</severeness> + </assertCustomVariableForm> + <assertCustomVariableInPage module="Magento_Core"> + <severeness>low</severeness> + </assertCustomVariableInPage> </constraint> diff --git a/dev/tests/functional/tests/app/Magento/Core/Test/etc/global/fixture.xml b/dev/tests/functional/tests/app/Magento/Core/Test/etc/global/fixture.xml index b71f00f7be2a3de3d9b324638e455a1a2709ae1c..81c2b35e314c06a8f80aa24e89ccfa87c0b24fd4 100644 --- a/dev/tests/functional/tests/app/Magento/Core/Test/etc/global/fixture.xml +++ b/dev/tests/functional/tests/app/Magento/Core/Test/etc/global/fixture.xml @@ -32,4 +32,16 @@ </entities> <collection>Magento\Core\Model\Resource\Variable\Collection</collection> </systemVariable> + <configData module="Magento_Core"> + <module>Magento_Core</module> + <type>flat</type> + <entity_type>core_config_data</entity_type> + <collection>Magento\Core\Model\Resource\Config\Data\Collection</collection> + <fields> + <section> + <attribute_code>section</attribute_code> + <backend_type>virtual</backend_type> + </section> + </fields> + </configData> </fixture> diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Account/Dashboard/Address.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Account/Dashboard/Address.php index f50b7d565e09563813e745e583d9d31433586382..4ee0087a624343b6356b589f4a71439e863b4f39 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Account/Dashboard/Address.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Account/Dashboard/Address.php @@ -18,7 +18,6 @@ * versions in the future. If you wish to customize Magento for your * needs please refer to http://www.magentocommerce.com for more information. * - * @spi * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ @@ -28,23 +27,59 @@ namespace Magento\Customer\Test\Block\Account\Dashboard; use Mtf\Block\Block; /** + * Class Address * Customer Dashboard Address Book block - * */ class Address extends Block { /** - * Default Billing Address Edit link + * Default Billing Address Edit link * * @var string */ protected $defaultBillingAddressEdit = '[data-ui-id=default-billing-edit-link]'; + /** + * Shipping address block selector + * + * @var string + */ + protected $shippingAddressBlock = '.shipping address'; + + /** + * Billing address block selector + * + * @var string + */ + protected $billingAddressBlock = '.billing address'; + /** * Edit Default Billing Address + * + * @return void */ public function editBillingAddress() { $this->_rootElement->find($this->defaultBillingAddressEdit)->click(); } + + /** + * Returns Default Billing Address Text + * + * @return array|string + */ + public function getDefaultBillingAddressText() + { + return $this->_rootElement->find($this->billingAddressBlock)->getText(); + } + + /** + * Returns Default Shipping Address Text + * + * @return array|string + */ + public function getDefaultShippingAddressText() + { + return $this->_rootElement->find($this->shippingAddressBlock)->getText(); + } } diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Account/Dashboard/Info.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Account/Dashboard/Info.php new file mode 100644 index 0000000000000000000000000000000000000000..8a9b81871bc3148b0cbc7162d1b7ee64fbd1e7f1 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Account/Dashboard/Info.php @@ -0,0 +1,51 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Customer\Test\Block\Account\Dashboard; + +use Mtf\Block\Block; + +/** + * Class Info + * Main block on customer account page + */ +class Info extends Block +{ + /** + * Css selector for Contact Information Edit Link + * + * @var string + */ + protected $contactInfoEditLink = '.dashboard.info .information a.edit'; + + /** + * Click on Contact Information Edit Link + * + * @return void + */ + public function openEditContactInfo() + { + $this->_rootElement->find($this->contactInfoEditLink)->click(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Address/Edit.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Address/Edit.php index 935c115d21153348355be27175e85b6ff468b2ad..e75dfad97e5e6bbcb09ca203178ba8e9616911a5 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Address/Edit.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Address/Edit.php @@ -32,7 +32,6 @@ use Magento\Customer\Test\Fixture\Address; /** * Class Edit * Customer address edit block - * */ class Edit extends Form { @@ -58,7 +57,7 @@ class Edit extends Form public function editCustomerAddress(Address $fixture) { $this->fill($fixture); - $this->_rootElement->find($this->saveAddress, Locator::SELECTOR_CSS)->click(); + $this->saveAddress(); } /** @@ -69,6 +68,16 @@ class Edit extends Form public function saveVatID($vat) { $this->_rootElement->find($this->vatFieldId, Locator::SELECTOR_ID)->setValue($vat); - $this->_rootElement->find($this->saveAddress, Locator::SELECTOR_CSS)->click(); + $this->saveAddress(); + } + + /** + * Click on save address button + * + * @return void + */ + public function saveAddress() + { + $this->_rootElement->find($this->saveAddress)->click(); } } diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Address/Edit.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Address/Edit.xml index cbd9f0a7f53d234d271635ae98c4a79ed91cd77f..c9445fac697099aee1ed8323a7bad8e2a3f038fc 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Address/Edit.xml +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Address/Edit.xml @@ -29,9 +29,9 @@ <lastname /> <company /> <telephone /> - <street_1> + <street> <selector>#street_1</selector> - </street_1> + </street> <city /> <region_id> <input>select</input> diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Store/Actions.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Form/CustomerForm.php similarity index 70% rename from dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Store/Actions.php rename to dev/tests/functional/tests/app/Magento/Customer/Test/Block/Form/CustomerForm.php index a877c7b542564763c2822f9fabaa0ad014a90d71..46aa3b0f48b1be6c6203e1c7220b64dbb80e9626 100644 --- a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Store/Actions.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Form/CustomerForm.php @@ -1,7 +1,5 @@ <?php /** - * Store actions block - * * Magento * * NOTICE OF LICENSE @@ -23,38 +21,37 @@ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ -namespace Magento\Backend\Test\Block\System\Store; -use Mtf\Block\Block; +namespace Magento\Customer\Test\Block\Form; + +use Mtf\Block\Form; -class Actions extends Block +/** + * Class CustomerForm + * Customer account edit form + */ +class CustomerForm extends Form { /** - * Save button + * Save button button css selector * * @var string */ - protected $saveButton = '#save'; + protected $saveButton = '[type="submit"]'; /** - * Add Store button + * Locator for customer attribute on Edit Account Information page * * @var string */ - protected $addStoreButton = '#add_store'; - - /** - * Add store - */ - public function addStoreView() - { - $this->_rootElement->find($this->addStoreButton)->click(); - } + protected $customerAttribute = "[name='%s[]']"; /** - * Click "Save" button + * Click on save button + * + * @return void */ - public function clickSave() + public function submit() { $this->_rootElement->find($this->saveButton)->click(); } diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Form/CustomerForm.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Form/CustomerForm.xml new file mode 100644 index 0000000000000000000000000000000000000000..65bf5562f40438d336e6d379d7a5d31528bd766a --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Form/CustomerForm.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" ?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<mapping strict="0"> + <fields> + <firstname /> + <lastname /> + <email /> + </fields> +</mapping> diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Form/Register.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Form/Register.php index e49ebe26969aaa3923b59c6c50c4cb238232f070..0fa8b89b81282f997d1f2168788b5c0038b62def 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Form/Register.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Form/Register.php @@ -31,7 +31,6 @@ use Mtf\Fixture\FixtureInterface; /** * Class Register * Register new customer on Frontend - * */ class Register extends Form { @@ -42,6 +41,13 @@ class Register extends Form */ protected $submit = '.action.submit'; + /** + * Locator for customer attribute on New Order page + * + * @var string + */ + protected $customerAttribute = "[name='%s']"; + /** * Create new customer account and fill billing address if it exists * diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Form/Register.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Form/Register.xml index 5809ede11fb8e82b0a2c39e52f11701220dfdb9f..cbef022f1223496f4cc62f5bc3d936d1e742259c 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Form/Register.xml +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Form/Register.xml @@ -30,9 +30,9 @@ <email /> <company /> <telephone /> - <street_1> + <street> <selector>#street_1</selector> - </street_1> + </street> <city /> <region_id> <input>select</input> diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerAddressSuccessSaveMessage.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerAddressSuccessSaveMessage.php new file mode 100644 index 0000000000000000000000000000000000000000..d23bdd6c0d041f063eb738ca62b45494f58cb2c7 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerAddressSuccessSaveMessage.php @@ -0,0 +1,71 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Customer\Test\Constraint; + +use Mtf\Constraint\AbstractConstraint; +use Magento\Customer\Test\Page\CustomerAccountIndex; + +/** + * Class AssertCustomerAddressSuccessSaveMessage + */ +class AssertCustomerAddressSuccessSaveMessage extends AbstractConstraint +{ + const SUCCESS_MESSAGE = 'The address has been saved.'; + + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Asserts that success message equals to expected message + * + * @param CustomerAccountIndex $customerAccountIndex + * @return void + */ + public function processAssert(CustomerAccountIndex $customerAccountIndex) + { + $successMessage = $customerAccountIndex->getMessages()->getSuccessMessages(); + \PHPUnit_Framework_Assert::assertEquals( + self::SUCCESS_MESSAGE, + $successMessage, + 'Wrong success message is displayed.' + . "\nExpected: " . self::SUCCESS_MESSAGE + . "\nActual: " . $successMessage + ); + } + + /** + * Returns success message if equals to expected message + * + * @return string + */ + public function toString() + { + return 'Success address save message on customer account index page is correct.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerDefaultAddresses.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerDefaultAddresses.php new file mode 100644 index 0000000000000000000000000000000000000000..5efcb572fd49744c23d31fe20a701acc36156dd2 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerDefaultAddresses.php @@ -0,0 +1,123 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Customer\Test\Constraint; + +use Magento\Customer\Test\Fixture\AddressInjectable; +use Mtf\Constraint\AbstractConstraint; +use Magento\Customer\Test\Page\CustomerAccountIndex; + +/** + * Class AssertCustomerDefaultAddresses + */ +class AssertCustomerDefaultAddresses extends AbstractConstraint +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Asserts that Default Billing Address and Default Shipping Address equal to data from fixture + * + * @param CustomerAccountIndex $customerAccountIndex + * @param AddressInjectable $address + * @return void + */ + public function processAssert(CustomerAccountIndex $customerAccountIndex, AddressInjectable $address) + { + $defaultBillingAddress = explode( + "\n", + $customerAccountIndex->getDashboardAddress()->getDefaultBillingAddressText() + ); + $defaultShippingAddress = explode( + "\n", + $customerAccountIndex->getDashboardAddress()->getDefaultShippingAddressText() + ); + $pattern = $this->makeAddressPattern($address); + $billingDataDiff = $this->verifyForm($pattern, $defaultBillingAddress); + $shippingDataDiff = $this->verifyForm($pattern, $defaultShippingAddress); + $dataDiff = array_merge($billingDataDiff, $shippingDataDiff); + + \PHPUnit_Framework_Assert::assertEmpty( + $dataDiff, + 'Billing or shipping form was filled incorrectly.' + . "\nLog:\n" . implode(";\n", $dataDiff) + ); + } + + /** + * String representation of success assert + * + * @return string + */ + public function toString() + { + return 'Default billing and shipping address form is correct.'; + } + + /** + * Verifying that form is filled correctly + * + * @param array $pattern + * @param array $address + * @return array + */ + protected function verifyForm(array $pattern, array $address) + { + $errorMessages = []; + foreach ($pattern as $key => $value) { + if ($value !== $address[$key]) { + $errorMessages[] = "Data in fields is not equal." + . "\nExpected: " . $value + . "\nActual: " . $pattern[$key]; + } + } + return $errorMessages; + } + + /** + * Make pattern for form verifying + * + * @param AddressInjectable $address + * @return array + */ + protected function makeAddressPattern(AddressInjectable $address) + { + $pattern = []; + $regionId = $address->getRegionId(); + $region = $regionId ? $regionId: $address->getRegion(); + + $pattern[] = $address->getFirstname() . " " . $address->getLastname(); + $pattern[] = $address->getCompany(); + $pattern[] = $address->getStreet(); + $pattern[] = $address->getCity() . ", " . $region . ", " . $address->getPostcode(); + $pattern[] = $address->getCountryId(); + $pattern[] = "T: " . $address->getTelephone(); + $pattern[] = "F: " . $address->getFax(); + return $pattern; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerInfoSuccessSavedMessage.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerInfoSuccessSavedMessage.php new file mode 100644 index 0000000000000000000000000000000000000000..2dce65abd7328eb8ab71cae34ac35a0aafb8e4ac --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerInfoSuccessSavedMessage.php @@ -0,0 +1,71 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Customer\Test\Constraint; + +use Magento\Customer\Test\Page\CustomerAccountIndex; +use Mtf\Constraint\AbstractConstraint; + +/** + * Class AssertCustomerInfoSuccessSavedMessage + */ +class AssertCustomerInfoSuccessSavedMessage extends AbstractConstraint +{ + const SUCCESS_MESSAGE = 'The account information has been saved.'; + + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Asserts that success message equals to expected message + * + * @param CustomerAccountIndex $customerAccountIndex + * @return void + */ + public function processAssert(CustomerAccountIndex $customerAccountIndex) + { + $successMessage = $customerAccountIndex->getMessages()->getSuccessMessages(); + \PHPUnit_Framework_Assert::assertEquals( + self::SUCCESS_MESSAGE, + $successMessage, + 'Wrong success message is displayed.' + . "\nExpected: " . self::SUCCESS_MESSAGE + . "\nActual: " . $successMessage + ); + } + + /** + * Returns success message if equals to expected message + * + * @return string + */ + public function toString() + { + return 'Success customer info save message on customer account index page is correct.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/Address.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/Address.php index ee399ef8aaa7efca33d6911841669839c3a3010e..740aba7e777d73a1e1e3660ac64f299c551827d8 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/Address.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/Address.php @@ -53,7 +53,7 @@ class Address extends DataFixture . (isset($data['fields']['middlename']['value']) ? $data['fields']['middlename']['value'] . ' ' : '') . $data['fields']['lastname']['value'] . ', ' . (isset($data['fields']['suffix']['value']) ? $data['fields']['suffix']['value'] . ' ' : '') - . $data['fields']['street_1']['value'] . ', ' + . $data['fields']['street']['value'] . ', ' . $data['fields']['city']['value'] . ', ' . $data['fields']['region_id']['value'] . ' ' . $data['fields']['postcode']['value'] . ', ' diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/AddressBook.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/AddressBook.php index 58edc8d459c0e0a6efcbb53e2ef963cd91193281..d9e08439f22bd1048da826431d914984e34cb9cf 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/AddressBook.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/AddressBook.php @@ -67,7 +67,7 @@ class AddressBook extends \Mtf\Fixture\DataFixture $this->_data = array('fields' => array('address_id' => array( 'value' => $data['fields']['firstname']['value'] . ' ' . $data['fields']['lastname']['value'] . ', ' - . $data['fields']['street_1']['value'] . ', ' + . $data['fields']['street']['value'] . ', ' . $data['fields']['city']['value'] . ', ' . $data['fields']['region_id']['value'] . ' ' . $data['fields']['postcode']['value'] . ', ' diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/CustomerInjectable.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/CustomerInjectable.php index e493d886dd1e48fab0b4138bb87591839a4a6141..910c8760105de9b140cd46c560e98c94a772e40b 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/CustomerInjectable.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/CustomerInjectable.php @@ -60,6 +60,12 @@ class CustomerInjectable extends InjectableFixture 'input' => 'text', ]; + protected $id = [ + 'attribute_code' => 'id', + 'backend_type' => 'virtual', + 'group' => null, + ]; + protected $created_at = [ 'attribute_code' => 'created_at', 'backend_type' => 'static', @@ -234,6 +240,15 @@ class CustomerInjectable extends InjectableFixture 'group' => 'account_information', ]; + protected $amount_delta = [ + 'attribute_code' => 'amount_delta', + 'backend_type' => 'static', + 'is_required' => '1', + 'default_value' => '', + 'input' => 'text', + 'group' => 'store_credit', + ]; + protected $is_subscribed = [ 'attribute_code' => 'is_subscribed', 'backend_type' => 'virtual', @@ -242,11 +257,13 @@ class CustomerInjectable extends InjectableFixture protected $password = [ 'attribute_code' => 'password', 'backend_type' => 'virtual', + 'group' => null, ]; protected $password_confirmation = [ 'attribute_code' => 'password_confirmation', 'backend_type' => 'virtual', + 'group' => null, ]; public function getConfirmation() @@ -319,6 +336,11 @@ class CustomerInjectable extends InjectableFixture return $this->getData('password_hash'); } + public function getAmountDelta() + { + return $this->getData('amount_delta'); + } + public function getPrefix() { return $this->getData('prefix'); diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/CustomerInjectable.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/CustomerInjectable.xml index 439a6cb0d5d27662a3af8c24ebc08e5312eea0d3..5953126c4a8ca0e01b6180a17e4fdbd23df11135 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/CustomerInjectable.xml +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/CustomerInjectable.xml @@ -44,6 +44,11 @@ <default_value></default_value> <input>date</input> </created_at> + <id> + <attribute_code>id</attribute_code> + <backend_type>virtual</backend_type> + <group>null</group> + </id> <created_in> <attribute_code>created_in</attribute_code> <backend_type>varchar</backend_type> @@ -183,6 +188,14 @@ <input>text</input> <group>account_information</group> </taxvat> + <amount_delta> + <attribute_code>amount_delta</attribute_code> + <backend_type>varchar</backend_type> + <is_required>0</is_required> + <default_value></default_value> + <input>text</input> + <group>store_credit</group> + </amount_delta> <website_id> <attribute_code>website_id</attribute_code> <backend_type>static</backend_type> diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAccountEdit.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAccountEdit.php new file mode 100644 index 0000000000000000000000000000000000000000..98dca9d9a249928771c5e042dd007a1d3630d129 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAccountEdit.php @@ -0,0 +1,53 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Customer\Test\Page; + +use Mtf\Page\FrontendPage; + +/** + * Class CustomerAccountEdit + * Customer account info edit page + */ +class CustomerAccountEdit extends FrontendPage +{ + const MCA = 'customer/account/edit'; + + protected $_blocks = [ + 'accountInfoForm' => [ + 'name' => 'accountInfoForm', + 'class' => 'Magento\Customer\Test\Block\Form\CustomerForm', + 'locator' => '#form-validate', + 'strategy' => 'css selector', + ], + ]; + + /** + * @return \Magento\Customer\Test\Block\Form\CustomerForm + */ + public function getAccountInfoForm() + { + return $this->getBlockInstance('accountInfoForm'); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAccountEdit.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAccountEdit.xml new file mode 100644 index 0000000000000000000000000000000000000000..4309564d602be74dced7d1b6f5f4b2e15857984b --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAccountEdit.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" ?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<page mca="customer/account/edit" > + <block> + <name>accountInfoForm</name> + <class>Magento\Customer\Test\Block\Form\CustomerForm</class> + <locator>#form-validate</locator> + <strategy>css selector</strategy> + </block> +</page> diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAccountIndex.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAccountIndex.php index ab1e5b4281214a8cea16fc8d0637cc7381d01778..f1001498cf7b64231182e9b3e0ee98b77f498415 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAccountIndex.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAccountIndex.php @@ -45,7 +45,7 @@ class CustomerAccountIndex extends FrontendPage 'dashboardAddress' => [ 'name' => 'dashboardAddress', 'class' => 'Magento\Customer\Test\Block\Account\Dashboard\Address', - 'locator' => '.block.dashboard.addresses', + 'locator' => '.block-dashboard-addresses', 'strategy' => 'css selector', ], 'titleBlock' => [ @@ -60,6 +60,18 @@ class CustomerAccountIndex extends FrontendPage 'locator' => '.nav.items', 'strategy' => 'css selector', ], + 'infoBlock' => [ + 'name' => 'infoBlock', + 'class' => 'Magento\Customer\Test\Block\Account\Dashboard\Info', + 'locator' => '.column.main', + 'strategy' => 'css selector', + ], + 'compareProductsBlock' => [ + 'name' => 'compareProductsBlock', + 'class' => 'Magento\Catalog\Test\Block\Product\Compare\Sidebar', + 'locator' => '.block.compare', + 'strategy' => 'css selector', + ], ]; /** @@ -95,4 +107,24 @@ class CustomerAccountIndex extends FrontendPage { return $this->getBlockInstance('accountMenuBlock'); } + + /** + * Get Account Info Block + * + * @return \Magento\Customer\Test\Block\Account\Dashboard\Info + */ + public function getInfoBlock() + { + return $this->getBlockInstance('infoBlock'); + } + + /** + * Get compare products block + * + * @return \Magento\Catalog\Test\Block\Product\Compare\Sidebar + */ + public function getCompareProductsBlock() + { + return $this->getBlockInstance('compareProductsBlock'); + } } diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAccountIndex.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAccountIndex.xml index a550144c4b2731013344f1b420de5d29afa84ca5..26fe9095fdad2670b178d23abbcd1282e27d654b 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAccountIndex.xml +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAccountIndex.xml @@ -33,7 +33,7 @@ <block> <name>dashboardAddress</name> <class>Magento\Customer\Test\Block\Account\Dashboard\Address</class> - <locator>.block.dashboard.addresses</locator> + <locator>.block-dashboard-addresses</locator> <strategy>css selector</strategy> </block> <block> @@ -48,4 +48,16 @@ <locator>.nav.items</locator> <strategy>css selector</strategy> </block> + <block> + <name>infoBlock</name> + <class>Magento\Customer\Test\Block\Account\Dashboard\Info</class> + <locator>.column.main</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>compareProductsBlock</name> + <class>Magento\Catalog\Test\Block\Product\Compare\Sidebar</class> + <locator>.block.compare</locator> + <strategy>css selector</strategy> + </block> </page> diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Repository/Address.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Repository/Address.php index 29fa24e366e176067d0b9da8011124423e1d013a..be9ded8b623f15666fe0ff580a7fc8b0ad2bd4ac 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/Repository/Address.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Repository/Address.php @@ -69,7 +69,7 @@ class Address extends AbstractRepository 'company' => array( 'value' => 'Magento %isolation%' ), - 'street_1' => array( + 'street' => array( 'value' => '6161 West Centinela Avenue' ), 'city' => array( @@ -125,7 +125,7 @@ class Address extends AbstractRepository 'company' => array( 'value' => 'Magento %isolation%' ), - 'street_1' => array( + 'street' => array( 'value' => '727 5th Ave' ), 'city' => array( @@ -164,7 +164,7 @@ class Address extends AbstractRepository 'company' => array( 'value' => 'Magento %isolation%' ), - 'street_1' => array( + 'street' => array( 'value' => '6161 West Centinela Avenue' ), 'country_id' => array( @@ -255,7 +255,7 @@ class Address extends AbstractRepository 'telephone' => array( 'value' => '444-44-444-44' ), - 'street_1' => array( + 'street' => array( 'value' => '42 King Street West' ), 'country_id' => array( @@ -323,7 +323,7 @@ class Address extends AbstractRepository 'value' => 'Germany', 'input' => 'select' ), - 'street_1' => array( + 'street' => array( 'value' => 'Augsburger Strabe 41' ), 'city' => array( diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Repository/CustomerInjectable.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Repository/CustomerInjectable.php index 9c271b32400431e7d6b8d64a2262aba34c35834a..85e4d3cf880f2437935b41709d10408416e9e746 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/Repository/CustomerInjectable.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Repository/CustomerInjectable.php @@ -28,8 +28,7 @@ use Mtf\Repository\AbstractRepository; /** * Class CustomerInjectable - * - * @package Magento\Customer\Test\Repository + * Customer repository */ class CustomerInjectable extends AbstractRepository { @@ -49,6 +48,38 @@ class CustomerInjectable extends AbstractRepository 'password_confirmation' => '123123q', ]; + $this->_data['johndoe'] = [ + 'firstname' => 'John', + 'lastname' => 'Doe', + 'email' => 'JohnDoe_%isolation%@example.com', + 'password' => '123123q', + 'password_confirmation' => '123123q', + 'dob' => '01/01/1990', + 'gender' => 'Male', + ]; + + $this->_data['johndoe_retailer'] = [ + 'firstname' => 'John', + 'lastname' => 'Doe', + 'group_id' => 'Retailer', + 'email' => 'JohnDoe_%isolation%@example.com', + 'password' => '123123q', + 'password_confirmation' => '123123q', + 'dob' => '01/01/1990', + 'gender' => 'Male', + ]; + + $this->_data['johndoe_with_balance'] = [ + 'firstname' => 'John', + 'lastname' => 'Doe', + 'email' => 'JohnDoe_%isolation%@example.com', + 'password' => '123123q', + 'password_confirmation' => '123123q', + 'dob' => '01/01/1990', + 'gender' => 'Male', + 'amount_delta' => 501 + ]; + $this->_data['defaultBackend'] = [ 'firstname' => 'John', 'lastname' => 'Doe', diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerFrontendEntity.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerFrontendEntity.php new file mode 100644 index 0000000000000000000000000000000000000000..da3a56dd0a0c7640894999cbf3ba8e2480b50b8d --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerFrontendEntity.php @@ -0,0 +1,174 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Customer\Test\TestCase; + +use Magento\Customer\Test\Constraint\AssertCustomerInfoSuccessSavedMessage; +use Magento\Customer\Test\Fixture\AddressInjectable; +use Magento\Customer\Test\Fixture\CustomerInjectable; +use Magento\Customer\Test\Page\CustomerAccountEdit; +use Magento\Customer\Test\Page\CustomerAccountIndex; +use Magento\Customer\Test\Page\CustomerAddressEdit; +use Mtf\TestCase\Injectable; +use Mtf\Fixture\FixtureFactory; +use Magento\Cms\Test\Page\CmsIndex; +use Magento\Customer\Test\Page\CustomerAccountLogin; + +/** + * Test Creation for UpdateCustomerFrontendEntity + * + * Test Flow: + * Preconditions: + * 1. Default test customer is created + * + * Steps: + * 1. Login to fronted as test customer from preconditions + * 2. Navigate to Account Dashboard page: + * 3. Click "Edit" link near "Contact Information" + * 4. Fill fields with test data and save + * 5. Click "Edit Address" link near "Default Billing Address", save and return to Account Dashboard page + * 6. Fill fields with test data and save + * 7. Perform all assertions + * + * @group Customer_Account_(CS) + * @ZephyrId MAGETWO-25925 + */ +class UpdateCustomerFrontendEntity extends Injectable +{ + /** + * Factory for Fixtures + * + * @var FixtureFactory + */ + protected $fixtureFactory; + + /** + * CmsIndex page + * + * @var CmsIndex + */ + protected $cmsIndex; + + /** + * CustomerAccountLogin page + * + * @var CustomerAccountLogin + */ + protected $customerAccountLogin; + + /** + * CustomerAccountIndex page + * + * @var CustomerAccountIndex + */ + protected $customerAccountIndex; + + /** + * CustomerAccountEdit page + * + * @var CustomerAccountEdit + */ + protected $customerAccountEdit; + + /** + * CustomerAddressEdit page + * + * @var CustomerAddressEdit + */ + protected $customerAddressEdit; + + /** + * Preparing data for test + * + * @param CmsIndex $cmsIndex + * @param FixtureFactory $fixtureFactory + * @param CustomerAccountLogin $customerAccountLogin + * @param CustomerAccountIndex $customerAccountIndex + * @param CustomerAccountEdit $customerAccountEdit + * @param CustomerAddressEdit $customerAddressEdit + * @return void + */ + public function __inject( + CmsIndex $cmsIndex, + FixtureFactory $fixtureFactory, + CustomerAccountLogin $customerAccountLogin, + CustomerAccountIndex $customerAccountIndex, + CustomerAccountEdit $customerAccountEdit, + CustomerAddressEdit $customerAddressEdit + ) { + $this->cmsIndex = $cmsIndex; + $this->fixtureFactory = $fixtureFactory; + $this->customerAccountLogin = $customerAccountLogin; + $this->customerAccountIndex = $customerAccountIndex; + $this->customerAccountEdit = $customerAccountEdit; + $this->customerAddressEdit = $customerAddressEdit; + } + + /** + * Run Update Customer Entity test + * + * @param CustomerInjectable $initialCustomer + * @param CustomerInjectable $customer + * @param AddressInjectable $address + * @param AssertCustomerInfoSuccessSavedMessage $assertCustomerInfoSuccessSavedMessage + * @return void + */ + public function test( + CustomerInjectable $initialCustomer, + CustomerInjectable $customer, + AddressInjectable $address, + AssertCustomerInfoSuccessSavedMessage $assertCustomerInfoSuccessSavedMessage + ) { + // Preconditions + $initialCustomer->persist(); + + // Steps + $this->cmsIndex->open(); + $this->cmsIndex->getLinksBlock()->openLink('Log In'); + $this->customerAccountLogin->getLoginBlock()->fill($initialCustomer); + $this->customerAccountLogin->getLoginBlock()->submit(); + + $this->customerAccountIndex->getInfoBlock()->openEditContactInfo(); + $this->customerAccountEdit->getAccountInfoForm()->fill($customer); + $this->customerAccountEdit->getAccountInfoForm()->submit(); + + \PHPUnit_Framework_Assert::assertThat($this->getName(), $assertCustomerInfoSuccessSavedMessage); + + $this->customerAccountIndex->getDashboardAddress()->editBillingAddress(); + $this->customerAddressEdit->getEditForm()->fill($address); + $this->customerAddressEdit->getEditForm()->saveAddress(); + } + + /** + * Customer logout from account + * + * @return void + */ + public function tearDown() + { + if ($this->cmsIndex->getLinksBlock()->isVisible()) { + $this->cmsIndex->getLinksBlock()->openLink('Log Out'); + } + } +} diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerFrontendEntity/test.csv b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerFrontendEntity/test.csv new file mode 100644 index 0000000000000000000000000000000000000000..739a564e68628dcdbfc136e38b3f4c9c89335c20 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerFrontendEntity/test.csv @@ -0,0 +1,3 @@ +"customer/data/firstname";"customer/data/lastname";"customer/data/email";"address/data/firstname";"address/data/lastname";"address/data/company";"address/data/street";"address/data/city";"address/data/country_id";"address/data/region_id";"address/data/region";"address/data/telephone";"address/data/fax";"address/data/postcode";"constraint" +"Jany %isolation%";"Doe %isolation%";"janydoe%isolation%@example.com";"Jany %isolation%";"Doe %isolation%";"Company %isolation%";"Some street %isolation%";"City %isolation%";"United States";"Colorado";"-";"555-888-111-999";"161-999-8888";"12345";"assertCustomerAddressSuccessSaveMessage, assertCustomerDefaultAddresses" +"Jonny %isolation%";"Doe %isolation%";"jonny%isolation%@example.com";"John %isolation%";"Doe %isolation%";"Company %isolation%";"Some street %isolation%";"City %isolation%";"United Kingdom";"-";"Region %isolation%";"0123456789-02134567";"5555-874-99634";"12345";"assertCustomerAddressSuccessSaveMessage, assertCustomerDefaultAddresses" diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/etc/global/constraint.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/etc/global/constraint.xml index 87100e00439d0fdd00d444a86aa46bdcaa3129b7..a235bf6c8a7a2a22061b407ddb4393c5c1e4f66e 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/etc/global/constraint.xml +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/etc/global/constraint.xml @@ -102,4 +102,23 @@ <assertCustomerGroupForm module="Magento_Customer"> <severeness>low</severeness> </assertCustomerGroupForm> + <assertCustomerInfoSuccessSavedMessage module="Magento_Customer"> + <severeness>low</severeness> + <require> + <customerAccountIndex class="Magento\Customer\Test\Page\CustomerAccountIndex" /> + </require> + </assertCustomerInfoSuccessSavedMessage> + <assertCustomerAddressSuccessSaveMessage module="Magento_Customer"> + <severeness>low</severeness> + <require> + <customerAccountIndex class="Magento\Customer\Test\Page\CustomerAccountIndex" /> + </require> + </assertCustomerAddressSuccessSaveMessage> + <assertCustomerDefaultAddresses module="Magento_Customer"> + <severeness>low</severeness> + <require> + <customerAccountIndex class="Magento\Customer\Test\Page\CustomerAccountIndex" /> + <address class="Magento\Customer\Test\Fixture\AddressInjectable" /> + </require> + </assertCustomerDefaultAddresses> </constraint> diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/etc/global/page.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/etc/global/page.xml index 968424e9029fb5f5757530d32ad8fd2b19dd9c17..c1ef19574065900460016eb4698ecbc9d82e5a6a 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/etc/global/page.xml +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/etc/global/page.xml @@ -32,6 +32,10 @@ <mca>customer/account/index</mca> <class>Magento\Customer\Test\Page\CustomerAccountIndex</class> </customerAccountIndex> + <customerAccountEdit> + <mca>customer/account/edit</mca> + <class>Magento\Customer\Test\Page\CustomerAccountEdit</class> + </customerAccountEdit> <customerIndex> <mca>customer/index</mca> <area>adminhtml</area> diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Constraint/AssertDownloadableDuplicateForm.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Constraint/AssertDownloadableDuplicateForm.php new file mode 100644 index 0000000000000000000000000000000000000000..b831d11b23e7ad4bc32947a51a9b83869c37d2d6 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Constraint/AssertDownloadableDuplicateForm.php @@ -0,0 +1,110 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Downloadable\Test\Constraint; + +use Mtf\Fixture\FixtureInterface; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex; +use Magento\Catalog\Test\Constraint\AssertProductDuplicateForm; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductEdit; + +/** + * Class AssertDownloadableDuplicateForm + */ +class AssertDownloadableDuplicateForm extends AssertProductDuplicateForm +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Assert form data equals duplicate product downloadable data + * + * @param FixtureInterface $product + * @param CatalogProductIndex $productGrid + * @param CatalogProductEdit $productPage + * @return void + */ + public function processAssert( + FixtureInterface $product, + CatalogProductIndex $productGrid, + CatalogProductEdit $productPage + ) { + $filter = ['sku' => $product->getSku() . '-1']; + $productGrid->open()->getProductGrid()->searchAndOpen($filter); + + $formData = $productPage->getForm()->getData($product); + $fixtureData = $this->convertDownloadableArray($this->prepareFixtureData($product->getData())); + $errors = $this->verifyData($fixtureData, $formData); + + \PHPUnit_Framework_Assert::assertEmpty($errors, $errors); + } + + /** + * Sort downloadable array + * + * @param array $fields + * @return array + */ + protected function sortDownloadableArray(array $fields) + { + usort( + $fields, + function ($row1, $row2) { + if ($row1['sort_order'] == $row2['sort_order']) { + return 0; + } + + return ($row1['sort_order'] < $row2['sort_order']) ? -1 : 1; + } + ); + + return $fields; + } + + /** + * Convert fixture array + * + * @param array $fields + * @return array + */ + protected function convertDownloadableArray(array $fields) + { + if (isset($fields['downloadable_links']['downloadable']['link'])) { + $fields['downloadable_links']['downloadable']['link'] = $this->sortDownloadableArray( + $fields['downloadable_links']['downloadable']['link'] + ); + } + if (isset($fields['downloadable_sample']['downloadable']['sample'])) { + $fields['downloadable_sample']['downloadable']['sample'] = $this->sortDownloadableArray( + $fields['downloadable_sample']['downloadable']['sample'] + ); + } + + return $fields; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Constraint/AssertDownloadableProductForm.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Constraint/AssertDownloadableProductForm.php old mode 100644 new mode 100755 index f66ca5e12877e1ca3bb3c45bf2290f9937de5627..c52f86168016c2e3e3c7ce92ad9dab9f38722659 --- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Constraint/AssertDownloadableProductForm.php +++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Constraint/AssertDownloadableProductForm.php @@ -24,10 +24,10 @@ namespace Magento\Downloadable\Test\Constraint; -use Magento\Catalog\Test\Constraint\AssertProductForm; use Mtf\Fixture\FixtureInterface; -use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex; +use Magento\Catalog\Test\Constraint\AssertProductForm; use Magento\Catalog\Test\Page\Adminhtml\CatalogProductEdit; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex; /** * Class AssertDownloadableProductForm @@ -35,6 +35,13 @@ use Magento\Catalog\Test\Page\Adminhtml\CatalogProductEdit; */ class AssertDownloadableProductForm extends AssertProductForm { + /** + * Sort fields for fixture and form data + * + * @var array + */ + protected $sortFields = ['downloadable_links/downloadable/link::sort_order']; + /** * Constraint severeness * @@ -58,51 +65,10 @@ class AssertDownloadableProductForm extends AssertProductForm $filter = ['sku' => $product->getData('sku')]; $productGrid->open()->getProductGrid()->searchAndOpen($filter); - $fields = $this->convertDownloadableArray($this->prepareFixtureData($product)); - - $fieldsForm = $productPage->getForm()->getData($product); - \PHPUnit_Framework_Assert::assertEquals($fields, $fieldsForm, 'Form data not equals fixture data.'); - } - - /** - * Sort downloadable array - * - * @param array $fields - * @return array - */ - protected function sortDownloadableArray(&$fields) - { - usort( - $fields, - function ($row1, $row2) { - if ($row1['sort_order'] == $row2['sort_order']) { - return 0; - } - return ($row1['sort_order'] < $row2['sort_order']) ? -1 : 1; - } - ); - } - - /** - * Convert fixture array - * - * @param array $fields - * @return array - */ - protected function convertDownloadableArray(array $fields) - { - if (isset($fields['downloadable_links']['downloadable']['link'])) { - $this->sortDownloadableArray( - $fields['downloadable_links']['downloadable']['link'] - ); - } - if (isset($fields['downloadable_sample']['downloadable']['sample'])) { - $this->sortDownloadableArray( - $fields['downloadable_sample']['downloadable']['sample'] - ); - } - - return $fields; + $fieldsFixture = $this->prepareFixtureData($product->getData(), $this->sortFields); + $fieldsForm = $this->prepareFormData($productPage->getForm()->getData($product), $this->sortFields); + $error = $this->verifyData($fieldsFixture, $fieldsForm); + \PHPUnit_Framework_Assert::assertEmpty($error, $error); } /** diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/CatalogProductDownloadable.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/CatalogProductDownloadable.php index 8194ce7e3e85aaa74be140c1c1bb1866db1bab72..cee9b2e3e56186ae0a9ea354731905d1812a72b0 100644 --- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/CatalogProductDownloadable.php +++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/CatalogProductDownloadable.php @@ -381,13 +381,8 @@ class CatalogProductDownloadable extends InjectableFixture 'is_required' => '1', 'default_value' => '', 'input' => 'price', - 'group' => 'product-details' - ]; - - protected $inventory_manage_stock = [ - 'attribute_code' => 'inventory_manage_stock', - 'input' => 'select', - 'group' => 'advanced-inventory', + 'group' => 'product-details', + 'source' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\Price', ]; protected $stock_data = [ @@ -396,24 +391,6 @@ class CatalogProductDownloadable extends InjectableFixture 'group' => 'advanced-inventory', ]; - protected $stock_data_min_qty = [ - 'attribute_code' => 'stock_data', - 'input' => 'text', - 'group' => 'advanced-inventory', - ]; - - protected $stock_data_use_config_min_qty = [ - 'attribute_code' => 'stock_data_use_config_min_qty', - 'input' => 'checkbox', - 'group' => 'advanced-inventory' - ]; - - protected $inventory_qty = [ - 'attribute_code' => 'inventory_qty', - 'input' => 'text', - 'group' => 'advanced-inventory', - ]; - protected $quantity_and_stock_status = [ 'attribute_code' => 'quantity_and_stock_status', 'backend_type' => 'int', @@ -666,7 +643,9 @@ class CatalogProductDownloadable extends InjectableFixture protected $website_ids = [ 'attribute_code' => 'website_ids', - 'backend_type' => 'virtual' + 'backend_type' => 'virtual', + 'default_value' => ['Main Website'], + 'group' => 'websites', ]; public function getCategoryIds() diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/CatalogProductDownloadable.xml b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/CatalogProductDownloadable.xml old mode 100644 new mode 100755 index 34b7746109a689b15c2c8c87b8d062ee4669f6aa..e83b7dea98518d8a973b6e8a2ca688d787f4d6ab --- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/CatalogProductDownloadable.xml +++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/CatalogProductDownloadable.xml @@ -86,6 +86,7 @@ <is_required>0</is_required> <default_value></default_value> <input>textarea</input> + <group>product-details</group> </description> <gallery> <attribute_code>gallery</attribute_code> @@ -261,6 +262,7 @@ <is_required>1</is_required> <default_value></default_value> <input>price</input> + <source>Magento\Catalog\Test\Fixture\CatalogProductSimple\Price</source> </price> <related_tgtr_position_behavior> <attribute_code>related_tgtr_position_behavior</attribute_code> @@ -296,6 +298,7 @@ <is_required>0</is_required> <default_value></default_value> <input>textarea</input> + <group>autosetting</group> </short_description> <sku> <attribute_code>sku</attribute_code> @@ -448,6 +451,12 @@ <attribute_code>stock_data_min_qty</attribute_code> <input>text</input> </stock_data_min_qty> + <website_ids> + <attribute_code>website_ids</attribute_code> + <backend_type>virtual</backend_type> + <default_value>Main Website</default_value> + <group>websites</group> + </website_ids> </fields> <data_set> <sku></sku> diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/DownloadableProduct.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/DownloadableProduct.php index 2cf30517f9034c5632773127c6470e14d125294b..29d7bc57ff924bc300a0755ed02df7918575502f 100644 --- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/DownloadableProduct.php +++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/DownloadableProduct.php @@ -59,7 +59,26 @@ class DownloadableProduct extends Product 'price' => [ 'value' => '1', 'group' => static::GROUP_PRODUCT_DETAILS - ] + ], + 'qty' => array( + 'value' => 1000, + 'group' => static::GROUP_PRODUCT_DETAILS, + 'input_name' => 'product[quantity_and_stock_status][qty]' + ), + 'quantity_and_stock_status' => array( + 'value' => 'In Stock', + 'input_value' => 1, + 'group' => static::GROUP_PRODUCT_DETAILS, + 'input_name' => 'product[quantity_and_stock_status][is_in_stock]' + ), + 'product_website_1' => array( + 'value' => 'Yes', + 'input_value' => 1, + 'group' => static::GROUP_PRODUCT_WEBSITE, + 'input' => 'checkbox', + 'input_name' => 'product[website_ids][]' + ), + ); $this->_data['fields'] = $data + $this->_data['fields']; diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Handler/CatalogProductDownloadable/Curl.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Handler/CatalogProductDownloadable/Curl.php index ca5aead81bec4fcdbd4acdd85037a61be6cdcaa7..917ec398302d271c917bc19767f7252a637c98e9 100644 --- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Handler/CatalogProductDownloadable/Curl.php +++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Handler/CatalogProductDownloadable/Curl.php @@ -66,10 +66,40 @@ class Curl extends ProductCurl implements CatalogProductDownloadableInterface protected function prepareData(FixtureInterface $fixture, $prefix = null) { $data = parent::prepareData($fixture, null); - $downloadable = $data['downloadable']; - unset($data['downloadable']); + + $downloadableData = []; + if (!empty($data['downloadable_links'])) { + $data['links_title'] = $data['downloadable_links']['title']; + foreach ($data['downloadable_links']['downloadable']['link'] as $key => $link) { + $downloadableData['downloadable']['link'][$key]['title'] = $link['title']; + // only url type + $downloadableData['downloadable']['link'][$key]['type'] = 'url'; + $downloadableData['downloadable']['link'][$key]['link_url'] = $link['file_link_url']; + $downloadableData['downloadable']['link'][$key]['price'] = $link['price']; + $downloadableData['downloadable']['link'][$key]['number_of_downloads'] = $link['number_of_downloads']; + $downloadableData['downloadable']['link'][$key]['is_shareable'] = $link['is_shareable']; + $downloadableData['downloadable']['link'][$key]['sort_order'] = $link['sort_order']; + // only url type + $downloadableData['downloadable']['link'][$key]['sample']['type'] = 'url'; + $downloadableData['downloadable']['link'][$key]['sample']['url'] = $link['sample']['sample_url']; + } + unset($data['downloadable_links']); + } + + if (!empty($data['downloadable_sample'])) { + $data['samples_title'] = $data['downloadable_sample']['title']; + foreach ($data['downloadable_sample']['downloadable']['sample'] as $key => $sample) { + $downloadableData['downloadable']['sample'][$key]['title'] = $sample['title']; + // only url type + $downloadableData['downloadable']['sample'][$key]['type'] = 'url'; + $downloadableData['downloadable']['sample'][$key]['sample_url'] = $sample['sample_url']; + $downloadableData['downloadable']['sample'][$key]['sort_order'] = $sample['sort_order']; + } + unset($data['downloadable_sample']); + } + $data = $prefix ? [$prefix => $data] : $data; - $data['downloadable'] = $downloadable; + $data = array_merge($data, $downloadableData); return $this->replaceMappingData($data); } diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Handler/Curl/CreateDownloadable.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Handler/Curl/CreateDownloadable.php index b7c2d936812dbaed31dc3d0d196be6218efc3d43..7c5ddb2eb8838516ef08a4ddf1e91d28664580ba 100644 --- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Handler/Curl/CreateDownloadable.php +++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Handler/Curl/CreateDownloadable.php @@ -52,9 +52,8 @@ class CreateDownloadable extends Curl continue; } if (isset($values['input_name'])) { - $key = $values['input_name']; - } - if ($prefix) { + $data[$values['input_name']] = $value; + } elseif ($prefix) { $data[$prefix][$key] = $value; } else { $data[$key] = $value; diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Repository/CatalogProductDownloadable.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Repository/CatalogProductDownloadable.php index e13fb5242c35889f0964e68c861cd71404677e75..69f62020455072ab10d9b9579fde9367acb144d5 100644 --- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Repository/CatalogProductDownloadable.php +++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Repository/CatalogProductDownloadable.php @@ -45,7 +45,7 @@ class CatalogProductDownloadable extends AbstractRepository $this->_data['default'] = [ 'name' => 'Test downloadable product %isolation%', 'sku' => 'sku_test_downloadable_product_%isolation%', - 'price' => 280.00, + 'price' => ['value' => 280.00, 'preset' => '-'], 'type_id' => 'downloadable', 'tax_class_id' => ['dataSet' => 'Taxable Goods'], 'quantity_and_stock_status' => [ @@ -55,30 +55,8 @@ class CatalogProductDownloadable extends AbstractRepository 'status' => 'Product online', 'visibility' => 'Catalog, Search', 'url_key' => 'test-downloadable-product-%isolation%', - 'stock_data' => [ - 'manage_stock' => 'Yes', - 'qty' => 90.0000, - 'is_in_stock' => 'Yes' - ], 'is_virtual' => 'Yes', - 'links_title' => 'Links', - 'links_purchased_separately' => 'Yes', - 'downloadable' => [ - 'link' => [ - [ - 'title' => 'Link title', - 'price' => '1', - 'number_of_downloads' => 1, - 'is_shareable' => 'Use config', - 'sample' => [ - 'type' => 'url', - 'url' => 'http://example.com/', - ], - 'type' => 'url', - 'link_url' => 'http://example.com/', - ] - ] - ], + 'downloadable_links' => ['preset' => 'default'], 'website_ids' => ['Main Website'], ]; } diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/Create/LinksPurchasedSeparatelyTest.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/Create/LinksPurchasedSeparatelyTest.php old mode 100644 new mode 100755 index b05377f2d3e87ed87923e83741d37029a202015d..b45347461cb8a21176f9014f9e10b0f7eb28a522 --- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/Create/LinksPurchasedSeparatelyTest.php +++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/Create/LinksPurchasedSeparatelyTest.php @@ -58,12 +58,13 @@ class LinksPurchasedSeparatelyTest extends Functional { $createProductPage = Factory::getPageFactory()->getCatalogProductIndex(); $createProductPage->open(); - $createProductPage->getProductBlock()->addProduct('downloadable'); + $createProductPage->getGridPageActionBlock()->addProduct('downloadable'); $createProductPageNew = Factory::getPageFactory()->getCatalogProductNew(); $productBlockForm = $createProductPageNew->getForm(); - $productBlockForm->fillProduct($this->product); + $category = $this->product->getCategories()['category']; + $productBlockForm->fill($this->product, null, $category); $createProductPageNew->getFormAction()->save(); $createProductPageNew->getMessagesBlock()->assertSuccessMessage(); diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/CreateDownloadableProductEntityTest.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/CreateDownloadableProductEntityTest.php index 12b34392d648e56e00a6cd7c0b13af05236b0577..7c7f564bc8f604fcf7806eeff524c7133086410b 100644 --- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/CreateDownloadableProductEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/CreateDownloadableProductEntityTest.php @@ -88,6 +88,7 @@ class CreateDownloadableProductEntityTest extends Injectable * @param CatalogCategory $category * @param CatalogProductIndex $catalogProductIndexNewPage * @param CatalogProductNew $catalogProductNewPage + * @return void */ public function __inject( CatalogCategory $category, @@ -104,13 +105,14 @@ class CreateDownloadableProductEntityTest extends Injectable * * @param CatalogProductDownloadable $product * @param CatalogCategory $category + * @return void */ public function testCreateDownloadableProduct(CatalogProductDownloadable $product, CatalogCategory $category) { $this->catalogProductIndex->open(); - $this->catalogProductIndex->getProductBlock()->addProduct('downloadable'); + $this->catalogProductIndex->getGridPageActionBlock()->addProduct('downloadable'); $productBlockForm = $this->catalogProductNew->getForm(); - $productBlockForm->fillProduct($product, $category); + $productBlockForm->fill($product, null, $category); $this->catalogProductNew->getFormAction()->save(); } } diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/CreateDownloadableProductEntityTest/testCreateDownloadableProduct.csv b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/CreateDownloadableProductEntityTest/testCreateDownloadableProduct.csv old mode 100644 new mode 100755 index 19443badf94798f2c292c5fd8ea942adcbd1dcd6..5e5d12355e27b1b620d4359a09964901576a8d1f --- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/CreateDownloadableProductEntityTest/testCreateDownloadableProduct.csv +++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/CreateDownloadableProductEntityTest/testCreateDownloadableProduct.csv @@ -1,15 +1,15 @@ product/data/name;product/data/sku;product/data/price;product/data/tax_class_id/dataSet;product/data/quantity_and_stock_status/qty;product/data/quantity_and_stock_status/is_in_stock;product/data/is_virtual;product/data/category;product/data/description;product/data/short_description;product/data/inventory_manage_stock;product/data/inventory_qty;product/data/stock_data_use_config_min_qty;product/data/stock_data_min_qty;product/data/downloadable_sample/preset;product/data/downloadable_links/preset;product/data/custom_options/preset;product/data/special_price;product/data/group_price/preset;product/data/tier_price/preset;constraint DownloadableProduct_%isolation%;DownloadableProduct_%isolation%;100;Taxable Goods;1;In Stock;Yes;Default Category;-;-;-;-;-;-;-;default;-;-;-;-;assertProductSaveMessage, assertProductInGrid, assertDownloadableProductForm, assertProductVisibleInCategory, assertProductPage, assertProductInStock DownloadableProduct_%isolation%;DownloadableProduct_%isolation%;1;Taxable Goods;10;In Stock;Yes;category %isolation%;-;-;-;-;-;-;default;default;-;-;-;-;assertProductSaveMessage, assertProductInGrid, assertDownloadableProductForm, assertProductVisibleInCategory, assertDownloadableSamplesData, assertDownloadableLinksData -DownloadableProduct_%isolation%;DownloadableProduct_%isolation%;33;Taxable Goods;10;In Stock;Yes;category %isolation%;-;-;-;-;-;-;-;default;default;-;-;-;assertProductSaveMessage, assertDownloadableProductForm, assertCustomOptionsOnProductPage, assertProductVisibleInCategory, assertProductPage, assertDownloadableLinksData -DownloadableProduct_%isolation%;DownloadableProduct_%isolation%;55;Taxable Goods;10;In Stock;Yes;-;-;-;-;-;-;-;with_three_samples;with_three_links;two_options;-;-;-;assertProductSaveMessage, assertCustomOptionsOnProductPage, assertProductInGrid, assertDownloadableProductForm, assertProductVisibleInCategory, assertProductPage, assertDownloadableLinksData, assertProductInStock, assertProductSearchableBySku +DownloadableProduct_%isolation%;DownloadableProduct_%isolation%;33;Taxable Goods;10;In Stock;Yes;category %isolation%;-;-;-;-;-;-;-;default;default;-;-;-;assertProductSaveMessage, assertDownloadableProductForm, assertProductCustomOptionsOnProductPage, assertProductVisibleInCategory, assertProductPage, assertDownloadableLinksData +DownloadableProduct_%isolation%;DownloadableProduct_%isolation%;55;Taxable Goods;10;In Stock;Yes;-;-;-;-;-;-;-;with_three_samples;with_three_links;two_options;-;-;-;assertProductSaveMessage, assertProductCustomOptionsOnProductPage, assertProductInGrid, assertDownloadableProductForm, assertProductVisibleInCategory, assertProductPage, assertDownloadableLinksData, assertProductInStock, assertProductSearchableBySku DownloadableProduct_%isolation%;DownloadableProduct_%isolation%;100;Taxable Goods;50;Out of Stock;Yes;Default Category;-;-;-;-;-;-;-;default;-;-;-;-;assertProductSaveMessage, assertProductOutOfStock, assertProductInGrid, assertDownloadableProductForm DownloadableProduct_%isolation%;DownloadableProduct_%isolation%;9999;Taxable Goods;-;-;Yes;Default Category;-;-;Yes;123;No;123;-;default;-;-;-;-;assertProductSaveMessage, assertProductInGrid, assertDownloadableProductForm, assertProductOutOfStock DownloadableProduct_%isolation%;DownloadableProduct_%isolation%;98;None;5;In Stock;Yes;Default Category;This is description for downloadable product;-;-;-;-;-;-;default;-;-;-;-;assertProductSaveMessage, assertProductInGrid, assertDownloadableProductForm, assertProductPage -DownloadableProduct_%isolation%;DownloadableProduct_%isolation%;57;Taxable Goods;10;In Stock;Yes;category %isolation%;-;This is short description for downloadable product;-;-;-;-;default;with_three_links;default;-;-;-;assertProductSaveMessage, assertProductInGrid, assertDownloadableProductForm, assertProductPage, assertCustomOptionsOnProductPage, assertDownloadableSamplesData, assertDownloadableLinksData -DownloadableProduct_%isolation%;DownloadableProduct_%isolation%;65;Taxable Goods;11;In Stock;Yes;category %isolation%;This is description for downloadable product;This is short description for downloadable product;-;-;-;-;default;with_three_links;default;-;-;-;assertProductSaveMessage, assertProductPage, assertProductInGrid, assertDownloadableProductForm, assertCustomOptionsOnProductPage, assertDownloadableSamplesData, assertDownloadableLinksData -DownloadableProduct_%isolation%;DownloadableProduct_%isolation%;65;Taxable Goods;11;In Stock;Yes;category %isolation%;-;-;-;-;-;-;default;with_three_links;default;-;-;-;assertProductSaveMessage, assertProductInGrid, assertDownloadableProductForm, assertProductPage, assertDownloadableLinksData, assertCustomOptionsOnProductPage +DownloadableProduct_%isolation%;DownloadableProduct_%isolation%;57;Taxable Goods;10;In Stock;Yes;category %isolation%;-;This is short description for downloadable product;-;-;-;-;default;with_three_links;default;-;-;-;assertProductSaveMessage, assertProductInGrid, assertDownloadableProductForm, assertProductPage, assertProductCustomOptionsOnProductPage, assertDownloadableSamplesData, assertDownloadableLinksData +DownloadableProduct_%isolation%;DownloadableProduct_%isolation%;65;Taxable Goods;11;In Stock;Yes;category %isolation%;This is description for downloadable product;This is short description for downloadable product;-;-;-;-;default;with_three_links;default;-;-;-;assertProductSaveMessage, assertProductPage, assertProductInGrid, assertDownloadableProductForm, assertProductCustomOptionsOnProductPage, assertDownloadableSamplesData, assertDownloadableLinksData +DownloadableProduct_%isolation%;DownloadableProduct_%isolation%;65;Taxable Goods;11;In Stock;Yes;category %isolation%;-;-;-;-;-;-;default;with_three_links;default;-;-;-;assertProductSaveMessage, assertProductInGrid, assertDownloadableProductForm, assertProductPage, assertDownloadableLinksData, assertProductCustomOptionsOnProductPage DownloadableProduct_%isolation%;DownloadableProduct_%isolation%;100;Taxable Goods;-;-;Yes;Default Category;-;-;-;-;-;-;-;default;-;-;-;-;assertProductSaveMessage, assertDownloadableProductForm, assertProductVisibleInCategory, assertProductPage -DownloadableProduct_%isolation%;DownloadableProduct_%isolation%;10;Taxable Goods;10;In Stock;Yes;category %isolation%;-;-;-;-;-;-;-;-;-;5;-;-;assertProductSaveMessage, assertProductInGrid, assertDownloadableProductForm, assertProductPage, assertSpecialPriceOnProductPage -DownloadableProduct_%isolation%;DownloadableProduct_%isolation%;365;Taxable Goods;23;In Stock;Yes;category %isolation%;-;-;-;-;-;-;-;-;-;-;default;-;assertProductSaveMessage, assertProductInGrid, assertDownloadableProductForm, assertProductPage, assertGroupedPriceOnProductPage -DownloadableProduct_%isolation%;DownloadableProduct_%isolation%;250;Taxable Goods;65;In Stock;Yes;category %isolation%;-;-;-;-;-;-;-;-;-;-;-;default;assertProductSaveMessage, assertProductInGrid, assertDownloadableProductForm, assertProductPage, assertTierPriceOnProductPage \ No newline at end of file +DownloadableProduct_%isolation%;DownloadableProduct_%isolation%;10;Taxable Goods;10;In Stock;Yes;category %isolation%;-;-;-;-;-;-;-;-;-;5;-;-;assertProductSaveMessage, assertProductInGrid, assertDownloadableProductForm, assertProductPage, assertProductSpecialPriceOnProductPage +DownloadableProduct_%isolation%;DownloadableProduct_%isolation%;365;Taxable Goods;23;In Stock;Yes;category %isolation%;-;-;-;-;-;-;-;-;-;-;default;-;assertProductSaveMessage, assertProductInGrid, assertDownloadableProductForm, assertProductPage, assertProductGroupedPriceOnProductPage +DownloadableProduct_%isolation%;DownloadableProduct_%isolation%;250;Taxable Goods;65;In Stock;Yes;category %isolation%;-;-;-;-;-;-;-;-;-;-;-;default;assertProductSaveMessage, assertProductInGrid, assertDownloadableProductForm, assertProductPage, assertProductTierPriceOnProductPage \ No newline at end of file diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/UpdateDownloadableProductEntityTest.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/UpdateDownloadableProductEntityTest.php index 3a601fb7e55b5ee914a26e6ef372d470d1efdbfd..0c0de0794e321460be47f6792c72dc235f72f94d 100644 --- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/UpdateDownloadableProductEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/UpdateDownloadableProductEntityTest.php @@ -122,7 +122,7 @@ class UpdateDownloadableProductEntityTest extends Injectable $filter = ['sku' => $this->product->getSku()]; $this->catalogProductIndex->open()->getProductGrid()->searchAndOpen($filter); $productBlockForm = $this->catalogProductEdit->getForm(); - $productBlockForm->fillProduct($product, $category); + $productBlockForm->fill($product, null, $category); $this->catalogProductEdit->getFormAction()->save(); } } diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/UpdateDownloadableProductEntityTest/testUpdateDownloadableProduct.csv b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/UpdateDownloadableProductEntityTest/testUpdateDownloadableProduct.csv index dad29f9cefecde208aaf75546ec68253d650d9dc..9476d7b7a89d654a4d61bdba664dcaba86223cef 100644 --- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/UpdateDownloadableProductEntityTest/testUpdateDownloadableProduct.csv +++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/UpdateDownloadableProductEntityTest/testUpdateDownloadableProduct.csv @@ -1,8 +1,8 @@ "product/data/name";"product/data/sku";"product/data/price";"product/data/tax_class_id/dataSet";"product/data/quantity_and_stock_status/qty";"product/data/quantity_and_stock_status/is_in_stock";"product/data/is_virtual";"product/data/weight";"product/data/category";"product/data/description";"product/data/short_description";"product/data/inventory_manage_stock";"product/data/inventory_qty";"product/data/stock_data_use_config_min_qty";"product/data/stock_data_min_qty";"product/data/downloadable_sample/preset";"product/data/downloadable_links/preset";"product/data/custom_options/preset";"product/data/special_price";"isRequired";"constraint" -"DownloadableProduct_%isolation%";"DownloadableProduct_%isolation%";"55";"Taxable Goods";"10";"In Stock";"Yes";"-";"-";"-";"-";"-";"-";"-";"-";"with_three_samples";"with_three_links";"two_options";"-";"No";"assertProductSaveMessage, assertProductInGrid, assertDownloadableProductForm, assertProductPage, assertDownloadableLinksData, assertProductInStock, assertCustomOptionsOnProductPage, assertProductSearchableBySku" +"DownloadableProduct_%isolation%";"DownloadableProduct_%isolation%";"55";"Taxable Goods";"10";"In Stock";"Yes";"-";"-";"-";"-";"-";"-";"-";"-";"with_three_samples";"with_three_links";"two_options";"-";"No";"assertProductSaveMessage, assertProductInGrid, assertDownloadableProductForm, assertProductPage, assertDownloadableLinksData, assertProductInStock, assertProductCustomOptionsOnProductPage, assertProductSearchableBySku" "DownloadableProduct_%isolation%";"DownloadableProduct_%isolation%";"100";"Taxable Goods";"50";"Out of Stock";"Yes";"-";"Default Category";"-";"-";"-";"-";"-";"-";"-";"default";"-";"-";"No";"assertProductSaveMessage, assertProductOutOfStock, assertProductInGrid, assertDownloadableProductForm" "DownloadableProduct_%isolation%";"DownloadableProduct_%isolation%";"9999";"Taxable Goods";"123";"-";"Yes";"-";"Default Category";"-";"-";"Yes";"-";"No";"123";"-";"-";"-";"-";"No";"assertProductSaveMessage, assertProductInGrid, assertDownloadableProductForm, assertProductOutOfStock" "DownloadableProduct_%isolation%";"DownloadableProduct_%isolation%";"48";"None";"5";"In Stock";"Yes";"-";"Default Category";"This is description for downloadable product";"-";"-";"-";"-";"-";"-";"default";"-";"-";"No";"assertProductSaveMessage, assertProductInGrid, assertDownloadableProductForm, assertProductPage" -"DownloadableProduct_%isolation%";"DownloadableProduct_%isolation%";"54";"Taxable Goods";"10";"In Stock";"Yes";"-";"category %isolation%";"-";"This is short description for downloadable product";"-";"-";"-";"-";"default";"with_three_links";"default";"-";"Yes";"assertProductSaveMessage, assertProductInGrid, assertDownloadableProductForm, assertProductPage, assertCustomOptionsOnProductPage, assertDownloadableSamplesData, assertDownloadableLinksData, assertProductInCategory" +"DownloadableProduct_%isolation%";"DownloadableProduct_%isolation%";"54";"Taxable Goods";"10";"In Stock";"Yes";"-";"category %isolation%";"-";"This is short description for downloadable product";"-";"-";"-";"-";"default";"with_three_links";"default";"-";"Yes";"assertProductSaveMessage, assertProductInGrid, assertDownloadableProductForm, assertProductPage, assertProductCustomOptionsOnProductPage, assertDownloadableSamplesData, assertDownloadableLinksData, assertProductInCategory" "DownloadableProduct_%isolation%";"DownloadableProduct_%isolation%";"57";"Taxable Goods";"10";"In Stock";"No";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"No";"assertProductSaveMessage, assertProductInGrid" -"DownloadableProduct_%isolation%";"DownloadableProduct_%isolation%";"43";"Taxable Goods";"10";"In Stock";"No";"10";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"40";"No";"assertProductSaveMessage, assertProductInGrid, assertSpecialPriceOnProductPage, assertProductPage" +"DownloadableProduct_%isolation%";"DownloadableProduct_%isolation%";"43";"Taxable Goods";"10";"In Stock";"No";"10";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"40";"No";"assertProductSaveMessage, assertProductInGrid, assertProductSpecialPriceOnProductPage, assertProductPage" diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/etc/global/constraint.xml b/dev/tests/functional/tests/app/Magento/Downloadable/Test/etc/global/constraint.xml index e2332785b79ea18770f035f1adf43b6e0dfc19ab..2e24ac40083a775527f6c575c7a7b3a7ae0812ff 100644 --- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/etc/global/constraint.xml +++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/etc/global/constraint.xml @@ -33,4 +33,12 @@ <assertDownloadableProductForm module="Magento_Downloadable"> <severeness>low</severeness> </assertDownloadableProductForm> + <assertDownloadableDuplicateForm module="Magento_Downloadable"> + <severeness>high</severeness> + <require> + <productGrid class="Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex" /> + <productPage class="Magento\Catalog\Test\Page\Adminhtml\CatalogProductEdit" /> + <product class="Mtf\Fixture\FixtureInterface" /> + </require> + </assertDownloadableDuplicateForm> </constraint> diff --git a/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/Block/Adminhtml/Types/Edit/GoogleShoppingForm.php b/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/Block/Adminhtml/Types/Edit/GoogleShoppingForm.php new file mode 100644 index 0000000000000000000000000000000000000000..aec5eca6ab58d73cb9aa45e13ff91bcf313946bf --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/Block/Adminhtml/Types/Edit/GoogleShoppingForm.php @@ -0,0 +1,114 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\GoogleShopping\Test\Block\Adminhtml\Types\Edit; + +use Mtf\Block\Form; +use Mtf\Client\Element; +use Mtf\Client\Element\Locator; + +/** + * Class GoogleShoppingForm + * Google Shopping form + */ +class GoogleShoppingForm extends Form +{ + /** + * Attribute options locator + * + * @var string + */ + protected $attributeOptions = '//select[@id="gcontent_attribute_0_attribute"]//option'; + + /** + * Loading Mask locator + * + * @var string + */ + protected $loadingMask = '//ancestor::body/div[@id="loading-mask"]'; + + /** + * Fill specified form data + * + * @param array $fields + * @param Element $element + * @return void + */ + protected function _fill(array $fields, Element $element = null) + { + $context = ($element === null) ? $this->_rootElement : $element; + foreach ($fields as $field) { + $element = $this->getElement($context, $field); + if ($this->mappingMode || ($element->isVisible() && !$element->isDisabled())) { + $element->setValue($field['value']); + $this->waitForElementNotVisible($this->loadingMask, Locator::SELECTOR_XPATH); + } + } + } + + /** + * Find Attribute in Attribute set mapping form + * + * @param string $attributeName + * @return bool + */ + public function findAttribute($attributeName) + { + $attributes = $this->getOptions(); + foreach ($attributes as $attribute) { + if ($attribute == $attributeName) { + return true; + } + } + + return false; + } + + /** + * Click "Add New Attribute" button + * + * @return void + */ + public function clickAddNewAttribute() + { + $this->_rootElement->find('#add_new_attribute')->click(); + } + + /** + * Getting all options in select list + * + * @return array + */ + protected function getOptions() + { + $elements = $this->_rootElement->find($this->attributeOptions, Locator::SELECTOR_XPATH)->getElements(); + + $options = []; + foreach ($elements as $key => $element) { + $options[$key] = $element->getText(); + } + + return $options; + } +} diff --git a/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/Block/Adminhtml/Types/Edit/GoogleShoppingForm.xml b/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/Block/Adminhtml/Types/Edit/GoogleShoppingForm.xml new file mode 100644 index 0000000000000000000000000000000000000000..fee98d9655b4b1e7550239681539af8145d158f1 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/Block/Adminhtml/Types/Edit/GoogleShoppingForm.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" ?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<mapping strict="0"> + <fields> + <target_country> + <input>select</input> + </target_country> + <attribute_set_id> + <input>select</input> + </attribute_set_id> + <category> + <input>select</input> + </category> + </fields> +</mapping> diff --git a/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/Block/Adminhtml/Types/FormPageActions.php b/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/Block/Adminhtml/Types/FormPageActions.php new file mode 100644 index 0000000000000000000000000000000000000000..db3f2cc136f1fc84d35b8ad3baa3af1498bd9908 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/Block/Adminhtml/Types/FormPageActions.php @@ -0,0 +1,41 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\GoogleShopping\Test\Block\Adminhtml\Types; + +use Magento\Backend\Test\Block\FormPageActions as AbstractFormPageActions; + +/** + * Class FormPageActions + * Page Actions for Google Shopping + */ +class FormPageActions extends AbstractFormPageActions +{ + /** + * "Save" button + * + * @var string + */ + protected $saveButton = '#save_button'; +} diff --git a/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/Constraint/AssertProductAttributeAbsenceForAttributeMapping.php b/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/Constraint/AssertProductAttributeAbsenceForAttributeMapping.php new file mode 100644 index 0000000000000000000000000000000000000000..a4b53e900627db3f8a121ba63ac6ee7b447e4aaa --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/Constraint/AssertProductAttributeAbsenceForAttributeMapping.php @@ -0,0 +1,98 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\GoogleShopping\Test\Constraint; + +use Mtf\Fixture\FixtureFactory; +use Mtf\Constraint\AbstractConstraint; +use Magento\Catalog\Test\Fixture\CatalogAttributeSet; +use Magento\GoogleShopping\Test\Page\Adminhtml\GoogleShoppingTypesIndex; +use Magento\GoogleShopping\Test\Page\Adminhtml\GoogleShoppingTypesNew; + +/** + * Class AssertProductAttributeAbsenceForAttributeMapping + * Assert that deleted attribute can't be mapped to Google Attribute + */ +class AssertProductAttributeAbsenceForAttributeMapping extends AbstractConstraint +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Assert that deleted attribute can't be mapped to Google Attribute (attribute doesn't appear in Attributes + * Mapping -> Google Content - Attributes after selecting attribute set) + * + * @param FixtureFactory $fixtureFactory + * @param CatalogAttributeSet $productTemplate + * @param GoogleShoppingTypesIndex $shoppingTypesIndex + * @param GoogleShoppingTypesNew $shoppingTypesNew + * @return void + */ + public function processAssert( + FixtureFactory $fixtureFactory, + CatalogAttributeSet $productTemplate, + GoogleShoppingTypesIndex $shoppingTypesIndex, + GoogleShoppingTypesNew $shoppingTypesNew + ) { + $shoppingTypesIndex->open(); + $shoppingTypesIndex->getPageActionsBlock()->addNew(); + + $shoppingAttributes = $fixtureFactory->createByCode( + 'googleShoppingAttribute', + [ + 'dataSet' => 'default', + 'data' => [ + 'attribute_set_id' => ['attribute_set' => $productTemplate] + ], + ] + ); + + $shoppingTypesNew->getGoogleShoppingForm()->fill($shoppingAttributes); + $shoppingTypesNew->getGoogleShoppingForm()->clickAddNewAttribute(); + + $attributeCode = $productTemplate + ->getDataFieldConfig('assigned_attributes')['source'] + ->getAttributes()[0] + ->getAttributeCode(); + + \PHPUnit_Framework_Assert::assertFalse( + $shoppingTypesNew->getGoogleShoppingForm()->findAttribute($attributeCode), + "Attribute " . $attributeCode . " is present in Attribute set mapping" + ); + } + + /** + * Text absent Product Attribute in Google Content Attribute Mapping + * + * @return string + */ + public function toString() + { + return "Attribute is absent in Google Content Attribute Mapping."; + } +} diff --git a/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/Fixture/GoogleShoppingAttribute.php b/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/Fixture/GoogleShoppingAttribute.php new file mode 100644 index 0000000000000000000000000000000000000000..8c4ee9b4598447229b69553da82a3702c7e353e8 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/Fixture/GoogleShoppingAttribute.php @@ -0,0 +1,106 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\GoogleShopping\Test\Fixture; + +use Mtf\Fixture\InjectableFixture; + +/** + * Class GoogleShoppingAttribute + * Google Shopping Attribute fixture + * + */ +class GoogleShoppingAttribute extends InjectableFixture +{ + /** + * @var string + */ + protected $repositoryClass = 'Magento\GoogleShopping\Test\Repository\GoogleShoppingAttribute'; + + // @codingStandardsIgnoreStart + /** + * @var string + */ + protected $handlerInterface = 'Magento\GoogleShopping\Test\Handler\GoogleShoppingAttribute\GoogleShoppingAttributeInterface'; + // @codingStandardsIgnoreEnd + + protected $defaultDataSet = [ + 'target_country' => 'United States', + 'attribute_set_id' => ['dataSet' => 'default'], + 'category' => 'Apparel & Accessories', + ]; + + protected $type_id = [ + 'attribute_code' => 'type_id', + 'backend_type' => 'int', + 'is_required' => '1', + 'default_value' => '', + 'input' => '', + ]; + + protected $attribute_set_id = [ + 'attribute_code' => 'attribute_set_id', + 'backend_type' => 'smallint', + 'is_required' => '', + 'default_value' => '', + 'input' => '', + 'source' => 'Magento\GoogleShopping\Test\Fixture\GoogleShoppingAttribute\AttributeSetId', + ]; + + protected $target_country = [ + 'attribute_code' => 'target_country', + 'backend_type' => 'varchar', + 'is_required' => '', + 'default_value' => 'US', + 'input' => '', + ]; + + protected $category = [ + 'attribute_code' => 'category', + 'backend_type' => 'varchar', + 'is_required' => '', + 'default_value' => '', + 'input' => '', + ]; + + public function getTypeId() + { + return $this->getData('type_id'); + } + + public function getAttributeSetId() + { + return $this->getData('attribute_set_id'); + } + + public function getTargetCountry() + { + return $this->getData('target_country'); + } + + public function getCategory() + { + return $this->getData('category'); + } +} diff --git a/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/Fixture/GoogleShoppingAttribute.xml b/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/Fixture/GoogleShoppingAttribute.xml new file mode 100644 index 0000000000000000000000000000000000000000..71dfd2bc309f0c6140ecf140b3b859bd208fdc42 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/Fixture/GoogleShoppingAttribute.xml @@ -0,0 +1,64 @@ +<?xml version="1.0" ?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<fixture class="Magento\GoogleShopping\Test\Fixture\GoogleShoppingAttribute"> + <module>Magento_GoogleShopping</module> + <type>flat</type> + <entity_type>googleshopping_types</entity_type> + <collection>Magento\GoogleShopping\Model\Resource\Attribute\Collection</collection> + <fields> + <type_id> + <attribute_code>type_id</attribute_code> + <backend_type>int</backend_type> + <is_required>1</is_required> + <default_value></default_value> + <input></input> + </type_id> + <attribute_set_id> + <attribute_code>attribute_set_id</attribute_code> + <backend_type>smallint</backend_type> + <source>Magento\GoogleShopping\Test\Fixture\GoogleShoppingAttribute\AttributeSetId</source> + <is_required></is_required> + <default_value></default_value> + <input></input> + </attribute_set_id> + <target_country> + <attribute_code>target_country</attribute_code> + <backend_type>varchar</backend_type> + <is_required></is_required> + <default_value>US</default_value> + <input></input> + </target_country> + <category> + <attribute_code>category</attribute_code> + <backend_type>varchar</backend_type> + <is_required></is_required> + <default_value></default_value> + <input></input> + </category> + </fields> + <repository_class>Magento\GoogleShopping\Test\Repository\GoogleShoppingAttribute</repository_class> + <handler_interface>Magento\GoogleShopping\Test\Handler\GoogleShoppingAttribute\GoogleShoppingAttributeInterface</handler_interface> +</fixture> diff --git a/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/Fixture/GoogleShoppingAttribute/AttributeSetId.php b/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/Fixture/GoogleShoppingAttribute/AttributeSetId.php new file mode 100644 index 0000000000000000000000000000000000000000..41cefa2cd7d49eb594c89d98707e146508a97de1 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/Fixture/GoogleShoppingAttribute/AttributeSetId.php @@ -0,0 +1,139 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\GoogleShopping\Test\Fixture\GoogleShoppingAttribute; + +use Mtf\Fixture\FixtureInterface; +use Mtf\Fixture\FixtureFactory; +use Magento\Catalog\Test\Fixture\CatalogAttributeSet; + +/** + * Class AttributeSetId + * Prepare Attribute Set + * + * Data keys: + * - dataSet + * - attribute_set + */ +class AttributeSetId implements FixtureInterface +{ + /** + * Data set configuration settings + * + * @var array + */ + protected $params = []; + + /** + * Attribute Set name + * + * @var string + */ + protected $data; + + /** + * Attribute Set fixture + * + * @var CatalogAttributeSet + */ + protected $attributeSet; + + /** + * @param FixtureFactory $fixtureFactory + * @param array $params + * @param array $data + */ + public function __construct(FixtureFactory $fixtureFactory, array $params, array $data = []) + { + $this->params = $params; + if (isset($data['dataSet'])) { + /** @var CatalogAttributeSet $attributeSet */ + $attributeSet = $fixtureFactory->createByCode('catalogAttributeSet', ['dataSet' => $data['dataSet']]); + $this->prepareData($attributeSet); + } + + if (isset($data['attribute_set']) && $data['attribute_set'] instanceof CatalogAttributeSet) { + $this->prepareData($data['attribute_set']); + } + } + + /** + * Prepare Catalog Attribute Set data + * + * @param CatalogAttributeSet $attributeSet + * @return void + */ + protected function prepareData(CatalogAttributeSet $attributeSet) + { + if (!$attributeSet->hasData('attribute_set_id')) { + $attributeSet->persist(); + } + + $this->data = $attributeSet->getAttributeSetName(); + $this->attributeSet = $attributeSet; + } + + /** + * Persist attribute options + * + * @return void + */ + public function persist() + { + // + } + + /** + * Return prepared data set + * + * @param string|null $key + * @return mixed + * + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function getData($key = null) + { + return $this->data; + } + + /** + * Return Attribute Set fixture + * + * @return CatalogAttributeSet + */ + public function getAttributeSet() + { + return $this->attributeSet; + } + + /** + * Return data set configuration settings + * + * @return array + */ + public function getDataConfig() + { + return $this->params; + } +} diff --git a/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/Page/Adminhtml/GoogleShoppingTypesIndex.php b/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/Page/Adminhtml/GoogleShoppingTypesIndex.php new file mode 100644 index 0000000000000000000000000000000000000000..eeec2cdc9df6a639aa0a4b7539cd393f96aa147a --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/Page/Adminhtml/GoogleShoppingTypesIndex.php @@ -0,0 +1,66 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\GoogleShopping\Test\Page\Adminhtml; + +use Mtf\Page\BackendPage; + +/** + * Class GoogleShoppingTypesIndex + */ +class GoogleShoppingTypesIndex extends BackendPage +{ + const MCA = 'admin/googleshopping_types/index'; + + protected $_blocks = [ + 'pageActionsBlock' => [ + 'name' => 'pageActionsBlock', + 'class' => 'Magento\Backend\Test\Block\GridPageActions', + 'locator' => '.page-main-actions', + 'strategy' => 'css selector', + ], + 'grid' => [ + 'name' => 'grid', + 'class' => 'Magento\Backend\Test\Block\Widget\Grid', + 'locator' => '#types_grid', + 'strategy' => 'css selector', + ], + ]; + + /** + * @return \Magento\Backend\Test\Block\GridPageActions + */ + public function getPageActionsBlock() + { + return $this->getBlockInstance('pageActionsBlock'); + } + + /** + * @return \Magento\Backend\Test\Block\Widget\Grid + */ + public function getGrid() + { + return $this->getBlockInstance('grid'); + } +} diff --git a/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/Page/Adminhtml/GoogleShoppingTypesIndex.xml b/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/Page/Adminhtml/GoogleShoppingTypesIndex.xml new file mode 100644 index 0000000000000000000000000000000000000000..60f2a3b0f88986b389b4518a98c10c3ab9b1494f --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/Page/Adminhtml/GoogleShoppingTypesIndex.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" ?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<page mca="admin/googleshopping_types/index" > + <block> + <name>pageActionsBlock</name> + <class>Magento\Backend\Test\Block\GridPageActions</class> + <locator>.page-main-actions</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>grid</name> + <class>Magento\Backend\Test\Block\Widget\Grid</class> + <locator>#types_grid</locator> + <strategy>css selector</strategy> + </block> +</page> diff --git a/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/Page/Adminhtml/GoogleShoppingTypesNew.php b/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/Page/Adminhtml/GoogleShoppingTypesNew.php new file mode 100644 index 0000000000000000000000000000000000000000..b85bfa2a43923b9fc56ca3631275948ba6277777 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/Page/Adminhtml/GoogleShoppingTypesNew.php @@ -0,0 +1,66 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\GoogleShopping\Test\Page\Adminhtml; + +use Mtf\Page\BackendPage; + +/** + * Class GoogleShoppingTypesNew + */ +class GoogleShoppingTypesNew extends BackendPage +{ + const MCA = 'admin/googleshopping_types/new'; + + protected $_blocks = [ + 'pageActions' => [ + 'name' => 'pageActions', + 'class' => 'Magento\GoogleShopping\Test\Block\Adminhtml\Types\FormPageActions', + 'locator' => '.page-main-actions', + 'strategy' => 'css selector', + ], + 'googleShoppingForm' => [ + 'name' => 'googleShoppingForm', + 'class' => 'Magento\GoogleShopping\Test\Block\Adminhtml\Types\Edit\GoogleShoppingForm', + 'locator' => '#edit_form', + 'strategy' => 'css selector', + ], + ]; + + /** + * @return \Magento\GoogleShopping\Test\Block\Adminhtml\Types\FormPageActions + */ + public function getPageActions() + { + return $this->getBlockInstance('pageActions'); + } + + /** + * @return \Magento\GoogleShopping\Test\Block\Adminhtml\Types\Edit\GoogleShoppingForm + */ + public function getGoogleShoppingForm() + { + return $this->getBlockInstance('googleShoppingForm'); + } +} diff --git a/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/Page/Adminhtml/GoogleShoppingTypesNew.xml b/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/Page/Adminhtml/GoogleShoppingTypesNew.xml new file mode 100644 index 0000000000000000000000000000000000000000..ede1f39f873f65875af34fe309409d0a004cf44e --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/Page/Adminhtml/GoogleShoppingTypesNew.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" ?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<page mca="admin/googleshopping_types/new" > + <block> + <name>pageActions</name> + <class>Magento\GoogleShopping\Test\Block\Adminhtml\Types\FormPageActions</class> + <locator>.page-main-actions</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>googleShoppingForm</name> + <class>Magento\GoogleShopping\Test\Block\Adminhtml\Types\Edit\GoogleShoppingForm</class> + <locator>#edit_form</locator> + <strategy>css selector</strategy> + </block> +</page> diff --git a/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/Repository/GoogleShoppingAttribute.php b/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/Repository/GoogleShoppingAttribute.php new file mode 100644 index 0000000000000000000000000000000000000000..ad0f63787acb69beb376f063ad35844c51c1ae7c --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/Repository/GoogleShoppingAttribute.php @@ -0,0 +1,51 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\GoogleShopping\Test\Repository; + +use Mtf\Repository\AbstractRepository; + +/** + * Class GoogleShoppingAttribute + * Data for creation Google Shopping Attribute + */ +class GoogleShoppingAttribute extends AbstractRepository +{ + /** + * Construct + * + * @param array $defaultConfig + * @param array $defaultData + * + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function __construct(array $defaultConfig = [], array $defaultData = []) + { + $this->_data['default'] = [ + 'target_country' => 'United States', + 'attribute_set_id' => ['dataSet' => 'default'], + 'category' => 'Apparel & Accessories', + ]; + } +} diff --git a/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/etc/global/constraint.xml b/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/etc/global/constraint.xml new file mode 100644 index 0000000000000000000000000000000000000000..98f2758d87a6918ff56d1ab03e14e96779489b65 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/etc/global/constraint.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" ?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<constraint> + <assertProductAttributeAbsenceForAttributeMapping module="Magento_GoogleShopping"> + <severeness>low</severeness> + </assertProductAttributeAbsenceForAttributeMapping> +</constraint> diff --git a/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/etc/global/fixture.xml b/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/etc/global/fixture.xml new file mode 100644 index 0000000000000000000000000000000000000000..360dd77494cf29a0517da551238287bf6bae45fa --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/etc/global/fixture.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" ?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<fixture> + <googleShoppingAttribute module="Magento_GoogleShopping"> + <type>flat</type> + <entity_type>googleshopping_types</entity_type> + <collection>Magento\GoogleShopping\Model\Resource\Attribute\Collection</collection> + </googleShoppingAttribute> +</fixture> diff --git a/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/etc/global/page.xml b/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/etc/global/page.xml new file mode 100644 index 0000000000000000000000000000000000000000..11e855db77eb18dba256ddc7d1ebd95572c03ba6 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/GoogleShopping/Test/etc/global/page.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" ?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<page> + <googleShoppingTypesIndex> + <mca>admin/googleshopping_types/index</mca> + <area>adminhtml</area> + <class>Magento\GoogleShopping\Test\Page\Adminhtml\GoogleShoppingTypesIndex</class> + </googleShoppingTypesIndex> + <googleShoppingTypesNew> + <mca>admin/googleshopping_types/new</mca> + <area>adminhtml</area> + <class>Magento\GoogleShopping\Test\Page\Adminhtml\GoogleShoppingTypesNew</class> + </googleShoppingTypesNew> +</page> diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Adminhtml/Product/Grouped/AssociatedProducts.php b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Adminhtml/Product/Grouped/AssociatedProducts.php new file mode 100644 index 0000000000000000000000000000000000000000..265f133d48040bec7b42adcae5f053edd4a4a5ac --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Adminhtml/Product/Grouped/AssociatedProducts.php @@ -0,0 +1,123 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\GroupedProduct\Test\Block\Adminhtml\Product\Grouped; + +use Mtf\Client\Element; +use Mtf\Client\Element\Locator; +use Magento\Backend\Test\Block\Widget\Tab; + +/** + * Class AssociatedProducts + * Grouped products tab + */ +class AssociatedProducts extends Tab +{ + /** + * 'Create New Option' button + * + * @var string + */ + protected $addNewOption = '#grouped-product-container>button'; + + /** + * Associated products grid locator + * + * @var string + */ + protected $productSearchGrid = "./ancestor::body//div[div[contains(@data-role,'add-product-dialog')]]"; + + /** + * Associated products list block + * + * @var string + */ + protected $associatedProductsBlock = '[data-role=grouped-product-grid]'; + + /** + * Get search grid + * + * @return AssociatedProducts\Search\Grid + */ + protected function getSearchGridBlock() + { + return $this->blockFactory->create( + 'Magento\GroupedProduct\Test\Block\Adminhtml\Product\Grouped\AssociatedProducts\Search\Grid', + ['element' => $this->_rootElement->find($this->productSearchGrid, Locator::SELECTOR_XPATH)] + ); + } + + /** + * Get associated products list block + * + * @return AssociatedProducts\ListAssociatedProducts + */ + protected function getListAssociatedProductsBlock() + { + return $this->blockFactory->create( + 'Magento\GroupedProduct\Test\Block\Adminhtml\Product\Grouped\AssociatedProducts\ListAssociatedProducts', + ['element' => $this->_rootElement->find($this->associatedProductsBlock)] + ); + } + + /** + * Fill data to fields on tab + * + * @param array $fields + * @param Element|null $element + * @return $this + */ + public function fillFormTab(array $fields, Element $element = null) + { + if (isset($fields['associated'])) { + foreach ($fields['associated']['value']['assigned_products'] as $key => $groupedProduct) { + $element->find($this->addNewOption)->click(); + $searchBlock = $this->getSearchGridBlock(); + $searchBlock->searchAndSelect(['name' => $groupedProduct['name']]); + $searchBlock->addProducts(); + $this->getListAssociatedProductsBlock()->fillProductOptions($groupedProduct, ($key + 1)); + } + } + return $this; + } + + /** + * Get data to fields on group tab + * + * @param array|null $fields + * @param Element|null $element + * @return array + */ + public function getDataFormTab($fields = null, Element $element = null) + { + $newFields = []; + if (isset($fields['associated'])) { + foreach ($fields['associated']['value']['assigned_products'] as $key => $groupedProduct) { + $newFields['associated']['assigned_products'][$key] = $this->getListAssociatedProductsBlock() + ->getProductOptions($groupedProduct, ($key + 1)); + } + } + return $newFields; + } +} diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Adminhtml/Product/Grouped/AssociatedProducts/ListAssociatedProducts.php b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Adminhtml/Product/Grouped/AssociatedProducts/ListAssociatedProducts.php new file mode 100644 index 0000000000000000000000000000000000000000..8a7889aaa7dc7632880d24b5dd4b8cc6726d3f85 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Adminhtml/Product/Grouped/AssociatedProducts/ListAssociatedProducts.php @@ -0,0 +1,83 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\GroupedProduct\Test\Block\Adminhtml\Product\Grouped\AssociatedProducts; + +use Mtf\Block\Form; +use Mtf\Client\Element; +use Mtf\Client\Element\Locator; + +/** + * Class ListAssociatedProducts + * List associated products on the page + */ +class ListAssociatedProducts extends Form +{ + /** + * Selector with item product + * + * @var string + */ + protected $itemProduct = '//tr[@data-role="row"][%d]'; + + /** + * Getting block products + * + * @param string $index + * @return ListAssociatedProducts\Product + */ + private function getProductBlock($index) + { + $className = 'Magento\GroupedProduct\Test\Block\Adminhtml\Product\\' . + 'Grouped\AssociatedProducts\ListAssociatedProducts\Product'; + return $this->blockFactory->create( + $className, + ['element' => $this->_rootElement->find(sprintf($this->itemProduct, $index), Locator::SELECTOR_XPATH)] + ); + } + + /** + * Filling options products + * + * @param array $data + * @param int $index + * @return void + */ + public function fillProductOptions(array $data, $index) + { + $this->getProductBlock($index)->fillOption($data); + } + + /** + * Get options products + * + * @param array $data + * @param int $index + * @return array + */ + public function getProductOptions(array $data, $index) + { + return $this->getProductBlock($index)->getOption($data); + } +} diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Adminhtml/Product/Grouped/AssociatedProducts/ListAssociatedProducts/Product.php b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Adminhtml/Product/Grouped/AssociatedProducts/ListAssociatedProducts/Product.php new file mode 100644 index 0000000000000000000000000000000000000000..c92fdd60b4d13bd0510baaee822885649dab6e6f --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Adminhtml/Product/Grouped/AssociatedProducts/ListAssociatedProducts/Product.php @@ -0,0 +1,60 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\GroupedProduct\Test\Block\Adminhtml\Product\Grouped\AssociatedProducts\ListAssociatedProducts; + +use Mtf\Block\Form; + +/** + * Class Product + * Assigned product row to grouped option + */ +class Product extends Form +{ + /** + * Fill product options + * + * @param string $qtyValue + * @return void + */ + public function fillOption($qtyValue) + { + $mapping = $this->dataMapping($qtyValue); + $this->_fill($mapping); + } + + /** + * Get product options + * + * @param array $fields + * @return array + */ + public function getOption(array $fields) + { + $mapping = $this->dataMapping($fields); + $newFields = $this->_getData($mapping); + $newFields['name'] = $this->_rootElement->find('td.col-name')->getText(); + return $newFields; + } +} diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Adminhtml/Product/Grouped/AssociatedProducts/ListAssociatedProducts/Product.xml b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Adminhtml/Product/Grouped/AssociatedProducts/ListAssociatedProducts/Product.xml new file mode 100644 index 0000000000000000000000000000000000000000..909234b8b1fa95ecddc864cd6d3bb36e5357a881 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Adminhtml/Product/Grouped/AssociatedProducts/ListAssociatedProducts/Product.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" ?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<mapping strict="1"> + <fields> + <qty> + <selector>[name$='[qty]']</selector> + </qty> + </fields> +</mapping> diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Adminhtml/Product/Grouped/AssociatedProducts/Search/Grid.php b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Adminhtml/Product/Grouped/AssociatedProducts/Search/Grid.php new file mode 100644 index 0000000000000000000000000000000000000000..ee9598ef65b80c87561dd644fc59ff1488d4952f --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Adminhtml/Product/Grouped/AssociatedProducts/Search/Grid.php @@ -0,0 +1,70 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\GroupedProduct\Test\Block\Adminhtml\Product\Grouped\AssociatedProducts\Search; + +use Mtf\Client\Element; +use Magento\Backend\Test\Block\Widget\Grid as GridInterface; + +/** + * Class Grid + * 'Add Products to Grouped product list' grid + */ +class Grid extends GridInterface +{ + /** + * 'Add Selected Products' button + * + * @var string + */ + protected $addProducts = 'button.add'; + + /** + * Filters array mapping + * + * @var array + */ + protected $filters = [ + 'name' => [ + 'selector' => '#grouped_grid_popup_filter_name' + ] + ]; + + /** + * An element locator which allows to select entities in grid + * + * @var string + */ + protected $selectItem = '[data-column=entity_id] input'; + + /** + * Press 'Add Selected Products' button + * + * @return void + */ + public function addProducts() + { + $this->_rootElement->find($this->addProducts)->click(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Adminhtml/Product/ProductForm.xml b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Adminhtml/Product/ProductForm.xml new file mode 100644 index 0000000000000000000000000000000000000000..75d062205693372768fb598010fb7f9980a2d7a9 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Adminhtml/Product/ProductForm.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" ?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<tabs> + <grouped> + <class>\Magento\GroupedProduct\Test\Block\Adminhtml\Product\Grouped\AssociatedProducts</class> + <selector>#product_info_tabs_product-details</selector> + <strategy>css selector</strategy> + </grouped> +</tabs> diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Catalog/Product/View.php b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Catalog/Product/View.php new file mode 100755 index 0000000000000000000000000000000000000000..3c0134fa4cfe95bca48430e40d24ed1ee629d99e --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Catalog/Product/View.php @@ -0,0 +1,92 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\GroupedProduct\Test\Block\Catalog\Product; + +use Magento\Catalog\Test\Block\Product\View as ParentView; + +/** + * Class View + * Grouped product view block on the product page + */ +class View extends ParentView +{ + /** + * Block grouped product + * + * @var string + */ + protected $groupedProductBlock = '.wrapper.table.grouped'; + + /** + * This member holds the class name of the tier price block. + * + * @var string + */ + protected $formatTierPrice = "//tbody[%row-number%]//ul[contains(@class,'tier')]//*[@class='item'][%line-number%]"; + + /** + * This member holds the class name of the special price block. + * + * @var string + */ + protected $formatSpecialPrice = ".product-info-main tr:nth-child(%row-number%) .price-box"; + + /** + * Get grouped product block + * + * @return \Magento\GroupedProduct\Test\Block\Catalog\Product\View\Type\Grouped + */ + public function getGroupedProductBlock() + { + return $this->blockFactory->create( + 'Magento\GroupedProduct\Test\Block\Catalog\Product\View\Type\Grouped', + [ + 'element' => $this->_rootElement->find($this->groupedProductBlock) + ] + ); + } + + /** + * Change tier price selector + * + * @param int $index + * @return void + */ + public function itemTierPriceProductBlock($index) + { + $this->tierPricesSelector = str_replace('%row-number%', $index, $this->formatTierPrice); + } + + /** + * Change tier price selector + * + * @param int $index + * @return void + */ + public function itemPriceProductBlock($index) + { + $this->priceBlock = str_replace('%row-number%', $index, $this->formatSpecialPrice); + } +} diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Catalog/Product/View/Type/Grouped.php b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Catalog/Product/View/Type/Grouped.php new file mode 100644 index 0000000000000000000000000000000000000000..ce889be6f7368673e68fb0c29a39ec7374e78ab0 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Catalog/Product/View/Type/Grouped.php @@ -0,0 +1,52 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\GroupedProduct\Test\Block\Catalog\Product\View\Type; + +use Mtf\Block\Block; + +/** + * Class Grouped + * Grouped product blocks on frontend + */ +class Grouped extends Block +{ + /** + * Selector qty for sub product + * + * @var string + */ + protected $qtySubProduct = '[name="super_group[%d]"]'; + + /** + * Get qty for subProduct + * + * @param int $subProductId + * @return string + */ + public function getQty($subProductId) + { + return $this->_rootElement->find(sprintf($this->qtySubProduct, $subProductId))->getValue(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Constraint/AbstractAssertPriceOnGroupedProductPage.php b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Constraint/AbstractAssertPriceOnGroupedProductPage.php new file mode 100644 index 0000000000000000000000000000000000000000..61efaeeb4e23e23047c937db44c7494e005e9900 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Constraint/AbstractAssertPriceOnGroupedProductPage.php @@ -0,0 +1,91 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\GroupedProduct\Test\Constraint; + +use Mtf\Fixture\InjectableFixture; +use Mtf\Constraint\AbstractConstraint; +use Magento\GroupedProduct\Test\Fixture\CatalogProductGrouped; +use Magento\GroupedProduct\Test\Page\Product\CatalogProductView; +use Magento\Catalog\Test\Constraint\AssertPriceOnProductPageInterface; + +/** + * Class AbstractAssertPriceOnGroupedProductPage + * Assert that displayed price on grouped product page equals passed from fixture + */ +abstract class AbstractAssertPriceOnGroupedProductPage extends AbstractConstraint +{ + /** + * Format error message + * + * @var string + */ + protected $errorMessage; + + /** + * Successful message + * + * @var string + */ + protected $successfulMessage; + + /** + * Verify product price on grouped product view page + * + * @param CatalogProductGrouped $product + * @param CatalogProductView $catalogProductView + * @param AssertPriceOnProductPageInterface $object + * @param string $typePrice [optional] + * @return bool|string + */ + protected function processAssertPrice( + CatalogProductGrouped $product, + CatalogProductView $catalogProductView, + AssertPriceOnProductPageInterface $object, + $typePrice = '' + ) { + $catalogProductView->init($product); + $catalogProductView->open(); + + $groupedData = $product->getAssociated(); + /** @var InjectableFixture $subProduct */ + foreach ($groupedData['products'] as $key => $subProduct) { + //Process assertions + $catalogProductView->getGroupedViewBlock() + ->{'item' . $typePrice . 'PriceProductBlock'}(++$key); + $object->setErrorMessage(sprintf($this->errorMessage, $subProduct->getData('name'))); + $object->assertPrice($subProduct, $catalogProductView, 'Grouped'); + } + } + + /** + * Returns a string representation of the object + * + * @return string + */ + public function toString() + { + return $this->successfulMessage; + } +} diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Constraint/AssertGroupedPriceOnGroupedProductPage.php b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Constraint/AssertGroupedPriceOnGroupedProductPage.php new file mode 100644 index 0000000000000000000000000000000000000000..246a06f43ee8da3199d4b140e514e2cc340b44dd --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Constraint/AssertGroupedPriceOnGroupedProductPage.php @@ -0,0 +1,72 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\GroupedProduct\Test\Constraint; + +use Magento\GroupedProduct\Test\Fixture\CatalogProductGrouped; +use Magento\GroupedProduct\Test\Page\Product\CatalogProductView; +use Magento\Catalog\Test\Constraint\AssertProductGroupedPriceOnProductPage; + +/** + * Class AssertGroupedPriceOnGroupedProductPage + */ +class AssertGroupedPriceOnGroupedProductPage extends AbstractAssertPriceOnGroupedProductPage +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Format error message + * + * @var string + */ + protected $errorMessage = 'This "%s" product\'s grouped price on product page NOT equals passed from fixture.'; + + /** + * Successful message + * + * @var string + */ + protected $successfulMessage = 'Displayed grouped price on grouped product page equals to passed from a fixture.'; + + /** + * Assert that displayed grouped price on grouped product page equals passed from fixture + * + * @param CatalogProductView $catalogProductView + * @param CatalogProductGrouped $product + * @param AssertProductGroupedPriceOnProductPage $groupedPrice + * @return void + */ + public function processAssert( + CatalogProductView $catalogProductView, + CatalogProductGrouped $product, + AssertProductGroupedPriceOnProductPage $groupedPrice + ) { + $this->processAssertPrice($product, $catalogProductView, $groupedPrice); + } +} diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Constraint/AssertGroupedProductForm.php b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Constraint/AssertGroupedProductForm.php new file mode 100644 index 0000000000000000000000000000000000000000..b85ac418f65fcbe4881b5c0719c54165913b78b2 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Constraint/AssertGroupedProductForm.php @@ -0,0 +1,83 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\GroupedProduct\Test\Constraint; + +use Mtf\Fixture\FixtureInterface; +use Magento\Catalog\Test\Constraint\AssertProductForm; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductEdit; + +/** + * Class AssertGroupedProductForm + */ +class AssertGroupedProductForm extends AssertProductForm +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Assert form data equals fixture data + * + * @param FixtureInterface $product + * @param CatalogProductIndex $productGrid + * @param CatalogProductEdit $productPage + * @return void + */ + public function processAssert( + FixtureInterface $product, + CatalogProductIndex $productGrid, + CatalogProductEdit $productPage + ) { + $filter = ['sku' => $product->getSku()]; + $productGrid->open()->getProductGrid()->searchAndOpen($filter); + $fieldsForm = $productPage->getForm()->getData($product); + $fieldsFixture = $this->prepareFixtureData($product->getData()); + $fieldsFixture['associated'] = $this->prepareGroupedOptions($fieldsFixture['associated']); + + $errors = $this->verifyData($fieldsFixture, $fieldsForm); + \PHPUnit_Framework_Assert::assertEmpty($errors, $errors); + } + + /** + * Prepare Grouped Options array from preset + * + * @param array $fields + * @return array + */ + protected function prepareGroupedOptions(array $fields) + { + $result = []; + foreach ($fields['assigned_products'] as $key => $item) { + $result['assigned_products'][$key]['name'] = $item['name']; + $result['assigned_products'][$key]['qty'] = $item['qty']; + } + + return $result; + } +} diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Constraint/AssertGroupedProductsDefaultQty.php b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Constraint/AssertGroupedProductsDefaultQty.php new file mode 100644 index 0000000000000000000000000000000000000000..06e42f6130f991fbd91b10f687e2a358c189ac44 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Constraint/AssertGroupedProductsDefaultQty.php @@ -0,0 +1,75 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\GroupedProduct\Test\Constraint; + +use Mtf\Constraint\AbstractConstraint; +use Magento\GroupedProduct\Test\Page\Product\CatalogProductView; +use Magento\GroupedProduct\Test\Fixture\CatalogProductGrouped; + +/** + * Class AssertGroupedProductsDefaultQty + */ +class AssertGroupedProductsDefaultQty extends AbstractConstraint +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Assert that default qty for sub products in grouped product displays according to dataset on product page. + * + * @param CatalogProductView $groupedProductView + * @param CatalogProductGrouped $product + * @return void + */ + public function processAssert(CatalogProductView $groupedProductView, CatalogProductGrouped $product) + { + $groupedProductView->init($product); + $groupedProductView->open(); + $groupedBlock = $groupedProductView->getGroupedViewBlock()->getGroupedProductBlock(); + $groupedProduct = $product->getData(); + + foreach ($groupedProduct['associated']['assigned_products'] as $item) { + \PHPUnit_Framework_Assert::assertEquals( + $groupedBlock->getQty($item['id']), + $item['qty'], + 'Default qty for sub product "' . $item['name'] . '" in grouped product according to dataset.' + ); + } + } + + /** + * Text of Visible in grouped assert for default qty for sub products + * + * @return string + */ + public function toString() + { + return 'Default qty for sub products in grouped product displays according to dataset on product page.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Constraint/AssertSpecialPriceOnGroupedProductPage.php b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Constraint/AssertSpecialPriceOnGroupedProductPage.php new file mode 100644 index 0000000000000000000000000000000000000000..35c2f9babbd39d80dfea4527a7192133940900cd --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Constraint/AssertSpecialPriceOnGroupedProductPage.php @@ -0,0 +1,72 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\GroupedProduct\Test\Constraint; + +use Magento\GroupedProduct\Test\Fixture\CatalogProductGrouped; +use Magento\GroupedProduct\Test\Page\Product\CatalogProductView; +use Magento\Catalog\Test\Constraint\AssertProductSpecialPriceOnProductPage; + +/** + * Class AssertSpecialPriceOnGroupedProductPage + */ +class AssertSpecialPriceOnGroupedProductPage extends AbstractAssertPriceOnGroupedProductPage +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Format error message + * + * @var string + */ + protected $errorMessage = 'This "%s" product\'s special price on product page NOT equals passed from fixture.'; + + /** + * Successful message + * + * @var string + */ + protected $successfulMessage = 'Special price on grouped product page equals passed from fixture.'; + + /** + * Assert that displayed grouped price on grouped product page equals passed from fixture + * + * @param CatalogProductView $catalogProductView + * @param CatalogProductGrouped $product + * @param AssertProductSpecialPriceOnProductPage $specialPrice + * @return void + */ + public function processAssert( + CatalogProductView $catalogProductView, + CatalogProductGrouped $product, + AssertProductSpecialPriceOnProductPage $specialPrice + ) { + $this->processAssertPrice($product, $catalogProductView, $specialPrice); + } +} diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Constraint/AssertTierPriceOnGroupedProductPage.php b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Constraint/AssertTierPriceOnGroupedProductPage.php new file mode 100644 index 0000000000000000000000000000000000000000..315be6c14d9d25e4668ad1033348db5a6f08385c --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Constraint/AssertTierPriceOnGroupedProductPage.php @@ -0,0 +1,72 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\GroupedProduct\Test\Constraint; + +use Magento\GroupedProduct\Test\Fixture\CatalogProductGrouped; +use Magento\GroupedProduct\Test\Page\Product\CatalogProductView; +use Magento\Catalog\Test\Constraint\AssertProductTierPriceOnProductPage; + +/** + * Class AssertTierPriceOnGroupedProductPage + */ +class AssertTierPriceOnGroupedProductPage extends AbstractAssertPriceOnGroupedProductPage +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Format error message + * + * @var string + */ + protected $errorMessage = 'For "%s" Product tier price on product page is not correct.'; + + /** + * Successful message + * + * @var string + */ + protected $successfulMessage = 'Tier price is displayed on the grouped product page.'; + + /** + * Assert that displayed grouped price on grouped product page equals passed from fixture + * + * @param CatalogProductView $catalogProductView + * @param CatalogProductGrouped $product + * @param AssertProductTierPriceOnProductPage $tierPrice + * @return void + */ + public function processAssert( + CatalogProductView $catalogProductView, + CatalogProductGrouped $product, + AssertProductTierPriceOnProductPage $tierPrice + ) { + $this->processAssertPrice($product, $catalogProductView, $tierPrice, 'Tier'); + } +} diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Fixture/CatalogProductGrouped.php b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Fixture/CatalogProductGrouped.php index 7944dfd15aa15c6a232fb517336e56c215e09a5e..8137dfa827a54a2a058091f6a65787f95bb36186 100644 --- a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Fixture/CatalogProductGrouped.php +++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Fixture/CatalogProductGrouped.php @@ -89,7 +89,6 @@ class CatalogProductGrouped extends InjectableFixture if (!isset($this->data['url_key']) && isset($this->data['name'])) { $this->data['url_key'] = trim(strtolower(preg_replace('#[^0-9a-z%]+#i', '-', $this->data['name'])), '-'); } - } protected $dataConfig = [ @@ -103,7 +102,6 @@ class CatalogProductGrouped extends InjectableFixture protected $defaultDataSet = [ 'name' => 'GroupedProduct_%isolation%', 'sku' => 'GroupedProduct_%isolation%', - 'price' => '100', 'tax_class' => 'Taxable Goods', 'description' => 'This is description for grouped product', 'short_description' => 'This is short description for grouped product', @@ -119,7 +117,7 @@ class CatalogProductGrouped extends InjectableFixture 'is_required' => '0', 'default_value' => '', 'input' => 'text', - 'source' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\CategoryIds' + 'source' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\CategoryIds', ]; protected $country_of_manufacture = [ @@ -477,7 +475,14 @@ class CatalogProductGrouped extends InjectableFixture protected $website_ids = [ 'attribute_code' => 'website_ids', 'backend_type' => 'virtual', - 'default_value' => 'Main Website', + 'default_value' => ['Main Website'], + 'group' => 'websites', + ]; + + protected $price = [ + 'attribute_code' => 'price', + 'backend_type' => 'virtual', + 'source' => 'Magento\GroupedProduct\Test\Fixture\CatalogProductGrouped\Price', ]; public function getCategoryIds() diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Fixture/CatalogProductGrouped.xml b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Fixture/CatalogProductGrouped.xml index 95e73b5137daf9676adcc83c527b5c9b5e66f461..4bd9649b5cd262e88d9d4281d9e52aa9c987e47c 100644 --- a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Fixture/CatalogProductGrouped.xml +++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Fixture/CatalogProductGrouped.xml @@ -343,7 +343,13 @@ <attribute_code>website_ids</attribute_code> <backend_type>virtual</backend_type> <default_value>Main Website</default_value> + <group>websites</group> </website_ids> + <price> + <attribute_code>price</attribute_code> + <backend_type>virtual</backend_type> + <source>'Magento\Catalog\Test\Fixture\CatalogProductSimple\Price</source> + </price> </fields> <data_set> <sku></sku> @@ -360,5 +366,6 @@ <input_prefix>product</input_prefix> </data_config> <repository_class>Magento\Catalog\Test\Repository\CatalogProductGrouped</repository_class> - <handler_interface>Magento\Catalog\Test\Handler\CatalogProductGrouped\CatalogProductGroupedInterface</handler_interface> + <handler_interface>Magento\Catalog\Test\Handler\CatalogProductGrouped\CatalogProductGroupedInterface + </handler_interface> </fixture> diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Fixture/CatalogProductGrouped/Associated.php b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Fixture/CatalogProductGrouped/Associated.php index 7f6acc8d1d50a6bac93a87bdf7c41f2b9e3abb09..9f0b5ff31f0c41f1d8ef0b8f692501f073639d76 100644 --- a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Fixture/CatalogProductGrouped/Associated.php +++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Fixture/CatalogProductGrouped/Associated.php @@ -72,6 +72,9 @@ class Associated implements FixtureInterface } if (!empty($this->data['products'])) { + $this->data['products'] = is_array($this->data['products']) + ? $this->data['products'] + : explode(',', $this->data['products']); foreach ($this->data['products'] as $key => $product) { list($fixture, $dataSet) = explode('::', $product); /** @var $productFixture InjectableFixture */ @@ -85,6 +88,7 @@ class Associated implements FixtureInterface $assignedProducts = & $this->data['assigned_products']; foreach (array_keys($assignedProducts) as $key) { + $assignedProducts[$key]['name'] = $this->data['products'][$key]->getName(); $assignedProducts[$key]['id'] = $this->data['products'][$key]->getId(); $assignedProducts[$key]['position'] = $key + 1; } @@ -137,14 +141,16 @@ class Associated implements FixtureInterface 'assigned_products' => [ [ 'id' => '%id%', + 'name' => '%item1_simple::getProductName%', 'position' => '%position%', - 'qty' => 5 + 'qty' => 1, ], [ 'id' => '%id%', + 'name' => '%item1_simple::getProductName%', 'position' => '%position%', - 'qty' => 6 - ] + 'qty' => 2, + ], ], 'products' => [ 'catalogProductSimple::default', @@ -155,14 +161,16 @@ class Associated implements FixtureInterface 'assigned_products' => [ [ 'id' => '%id%', + 'name' => '%item1_virtual::getProductName%', 'position' => '%position%', - 'qty' => 5 + 'qty' => 1, ], [ 'id' => '%id%', + 'name' => '%item1_virtual::getProductName%', 'position' => '%position%', - 'qty' => 6 - ] + 'qty' => 2, + ], ], 'products' => [ 'catalogProductVirtual::default', @@ -170,11 +178,9 @@ class Associated implements FixtureInterface ], ] ]; - if (!isset($presets[$name])) { return null; } - return $presets[$name]; } } diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Fixture/CatalogProductGrouped/Price.php b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Fixture/CatalogProductGrouped/Price.php new file mode 100644 index 0000000000000000000000000000000000000000..f045ffde4d5b10aa3079005270d0e786bd269800 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Fixture/CatalogProductGrouped/Price.php @@ -0,0 +1,58 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\GroupedProduct\Test\Fixture\CatalogProductGrouped; + +use Mtf\Fixture\FixtureInterface; +use Magento\Catalog\Test\Fixture\CatalogProductSimple\Price as ParentPrice; + +/** + * Class Price + * + * Data keys: + * - preset (Price verification preset name) + * - value (Price value) + */ +class Price extends ParentPrice implements FixtureInterface +{ + /** + * Preset for price + * + * @return array|null + */ + public function getPreset() + { + $presets = [ + 'starting-560' => [ + 'compare_price' => [ + 'price_starting' => '560.00', + ] + ], + ]; + if (!isset($presets[$this->currentPreset])) { + return null; + } + return $presets[$this->currentPreset]; + } +} diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Page/Product/CatalogProductView.php b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Page/Product/CatalogProductView.php new file mode 100755 index 0000000000000000000000000000000000000000..d0bf56970017ab5a2c1db5998830ea46ee7a6a3f --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Page/Product/CatalogProductView.php @@ -0,0 +1,60 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\GroupedProduct\Test\Page\Product; + +use Magento\Catalog\Test\Page\Product\CatalogProductView as ParentCatalogProductView; + +/** + * Class CatalogProductView + * Frontend grouped product view page + */ +class CatalogProductView extends ParentCatalogProductView +{ + const MCA = 'grouped/catalog/product/view'; + + /** + * Custom constructor + * + * @return void + */ + protected function _init() + { + $this->_blocks['groupedViewBlock'] = [ + 'name' => 'groupedViewBlock', + 'class' => 'Magento\GroupedProduct\Test\Block\Catalog\Product\View', + 'locator' => '.product-info-main', + 'strategy' => 'css selector', + ]; + parent::_init(); + } + + /** + * @return \Magento\GroupedProduct\Test\Block\Catalog\Product\View + */ + public function getGroupedViewBlock() + { + return $this->getBlockInstance('groupedViewBlock'); + } +} diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Page/Product/CatalogProductView.xml b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Page/Product/CatalogProductView.xml new file mode 100755 index 0000000000000000000000000000000000000000..925691cd6a4a4cffa1f500bad84a850067488879 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Page/Product/CatalogProductView.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" ?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<page mca="catalog/product/view"> + <block> + <name>groupedViewBlock</name> + <class>Magento\GroupedProduct\Test\Block\Catalog\Product\View</class> + <locator>.product-info-main</locator> + <strategy>css selector</strategy> + </block> +</page> diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Repository/CatalogProductGrouped.php b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Repository/CatalogProductGrouped.php index d97cbf8e1ce1aecbbc0af30ad2eeae4cd2944f99..de41d75a51d5c2871673dc5b4a6dfebcc8baa32c 100644 --- a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Repository/CatalogProductGrouped.php +++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Repository/CatalogProductGrouped.php @@ -45,7 +45,25 @@ class CatalogProductGrouped extends AbstractRepository $this->_data['default'] = [ 'name' => 'Test grouped product %isolation%', 'sku' => 'sku_test_grouped_product_%isolation%', - 'price' => ['value' => 120.00], + 'weight' => 30.0000, + 'category_ids' => ['presets' => 'default'], + 'associated' => ['preset' => 'defaultSimpleProduct'], + 'status' => 'Product online', + 'visibility' => 'Catalog, Search', + 'tax_class_id' => ['dataSet' => 'Taxable Goods'], + 'url_key' => 'test-grouped-product-%isolation%', + 'quantity_and_stock_status' => [ + 'qty' => 666.0000, + 'is_in_stock' => 'In Stock', + ], + 'website_ids' => ['Main Website'], + 'attribute_set_id' => ['dataSet' => 'default'], + ]; + + $this->_data['grouped_product_with_price'] = [ + 'name' => 'Test grouped product %isolation%', + 'sku' => 'sku_test_grouped_product_%isolation%', + 'price' => ['value' => '-', 'preset' => 'starting-560'], 'weight' => 30.0000, 'category_ids' => ['presets' => 'default'], 'associated' => ['preset' => 'defaultSimpleProduct'], diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/CreateGroupedProductEntityTest.php b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/CreateGroupedProductEntityTest.php new file mode 100755 index 0000000000000000000000000000000000000000..ed912e0c5b66412745e274be662d6fa69ffb8591 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/CreateGroupedProductEntityTest.php @@ -0,0 +1,112 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\GroupedProduct\Test\TestCase; + +use Mtf\TestCase\Injectable; +use Magento\Catalog\Test\Fixture\CatalogCategory; +use Magento\GroupedProduct\Test\Fixture\CatalogProductGrouped; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductNew; + +/** + * Test Creation for CreateGroupedProductEntity + * + * Preconditions: + * 1. Simple product is created. + * 2. Virtual product is created. + * + * Test Flow: + * 1. Login to the backend. + * 2. Navigate to Products > Catalog. + * 3. Start to create Grouped Product. + * 4. Fill in data according to data set. + * 5. Click "Add Products to Group" button and select products'. + * 6. Click "Add Selected Product" button + * 7. Save the Product. + * 8. Perform assertions. + * + * @group Grouped_Product_(MX) + * @ZephyrId MAGETWO-24877 + */ +class CreateGroupedProductEntityTest extends Injectable +{ + /** + * Page product on backend + * + * @var CatalogProductIndex + */ + protected $catalogProductIndex; + + /** + * New page on backend + * + * @var CatalogProductNew + */ + protected $catalogProductNew; + + /** + * Persist category + * + * @param CatalogCategory $category + * @return array + */ + public function __prepare(CatalogCategory $category) + { + $category->persist(); + return ['category' => $category]; + } + + /** + * Injection pages + * + * @param CatalogProductIndex $catalogProductIndexNewPage + * @param CatalogProductNew $catalogProductNewPage + * @return void + */ + public function __inject( + CatalogProductIndex $catalogProductIndexNewPage, + CatalogProductNew $catalogProductNewPage + ) { + $this->catalogProductIndex = $catalogProductIndexNewPage; + $this->catalogProductNew = $catalogProductNewPage; + } + + /** + * Test create grouped product + * + * @param CatalogProductGrouped $product + * @param CatalogCategory $category + * @return void + */ + public function test(CatalogProductGrouped $product, CatalogCategory $category) + { + //Steps + $this->catalogProductIndex->open(); + $this->catalogProductIndex->getGridPageActionBlock()->addProduct('grouped'); + $productBlockForm = $this->catalogProductNew->getForm(); + $productBlockForm->fill($product, null, $category); + $this->catalogProductNew->getFormAction()->save(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/CreateGroupedProductEntityTest/test.csv b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/CreateGroupedProductEntityTest/test.csv new file mode 100644 index 0000000000000000000000000000000000000000..6c8d715e10f0f2797f3007f5bb05f639657f78ad --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/CreateGroupedProductEntityTest/test.csv @@ -0,0 +1,9 @@ +"product/data/name";"product/data/sku";"product/data/quantity_and_stock_status/is_in_stock";"product/data/category";"product/data/description";"product/data/associated/products";"product/data/associated/preset";"product/data/short_description";"isRequired";"constraint" +"GroupedProduct %isolation%";"GroupedProduct_sku%isolation%";"In Stock";"category_%isolation%";"This is description for grouped product";"catalogProductSimple::simple_for_composite_products,catalogProductSimple::simple_for_composite_products";"defaultSimpleProduct";"This is short description for grouped product";"Yes";"assertProductSaveMessage, assertGroupedProductsDefaultQty" +"GroupedProduct %isolation%";"-";"In Stock";"-";"-";"catalogProductSimple::simple_for_composite_products,catalogProductSimple::simple_for_composite_products";"defaultSimpleProduct";"-";"No";"assertProductInStock, assertProductSkuAutoGenerated, assertProductSearchableBySku" +"GroupedProduct %isolation%";"GroupedProduct_sku%isolation%";"Out of Stock";"category_%isolation%";"-";"catalogProductSimple::simple_for_composite_products,catalogProductSimple::simple_for_composite_products";"defaultSimpleProduct";"-";"No";"assertProductOutOfStock" +"GroupedProduct %isolation%";"GroupedProduct_sku%isolation%";"In Stock";"category_%isolation%";"-";"catalogProductSimple::simple_for_composite_products,catalogProductSimple::simple_for_composite_products";"defaultSimpleProduct";"-";"No";"assertGroupedProductsDefaultQty, assertGroupedProductForm, assertProductPage" +"GroupedProduct %isolation%";"GroupedProduct_sku%isolation%";"In Stock";"category_%isolation%";"-";"catalogProductSimple::withSpecialPrice,catalogProductSimple::withSpecialPrice";"defaultSimpleProduct";"-";"No";"assertSpecialPriceOnGroupedProductPage, assertGroupedProductForm, assertProductPage" +"GroupedProduct %isolation%";"GroupedProduct_sku%isolation%";"In Stock";"category_%isolation%";"-";"catalogProductSimple::simple_with_group_price,catalogProductSimple::simple_with_group_price";"defaultSimpleProduct";"-";"No";"assertGroupedPriceOnGroupedProductPage, assertGroupedProductForm, assertProductPage" +"GroupedProduct %isolation%";"GroupedProduct_sku%isolation%";"In Stock";"category_%isolation%";"-";"catalogProductVirtual::virtual_product,catalogProductVirtual::virtual_product";"defaultVirtualProduct";"-";"Yes";"assertProductSaveMessage, assertGroupedProductsDefaultQty" +"GroupedProduct %isolation%";"GroupedProduct_sku%isolation%";"In Stock";"category_%isolation%";"-";"catalogProductSimple::simple_with_tier_price,catalogProductSimple::simple_with_tier_price";"defaultSimpleProduct";"-";"No";"assertTierPriceOnGroupedProductPage, assertGroupedProductForm, assertProductPage" diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/etc/global/constraint.xml b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/etc/global/constraint.xml new file mode 100644 index 0000000000000000000000000000000000000000..ee4fcf2cb0c6caacb2d5b491d332bf882a6bd683 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/etc/global/constraint.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" ?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<constraint> + <assertGroupedProductsDefaultQty module="Magento_GroupedProduct"> + <severeness>low</severeness> + </assertGroupedProductsDefaultQty> + <assertGroupedProductForm module="Magento_GroupedProduct"> + <severeness>low</severeness> + </assertGroupedProductForm> + <assertTierPriceOnGroupedProductPage module="Magento_GroupedProduct"> + <severeness>low</severeness> + </assertTierPriceOnGroupedProductPage> + <assertSpecialPriceOnGroupedProductPage module="Magento_GroupedProduct"> + <severeness>low</severeness> + </assertSpecialPriceOnGroupedProductPage> + <assertGroupedPriceOnGroupedProductPage module="Magento_GroupedProduct"> + <severeness>low</severeness> + </assertGroupedPriceOnGroupedProductPage> +</constraint> diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/etc/global/fixture.xml b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/etc/global/fixture.xml index 6e618562b008cc4c888516acca1a2637d2d5e672..8c5d35ae0c9f71f74bfe4d9ae3f61870086b43b5 100644 --- a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/etc/global/fixture.xml +++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/etc/global/fixture.xml @@ -28,20 +28,13 @@ <type>eav</type> <entity_type>catalog_product</entity_type> <product_type>grouped</product_type> - <collection>Magento\GroupedProduct\Model\Resource\Product\Collection</collection> + <collection>Magento\GroupedProduct\Model\Resource\Product\Type\Grouped\AssociatedProductsCollection</collection> <identifier>sku</identifier> <fields> <id> <attribute_code>id</attribute_code> <backend_type>virtual</backend_type> </id> - <grouped_products> - <attribute_code>grouped_selections</attribute_code> - <backend_type>virtual</backend_type> - <is_required>1</is_required> - <group>grouped</group> - <fixture>Magento\GroupedProduct\Test\Fixture\Grouped\Selections</fixture> - </grouped_products> </fields> <data_set> <sku /> diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Block/Product/View.php b/dev/tests/functional/tests/app/Magento/Review/Test/Block/Product/View.php index 57e24509a585ebfa9fd39a07afa8df9e13012670..768536202e63b6cea4f6afe9834b060e77a0d90c 100755 --- a/dev/tests/functional/tests/app/Magento/Review/Test/Block/Product/View.php +++ b/dev/tests/functional/tests/app/Magento/Review/Test/Block/Product/View.php @@ -39,28 +39,28 @@ class View extends Block * * @var string */ - protected $itemSelector = '.reviews.items .item.review'; + protected $itemSelector = '.review-items .review-item'; /** * Nickname selector * * @var string */ - protected $nicknameSelector = '.nickname'; + protected $nicknameSelector = '.review-author .review-details-value'; /** * Title selector * * @var string */ - protected $titleSelector = '.title'; + protected $titleSelector = '.review-title'; /** * Detail selector * * @var string */ - protected $detailSelector = '.content'; + protected $detailSelector = '.review-content'; /** * Selectors mapping diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Constraint/AssertProductRatingOnReviewPage.php b/dev/tests/functional/tests/app/Magento/Review/Test/Constraint/AssertProductRatingOnReviewPage.php index aec069bf2e271ba2c2e7e682a29b71d5333d1a94..6211b78e4ba0fb7d44214a0db69a5e7c24bc37fb 100755 --- a/dev/tests/functional/tests/app/Magento/Review/Test/Constraint/AssertProductRatingOnReviewPage.php +++ b/dev/tests/functional/tests/app/Magento/Review/Test/Constraint/AssertProductRatingOnReviewPage.php @@ -65,9 +65,9 @@ class AssertProductRatingOnReviewPage extends AbstractAssertForm ($reviewInitial && $reviewInitial->hasData('ratings')) ? $reviewInitial->getRatings() : [], $review->hasData('ratings') ? $review->getRatings() : [] ); - $ratingReview = $this->sortData($ratingReview, ['::title']); + $ratingReview = $this->sortDataByPath($ratingReview, '::title'); $ratingForm = $reviewEdit->getReviewForm()->getRatings(); - $ratingForm = $this->sortData($ratingForm, ['::title']); + $ratingForm = $this->sortDataByPath($ratingForm, '::title'); $error = $this->verifyData($ratingReview, $ratingForm); \PHPUnit_Framework_Assert::assertTrue(empty($error), $error); } diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/Block/Switcher.php b/dev/tests/functional/tests/app/Magento/Store/Test/Block/Switcher.php index 4b72b0a321ca5c14f26104abe0e3d1cf20a5b6bd..8e891f8a7b4aed1dfb79d7a12783277a0e21929c 100644 --- a/dev/tests/functional/tests/app/Magento/Store/Test/Block/Switcher.php +++ b/dev/tests/functional/tests/app/Magento/Store/Test/Block/Switcher.php @@ -44,7 +44,19 @@ class Switcher extends Block */ public function selectStoreView($name) { - $this->_rootElement->find($this->dropDownButton)->click(); - $this->_rootElement->find($name, Locator::SELECTOR_LINK_TEXT)->click(); + if ($this->_rootElement->find($this->dropDownButton)->isVisible() && ($this->getStoreView() !== $name)) { + $this->_rootElement->find($this->dropDownButton)->click(); + $this->_rootElement->find($name, Locator::SELECTOR_LINK_TEXT)->click(); + } + } + + /** + * Get store view + * + * @return string + */ + public function getStoreView() + { + return $this->_rootElement->find($this->dropDownButton)->getText(); } } diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/Fixture/Store.php b/dev/tests/functional/tests/app/Magento/Store/Test/Fixture/Store.php index 6b2549d2845803b9a6d31e3de7639490f12558a9..e530f73b84fc166bc5ddc7d198591dd63275f190 100644 --- a/dev/tests/functional/tests/app/Magento/Store/Test/Fixture/Store.php +++ b/dev/tests/functional/tests/app/Magento/Store/Test/Fixture/Store.php @@ -1,7 +1,5 @@ <?php /** - * Store fixture - * * Magento * * NOTICE OF LICENSE @@ -26,67 +24,119 @@ namespace Magento\Store\Test\Fixture; -use Mtf\Fixture\DataFixture; -use Mtf\Factory\Factory; +use Mtf\Fixture\InjectableFixture; -class Store extends DataFixture +/** + * Class Store + * Store View fixture + */ +class Store extends InjectableFixture { /** - * @param \Mtf\System\Config $configuration - * @param array $placeholders + * @var string */ - public function __construct(\Mtf\System\Config $configuration, array $placeholders = array()) - { - parent::__construct($configuration, $placeholders); - $this->_placeholders = $placeholders; - } + protected $repositoryClass = 'Magento\Store\Test\Repository\Store'; /** - * Initialize fixture data + * @var string */ - protected function _initData() + protected $handlerInterface = 'Magento\Store\Test\Handler\Store\StoreInterface'; + + protected $defaultDataSet = [ + 'group_id' => 'Main Website Store', + 'name' => 'Custom_Store_%isolation%', + 'code' => 'code_%isolation%', + 'is_active' => 'Enabled', + ]; + + protected $store_id = [ + 'attribute_code' => 'store_id', + 'backend_type' => 'smallint', + 'is_required' => '1', + 'default_value' => '', + 'input' => '', + ]; + + protected $code = [ + 'attribute_code' => 'code', + 'backend_type' => 'varchar', + 'is_required' => '', + 'default_value' => '', + 'input' => 'text', + ]; + + protected $website_id = [ + 'attribute_code' => 'website_id', + 'backend_type' => 'smallint', + 'is_required' => '', + 'default_value' => '0', + 'input' => '', + ]; + + protected $group_id = [ + 'attribute_code' => 'group_id', + 'backend_type' => 'smallint', + 'is_required' => '', + 'default_value' => '0', + 'input' => 'select', + ]; + + protected $name = [ + 'attribute_code' => 'name', + 'backend_type' => 'varchar', + 'is_required' => '', + 'default_value' => '', + 'input' => 'text', + ]; + + protected $sort_order = [ + 'attribute_code' => 'sort_order', + 'backend_type' => 'smallint', + 'is_required' => '', + 'default_value' => '0', + 'input' => 'text', + ]; + + protected $is_active = [ + 'attribute_code' => 'is_active', + 'backend_type' => 'smallint', + 'is_required' => '', + 'default_value' => '0', + 'input' => 'select', + ]; + + public function getStoreId() { - $this->_data = array( - 'fields' => array( - 'group' => array( - 'value' => 'Main Website Store', - 'input' => 'select' - ), - 'name' => array( - 'value' => 'DE%isolation%' - ), - 'code' => array( - 'value' => 'de%isolation%' - ), - 'is_active' => array( - 'value' => 'Enabled', - 'input' => 'select', - ), - ) - ); - - $this->_repository = Factory::getRepositoryFactory() - ->getMagentoStoreCustomStore($this->_dataConfig, $this->_data); + return $this->getData('store_id'); } + public function getCode() + { + return $this->getData('code'); + } - /** - * Create Store - * - * @return Store - */ - public function persist() + public function getWebsiteId() { - return Factory::getApp()->magentoStoreCreateStore($this); + return $this->getData('website_id'); + } + + public function getGroupId() + { + return $this->getData('group_id'); } - /** - * Get name - * - * @return string - */ public function getName() { - return $this->getData('fields/name/value'); + return $this->getData('name'); + } + + public function getSortOrder() + { + return $this->getData('sort_order'); + } + + public function getIsActive() + { + return $this->getData('is_active'); } } diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/Fixture/Store.xml b/dev/tests/functional/tests/app/Magento/Store/Test/Fixture/Store.xml new file mode 100644 index 0000000000000000000000000000000000000000..cd4f421f55cc2210d0749c073104562003680470 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Store/Test/Fixture/Store.xml @@ -0,0 +1,86 @@ +<?xml version="1.0" ?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<fixture class="Magento\Store\Test\Fixture\Store"> + <module>Magento_Store</module> + <type>flat</type> + <entity_type>store</entity_type> + <collection>Magento\Store\Model\Resource\Store\Collection</collection> + <fields> + <store_id> + <attribute_code>store_id</attribute_code> + <backend_type>smallint</backend_type> + <is_required>1</is_required> + <default_value></default_value> + <input></input> + </store_id> + <code> + <attribute_code>code</attribute_code> + <backend_type>varchar</backend_type> + <is_required></is_required> + <default_value></default_value> + <input>text</input> + </code> + <website_id> + <attribute_code>website_id</attribute_code> + <backend_type>smallint</backend_type> + <is_required></is_required> + <default_value>0</default_value> + <input></input> + </website_id> + <group_id> + <attribute_code>group_id</attribute_code> + <backend_type>smallint</backend_type> + <is_required></is_required> + <default_value>0</default_value> + <input>select</input> + </group_id> + <name> + <attribute_code>name</attribute_code> + <backend_type>varchar</backend_type> + <is_required></is_required> + <default_value></default_value> + <input>text</input> + </name> + <sort_order> + <attribute_code>sort_order</attribute_code> + <backend_type>smallint</backend_type> + <is_required></is_required> + <default_value>0</default_value> + <input>text</input> + </sort_order> + <is_active> + <attribute_code>is_active</attribute_code> + <backend_type>smallint</backend_type> + <is_required></is_required> + <default_value>0</default_value> + <input>select</input> + </is_active> + </fields> + <data_set></data_set> + <data_config></data_config> + <repository_class>Magento\Store\Test\Repository\Store</repository_class> + <handler_interface>Magento\Store\Test\Handler\Store\StoreInterface</handler_interface> +</fixture> diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/Handler/Curl/CreateStore.php b/dev/tests/functional/tests/app/Magento/Store/Test/Handler/Curl/CreateStore.php deleted file mode 100644 index 222d27febaef89caf6e5524e8892589507f4de86..0000000000000000000000000000000000000000 --- a/dev/tests/functional/tests/app/Magento/Store/Test/Handler/Curl/CreateStore.php +++ /dev/null @@ -1,116 +0,0 @@ -<?php -/** - * Magento - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://opensource.org/licenses/osl-3.0.php - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@magentocommerce.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade Magento to newer - * versions in the future. If you wish to customize Magento for your - * needs please refer to http://www.magentocommerce.com for more information. - * - * @spi - * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) - */ - -namespace Magento\Store\Test\Handler\Curl; - -use Mtf\Fixture\FixtureInterface; -use Mtf\Handler\Curl; -use Mtf\Util\Protocol\CurlInterface; -use Mtf\Util\Protocol\CurlTransport; -use Mtf\Util\Protocol\CurlTransport\BackendDecorator; -use Mtf\System\Config; - -/** - * Curl handler for persisting Magento store view - * - */ -class CreateStore extends Curl -{ - /** - * Prepare POST data for creating store view request - * - * @param array $params - * @return array - */ - protected function _prepareData($params) - { - $data = array(); - foreach ($params['fields'] as $name => $config) { - $data[$name] = $config['value']; - } - return $data; - } - - /** - * Get store id by store name - * - * @param string $storeName - * @return int - * @throws \UnexpectedValueException - */ - protected function _getStoreIdByStoreName($storeName) - { - //Set pager limit to 2000 in order to find created store view by name - $url = $_ENV['app_backend_url'] . 'admin/system_store/index/sort/store_title/dir/asc/limit/2000'; - $curl = new BackendDecorator(new CurlTransport(), new Config); - $curl->addOption(CURLOPT_HEADER, 1); - $curl->write(CurlInterface::POST, $url, '1.0'); - $response = $curl->read(); - - $expectedUrl = '/admin/system_store/editStore/store_id/'; - $expectedUrl = preg_quote($expectedUrl); - $expectedUrl = str_replace('/', '\/', $expectedUrl); - preg_match('/' . $expectedUrl . '([0-9]*)\/(.)*>' . $storeName . '<\/a>/', $response, $matches); - - if (empty($matches)) { - throw new \UnexpectedValueException('Cannot find store id'); - } - - return intval($matches[1]); - } - - /** - * Post request for persisting Magento Store View - * - * @param FixtureInterface $fixture - * @return array - * @throws \UnexpectedValueException - * @throws \UnderflowException - */ - public function persist(FixtureInterface $fixture = null) - { - $data = $this->_prepareData($fixture->getData()); - $data['store_id'] = ''; - $fields = array( - 'store' => $data, - 'store_action' => 'add', - 'store_type' => 'store', - ); - - $url = $_ENV['app_backend_url'] . 'admin/system_store/save/'; - $curl = new BackendDecorator(new CurlTransport(), new Config()); - $curl->write(CurlInterface::POST, $url, '1.0', array(), $fields); - $response = $curl->read(); - $curl->close(); - - if (!preg_match('/The store view has been saved/', $response)) { - throw new \UnderflowException('Store was\'t saved'); - } - - $data['id'] = $this->_getStoreIdByStoreName($fixture->getData('fields/name/value')); - - return $data; - } -} diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/Handler/Store/Curl.php b/dev/tests/functional/tests/app/Magento/Store/Test/Handler/Store/Curl.php new file mode 100644 index 0000000000000000000000000000000000000000..e7c2046822b2fc45ca09be3ea4ab74a868a96a5b --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Store/Test/Handler/Store/Curl.php @@ -0,0 +1,143 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Store\Test\Handler\Store; + +use Mtf\System\Config; +use Mtf\Fixture\FixtureInterface; +use Mtf\Util\Protocol\CurlInterface; +use Mtf\Util\Protocol\CurlTransport; +use Mtf\Util\Protocol\CurlTransport\BackendDecorator; +use Mtf\Handler\Curl as AbstractCurl; + +/** + * Class Curl + * Curl handler for creating Store view. + */ +class Curl extends AbstractCurl implements StoreInterface +{ + /** + * Url for saving data + * + * @var string + */ + protected $saveUrl = 'admin/system_store/save'; + + /** + * Mapping values for data + * + * @var array + */ + protected $mappingData = [ + 'group_id' => [ + 'Main Website Store' => 1 + ], + 'is_active' => [ + 'Enabled' => 1, + 'Disabled' => 0 + ], + ]; + + /** + * POST request for creating store + * + * @param FixtureInterface|null $fixture [optional] + * @return array + * @throws \Exception + */ + public function persist(FixtureInterface $fixture = null) + { + $data = $this->prepareData($fixture); + $url = $_ENV['app_backend_url'] . $this->saveUrl; + $curl = new BackendDecorator(new CurlTransport(), new Config()); + $curl->write(CurlInterface::POST, $url, '1.0', array(), $data); + $response = $curl->read(); + $curl->close(); + if (!strpos($response, 'data-ui-id="messages-message-success"')) { + throw new \Exception("Store View entity creating by curl handler was not successful! Response: $response"); + } + + return ['store_id' => $this->getStoreId($fixture->getName())]; + } + + /** + * Prepare data from text to values + * + * @param $fixture + * @return array + */ + protected function prepareData($fixture) + { + $data['store'] = $this->replaceMappingData($fixture->getData()); + $data['store_action'] = isset($data['store_action']) ? $data['store_action'] : 'add'; + $data['store_type'] = isset($data['store_type']) ? $data['store_type'] : 'store'; + + return $data; + } + + /** + * Get Store id by name after creating Store + * + * @param string $name + * @return int|null + * @throws \Exception + */ + protected function getStoreId($name) + { + //Set pager limit to 2000 in order to find created store view by name + $url = $_ENV['app_backend_url'] . 'admin/system_store/index/sort/store_title/dir/asc/limit/2000'; + $curl = new BackendDecorator(new CurlTransport(), new Config); + $curl->addOption(CURLOPT_HEADER, 1); + $curl->write(CurlInterface::POST, $url, '1.0'); + $response = $curl->read(); + + $expectedUrl = '/admin/system_store/editStore/store_id/'; + $expectedUrl = preg_quote($expectedUrl); + $expectedUrl = str_replace('/', '\/', $expectedUrl); + preg_match('/' . $expectedUrl . '([0-9]*)\/(.)*>' . $name . '<\/a>/', $response, $matches); + + if (empty($matches)) { + throw new \Exception('Cannot find store id'); + } + + return empty($matches[1]) ? null : $matches[1]; + } + + /** + * Encoded filter parameters + * + * @param array $filter + * @return string + */ + protected function encodeFilter(array $filter) + { + $result = []; + foreach ($filter as $name => $value) { + $result[] = "{$name}={$value}"; + } + $result = implode('&', $result); + + return base64_encode($result); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/Handler/Store/StoreInterface.php b/dev/tests/functional/tests/app/Magento/Store/Test/Handler/Store/StoreInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..4430bda6e296737a024dfe78f62a19c341667d5f --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Store/Test/Handler/Store/StoreInterface.php @@ -0,0 +1,35 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Store\Test\Handler\Store; + +use Mtf\Handler\HandlerInterface; + +/** + * Interface StoreInterface + */ +interface StoreInterface extends HandlerInterface +{ + // +} diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/Repository/CustomStore.php b/dev/tests/functional/tests/app/Magento/Store/Test/Repository/Store.php similarity index 53% rename from dev/tests/functional/tests/app/Magento/Store/Test/Repository/CustomStore.php rename to dev/tests/functional/tests/app/Magento/Store/Test/Repository/Store.php index 2911dbc2b3d1c7c8fa4f2f58f5e0bb865e51e29c..88d566f66e392f0d29c83c8c279ad2bf2420ea64 100644 --- a/dev/tests/functional/tests/app/Magento/Store/Test/Repository/CustomStore.php +++ b/dev/tests/functional/tests/app/Magento/Store/Test/Repository/Store.php @@ -27,38 +27,38 @@ namespace Magento\Store\Test\Repository; use Mtf\Repository\AbstractRepository; /** - * Class Custom Store Repository - * + * Class Store + * Data for creation Catalog Price Rule */ -class CustomStore extends AbstractRepository +class Store extends AbstractRepository { /** - * {@inheritdoc} + * @constructor + * @param array $defaultConfig + * @param array $defaultData + * + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function __construct(array $defaultConfig = array(), array $defaultData = array()) + public function __construct(array $defaultConfig = [], array $defaultData = []) { - $this->_data['default'] = array( - 'config' => $defaultConfig, - 'data' => $defaultData - ); + $this->_data['default'] = [ + 'group_id' => 'Main Website Store', + 'name' => 'Custom_Store_%isolation%', + 'code' => 'code_%isolation%', + 'is_active' => 'Enabled', + 'store_id' => 1, + ]; + + $this->_data['All Store Views'] = [ + 'name' => 'All Store Views', + 'store_id' => 0, + ]; - $this->_data['custom_store']['data'] = array( - 'fields' => array( - 'group_id' => array( - 'value' => '%store_group%', - 'input' => 'select' - ), - 'name' => array( - 'value' => 'StoreView%isolation%' - ), - 'code' => array( - 'value' => 'storeview%isolation%' - ), - 'is_active' => array( - 'value' => '1', - 'input' => 'select', - ) - ) - ); + $this->_data['german'] = [ + 'group_id' => 'Main Website Store', + 'name' => 'DE%isolation%', + 'code' => 'de%isolation%', + 'is_active' => 'Enabled', + ]; } } diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/StoreTest.php b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/StoreTest.php index 91a2df8e1c4e2e62356135a391249953bab5bdc4..a7826ac2da17eefc22285577fc4bd73a29b2b1f3 100644 --- a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/StoreTest.php +++ b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/StoreTest.php @@ -44,22 +44,23 @@ class StoreTest extends Functional */ public function testCreateNewLocalizedStoreView() { - $storeFixture = Factory::getFixtureFactory()->getMagentoStoreStore(); + $objectManager = Factory::getObjectManager(); + $storeFixture = $objectManager->create('\Magento\Store\Test\Fixture\Store', ['dataSet' => 'german']); $storeListPage = Factory::getPageFactory()->getAdminSystemStore(); $storeListPage->open(); - $storeListPage->getPageActionsBlock()->addStoreView(); + $storeListPage->getGridPageActions()->addStoreView(); $newStorePage = Factory::getPageFactory()->getAdminSystemStoreNewStore(); - $newStorePage->getFormBlock()->fill($storeFixture); - $newStorePage->getPageActionsBlock()->clickSave(); + $newStorePage->getStoreForm()->fill($storeFixture); + $newStorePage->getFormPageActions()->save(); $storeListPage->getMessagesBlock()->assertSuccessMessage(); $this->assertContains( 'The store view has been saved', $storeListPage->getMessagesBlock()->getSuccessMessages() ); $this->assertTrue( - $storeListPage->getGridBlock()->isStoreExists($storeFixture->getName()) + $storeListPage->getStoreGrid()->isStoreExists($storeFixture->getName()) ); $cachePage = Factory::getPageFactory()->getAdminCache(); diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/etc/curl/di.xml b/dev/tests/functional/tests/app/Magento/Store/Test/etc/curl/di.xml new file mode 100644 index 0000000000000000000000000000000000000000..5299f3cbd8e82fd696cd1745eb5a16c651981a54 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Store/Test/etc/curl/di.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" ?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd"> +<preference for="Magento\Store\Test\Handler\Store\StoreInterface" type="\Magento\Store\Test\Handler\Store\Curl" /> +</config> diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Repository/TaxRate.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Repository/TaxRate.php index 79f847e4fbaa453d4794b671047d4585a1f75fa7..c6dca29436eaaa756bce1c41ac0cb6550450bbd8 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/Repository/TaxRate.php +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Repository/TaxRate.php @@ -82,6 +82,7 @@ class TaxRate extends AbstractRepository 'rate' => '8.375', 'tax_country_id' => 'United States', 'tax_region_id' => 'New York', + 'tax_postcode' => '*', ]; $this->_data['us_ny_rate_8_1'] = [ @@ -89,6 +90,7 @@ class TaxRate extends AbstractRepository 'rate' => '8.1', 'tax_country_id' => 'United States', 'tax_region_id' => 'New York', + 'tax_postcode' => '*', ]; $this->_data['paypal_rate_8_25'] = [ diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Repository/TaxRule.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Repository/TaxRule.php index 5e6b4807ce9b97c77f20faeeef2e7f0508572e5a..e006d07610ce1b34823183bcacfbaed6f6410957 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/Repository/TaxRule.php +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Repository/TaxRule.php @@ -47,6 +47,8 @@ class TaxRule extends AbstractRepository 1 => 'us_ny_rate_8_375', ] ], + 'priority' => '0', + 'position' => '0', ]; $this->_data['us_ca_ny_rule'] = [ @@ -80,6 +82,8 @@ class TaxRule extends AbstractRepository 0 => 'uk_full_tax_rate', ], ], + 'priority' => '0', + 'position' => '0', ]; $this->_data['tax_rule_default'] = [ diff --git a/dev/tests/functional/tests/app/Magento/Theme/Test/Block/Html/Footer.php b/dev/tests/functional/tests/app/Magento/Theme/Test/Block/Html/Footer.php index b864569ac4c28b7227832eb1fc3f608d3b26773a..e8c6933006ce07de0866c7d41439a94005f4bb05 100644 --- a/dev/tests/functional/tests/app/Magento/Theme/Test/Block/Html/Footer.php +++ b/dev/tests/functional/tests/app/Magento/Theme/Test/Block/Html/Footer.php @@ -40,6 +40,13 @@ class Footer extends Block */ protected $linkSelector = '//*[contains(@class, "links")]//a[contains(text(), "%s")]'; + /** + * Variable selector + * + * @var string + */ + protected $variableSelector = './/div[contains(@class, "links")]/*[text()="%s"]'; + /** * Click on link by name * @@ -55,4 +62,18 @@ class Footer extends Block } $link->click(); } + + /** + * Check Variable visibility by html value + * + * @param string $htmlValue + * @return bool + */ + public function checkVariable($htmlValue) + { + return $this->_rootElement->find( + sprintf($this->variableSelector, $htmlValue), + Locator::SELECTOR_XPATH + )->isVisible(); + } } diff --git a/dev/tests/functional/tests/app/Magento/Theme/Test/Block/Html/Title.php b/dev/tests/functional/tests/app/Magento/Theme/Test/Block/Html/Title.php index b46afb86bb63dd185be049a3fdf45d0c264d3653..2f96684c3065e8cccb4503c1b1d2629789ae4c51 100644 --- a/dev/tests/functional/tests/app/Magento/Theme/Test/Block/Html/Title.php +++ b/dev/tests/functional/tests/app/Magento/Theme/Test/Block/Html/Title.php @@ -33,7 +33,7 @@ use Mtf\Block\Block; class Title extends Block { /** - * Get title of current category + * Get title of current page * * @return string */ diff --git a/dev/tests/functional/tests/app/Magento/Theme/Test/Block/Links.php b/dev/tests/functional/tests/app/Magento/Theme/Test/Block/Links.php index 41120ea7989925890f581f148bcfb1c8ed162cca..5217cc42de342803687febfe69a7533920a9fa26 100644 --- a/dev/tests/functional/tests/app/Magento/Theme/Test/Block/Links.php +++ b/dev/tests/functional/tests/app/Magento/Theme/Test/Block/Links.php @@ -30,11 +30,25 @@ use Mtf\Client\Element; use Mtf\Client\Element\Locator; /** + * Class Links * Page Top Links block - * */ class Links extends Block { + /** + * Selector for qty products on compare + * + * @var string + */ + protected $qtyCompareProducts = '.compare .counter.qty'; + + /** + * Link selector + * + * @var string + */ + protected $link = '//a[contains(text(), "%s")]'; + /** * Open Link by title * @@ -43,9 +57,10 @@ class Links extends Block */ public function openLink($linkTitle) { - $this->_rootElement - ->find('//a[contains(text(), "' . $linkTitle . '")]', Locator::SELECTOR_XPATH) - ->click(); + $link = $this->_rootElement->find(sprintf($this->link, $linkTitle), Locator::SELECTOR_XPATH); + if ($link->isVisible()) { + $link->click(); + } } /** @@ -56,8 +71,33 @@ class Links extends Block */ public function isLinkVisible($linkTitle) { - return $this->_rootElement - ->find('//a[contains(text(), "' . $linkTitle . '")]', Locator::SELECTOR_XPATH) - ->isVisible(); + return $this->_rootElement->find(sprintf($this->link, $linkTitle), Locator::SELECTOR_XPATH)->isVisible(); + } + + /** + * Get the number of products added to compare list + * + * @return string|bool + */ + public function getQtyInCompareList() + { + $compareProductLink = $this->_rootElement->find($this->qtyCompareProducts); + if ($compareProductLink->isVisible()) { + preg_match_all('/^\d+/', $compareProductLink->getText(), $matches); + return $matches[0][0]; + } else { + return false; + } + } + + /** + * Get url from link + * + * @param string $linkTitle + * @return string + */ + public function getLinkUrl($linkTitle) + { + return trim($this->_rootElement->find(sprintf($this->link, $linkTitle), Locator::SELECTOR_XPATH)->getUrl()); } } diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Block/Adminhtml/Catalog/Edit/Form.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Block/Adminhtml/Catalog/Edit/UrlRewriteForm.php similarity index 76% rename from dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Block/Adminhtml/Catalog/Edit/Form.php rename to dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Block/Adminhtml/Catalog/Edit/UrlRewriteForm.php index bbd0b6da9bd1cddb46959256625c3ce92321ea0c..cec8de81e554e8a96840e4f4a98d8968c9ae55ad 100644 --- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Block/Adminhtml/Catalog/Edit/Form.php +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Block/Adminhtml/Catalog/Edit/UrlRewriteForm.php @@ -26,31 +26,41 @@ namespace Magento\UrlRewrite\Test\Block\Adminhtml\Catalog\Edit; use Mtf\Client\Element; use Mtf\Fixture\FixtureInterface; -use Magento\Backend\Test\Block\Widget\Form as FormWidget; +use Magento\Backend\Test\Block\Widget\Form; /** - * Class Form + * Class UrlRewriteForm * Catalog URL rewrite edit form */ -class Form extends FormWidget +class UrlRewriteForm extends Form { /** * Fill the root form * * @param FixtureInterface $fixture * @param Element|null $element + * @param array $replace [optional] * @return $this */ - public function fill(FixtureInterface $fixture, Element $element = null) - { + public function fill( + FixtureInterface $fixture, + Element $element = null, + array $replace = [] + ) { $data = $fixture->getData(); - $getData = $this->getData(); - if (!$getData['target_path']) { + if (empty($this->getData()['target_path']) && !isset($data['target_path'])) { $entity = $fixture->getDataFieldConfig('id_path')['source']->getEntity(); $data['target_path'] = $entity->hasData('identifier') ? $entity->getIdentifier() : $entity->getUrlKey() . '.html'; } + + foreach ($replace as $key => $pairs) { + if (isset($data[$key])) { + $data[$key] = str_replace(array_keys($pairs), $pairs, $data[$key]); + } + } + // TODO: delete line after removing old fixture $fields = isset($data['fields']) ? $data['fields'] : $data; $mapping = $this->dataMapping($fields); diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Block/Adminhtml/Catalog/Edit/Form.xml b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Block/Adminhtml/Catalog/Edit/UrlRewriteForm.xml similarity index 100% rename from dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Block/Adminhtml/Catalog/Edit/Form.xml rename to dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Block/Adminhtml/Catalog/Edit/UrlRewriteForm.xml diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Block/Adminhtml/Selector.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Block/Adminhtml/Selector.php index d55a83a9a4442ed025005cc3ba8c118f94e13417..c987eeef5a1dc8fe56448ede857d71868a0ceef3 100644 --- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Block/Adminhtml/Selector.php +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Block/Adminhtml/Selector.php @@ -38,6 +38,7 @@ class Selector extends Block * Select URL type * * @param string $urlrewriteType + * @return void */ public function selectType($urlrewriteType) { diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertPageByUrlRewriteIsNotFound.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertPageByUrlRewriteIsNotFound.php index bf78bda113e33918d0976f340166fc00d95cb139..1862fc3296473e0681675becff722ec0835a161f 100644 --- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertPageByUrlRewriteIsNotFound.php +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertPageByUrlRewriteIsNotFound.php @@ -51,8 +51,8 @@ class AssertPageByUrlRewriteIsNotFound extends AbstractConstraint * Checking the server response 404 page on frontend * * @param Browser $browser - * @param UrlRewrite $productRedirect * @param CatalogProductView $catalogProductView + * @param UrlRewrite $productRedirect * @return void */ public function processAssert( diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteCmsPageRedirect.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteCustomSearchRedirect.php similarity index 58% rename from dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteCmsPageRedirect.php rename to dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteCustomSearchRedirect.php index 8a8988192c5009664d7ec988b3b9bd1281fd6bf1..2944bfa47c76854f8bfe9faa0436f0de93f7ef26 100644 --- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteCmsPageRedirect.php +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteCustomSearchRedirect.php @@ -27,13 +27,13 @@ namespace Magento\UrlRewrite\Test\Constraint; use Mtf\Client\Browser; use Mtf\Constraint\AbstractConstraint; use Magento\UrlRewrite\Test\Fixture\UrlRewrite; -use Magento\Cms\Test\Fixture\CmsPage; +use Magento\Catalog\Test\Page\Category\CatalogCategoryView; /** - * Class AssertUrlRewriteCmsPageRedirect - * Assert that created CMS Page URL Redirect lead to appropriate page in frontend + * Class AssertUrlRewriteCustomSearchRedirect + * Assert that product was found on search page */ -class AssertUrlRewriteCmsPageRedirect extends AbstractConstraint +class AssertUrlRewriteCustomSearchRedirect extends AbstractConstraint { /** * Constraint severeness @@ -43,46 +43,39 @@ class AssertUrlRewriteCmsPageRedirect extends AbstractConstraint protected $severeness = 'low'; /** - * URL for CMS Page - * - * @var string - */ - protected $url = 'cms/page/view/page_id/'; - - /** - * Assert that created CMS Page URL Redirect lead to appropriate page in frontend + * Assert that created entity was found on search page * + * @param UrlRewrite $initialRewrite * @param UrlRewrite $urlRewrite - * @param CmsPage $cmsPage * @param Browser $browser + * @param CatalogCategoryView $categoryView * @return void */ public function processAssert( + UrlRewrite $initialRewrite, UrlRewrite $urlRewrite, - CmsPage $cmsPage, - Browser $browser + Browser $browser, + CatalogCategoryView $categoryView ) { - $browser->open($_ENV['app_frontend_url'] . $urlRewrite->getRequestPath()); - $url = $urlRewrite->getOptions() == 'No' + $urlRequestPath = $urlRewrite->hasData('request_path') ? $urlRewrite->getRequestPath() - : $this->url . $cmsPage->getPageId(); + : $initialRewrite->getRequestPath(); + $browser->open($_ENV['app_frontend_url'] . $urlRequestPath); + $entity = $initialRewrite->getDataFieldConfig('id_path')['source']->getEntity()->getName(); - \PHPUnit_Framework_Assert::assertEquals( - $browser->getUrl(), - $_ENV['app_frontend_url'] . $url, - 'URL rewrite CMS Page redirect false.' - . "\nExpected: " . $_ENV['app_frontend_url'] . $url - . "\nActual: " . $browser->getUrl() + \PHPUnit_Framework_Assert::assertTrue( + $categoryView->getListProductBlock()->isProductVisible($entity), + "Created entity '{$entity}' isn't found." ); } /** - * URL Redirect lead to appropriate page in frontend + * Returns a string representation of the object * * @return string */ public function toString() { - return 'URL Redirect lead to appropriate page in frontend.'; + return 'Product is found on search page.'; } } diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteProductRedirect.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteProductRedirect.php index 12a84e1d84023c013eae6723d732f8449bc5f5f7..1b0e0ab5543d56d5aaa5511975048d0ddb6cd23e 100644 --- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteProductRedirect.php +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteProductRedirect.php @@ -48,8 +48,8 @@ class AssertUrlRewriteProductRedirect extends AbstractConstraint * * @param UrlRewrite $urlRewrite * @param CatalogProductView $catalogProductView - * @param InjectableFixture $product * @param Browser $browser + * @param InjectableFixture $product * @return void */ public function processAssert( diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteSuccessOutsideRedirect.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteSuccessOutsideRedirect.php new file mode 100644 index 0000000000000000000000000000000000000000..38c657bfcb39a87c1ce172812527a527170460b5 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteSuccessOutsideRedirect.php @@ -0,0 +1,82 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\UrlRewrite\Test\Constraint; + +use Mtf\Client\Browser; +use Mtf\Constraint\AbstractConstraint; +use Magento\UrlRewrite\Test\Fixture\UrlRewrite; + +/** + * Class AssertUrlRewriteSuccessOutsideRedirect + * Assert that outside redirect was success + */ +class AssertUrlRewriteSuccessOutsideRedirect extends AbstractConstraint +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Assert that outside redirect was success + * + * @param UrlRewrite $urlRewrite + * @param Browser $browser + * @param UrlRewrite|null $initialRewrite [optional] + * @return void + */ + public function processAssert(UrlRewrite $urlRewrite, Browser $browser, UrlRewrite $initialRewrite = null) + { + $urlRequestPath = $urlRewrite->hasData('request_path') + ? $urlRewrite->getRequestPath() + : $initialRewrite->getRequestPath(); + $urlTargetPath = $urlRewrite->hasData('target_path') + ? $urlRewrite->getTargetPath() + : $initialRewrite->getTargetPath(); + + $browser->open($_ENV['app_frontend_url'] . $urlRequestPath); + $browserUrl = $browser->getUrl(); + + \PHPUnit_Framework_Assert::assertEquals( + $browserUrl, + $urlTargetPath, + 'URL rewrite redirect false.' + . "\nExpected: " . $urlTargetPath + . "\nActual: " . $browserUrl + ); + } + + /** + * Returns a string representation of the object + * + * @return string + */ + public function toString() + { + return 'Custom outside URL rewrite redirect was success.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewrite.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewrite.php index e8dd121aec0b7c7582ec973896aa6765cbaf21b0..1e6dbe108fedc55541ec5eea508682b8a25e480b 100644 --- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewrite.php +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewrite.php @@ -42,7 +42,7 @@ class UrlRewrite extends InjectableFixture protected $handlerInterface = 'Magento\UrlRewrite\Test\Handler\UrlRewrite\UrlRewriteInterface'; protected $defaultDataSet = [ - 'store_id' => 'Default Store View', + 'store_id' => 'Main Website/Main Website Store/Default Store View', 'request_path' => 'test_request%isolation%', ]; @@ -62,6 +62,7 @@ class UrlRewrite extends InjectableFixture 'backend_type' => 'varchar', 'is_required' => '1', 'default_value' => 'Default Store View', + 'source' => 'Magento\UrlRewrite\Test\Fixture\UrlRewrite\StoreId', 'input' => 'select', ]; diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewrite/IdPath.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewrite/IdPath.php index 20851760e2b312adb434a8ae2812feacefa035b5..9c0905a2456f30df5f765b4caca29bff7cd18d94 100644 --- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewrite/IdPath.php +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewrite/IdPath.php @@ -41,11 +41,11 @@ class IdPath implements FixtureInterface protected $data; /** - * Return category + * Return entity * * @var FixtureInterface */ - protected $entity; + protected $entity = null; /** * Data set configuration settings @@ -57,20 +57,20 @@ class IdPath implements FixtureInterface /** * @param FixtureFactory $fixtureFactory * @param array $params - * @param array $data + * @param array $data [optional] */ public function __construct(FixtureFactory $fixtureFactory, array $params, array $data = []) { $this->params = $params; - if (!isset($data['entity'])) { + if (!isset($data['entity']) || $data['entity'] === '-') { $this->data = array_shift($data); return; } preg_match('`%(.*?)%`', $data['entity'], $dataSet); - $explodeValue = explode('::', $dataSet[1]); - if (!empty($explodeValue) && count($explodeValue) > 1) { + $entityConfig = isset($dataSet[1]) ? explode('::', $dataSet[1]) : []; + if (count($entityConfig) > 1) { /** @var FixtureInterface $fixture */ - $this->entity = $fixtureFactory->createByCode($explodeValue[0], ['dataSet' => $explodeValue[1]]); + $this->entity = $fixtureFactory->createByCode($entityConfig[0], ['dataSet' => $entityConfig[1]]); $this->entity->persist(); $id = $this->entity->hasData('id') ? $this->entity->getId() : $this->entity->getPageId(); $this->data = preg_replace('`(%.*?%)`', $id, $data['entity']); @@ -115,7 +115,7 @@ class IdPath implements FixtureInterface /** * Return entity * - * @return FixtureInterface + * @return FixtureInterface|null */ public function getEntity() { diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewrite/StoreId.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewrite/StoreId.php new file mode 100644 index 0000000000000000000000000000000000000000..aece5dd1fa3b655701480805f81bc8d8d5309f76 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewrite/StoreId.php @@ -0,0 +1,102 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\UrlRewrite\Test\Fixture\UrlRewrite; + +use Mtf\Fixture\FixtureFactory; +use Mtf\Fixture\FixtureInterface; +use Magento\Store\Test\Fixture\Store; + +/** + * Class StoreId + * Store id source + */ +class StoreId implements FixtureInterface +{ + /** + * Resource data + * + * @var string + */ + protected $data; + + /** + * Data set configuration settings + * + * @var array + */ + protected $params; + + /** + * @param FixtureFactory $fixtureFactory + * @param array $params + * @param string $data + */ + public function __construct(FixtureFactory $fixtureFactory, array $params, $data) + { + $this->params = $params; + if (preg_match('`%(.*?)%`', $data, $store)) { + /** @var Store $storeFixture */ + $storeFixture = $fixtureFactory->createByCode('store', ['dataSet' => $store[1]]); + if (!$storeFixture->hasData('store_id')) { + $storeFixture->persist(); + } + $data = str_replace('%' . $store[1] . '%', $storeFixture->getName(), $data); + } + $this->data = $data; + } + + /** + * Persist custom selections products + * + * @return void + */ + public function persist() + { + // + } + + /** + * Return prepared data + * + * @param string|null $key [optional] + * @return string + * + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function getData($key = null) + { + return $this->data; + } + + /** + * Return data set configuration settings + * + * @return array + */ + public function getDataConfig() + { + return $this->params; + } +} diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Handler/UrlRewrite/Curl.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Handler/UrlRewrite/Curl.php index fdd1c3eab70782438e581ce3a618d238de8ec820..53b1b18ae578b92766e9452976341c92102609a5 100644 --- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Handler/UrlRewrite/Curl.php +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Handler/UrlRewrite/Curl.php @@ -46,7 +46,7 @@ class Curl extends AbstractCurl implements UrlRewriteInterface 'store_id' => ['Default Store View' => 1], 'options' => [ 'Temporary (302)' => 'R', - 'Temporary (301)' => 'RP', + 'Permanent (301)' => 'RP', 'No' => '' ] ]; @@ -63,18 +63,18 @@ class Curl extends AbstractCurl implements UrlRewriteInterface * * @param FixtureInterface $fixture * @throws \Exception - * @return mixed|void + * @return void */ public function persist(FixtureInterface $fixture = null) { $url = $_ENV['app_backend_url'] . $this->url . $fixture->getIdPath(); $data = $this->replaceMappingData($fixture->getData()); $curl = new BackendDecorator(new CurlTransport(), new Config()); - $curl->write(CurlInterface::POST, $url, '1.0', array(), $data); + $curl->write(CurlInterface::POST, $url, '1.0', [], $data); $response = $curl->read(); if (!strpos($response, 'data-ui-id="messages-message-success"')) { - throw new \Exception("Product creation by curl handler was not successful! Response: $response"); + throw new \Exception("URL Rewrite creation by curl handler was not successful! Response: $response"); } $curl->close(); } diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Page/Adminhtml/UrlrewriteEdit.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Page/Adminhtml/UrlrewriteEdit.php index 0ab76c1f45b56f4dc3f4e0b0b39f217d865077ce..a298098256c712e7149e8139c4809aff3bb8493b 100644 --- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Page/Adminhtml/UrlrewriteEdit.php +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Page/Adminhtml/UrlrewriteEdit.php @@ -42,7 +42,7 @@ class UrlrewriteEdit extends BackendPage ], 'formBlock' => [ 'name' => 'formBlock', - 'class' => 'Magento\UrlRewrite\Test\Block\Adminhtml\Catalog\Edit\Form', + 'class' => 'Magento\UrlRewrite\Test\Block\Adminhtml\Catalog\Edit\UrlRewriteForm', 'locator' => '#edit_form', 'strategy' => 'css selector', ], @@ -87,7 +87,7 @@ class UrlrewriteEdit extends BackendPage } /** - * @return \Magento\UrlRewrite\Test\Block\Adminhtml\Catalog\Edit\Form + * @return \Magento\UrlRewrite\Test\Block\Adminhtml\Catalog\Edit\UrlRewriteForm */ public function getFormBlock() { diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Page/Adminhtml/UrlrewriteEdit.xml b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Page/Adminhtml/UrlrewriteEdit.xml index 35c41fe1518e9807ae1e38308e351b9b084d5b64..759ed44a996b56241d259d462e7708f2a7788eda 100644 --- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Page/Adminhtml/UrlrewriteEdit.xml +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Page/Adminhtml/UrlrewriteEdit.xml @@ -32,7 +32,7 @@ </block> <block> <name>formBlock</name> - <class>Magento\UrlRewrite\Test\Block\Adminhtml\Catalog\Edit\Form</class> + <class>Magento\UrlRewrite\Test\Block\Adminhtml\Catalog\Edit\UrlRewriteForm</class> <locator>#edit_form</locator> <strategy>css selector</strategy> </block> diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Repository/UrlRewrite.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Repository/UrlRewrite.php index e6cc865008aa4e8bf333aa6b57dafdf72ed10f7a..949d11d90aae6a254abc0223cabcd76a721cd6b8 100644 --- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Repository/UrlRewrite.php +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Repository/UrlRewrite.php @@ -42,8 +42,19 @@ class UrlRewrite extends AbstractRepository { $this->_data['default'] = [ 'request_path' => 'test-test-test%isolation%.html', + 'target_path' => 'http://www.ebayinc.com/', 'options' => 'Temporary (302)', - 'store_id' => 'Default Store View' + 'store_id' => 'Main Website/Main Website Store/Default Store View', + 'id_path' => ["test%isolation%"] + ]; + + $this->_data['custom_rewrite_wishlist'] = [ + 'store_id' => 'Main Website/Main Website Store/Default Store View', + 'request_path' => 'wishlist/%isolation%', + 'target_path' => 'http://google.com', + 'options' => 'Temporary (302)', + 'description' => 'test description', + 'id_path' => ['entity' => "wishlist/%catalogProductSimple::100_dollar_product%"] ]; } } diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Repository/UrlRewriteCategory.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Repository/UrlRewriteCategory.php index fa7d0c40ee35241df7b1b153c27e93b113d36be6..fbbac527e33ed07f381fa375a2dcb70f7f0572d5 100644 --- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Repository/UrlRewriteCategory.php +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Repository/UrlRewriteCategory.php @@ -41,22 +41,22 @@ class UrlRewriteCategory extends AbstractRepository */ public function __construct(array $defaultConfig = array(), array $defaultData = array()) { - $this->_data['default'] = array( + $this->_data['default'] = [ 'config' => $defaultConfig, - 'data' => array( - 'fields' => array( - 'request_path' => array( + 'data' => [ + 'fields' => [ + 'request_path' => [ 'value' => '%rewritten_category_request_path%', - ), - 'store' => array( - 'value' => 'Default Store View', - ), - ), - ), - ); + ], + 'store_id' => [ + 'value' => 'Main Website/Main Website Store/Default Store View', + ], + ], + ], + ]; $this->_data['category_with_permanent_redirect'] = $this->_data['default']; - $this->_data['category_with_permanent_redirect']['data']['fields']['options'] = array( + $this->_data['category_with_permanent_redirect']['data']['fields']['options'] = [ 'value' => 'Permanent (301)', - ); + ]; } } diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Repository/UrlRewriteProduct.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Repository/UrlRewriteProduct.php index 355014c69b5f8acaa232243244c1aa7fb504b855..18d169447933399db793f41c5b63cc8f09917b6b 100644 --- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Repository/UrlRewriteProduct.php +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Repository/UrlRewriteProduct.php @@ -41,23 +41,23 @@ class UrlRewriteProduct extends AbstractRepository */ public function __construct(array $defaultConfig = array(), array $defaultData = array()) { - $this->_data['default'] = array( + $this->_data['default'] = [ 'config' => $defaultConfig, - 'data' => array( + 'data' => [ 'url_rewrite_type' => 'For product', - 'fields' => array( - 'request_path' => array( + 'fields' => [ + 'request_path' => [ 'value' => '%rewritten_product_request_path%', - ), - 'store' => array( - 'value' => 'Default Store View' - ), - ), - ), - ); + ], + 'store_id' => [ + 'value' => 'Main Website/Main Website Store/Default Store View' + ], + ], + ], + ]; $this->_data['product_with_temporary_redirect'] = $this->_data['default']; - $this->_data['product_with_temporary_redirect']['data']['fields']['options'] = array( + $this->_data['product_with_temporary_redirect']['data']['fields']['options'] = [ 'value' => 'Temporary (302)', - ); + ]; } } diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CategoryTest.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CategoryTest.php index 84299120bd528abc0298dac74fa639fe3aa7053d..476fe956f19d342bbd7ee93b9459be2217679b7b 100644 --- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CategoryTest.php +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CategoryTest.php @@ -34,16 +34,12 @@ use Mtf\TestCase\Injectable; */ class CategoryTest extends Injectable { - public function __inject() - { - // - } - /** * Adding permanent redirect for category * - * @ZephyrId MAGETWO-12407 * @param UrlRewriteCategory $urlRewriteCategory + * @return void + * @ZephyrId MAGETWO-12407 */ public function test(\Magento\UrlRewrite\Test\Fixture\UrlRewriteCategory $urlRewriteCategory) { @@ -77,10 +73,10 @@ class CategoryTest extends Injectable /** * Assert that request URL redirects to target URL * - * * @param string $requestUrl * @param string $targetUrl * @param string $message + * @return void */ protected function assertUrlRedirect($requestUrl, $targetUrl, $message = '') { diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCmsPageRewriteEntityTest/testCmsPageRewrite.csv b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCmsPageRewriteEntityTest/testCmsPageRewrite.csv deleted file mode 100644 index 7edd14cc928acdc6f7f02af2592b12b233b0a3f8..0000000000000000000000000000000000000000 --- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCmsPageRewriteEntityTest/testCmsPageRewrite.csv +++ /dev/null @@ -1,5 +0,0 @@ -"cmsPage/dataSet";"urlRewrite/data/store_id";"urlRewrite/data/request_path";"urlRewrite/data/options";"urlRewrite/data/description";"isRequired";"constraint" -"default";"-";"request_path%isolation%";"No";"test_description_default";"Yes";"assertUrlRewriteSaveMessage, assertUrlRewriteCmsPageRedirect" -"default";"-";"request_path%isolation%.html";"Temporary (302)";"test description_302";"Yes";"assertUrlRewriteSaveMessage, assertUrlRewriteCmsPageRedirect" -"default";"-";"request_path%isolation%.htm";"Permanent (301)";"test description_301";"Yes";"assertUrlRewriteSaveMessage, assertUrlRewriteCmsPageRedirect" -"default";"-";"request_path%isolation%.aspx";"Permanent (301)";"test description_%isolation%";"Yes";"assertUrlRewriteSaveMessage, assertUrlRewriteCmsPageRedirect" diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCustomUrlRewriteEntityTest/test.csv b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCustomUrlRewriteEntityTest/test.csv index 7d2ee52bbb1c44f8363156e16f3f0a740521509c..b8daef7681ecdd67e673b0744d2fdb9cc913a8d0 100644 --- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCustomUrlRewriteEntityTest/test.csv +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCustomUrlRewriteEntityTest/test.csv @@ -1,5 +1,5 @@ -"urlRewrite/data/id_path/entity";"urlRewrite/data/request_path";"urlRewrite/data/options";"urlRewrite/data/description";"constraint" -"category/%catalogCategory::default_subcategory%";"category_request_path%isolation%";"Permanent (301)";"test_description_relative path";"assertUrlRewriteSaveMessage, assertUrlRewriteInGrid, assertUrlRewriteCustomRedirect" -"product/%catalogProductSimple::default%";"product_request_path%isolation%";"Temporary (302)";"test_description_relative path";"assertUrlRewriteSaveMessage, assertUrlRewriteInGrid, assertUrlRewriteCustomRedirect" -"cms_page/%cmsPage::cms-page-test%";"cms_page_request_path%isolation%";"No";"test description_full path";"assertUrlRewriteSaveMessage, assertUrlRewriteInGrid, assertUrlRewriteCustomRedirect" -"cms_page/%cmsPage::cms-page-test%";"cms_page_request_path%isolation%";"Temporary (302)";"test description_full path";"assertUrlRewriteSaveMessage, assertUrlRewriteInGrid, assertUrlRewriteCustomRedirect" +"urlRewrite/data/store_id";"urlRewrite/data/id_path/entity";"urlRewrite/data/request_path";"urlRewrite/data/options";"urlRewrite/data/description";"constraint" +"Main Website/Main Website Store/Default Store View";"category/%catalogCategory::default_subcategory%";"category_request_path%isolation%";"Permanent (301)";"test_description_relative path";"assertUrlRewriteSaveMessage, assertUrlRewriteInGrid, assertUrlRewriteCustomRedirect" +"Main Website/Main Website Store/Default Store View";"product/%catalogProductSimple::default%";"product_request_path%isolation%";"Temporary (302)";"test_description_relative path";"assertUrlRewriteSaveMessage, assertUrlRewriteInGrid, assertUrlRewriteCustomRedirect" +"Main Website/Main Website Store/Default Store View";"cms_page/%cmsPage::cms-page-test%";"cms_page_request_path%isolation%";"No";"test description_full path";"assertUrlRewriteSaveMessage, assertUrlRewriteInGrid, assertUrlRewriteCustomRedirect" +"Main Website/Main Website Store/Default Store View";"cms_page/%cmsPage::cms-page-test%";"cms_page_request_path%isolation%";"Temporary (302)";"test description_full path";"assertUrlRewriteSaveMessage, assertUrlRewriteInGrid, assertUrlRewriteCustomRedirect" diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteCustomUrlRewriteEntityTest.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteCustomUrlRewriteEntityTest.php new file mode 100644 index 0000000000000000000000000000000000000000..6a525d65302fefc340c83121f83ffdf2e6632288 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteCustomUrlRewriteEntityTest.php @@ -0,0 +1,95 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\UrlRewrite\Test\TestCase; + +use Mtf\TestCase\Injectable; +use Magento\UrlRewrite\Test\Fixture\UrlRewrite; +use Magento\UrlRewrite\Test\Page\Adminhtml\UrlrewriteEdit; +use Magento\UrlRewrite\Test\Page\Adminhtml\UrlrewriteIndex; + +/** + * Test Creation for DeleteCustomUrlRewriteEntity + * + * Test Flow: + * Preconditions: + * 1. Custom URL Rewrites is created. + * + * Steps: + * 1. Login to backend as Admin. + * 2. Go to the Marketing->SEO & Search->URL Redirects. + * 3. Search and open created URL Redirect. + * 4. Delete Redirect. + * 5. Perform all assertions. + * + * @group URL_Rewrites_(PS) + * @ZephyrId MAGETWO-26337 + */ +class DeleteCustomUrlRewriteEntityTest extends Injectable +{ + /** + * Url rewrite index page + * + * @var UrlrewriteIndex + */ + protected $urlRewriteIndex; + + /** + * Url rewrite edit page + * + * @var UrlrewriteEdit + */ + protected $urlRewriteEdit; + + /** + * Inject pages + * + * @param UrlrewriteIndex $urlRewriteIndex + * @param UrlrewriteEdit $urlRewriteEdit + * @return void + */ + public function __inject(UrlrewriteIndex $urlRewriteIndex, UrlrewriteEdit $urlRewriteEdit) + { + $this->urlRewriteIndex = $urlRewriteIndex; + $this->urlRewriteEdit = $urlRewriteEdit; + } + + /** + * Delete custom URL Rewrite + * + * @param UrlRewrite $urlRewrite + * @return void + */ + public function test(UrlRewrite $urlRewrite) + { + // Precondition + $urlRewrite->persist(); + + // Steps + $this->urlRewriteIndex->open(); + $filter = ['request_path' => $urlRewrite->getRequestPath()]; + $this->urlRewriteIndex->getUrlRedirectGrid()->searchAndOpen($filter); + $this->urlRewriteEdit->getPageMainActions()->delete(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteCustomUrlRewriteEntityTest/test.csv b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteCustomUrlRewriteEntityTest/test.csv new file mode 100644 index 0000000000000000000000000000000000000000..3b512c81f0f1bff5354a9b204ee1d80cbe6e1d2e --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteCustomUrlRewriteEntityTest/test.csv @@ -0,0 +1,2 @@ +"urlRewrite/dataSet";"constraint" +"default";"assertUrlRewriteDeletedMessage, assertUrlRewriteNotInGrid, assertPageByUrlRewriteIsNotFound" diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/ProductTest.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/ProductTest.php index 936f8235afe2a5931c306ad77c1e72d6e94c5b8f..805726b95a9087bc14b486d09767b591df557497 100644 --- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/ProductTest.php +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/ProductTest.php @@ -37,6 +37,7 @@ class ProductTest extends Functional /** * Adding temporary redirect for product * + * @return void * @ZephyrId MAGETWO-12409 */ public function testUrlRewriteCreation() @@ -80,6 +81,7 @@ class ProductTest extends Functional * @param string $requestUrl * @param string $targetUrl * @param string $message + * @return void */ protected function assertUrlRedirect($requestUrl, $targetUrl, $message = '') { diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCategoryUrlRewriteEntityTest.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCategoryUrlRewriteEntityTest.php index ae00d41bc8b458067df41f5abc3432dfabcae4aa..f432629855a858945d0d866fbadc646455a659b4 100644 --- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCategoryUrlRewriteEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCategoryUrlRewriteEntityTest.php @@ -104,7 +104,7 @@ class UpdateCategoryUrlRewriteEntityTest extends Injectable * @param UrlRewrite $urlRewrite * @return void */ - public function testUpdateCategoryUrlRewrite(UrlRewrite $categoryRedirect, UrlRewrite $urlRewrite) + public function test(UrlRewrite $categoryRedirect, UrlRewrite $urlRewrite) { //Steps $this->urlRewriteIndex->open(); diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCategoryUrlRewriteEntityTest/test.csv b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCategoryUrlRewriteEntityTest/test.csv new file mode 100644 index 0000000000000000000000000000000000000000..6f831e436460eb9de367a7fc7398e67d8ff34d22 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCategoryUrlRewriteEntityTest/test.csv @@ -0,0 +1,5 @@ +"urlRewrite/data/store_id";"category/dataSet";"categoryRewrite/dataSet";"urlRewrite/data/store_id";"urlRewrite/data/request_path";"urlRewrite/data/options";"urlRewrite/data/description";"constraint" +"Main Website/Main Website Store/Default Store View";"default_subcategory";"default";"-";"test_request%isolation%";"No";"test_description_defalt";"assertUrlRewriteSaveMessage, assertUrlRewriteInGrid, assertUrlRewriteCategoryRedirect" +"Main Website/Main Website Store/Default Store View";"default_subcategory";"default";"-";"request_path%isolation%.html";"Temporary (302)";"test description_302";"assertUrlRewriteSaveMessage, assertUrlRewriteInGrid, assertUrlRewriteCategoryRedirect" +"Main Website/Main Website Store/Default Store View";"default_subcategory";"default";"-";"request_path%isolation%.htm";"Permanent (301)";"test description_301";"assertUrlRewriteSaveMessage, assertUrlRewriteInGrid, assertUrlRewriteCategoryRedirect" +"Main Website/Main Website Store/Default Store View";"default_subcategory";"default";"-";"request_path%isolation%.aspx";"Temporary (302)";"test description_%isolation%";"assertUrlRewriteSaveMessage, assertUrlRewriteInGrid, assertUrlRewriteCategoryRedirect" \ No newline at end of file diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCategoryUrlRewriteEntityTest/testUpdateCategoryUrlRewrite.csv b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCategoryUrlRewriteEntityTest/testUpdateCategoryUrlRewrite.csv deleted file mode 100644 index 9b8902a40dcd563fed8f5b6db1305da58ea14249..0000000000000000000000000000000000000000 --- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCategoryUrlRewriteEntityTest/testUpdateCategoryUrlRewrite.csv +++ /dev/null @@ -1,5 +0,0 @@ -"category/dataSet";"categoryRewrite/dataSet";"urlRewrite/data/store_id";"urlRewrite/data/request_path";"urlRewrite/data/options";"urlRewrite/data/description";"constraint" -"default_subcategory";"default";"-";"test_request%isolation%";"No";"test_description_defalt";"assertUrlRewriteSaveMessage, assertUrlRewriteInGrid, assertUrlRewriteCategoryRedirect" -"default_subcategory";"default";"-";"request_path%isolation%.html";"Temporary (302)";"test description_302";"assertUrlRewriteSaveMessage, assertUrlRewriteInGrid, assertUrlRewriteCategoryRedirect" -"default_subcategory";"default";"-";"request_path%isolation%.htm";"Permanent (301)";"test description_301";"assertUrlRewriteSaveMessage, assertUrlRewriteInGrid, assertUrlRewriteCategoryRedirect" -"default_subcategory";"default";"-";"request_path%isolation%.aspx";"Temporary (302)";"test description_%isolation%";"assertUrlRewriteSaveMessage, assertUrlRewriteInGrid, assertUrlRewriteCategoryRedirect" diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCmsPageRewriteEntityTest.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCustomUrlRewriteEntityTest.php similarity index 58% rename from dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCmsPageRewriteEntityTest.php rename to dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCustomUrlRewriteEntityTest.php index 3bb8056bd214e3cd394514dfb83c03f51ba0edea..07a643add2cc258bf334bd0b98cf0af388e740f6 100644 --- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCmsPageRewriteEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCustomUrlRewriteEntityTest.php @@ -24,35 +24,32 @@ namespace Magento\UrlRewrite\Test\TestCase; -use Magento\UrlRewrite\Test\Page\Adminhtml\EditCmsPage; use Mtf\TestCase\Injectable; -use Magento\Cms\Test\Fixture\CmsPage; use Magento\UrlRewrite\Test\Fixture\UrlRewrite; use Magento\UrlRewrite\Test\Page\Adminhtml\UrlrewriteEdit; use Magento\UrlRewrite\Test\Page\Adminhtml\UrlrewriteIndex; /** - * Test Creation for CreateCmsPageRewriteEntity + * Test Creation for UpdateCustomUrlRewritesEntity * * Test Flow: * - * Preconditions - * 1. Create CMS-Page + * Preconditions: + * 1. Create default simple product + * 2. Create custom url rewrite * - * Steps + * Steps: * 1. Login to backend as Admin * 2. Go to the Marketing-> SEO & Search->URL Redirects - * 3. Click "Add Url Rewrite" button - * 4. Select "For CMS Page" in Create URL Rewrite dropdown - * 5. Select CMS page from preconditions in grid - * 6. Fill data according to data set - * 7. Save Rewrite - * 8. Perform all assertions + * 3. Search and open created URL Redirect + * 4. Fill data according to data set + * 5. Save Redirect + * 6. Perform all assertions * * @group URL_Rewrites_(PS) - * @ZephyrId MAGETWO-24847 + * @ZephyrId MAGETWO-25784 */ -class CreateCmsPageRewriteEntityTest extends Injectable +class UpdateCustomUrlRewriteEntityTest extends Injectable { /** * Url rewrite index page @@ -75,32 +72,48 @@ class CreateCmsPageRewriteEntityTest extends Injectable * @param UrlrewriteEdit $urlRewriteEdit * @return void */ - public function __inject( - UrlrewriteIndex $urlRewriteIndex, - UrlrewriteEdit $urlRewriteEdit - ) { + public function __inject(UrlrewriteIndex $urlRewriteIndex, UrlrewriteEdit $urlRewriteEdit) + { $this->urlRewriteIndex = $urlRewriteIndex; $this->urlRewriteEdit = $urlRewriteEdit; } /** - * Create CMS page rewrites + * Update custom URL Rewrite * - * @param CmsPage $cmsPage + * @param UrlRewrite $initialRewrite * @param UrlRewrite $urlRewrite * @return void */ - public function testCmsPageRewrite(CmsPage $cmsPage, UrlRewrite $urlRewrite) + public function test(UrlRewrite $initialRewrite, UrlRewrite $urlRewrite) { - //Preconditions - $cmsPage->persist(); + //Precondition + $initialRewrite->persist(); + //Steps $this->urlRewriteIndex->open(); - $this->urlRewriteIndex->getPageActionsBlock()->addNew(); - $this->urlRewriteEdit->getUrlRewriteTypeSelectorBlock()->selectType('For CMS page'); - $filter = ['title' => $cmsPage->getTitle()]; - $this->urlRewriteEdit->getCmsGridBlock()->searchAndOpen($filter); - $this->urlRewriteEdit->getFormBlock()->fill($urlRewrite); + $filter = ['request_path' => $initialRewrite->getRequestPath()]; + $replaceData = $this->getReplaceData($initialRewrite); + $this->urlRewriteIndex->getUrlRedirectGrid()->searchAndOpen($filter); + $this->urlRewriteEdit->getFormBlock()->fill($urlRewrite, null, $replaceData); $this->urlRewriteEdit->getPageMainActions()->save(); } + + /** + * Prepare data for replace + * + * @param UrlRewrite $initialRewrite + * @return array + */ + protected function getReplaceData(UrlRewrite $initialRewrite) + { + $replaceData = []; + $entity = $initialRewrite->getDataFieldConfig('id_path')['source']->getEntity(); + + if ($entity) { + $replaceData['target_path'] = ['%name%' => $entity->getName()]; + } + + return $replaceData; + } } diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCustomUrlRewriteEntityTest/test.csv b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCustomUrlRewriteEntityTest/test.csv new file mode 100644 index 0000000000000000000000000000000000000000..c614a683f0e573dc19e8c96cab66e899a7806fa9 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCustomUrlRewriteEntityTest/test.csv @@ -0,0 +1,3 @@ +"initialRewrite/dataSet";"urlRewrite/data/store_id";"urlRewrite/data/request_path";"urlRewrite/data/target_path";"urlRewrite/data/options";"urlRewrite/data/description";"constraint" +"default";"Main Website/Main Website Store/Default Store View";"wishlist/%isolation%";"http://www.magentocommerce.com/magento-connect/";"Permanent (301)";"test_description_relative path";"assertUrlRewriteSaveMessage, assertUrlRewriteInGrid, assertUrlRewriteSuccessOutsideRedirect" +"custom_rewrite_wishlist";"Main Website/Main Website Store/Default Store View";"wishlist/%isolation%";"catalogsearch/result/?q=%name%";"Temporary (302)";"test_description_relative path";"assertUrlRewriteSaveMessage, assertUrlRewriteInGrid, assertUrlRewriteCustomSearchRedirect" diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/etc/global/constraint.xml b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/etc/global/constraint.xml index fd070420677a58039dd0d8a7fca10fb194804c92..e16f263cf173d87d838d2e4868f3b7913fb64bfc 100644 --- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/etc/global/constraint.xml +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/etc/global/constraint.xml @@ -67,15 +67,22 @@ <browser class="Mtf\Client\Browser"/> </require> </assertPageByUrlRewriteIsNotFound> - <assertUrlRewriteCmsPageRedirect module="Magento_UrlRewrite"> + <assertUrlRewriteCustomRedirect module="Magento_UrlRewrite"> + <severeness>low</severeness> + </assertUrlRewriteCustomRedirect> + <assertUrlRewriteSuccessOutsideRedirect module="Magento_UrlRewrite"> <severeness>low</severeness> <require> - <cmsPage class="Magento\Cms\Test\Fixture\CmsPage"/> <urlRewrite class="Magento\UrlRewrite\Test\Fixture\UrlRewrite"/> <browser class="Mtf\Client\Browser"/> </require> - </assertUrlRewriteCmsPageRedirect> - <assertUrlRewriteCustomRedirect module="Magento_UrlRewrite"> + </assertUrlRewriteSuccessOutsideRedirect> + <assertUrlRewriteCustomSearchRedirect module="Magento_UrlRewrite"> <severeness>low</severeness> - </assertUrlRewriteCustomRedirect> + <require> + <urlRewrite class="Magento\UrlRewrite\Test\Fixture\UrlRewrite"/> + <browser class="Mtf\Client\Browser"/> + <categoryView class="Magento\Catalog\Test\Page\Category\CatalogCategoryView"/> + </require> + </assertUrlRewriteCustomSearchRedirect> </constraint> diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/etc/global/page.xml b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/etc/global/page.xml index d8be3b72836dde3715635803f25982e39451ebde..0e1e33bb730f44a15a9209cbd00d91b71bf7999b 100644 --- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/etc/global/page.xml +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/etc/global/page.xml @@ -34,9 +34,4 @@ <area>adminhtml</area> <class>Magento\UrlRewrite\Test\Page\Adminhtml\UrlrewriteEdit</class> </urlrewriteEdit> - <editCmsPage> - <mca>admin/urlrewrite/edit/cms_page</mca> - <area>adminhtml</area> - <class>Magento\UrlRewrite\Test\Page\Adminhtml\EditCmsPage</class> - </editCmsPage> </page> diff --git a/dev/tests/integration/testsuite/Magento/Bundle/_files/product_rollback.php b/dev/tests/integration/testsuite/Magento/Bundle/_files/product_rollback.php new file mode 100644 index 0000000000000000000000000000000000000000..f00679e883ba6defaebe8f295c73ced6ab37a659 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Bundle/_files/product_rollback.php @@ -0,0 +1,46 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +/* + * Since the bundle product creation GUI doesn't allow to choose values for bundled products' custom options, + * bundled items should not contain products with required custom options. + * However, if to create such a bundle product, it will be always out of stock. + */ +require __DIR__ . '/../../../Magento/Catalog/_files/products_rollback.php'; + +/** @var \Magento\Framework\Registry $registry */ +$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Framework\Registry'); + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +/** @var $product \Magento\Catalog\Model\Product */ +$product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Product'); +$product->load(3); +if ($product->getId()) { + $product->delete(); +} + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Action/AttributeTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Action/AttributeTest.php index 7470225e2e921cba231859b9133f1c8089797d7b..99b99a25af28834c4396086fb3cc9b5a60cd02db 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Action/AttributeTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Action/AttributeTest.php @@ -62,4 +62,58 @@ class AttributeTest extends \Magento\Backend\Utility\Controller $this->assertTrue($isRedirectPresent); } + + + /** + * @covers \Magento\Catalog\Controller\Adminhtml\Product\Action\Attribute::validateAction + * + * @dataProvider validateActionDataProvider + * + * @magentoDataFixture Magento/Catalog/_files/product_simple.php + * @magentoDataFixture Magento/Catalog/_files/product_simple_duplicated.php + */ + public function testValidateActionWithMassUpdate($attributes) + { + $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + + /** @var $session \Magento\Backend\Model\Session */ + $session = $objectManager->get('Magento\Backend\Model\Session'); + $session->setProductIds(array(1, 2)); + + $this->getRequest()->setParam('attributes', $attributes); + + $this->dispatch('backend/catalog/product_action_attribute/validate/store/0'); + + $this->assertEquals(200, $this->getResponse()->getHttpResponseCode()); + + $response = $this->getResponse()->getBody(); + $this->assertJson($response); + $data = json_decode($response, true); + $this->assertArrayHasKey('error', $data); + $this->assertFalse($data['error']); + $this->assertCount(1, $data); + } + + /** + * Data Provider for validation + * + * @return array + */ + public function validateActionDataProvider() + { + return array( + [ + 'arguments' => [ + 'name' => 'Name', + 'description' => 'Description', + 'short_description' => 'Short Description', + 'price' => '512', + 'weight' => '16', + 'meta_title' => 'Meta Title', + 'meta_keyword' => 'Meta Keywords', + 'meta_description' => 'Meta Description', + ], + ] + ); + } } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Category/_files/service_category_create.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Category/_files/service_category_create.php new file mode 100644 index 0000000000000000000000000000000000000000..9b677ee90e22c725589114cff590cc230194f6cf --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Category/_files/service_category_create.php @@ -0,0 +1,23 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Category/_files/service_category_create_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Category/_files/service_category_create_rollback.php new file mode 100644 index 0000000000000000000000000000000000000000..d7a5bb4b1185ab40d3eeda90728bc2c782be8473 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Category/_files/service_category_create_rollback.php @@ -0,0 +1,37 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +use Magento\TestFramework\Helper\Bootstrap; + +/** @var \Magento\Framework\Registry $registry */ +$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Framework\Registry'); +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +/** @var \Magento\Catalog\Model\Category $category */ +$category = Bootstrap::getObjectManager()->get('Magento\Catalog\Model\Category'); +$category = $category->loadByAttribute('url_key', 'test-category-name'); + +if ($category && $category->getId()) { + $category->delete(); +} diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Attribute/_files/create_attribute_service.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Attribute/_files/create_attribute_service.php new file mode 100644 index 0000000000000000000000000000000000000000..9b677ee90e22c725589114cff590cc230194f6cf --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Attribute/_files/create_attribute_service.php @@ -0,0 +1,23 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Attribute/_files/create_attribute_service_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Attribute/_files/create_attribute_service_rollback.php new file mode 100644 index 0000000000000000000000000000000000000000..a108926db18b9d3ea4b111132a738fd236f297a1 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Attribute/_files/create_attribute_service_rollback.php @@ -0,0 +1,45 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +use Magento\TestFramework\Helper\Bootstrap; + +/** @var \Magento\Framework\Registry $registry */ +$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Framework\Registry'); +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +/** @var \Magento\Catalog\Model\Resource\Eav\Attribute $attribute */ +$attribute = Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Resource\Eav\Attribute'); +$attribute->loadByCode(4, 'label_attr_code3df4tr3'); + +if ($attribute->getId()) { + $attribute->delete(); +} + +/** @var \Magento\Catalog\Model\Resource\Eav\Attribute $attribute */ +$attribute = Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Resource\Eav\Attribute'); +$attribute->loadByCode(4, 'test_attribute_code_l'); + +if ($attribute->getId()) { + $attribute->delete(); +} \ No newline at end of file diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/_files/service_product_create.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/_files/service_product_create.php new file mode 100644 index 0000000000000000000000000000000000000000..9b677ee90e22c725589114cff590cc230194f6cf --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/_files/service_product_create.php @@ -0,0 +1,23 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/_files/service_product_create_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/_files/service_product_create_rollback.php new file mode 100644 index 0000000000000000000000000000000000000000..55dc7bed661b3c67c25528fbdec718e206b86888 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/_files/service_product_create_rollback.php @@ -0,0 +1,43 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +use Magento\TestFramework\Helper\Bootstrap; + +/** @var \Magento\Framework\Registry $registry */ +$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Framework\Registry'); +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +/** @var \Magento\Catalog\Model\Product $productModel */ +$productModel = Bootstrap::getObjectManager()->get('Magento\Catalog\Model\Product'); +$productModel->load($productModel->getIdBySku('psku-test-1')); +if ($productModel->getId()) { + $productModel->delete(); +} + +/** @var \Magento\Catalog\Model\Product $productModel */ +$productModel = Bootstrap::getObjectManager()->get('Magento\Catalog\Model\Product'); +$productModel->load($productModel->getIdBySku('psku-test-2')); +if ($productModel->getId()) { + $productModel->delete(); +} diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Resource/Product/Indexer/Eav/SourceTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Resource/Product/Indexer/Eav/SourceTest.php index 552c9afad59b9f0390d29e0e8e655f31a8916464..50627358db89ee2ee2574367e259c518a7bbd8cf 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Resource/Product/Indexer/Eav/SourceTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Resource/Product/Indexer/Eav/SourceTest.php @@ -91,12 +91,12 @@ class SourceTest extends \PHPUnit_Framework_TestCase /** @var \Magento\Catalog\Model\Product $product1 **/ $product1 = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Catalog\Model\Product'); - $product1 = $product1->load($optionIds[0] * 10); + $product1 = $product1->load(10); $product1->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_DISABLED)->save(); /** @var \Magento\Catalog\Model\Product $product2 **/ $product2 = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Catalog\Model\Product'); - $product2 = $product2->load($optionIds[1] * 10); + $product2 = $product2->load(20); $product2->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_DISABLED)->save(); $result = $adapter->fetchAll($select); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_attribute.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_attribute.php new file mode 100644 index 0000000000000000000000000000000000000000..51def5c764a8671353790077bb38fcebf94d7d33 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_attribute.php @@ -0,0 +1,32 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +/** @var \Magento\Catalog\Model\Resource\Eav\Attribute $attribute */ +$attribute = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->create('Magento\Catalog\Model\Resource\Eav\Attribute'); +$attribute->setAttributeCode('test_attribute_code_333') + ->setEntityTypeId(4) + ->setIsGlobal(1) + ->setPrice(95); +$attribute->save(); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_attribute_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_attribute_rollback.php new file mode 100644 index 0000000000000000000000000000000000000000..796eeb55bf389502252290bdc6ce97b68896d10e --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_attribute_rollback.php @@ -0,0 +1,42 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +/** @var \Magento\Framework\Registry $registry */ +$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Framework\Registry'); + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +/** @var \Magento\Catalog\Model\Resource\Eav\Attribute $attribute */ +$attribute = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->create('Magento\Catalog\Model\Resource\Eav\Attribute'); + +$attribute->loadByCode(4, 'test_attribute_code_333'); + +if ($attribute->getId()) { + $attribute->delete(); +} + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/products_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/products_rollback.php new file mode 100644 index 0000000000000000000000000000000000000000..0a1e74d031491c6014098ba5f9ca7085ddf0294f --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/products_rollback.php @@ -0,0 +1,47 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +/** @var \Magento\Framework\Registry $registry */ +$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Framework\Registry'); + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +/** @var $product \Magento\Catalog\Model\Product */ +$product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Product'); +$product->load(1); +if ($product->getId()) { + $product->delete(); +} + +/** @var $customDesignProduct \Magento\Catalog\Model\Product */ +$customDesignProduct = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->create('Magento\Catalog\Model\Product'); +$customDesignProduct->load(2); +if ($customDesignProduct->getId()) { + $customDesignProduct->delete(); +} + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false); diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php index 5908f6749bf02ea117243a00403f1563ff328d06..5d2b8f9259108a3d9652c9d04f28ee00b9925434 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php @@ -183,17 +183,20 @@ class ProductTest extends \PHPUnit_Framework_TestCase } /** - * Tests adding of custom options with different behaviours + * Tests adding of custom options with existing and new product * * @param $behavior * * @magentoDataFixture Magento/Catalog/_files/product_simple.php * @dataProvider getBehaviorDataProvider + * @param string $behavior + * @param string $importFile + * @param string $sku */ - public function testSaveCustomOptionsDuplicate($behavior) + public function testSaveCustomOptions($behavior, $importFile, $sku) { // import data from CSV file - $pathToFile = __DIR__ . '/_files/product_with_custom_options.csv'; + $pathToFile = __DIR__ . '/_files/' . $importFile; $filesystem = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() ->create('Magento\Framework\App\Filesystem'); @@ -203,10 +206,10 @@ class ProductTest extends \PHPUnit_Framework_TestCase $this->_model->setSource($source)->setParameters(array('behavior' => $behavior))->isDataValid(); $this->_model->importData(); - $product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + $productModel = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( 'Magento\Catalog\Model\Product' ); - $product->load(1); + $product = $productModel->loadByAttribute('sku', $sku); // product from fixture $options = $product->getProductOptionsCollection(); @@ -462,8 +465,26 @@ class ProductTest extends \PHPUnit_Framework_TestCase public function getBehaviorDataProvider() { return array( - 'Append behavior' => array('$behavior' => \Magento\ImportExport\Model\Import::BEHAVIOR_APPEND), - 'Replace behavior' => array('$behavior' => \Magento\ImportExport\Model\Import::BEHAVIOR_REPLACE) + 'Append behavior with existing product' => array( + '$behavior' => \Magento\ImportExport\Model\Import::BEHAVIOR_APPEND, + '$importFile' => 'product_with_custom_options.csv', + '$sku' => 'simple' + ), + 'Append behavior with new product' => array( + '$behavior' => \Magento\ImportExport\Model\Import::BEHAVIOR_APPEND, + '$importFile' => 'product_with_custom_options_new.csv', + '$sku' => 'simple_new' + ), + 'Replace behavior with existing product' => array( + '$behavior' => \Magento\ImportExport\Model\Import::BEHAVIOR_REPLACE, + '$importFile' => 'product_with_custom_options.csv', + '$sku' => 'simple' + ), + 'Replace behavior with new product' => array( + '$behavior' => \Magento\ImportExport\Model\Import::BEHAVIOR_REPLACE, + '$importFile' => 'product_with_custom_options_new.csv', + '$sku' => 'simple_new' + ) ); } diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/product_with_custom_options_new.csv b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/product_with_custom_options_new.csv new file mode 100644 index 0000000000000000000000000000000000000000..9d6342ef458c69fafdffbfee9bc5e13d6f636960 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/product_with_custom_options_new.csv @@ -0,0 +1,11 @@ +"sku","_store","_attribute_set","_type","_category","_root_category","_product_websites","color","cost","country_of_manufacture","created_at","custom_design","custom_design_from","custom_design_to","custom_layout_update","description","gallery","gift_message_available","has_options","image","image_label","manufacturer","media_gallery","meta_description","meta_keyword","meta_title","minimal_price","msrp","msrp_display_actual_price_type","msrp_enabled","name","news_from_date","news_to_date","options_container","page_layout","price","required_options","short_description","small_image","small_image_label","special_from_date","special_price","special_to_date","status","tax_class_id","thumbnail","thumbnail_label","updated_at","url_key","url_path","visibility","weight","qty","min_qty","use_config_min_qty","is_qty_decimal","backorders","use_config_backorders","min_sale_qty","use_config_min_sale_qty","max_sale_qty","use_config_max_sale_qty","is_in_stock","notify_stock_qty","use_config_notify_stock_qty","manage_stock","use_config_manage_stock","use_config_qty_increments","qty_increments","use_config_enable_qty_inc","enable_qty_increments","is_decimal_divided","_related_sku","_related_position","_crosssell_sku","_crosssell_position","_upsell_sku","_upsell_position","_associated_sku","_associated_default_qty","_associated_position","_tier_price_website","_tier_price_customer_group","_tier_price_qty","_tier_price_price","_group_price_website","_group_price_customer_group","_group_price_price","_media_attribute_id","_media_image","_media_label","_media_position","_media_is_disabled","_custom_option_store","_custom_option_type","_custom_option_title","_custom_option_is_required","_custom_option_price","_custom_option_sku","_custom_option_max_characters","_custom_option_sort_order","_custom_option_row_title","_custom_option_row_price","_custom_option_row_sku","_custom_option_row_sort" +"simple_new",,"Default","simple",,,"base",,,,,,,,,,,,1,,,,,,,,,,,,"New Product",,,"Block after Info Column",,"10.0000",1,,,,,,,1,,,,"2012-07-13 12:04:17","new-product","new-product.html",4,,"100.0000","0.0000",1,0,0,1,"1.0000",1,"0.0000",1,1,,1,0,1,1,"0.0000",1,0,0,,,,,,,,,,,,,,,,,,,,,,,"field","Test Field",1,"1.0000","1-text",100,0,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,default,,"Test Field",,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,"date_time","Test Date and Time",1,"2.0000","2-date",,0,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,default,,"Test Date and Time",,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,"drop_down","New Select",1,,,,0,"Option 1","3.0000","3-1-select",0 +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,"Option 2","3.0000","3-2-select",0 +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,"default",,,,,,,,"Option 2",,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,"radio","New Radio",1,,,,0,"Option 1","3.0000","4-1-radio",0 +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,"Option 2","3.0000","4-2-radio",0 +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,"default",,,,,,,,"Option 2",,, diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Super/Config/MatrixTest.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Super/Config/MatrixTest.php index d894a169d9ae37fb8e861657074953963a7fed2f..e2265a5e6d522d1c45a1ea9c38ffab775c20de4d 100644 --- a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Super/Config/MatrixTest.php +++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Super/Config/MatrixTest.php @@ -23,28 +23,29 @@ */ namespace Magento\ConfigurableProduct\Block\Adminhtml\Product\Edit\Tab\Super\Config; +use Magento\TestFramework\ObjectManager; + /** * @magentoAppArea adminhtml */ -class MatrixTest extends \PHPUnit_Framework_TestCase +class MatrixTest extends \Magento\Backend\Utility\Controller { + const ATTRIBUTE_LABEL = 'New Attribute Label'; + const ATTRIBUTE_POSITION = 42; + /** * @magentoAppIsolation enabled * @magentoDataFixture Magento/ConfigurableProduct/_files/product_configurable.php */ public function testGetVariations() { - /** @var $objectManager \Magento\TestFramework\ObjectManager */ - $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); - $objectManager->get( + $this->_objectManager->get( 'Magento\Framework\Registry' )->register( 'current_product', \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( 'Magento\Catalog\Model\Product' - )->load( - 1 - ) + )->load(1) ); \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( 'Magento\Framework\View\LayoutInterface' @@ -86,4 +87,49 @@ class MatrixTest extends \PHPUnit_Framework_TestCase $variations ); } + + /** + * @magentoAppIsolation enabled + * @magentoDataFixture Magento/ConfigurableProduct/_files/product_configurable.php + */ + public function testAttributesMergingByGetAttributesMethod() + { + $this->_objectManager->get( + 'Magento\Framework\Registry' + )->register( + 'current_product', + $this->_objectManager->create('Magento\Catalog\Model\Product')->load(1) + ); + $this->_objectManager->get('Magento\Framework\View\LayoutInterface') + ->createBlock('Magento\Framework\View\Element\Text', 'head'); + /** @var \Magento\Catalog\Model\Entity\Attribute $usedAttribute */ + $usedAttribute = $this->_objectManager->get( + 'Magento\Catalog\Model\Entity\Attribute' + )->loadByCode( + $this->_objectManager->get('Magento\Eav\Model\Config') + ->getEntityType('catalog_product')->getId(), + 'test_configurable' + ); + /** @var $block \Magento\ConfigurableProduct\Block\Adminhtml\Product\Edit\Tab\Super\Config */ + $block = $this->_objectManager->get( + 'Magento\Framework\View\LayoutInterface' + )->createBlock( + 'Magento\ConfigurableProduct\Block\Adminhtml\Product\Edit\Tab\Super\Config' + ); + $productData = array( + $usedAttribute->getId() => array( + 'label' => static::ATTRIBUTE_LABEL, + 'position' => static::ATTRIBUTE_POSITION, + ), + ); + $this->getRequest()->setParam('product', array('configurable_attributes_data' => $productData)); + $attributes = $block->getAttributes(); + $this->assertArrayHasKey($usedAttribute->getId(), $attributes); + + $this->assertArrayHasKey('label', $attributes[$usedAttribute->getId()]); + $this->assertEquals(static::ATTRIBUTE_LABEL, $attributes[$usedAttribute->getId()]['label']); + + $this->assertArrayHasKey('position', $attributes[$usedAttribute->getId()]); + $this->assertEquals(static::ATTRIBUTE_POSITION, $attributes[$usedAttribute->getId()]['position']); + } } diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Super/ConfigTest.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Super/ConfigTest.php index 36363d90d4eb696372a806ba8d1affaada83e9aa..9d13b8ea65549fd730865be052a1bd63da3d04c1 100644 --- a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Super/ConfigTest.php +++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Super/ConfigTest.php @@ -23,26 +23,31 @@ */ namespace Magento\ConfigurableProduct\Block\Adminhtml\Product\Edit\Tab\Super; +use Magento\Catalog\Model\Resource\Eav\Attribute; +use Magento\TestFramework\ObjectManager; + /** * @magentoAppArea adminhtml */ -class ConfigTest extends \PHPUnit_Framework_TestCase +class ConfigTest extends \Magento\Backend\Utility\Controller { + const ATTRIBUTE_LABEL = 'New Attribute Label'; + const ATTRIBUTE_POSITION = 42; + /** * @magentoAppIsolation enabled */ public function testGetSelectedAttributesForSimpleProductType() { - /** @var $objectManager \Magento\TestFramework\ObjectManager */ - $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); - $objectManager->get( + $this->_objectManager->get( 'Magento\Framework\Registry' )->register( 'current_product', - $objectManager->create('Magento\Catalog\Model\Product') + $this->_objectManager->create('Magento\Catalog\Model\Product') ); + /** @var $block \Magento\ConfigurableProduct\Block\Adminhtml\Product\Edit\Tab\Super\Config */ - $block = $objectManager->get( + $block = $this->_objectManager->get( 'Magento\Framework\View\LayoutInterface' )->createBlock( 'Magento\ConfigurableProduct\Block\Adminhtml\Product\Edit\Tab\Super\Config' @@ -56,35 +61,85 @@ class ConfigTest extends \PHPUnit_Framework_TestCase */ public function testGetSelectedAttributesForConfigurableProductType() { - /** @var $objectManager \Magento\TestFramework\ObjectManager */ - $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); - $objectManager->get( + $this->_objectManager->get( 'Magento\Framework\Registry' )->register( 'current_product', - $objectManager->create('Magento\Catalog\Model\Product')->load(1) + $this->_objectManager->create('Magento\Catalog\Model\Product')->load(1) ); - $objectManager->get('Magento\Framework\View\LayoutInterface') + $this->_objectManager->get('Magento\Framework\View\LayoutInterface') ->createBlock('Magento\Framework\View\Element\Text', 'head'); - $usedAttribute = $objectManager->get( + /** @var \Magento\Catalog\Model\Entity\Attribute $usedAttribute */ + $usedAttribute = $this->_objectManager->get( 'Magento\Catalog\Model\Entity\Attribute' )->loadByCode( - \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( + $this->_objectManager->get( 'Magento\Eav\Model\Config' )->getEntityType( - 'catalog_product' - )->getId(), + 'catalog_product' + )->getId(), 'test_configurable' ); /** @var $block \Magento\ConfigurableProduct\Block\Adminhtml\Product\Edit\Tab\Super\Config */ - $block = $objectManager->get( + $block = $this->_objectManager->get( 'Magento\Framework\View\LayoutInterface' )->createBlock( 'Magento\ConfigurableProduct\Block\Adminhtml\Product\Edit\Tab\Super\Config' ); + /** @var Attribute[] $selectedAttributes */ $selectedAttributes = $block->getSelectedAttributes(); $this->assertEquals(array($usedAttribute->getId()), array_keys($selectedAttributes)); + /** @var Attribute $selectedAttribute */ $selectedAttribute = reset($selectedAttributes); $this->assertEquals('test_configurable', $selectedAttribute->getAttributeCode()); } + + /** + * @magentoAppIsolation enabled + * @magentoDataFixture Magento/ConfigurableProduct/_files/product_configurable.php + */ + public function testAttributesMergingByGetAttributesMethod() + { + $this->_objectManager->get( + 'Magento\Framework\Registry' + )->register( + 'current_product', + $this->_objectManager->create('Magento\Catalog\Model\Product')->load(1) + ); + $this->_objectManager->get('Magento\Framework\View\LayoutInterface') + ->createBlock('Magento\Framework\View\Element\Text', 'head'); + /** @var \Magento\Catalog\Model\Entity\Attribute $usedAttribute */ + $usedAttribute = $this->_objectManager->get( + 'Magento\Catalog\Model\Entity\Attribute' + )->loadByCode( + $this->_objectManager->get( + 'Magento\Eav\Model\Config' + )->getEntityType( + 'catalog_product' + )->getId(), + 'test_configurable' + ); + /** @var $block \Magento\ConfigurableProduct\Block\Adminhtml\Product\Edit\Tab\Super\Config */ + $block = $this->_objectManager->get( + 'Magento\Framework\View\LayoutInterface' + )->createBlock( + 'Magento\ConfigurableProduct\Block\Adminhtml\Product\Edit\Tab\Super\Config' + ); + $productData = array( + $usedAttribute->getId() => array( + 'label' => static::ATTRIBUTE_LABEL, + 'position' => static::ATTRIBUTE_POSITION, + ), + + ); + $this->getRequest()->setParam('product', array('configurable_attributes_data' => $productData)); + $attributes = $block->getAttributes(); + $this->assertArrayHasKey($usedAttribute->getId(), $attributes); + + $this->assertArrayHasKey('label', $attributes[$usedAttribute->getId()]); + $this->assertEquals(static::ATTRIBUTE_LABEL, $attributes[$usedAttribute->getId()]['label']); + + $this->assertArrayHasKey('position', $attributes[$usedAttribute->getId()]); + $this->assertEquals(static::ATTRIBUTE_POSITION, $attributes[$usedAttribute->getId()]['position']); + } } diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/Product/Type/ConfigurableTest.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/Product/Type/ConfigurableTest.php index 5a529226aefacd8ad2ad5223ce925191deaf128f..a42f6ed3657359eed333daac8d995608b921bc86 100644 --- a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/Product/Type/ConfigurableTest.php +++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/Product/Type/ConfigurableTest.php @@ -174,10 +174,7 @@ class ConfigurableTest extends \PHPUnit_Framework_TestCase */ public function testGetParentIdsByChild() { - $attributes = $this->_model->getConfigurableAttributesAsArray($this->_product); - $attribute = reset($attributes); - $optionValueId = $attribute['values'][0]['value_index']; - $result = $this->_model->getParentIdsByChild($optionValueId * 10); + $result = $this->_model->getParentIdsByChild(10); // fixture $this->assertEquals(array(1), $result); } @@ -248,7 +245,7 @@ class ConfigurableTest extends \PHPUnit_Framework_TestCase $this->_product ); $this->assertInstanceOf('Magento\Catalog\Model\Product', $product); - $this->assertEquals("simple_{$optionValueId}", $product->getSku()); + $this->assertEquals("simple_10", $product->getSku()); } /** diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/configurable_attribute.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/configurable_attribute.php index 697509c8e586b0c37cf3467787aea8925269e745..1e27312544cbbcaf86fbfe369f06132311804f40 100644 --- a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/configurable_attribute.php +++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/configurable_attribute.php @@ -28,6 +28,7 @@ $installer = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create 'Magento\Catalog\Model\Resource\Setup', array('resourceName' => 'catalog_setup') ); + /** @var $attribute \Magento\Catalog\Model\Resource\Eav\Attribute */ $attribute = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( 'Magento\Catalog\Model\Resource\Eav\Attribute' @@ -62,5 +63,10 @@ $attribute->setData( ); $attribute->save(); + /* Assign attribute to attribute set */ $installer->addAttributeToGroup('catalog_product', 'Default', 'General', $attribute->getId()); + +/** @var \Magento\Eav\Model\Config $eavConfig */ +$eavConfig = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Eav\Model\Config'); +$eavConfig->clear(); diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/configurable_attribute_rollback.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/configurable_attribute_rollback.php new file mode 100644 index 0000000000000000000000000000000000000000..4120f5ba4625c23cf823687dd9bd30dd880758e1 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/configurable_attribute_rollback.php @@ -0,0 +1,33 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +/** @var \Magento\Eav\Model\Config $eavConfig */ +$eavConfig = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Eav\Model\Config'); +$attribute = $eavConfig->getAttribute('catalog_product', 'test_configurable'); +if ($attribute instanceof \Magento\Eav\Model\Entity\Attribute\AbstractAttribute + && $attribute->getId() +) { + $attribute->delete(); +} +$eavConfig->clear(); \ No newline at end of file diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/delete_association.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/delete_association.php new file mode 100644 index 0000000000000000000000000000000000000000..efe7eaddbec20288e84ec199cc972f0da5d02e14 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/delete_association.php @@ -0,0 +1,29 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +/** @var $product \Magento\Catalog\Model\Product */ +$product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Product'); +$product->load(1); +$product->setAssociatedProductIds([20]); +$product->save(); diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_configurable.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_configurable.php index 7a9e71d2604b12057ab73de58112cdbd080d3d73..9d256742d66031be03594a54b637f19bad9c695a 100644 --- a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_configurable.php +++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_configurable.php @@ -39,21 +39,24 @@ $options->setAttributeFilter($attribute->getId()); $attributeValues = array(); $productIds = array(); +$attributeSetId = $installer->getAttributeSetId('catalog_product', 'Default'); +$productIds = array(10, 20); foreach ($options as $option) { /** @var $product \Magento\Catalog\Model\Product */ $product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Product'); + $productId = array_shift($productIds); $product->setTypeId( \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE )->setId( - $option->getId() * 10 + $productId )->setAttributeSetId( - $installer->getAttributeSetId('catalog_product', 'Default') + $attributeSetId )->setWebsiteIds( array(1) )->setName( 'Configurable Option' . $option->getId() )->setSku( - 'simple_' . $option->getId() + 'simple_' . $productId )->setPrice( 10 )->setTestConfigurable( @@ -65,6 +68,7 @@ foreach ($options as $option) { )->setStockData( array('use_config_manage_stock' => 1, 'qty' => 100, 'is_qty_decimal' => 0, 'is_in_stock' => 1) )->save(); + $attributeValues[] = array( 'label' => 'test', 'attribute_id' => $attribute->getId(), @@ -82,7 +86,7 @@ $product->setTypeId( )->setId( 1 )->setAttributeSetId( - $installer->getAttributeSetId('catalog_product', 'Default') + $attributeSetId )->setWebsiteIds( array(1) )->setName( diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_configurable_rollback.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_configurable_rollback.php new file mode 100644 index 0000000000000000000000000000000000000000..6c40df5c6473bbdeb8d31d5eded59fe3bbbde782 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_configurable_rollback.php @@ -0,0 +1,52 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +/** @var \Magento\Framework\Registry $registry */ +$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Framework\Registry'); + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +/** @var $product \Magento\Catalog\Model\Product */ +$product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Product'); +$product->load(10); +if ($product->getId()) { + $product->delete(); +} +$product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Product'); +$product->load(20); +if ($product->getId()) { + $product->delete(); +} +$product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Product'); +$product->load(1); +if ($product->getId()) { + $product->delete(); +} + + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false); + +require __DIR__ . '/configurable_attribute_rollback.php'; diff --git a/dev/tests/integration/testsuite/Magento/Customer/Block/Account/Dashboard/HelloTest.php b/dev/tests/integration/testsuite/Magento/Customer/Block/Account/Dashboard/HelloTest.php index b40d064667bc50aa9a869679af40eced55994cb4..3c7daefce8b7fbd71aec1b06424fcf48f6370075 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Block/Account/Dashboard/HelloTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Block/Account/Dashboard/HelloTest.php @@ -83,7 +83,7 @@ class HelloTest extends \PHPUnit_Framework_TestCase { $this->customerSession->setCustomerId(1); $html = $this->block->toHtml(); - $this->assertContains("<div class=\"block dashboard welcome\">", $html); + $this->assertContains("<div class=\"block block-dashboard-welcome\">", $html); $this->assertContains("<strong>Hello, Firstname Lastname!</strong>", $html); } } diff --git a/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php b/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php index 4df8fdb2486a8b0944ae22b62c93245e51463dc7..2cd653e6033e195621fa1acd054b63dc54b648c1 100755 --- a/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php @@ -53,7 +53,7 @@ class AccountTest extends \Magento\TestFramework\TestCase\AbstractController $this->dispatch('customer/account/index'); $body = $this->getResponse()->getBody(); - $this->assertContains('<div class="block dashboard welcome">', $body); + $this->assertContains('<div class="block block-dashboard-welcome">', $body); $this->assertContains('Hello, Firstname Lastname!', $body); $this->assertContains('Green str, 67', $body); } diff --git a/dev/tests/integration/testsuite/Magento/Fedex/Model/CarrierTest.php b/dev/tests/integration/testsuite/Magento/Fedex/Model/CarrierTest.php new file mode 100644 index 0000000000000000000000000000000000000000..e3044e617cd2d241820266f25421846d13e6ddf3 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Fedex/Model/CarrierTest.php @@ -0,0 +1,89 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Fedex\Model; + +class CarrierTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Fedex\Model\Carrier + */ + protected $_model; + + protected function setUp() + { + $this->_model = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + 'Magento\Fedex\Model\Carrier' + ); + } + + /** + * @dataProvider getCodeDataProvider + * @param string $type + * @param int $expectedCount + */ + public function testGetCode($type, $expectedCount) + { + $result = $this->_model->getCode($type); + $this->assertCount($expectedCount, $result); + } + + /** + * Data Provider for testGetCode + * @return array + */ + public function getCodeDataProvider() + { + return array( + array('method', 21), + array('dropoff', 5), + array('packaging', 7), + array('containers_filter', 4), + array('delivery_confirmation_types', 4), + array('unit_of_measure', 2), + ); + } + + /** + * @dataProvider getCodeUnitOfMeasureDataProvider + * @param string $code + */ + public function testGetCodeUnitOfMeasure($code) + { + $result = $this->_model->getCode('unit_of_measure', $code); + $this->assertNotEmpty($result); + } + + /** + * Data Provider for testGetCodeUnitOfMeasure + * @return array + */ + public function getCodeUnitOfMeasureDataProvider() + { + return array( + array('LB'), + array('KG'), + ); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Fedex/Model/Source/UnitofmeasureTest.php b/dev/tests/integration/testsuite/Magento/Fedex/Model/Source/UnitofmeasureTest.php new file mode 100644 index 0000000000000000000000000000000000000000..49ce870dbdd362d770c66ec20545b5faa6682a6a --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Fedex/Model/Source/UnitofmeasureTest.php @@ -0,0 +1,38 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Fedex\Model\Source; + +class UnitofmeasureTest extends \PHPUnit_Framework_TestCase +{ + public function testToOptionArray() + { + /** @var $model \Magento\Fedex\Model\Source\Unitofmeasure */ + $model = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + 'Magento\Fedex\Model\Source\Unitofmeasure' + ); + $result = $model->toOptionArray(); + $this->assertCount(2, $result); + } +} diff --git a/dev/tests/integration/testsuite/Magento/GoogleShopping/Controller/Adminhtml/GoogleShopping/TypesTest.php b/dev/tests/integration/testsuite/Magento/GoogleShopping/Controller/Adminhtml/GoogleShopping/TypesTest.php index f1945c148ec3e792a4bb14b494aef9ccdee6e6b8..99133c4392377f0bd5f27f91e29322123de43ae7 100644 --- a/dev/tests/integration/testsuite/Magento/GoogleShopping/Controller/Adminhtml/GoogleShopping/TypesTest.php +++ b/dev/tests/integration/testsuite/Magento/GoogleShopping/Controller/Adminhtml/GoogleShopping/TypesTest.php @@ -34,4 +34,23 @@ class TypesTest extends \Magento\Backend\Utility\Controller $body = $this->getResponse()->getBody(); $this->assertSelectCount('[data-role="row"]', 1, $body, 'Grid with row exists'); } + + public function testLoadAttributeSetsAction() + { + $this->dispatch('backend/admin/googleshopping_types/loadAttributeSets/'); + $body = $this->getResponse()->getBody(); + + $this->assertTag( + array( + 'tag' => 'select', + 'attributes' => array('name' => 'attribute_set_id'), + 'descendant' => array( + 'tag' => 'option', + 'attributes' => array('value' => 4), + 'content' => 'Default', + ) + ), + $body + ); + } } diff --git a/dev/tests/integration/testsuite/Magento/GoogleShopping/Model/Attribute/TaxTest.php b/dev/tests/integration/testsuite/Magento/GoogleShopping/Model/Attribute/TaxTest.php new file mode 100644 index 0000000000000000000000000000000000000000..4cf0b75d35d711d530e0685092ab3bd7b0675008 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/GoogleShopping/Model/Attribute/TaxTest.php @@ -0,0 +1,335 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\GoogleShopping\Model\Attribute; + +use Magento\Tax\Model\ClassModel; +use Magento\Tax\Service\V1\Data\TaxRuleBuilder; +use Magento\Tax\Service\V1\Data\TaxRateBuilder; +use Magento\Tax\Service\V1\TaxRuleFixtureFactory; + +/** + * Tests GoogleShopping\Model\Attribute\Tax + */ +class TaxTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\GoogleShopping\Model\Attribute\Tax + */ + protected $googleShoppingTaxAttribute; + + /** + * @var \Magento\Framework\ObjectManager + */ + protected $objectManager; + + /** + * TaxRule builder + * + * @var TaxRuleBuilder + */ + private $taxRuleBuilder; + + /** + * TaxRate builder + * + * @var TaxRateBuilder + */ + private $taxRateBuilder; + + /** + * TaxRuleService + * + * @var \Magento\Tax\Service\V1\TaxRuleServiceInterface + */ + private $taxRuleService; + + /** + * Helps in creating required tax rules. + * + * @var TaxRuleFixtureFactory + */ + private $taxRuleFixtureFactory; + + /** + * Array of default tax classes ids + * + * Key is class name + * + * @var int[] + */ + private $taxClasses; + + /** + * Array of default tax rates ids. + * + * Key is rate percentage as string. + * + * @var int[] + */ + private $taxRates; + + /** + * Array of default tax rules ids. + * + * Key is rule code. + * + * @var int[] + */ + private $taxRules; + + protected function setUp() + { + $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $this->googleShoppingTaxAttribute = $this->objectManager + ->create('Magento\GoogleShopping\Model\Attribute\Tax'); + $this->taxRateBuilder = $this->objectManager->create('Magento\Tax\Service\V1\Data\TaxRuleBuilder'); + $this->taxRuleService = $this->objectManager->get('Magento\Tax\Service\V1\TaxRuleServiceInterface'); + $this->taxRuleBuilder = $this->objectManager->create('Magento\Tax\Service\V1\Data\TaxRuleBuilder'); + $this->taxRuleFixtureFactory = new TaxRuleFixtureFactory(); + $this->setUpDefaultRules(); + } + + /** + * @magentoDataFixture Magento/Catalog/_files/product_simple.php + */ + public function testConvertAttributeWithSimpleProduct() + { + $defaultProductTaxClassProduct = $this->objectManager->create('Magento\Catalog\Model\Product'); + $defaultProductTaxClassProduct->load(1); + $defaultProductTaxClassProduct->setTaxClassId($this->taxClasses['DefaultProductClass']); + + $defaultGoogleShoppingEntry = $this->objectManager + ->create('Magento\Framework\Gdata\Gshopping\Entry'); + $defaultEntry = $this->googleShoppingTaxAttribute + ->convertAttribute($defaultProductTaxClassProduct, $defaultGoogleShoppingEntry); + + $this->assertEquals(2, count($defaultEntry->getTaxes())); + + foreach ($defaultEntry->getTaxes() as $tax) { + $this->assertEquals('US', $tax->__get('tax_country')); + $this->assertEquals(7.5, round($tax->__get('tax_rate'), 1)); + $this->assertTrue($tax->__get('tax_region') == 'NM' || $tax->__get('tax_region') == 'CA'); + } + + $higherProductTaxClassProduct = $this->objectManager->create('Magento\Catalog\Model\Product'); + $higherProductTaxClassProduct->load(1); + $higherProductTaxClassProduct->setTaxClassId($this->taxClasses['HigherProductClass']); + + $higherGoogleShoppingEntry = $this->objectManager + ->create('Magento\Framework\Gdata\Gshopping\Entry'); + $higherEntry = $this->googleShoppingTaxAttribute + ->convertAttribute($higherProductTaxClassProduct, $higherGoogleShoppingEntry); + + $this->assertEquals(2, count($higherEntry->getTaxes())); + + foreach ($higherEntry->getTaxes() as $tax) { + $this->assertEquals('US', $tax->__get('tax_country')); + if ($tax->__get('tax_region') == 'NM') { + $this->assertEquals(22.0, round($tax->__get('tax_rate'), 1)); + } elseif ($tax->__get('tax_region') == 'CA') { + $this->assertEquals(10.0, round($tax->__get('tax_rate'), 1)); + } else { + $this->fail('Invalid tax region'); + } + } + } + + /** + * @magentoDataFixture Magento/Catalog/_files/product_group_prices.php + */ + public function testConvertAttributeWithProductGroup() + { + $defaultProductTaxClassProduct = $this->objectManager->create('Magento\Catalog\Model\Product'); + $defaultProductTaxClassProduct->load(1); + $defaultProductTaxClassProduct->setTaxClassId($this->taxClasses['DefaultProductClass']); + + $defaultGoogleShoppingEntry = $this->objectManager + ->create('Magento\Framework\Gdata\Gshopping\Entry'); + $defaultEntry = $this->googleShoppingTaxAttribute + ->convertAttribute($defaultProductTaxClassProduct, $defaultGoogleShoppingEntry); + + $this->assertEquals(2, count($defaultEntry->getTaxes())); + + foreach ($defaultEntry->getTaxes() as $tax) { + $this->assertEquals('US', $tax->__get('tax_country')); + $this->assertEquals(7.5, round($tax->__get('tax_rate'), 1)); + $this->assertTrue($tax->__get('tax_region') == 'NM' || $tax->__get('tax_region') == 'CA'); + } + + $higherProductTaxClassProduct = $this->objectManager->create('Magento\Catalog\Model\Product'); + $higherProductTaxClassProduct->load(1); + $higherProductTaxClassProduct->setTaxClassId($this->taxClasses['HigherProductClass']); + + $higherGoogleShoppingEntry = $this->objectManager + ->create('Magento\Framework\Gdata\Gshopping\Entry'); + $higherEntry = $this->googleShoppingTaxAttribute + ->convertAttribute($higherProductTaxClassProduct, $higherGoogleShoppingEntry); + + $this->assertEquals(2, count($higherEntry->getTaxes())); + + foreach ($higherEntry->getTaxes() as $tax) { + $this->assertEquals('US', $tax->__get('tax_country')); + if ($tax->__get('tax_region') == 'NM') { + $this->assertEquals(22.0, round($tax->__get('tax_rate'), 1)); + } elseif ($tax->__get('tax_region') == 'CA') { + $this->assertEquals(10.0, round($tax->__get('tax_rate'), 1)); + } else { + $this->fail('Invalid tax region'); + } + } + } + + /** + * @magentoDataFixture Magento/Catalog/_files/multiple_products.php + */ + public function testConvertAttributeWithMultipleProducts() + { + $productA = $this->objectManager->create('Magento\Catalog\Model\Product'); + $productA->load(10); + $productA->setTaxClassId($this->taxClasses['DefaultProductClass']); + $productAGoogleShoppingEntry = $this->objectManager + ->create('Magento\Framework\Gdata\Gshopping\Entry'); + $productAEntry = $this->googleShoppingTaxAttribute + ->convertAttribute($productA, $productAGoogleShoppingEntry); + + $this->assertEquals(2, count($productAEntry->getTaxes())); + foreach ($productAEntry->getTaxes() as $tax) { + $this->assertEquals('US', $tax->__get('tax_country')); + $this->assertEquals(7.5, round($tax->__get('tax_rate'), 1)); + $this->assertTrue($tax->__get('tax_region') == 'NM' || $tax->__get('tax_region') == 'CA'); + } + + $productB = $this->objectManager->create('Magento\Catalog\Model\Product'); + $productB->load(11); + $productB->setTaxClassId($this->taxClasses['HigherProductClass']); + $productBGoogleShoppingEntry = $this->objectManager + ->create('Magento\Framework\Gdata\Gshopping\Entry'); + $productBEntry = $this->googleShoppingTaxAttribute + ->convertAttribute($productB, $productBGoogleShoppingEntry); + + $this->assertEquals(2, count($productBEntry->getTaxes())); + foreach ($productBEntry->getTaxes() as $tax) { + $this->assertEquals('US', $tax->__get('tax_country')); + if ($tax->__get('tax_region') == 'NM') { + $this->assertEquals(22.0, round($tax->__get('tax_rate'), 1)); + } elseif ($tax->__get('tax_region') == 'CA') { + $this->assertEquals(10.0, round($tax->__get('tax_rate'), 1)); + } else { + $this->fail('Invalid tax region'); + } + } + + $productC = $this->objectManager->create('Magento\Catalog\Model\Product'); + $productC->load(12); + $productC->setTaxClassId($this->taxClasses['HighestProductClass']); + $productCGoogleShoppingEntry = $this->objectManager + ->create('Magento\Framework\Gdata\Gshopping\Entry'); + $productCEntry = $this->googleShoppingTaxAttribute + ->convertAttribute($productC, $productCGoogleShoppingEntry); + + $this->assertEquals(2, count($productCEntry->getTaxes())); + foreach ($productCEntry->getTaxes() as $tax) { + $this->assertEquals('US', $tax->__get('tax_country')); + if ($tax->__get('tax_region') == 'NM') { + $this->assertEquals(22.5, round($tax->__get('tax_rate'), 1)); + } elseif ($tax->__get('tax_region') == 'CA') { + $this->assertEquals(15.0, round($tax->__get('tax_rate'), 1)); + } else { + $this->fail('Invalid tax_region'); + } + } + } + + /** + * Helper function that sets up some default rules + */ + private function setUpDefaultRules() + { + $this->taxClasses = $this->taxRuleFixtureFactory->createTaxClasses([ + ['name' => 'DefaultCustomerClass', 'type' => ClassModel::TAX_CLASS_TYPE_CUSTOMER], + ['name' => 'DefaultProductClass', 'type' => ClassModel::TAX_CLASS_TYPE_PRODUCT], + ['name' => 'HigherProductClass', 'type' => ClassModel::TAX_CLASS_TYPE_PRODUCT], + ['name' => 'HighestProductClass', 'type' => ClassModel::TAX_CLASS_TYPE_PRODUCT], + ]); + + $this->taxRates = $this->taxRuleFixtureFactory->createTaxRates([ + ['percentage' => 7.5, 'country' => 'US', 'region' => 42], + ['percentage' => 7.5, 'country' => 'US', 'region' => 12], // Default store rate + ['percentage' => 10, 'country' => 'MX', 'region' => 99], + ]); + + $higherRates = $this->taxRuleFixtureFactory->createTaxRates([ + ['percentage' => 22, 'country' => 'US', 'region' => 42], + ['percentage' => 10, 'country' => 'US', 'region' => 12], // Default store rate + ['percentage' => 15, 'country' => 'MX', 'region' => 99], + ]); + + $highestRates = $this->taxRuleFixtureFactory->createTaxRates([ + ['percentage' => 22.5, 'country' => 'US', 'region' => 42], + ['percentage' => 15, 'country' => 'US', 'region' => 12], // Default store rate + ['percentage' => 20, 'country' => 'MX', 'region' => 99], + ]); + + $this->taxRules = $this->taxRuleFixtureFactory->createTaxRules([ + [ + 'code' => 'Default Rule', + 'customer_tax_class_ids' => [$this->taxClasses['DefaultCustomerClass'], 3], + 'product_tax_class_ids' => [$this->taxClasses['DefaultProductClass']], + 'tax_rate_ids' => array_values($this->taxRates), + 'sort_order' => 0, + 'priority' => 0, + ], + [ + 'code' => 'Higher Rate Rule', + 'customer_tax_class_ids' => [$this->taxClasses['DefaultCustomerClass'], 3], + 'product_tax_class_ids' => [$this->taxClasses['HigherProductClass']], + 'tax_rate_ids' => array_values($higherRates), + 'sort_order' => 0, + 'priority' => 0, + ], + [ + 'code' => 'Highest Rate Rule', + 'customer_tax_class_ids' => [$this->taxClasses['DefaultCustomerClass'], 3], + 'product_tax_class_ids' => [$this->taxClasses['HighestProductClass']], + 'tax_rate_ids' => array_values($highestRates), + 'sort_order' => 1, + 'priority' => 1, + ], + ]); + + // For cleanup + $this->taxRates = array_merge($this->taxRates, $higherRates, $highestRates); + } + + /** + * Helper function that tears down some default rules + */ + public function tearDown() + { + $this->taxRuleFixtureFactory->deleteTaxRules(array_values($this->taxRules)); + $this->taxRuleFixtureFactory->deleteTaxRates(array_values($this->taxRates)); + $this->taxRuleFixtureFactory->deleteTaxClasses(array_values($this->taxClasses)); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Multishipping/Controller/CheckoutTest.php b/dev/tests/integration/testsuite/Magento/Multishipping/Controller/CheckoutTest.php index 29a06b99a55515fb466a3957da54579817f1c59e..f912c1b0b5d15a8fa03cd032edb588511b36d2f1 100644 --- a/dev/tests/integration/testsuite/Magento/Multishipping/Controller/CheckoutTest.php +++ b/dev/tests/integration/testsuite/Magento/Multishipping/Controller/CheckoutTest.php @@ -50,6 +50,7 @@ class CheckoutTest extends \Magento\TestFramework\TestCase\AbstractController )->setQuoteId( $quote->getId() ); + $formKey = $this->_objectManager->get('Magento\Framework\Data\Form\FormKey'); $logger = $this->getMock('Magento\Framework\Logger', array(), array(), '', false); /** @var $session \Magento\Customer\Model\Session */ $session = Bootstrap::getObjectManager()->create('Magento\Customer\Model\Session', array($logger)); @@ -67,5 +68,6 @@ class CheckoutTest extends \Magento\TestFramework\TestCase\AbstractController $html ); $this->assertContains('<span class="price">$10.00</span>', $html); + $this->assertContains('<input name="form_key" type="hidden" value="' . $formKey->getFormKey(), $html); } } diff --git a/dev/tests/integration/testsuite/Magento/Paypal/Model/Express/CheckoutTest.php b/dev/tests/integration/testsuite/Magento/Paypal/Model/Express/CheckoutTest.php index c52c685aa57221a188d801cabaabff4fc03eecc6..78541ca25939e1efa227b2b53e3fe7f72abbca9c 100644 --- a/dev/tests/integration/testsuite/Magento/Paypal/Model/Express/CheckoutTest.php +++ b/dev/tests/integration/testsuite/Magento/Paypal/Model/Express/CheckoutTest.php @@ -248,14 +248,9 @@ class CheckoutTest extends \PHPUnit_Framework_TestCase $checkoutModel->returnFromPaypal('token'); $billingAddress = $quote->getBillingAddress(); - $this->assertEquals($billingAddress->getEmail(), $quote->getCustomerEmail()); - $this->assertEquals($billingAddress->getPrefix(), $quote->getCustomerPrefix()); - $this->assertEquals($billingAddress->getFirstname(), $quote->getCustomerFirstname()); - $this->assertEquals($billingAddress->getMiddlename(), $quote->getCustomerMiddlename()); - $this->assertEquals($billingAddress->getLastname(), $quote->getCustomerLastname()); - $this->assertEquals($billingAddress->getSuffix(), $quote->getCustomerSuffix()); - $this->assertTrue($billingAddress->getShouldIgnoreValidation()); + $this->assertContains('exported', $billingAddress->getFirstname()); + $this->assertEquals('note', $billingAddress->getCustomerNote()); $shippingAddress = $quote->getShippingAddress(); $this->assertTrue((bool)$shippingAddress->getSameAsBilling()); @@ -293,6 +288,7 @@ class CheckoutTest extends \PHPUnit_Framework_TestCase } $fixture = new \Magento\Framework\Object($result); $fixture->setExportedKeys($addressDataKeys); + $fixture->setData('note', 'note'); return $fixture; } diff --git a/dev/tests/integration/testsuite/Magento/Paypal/Model/PayflowproTest.php b/dev/tests/integration/testsuite/Magento/Paypal/Model/PayflowproTest.php new file mode 100644 index 0000000000000000000000000000000000000000..f68eefd2abe65ccaacb1b2bd333d42357cfa5aaa --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Paypal/Model/PayflowproTest.php @@ -0,0 +1,84 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Paypal\Model; + +class PayflowproTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Framework\ObjectManager + */ + protected $_objectManager; + + /** + * @var \Magento\Paypal\Model\Payflowpro + */ + protected $_model; + + /** + * @var \Magento\Framework\HTTP\ZendClient + */ + protected $_httpClientMock; + + public function setUp() + { + $this->_objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $httpClientFactoryMock = $this->getMockBuilder('Magento\Framework\HTTP\ZendClientFactory') + ->setMethods(['create']) + ->disableOriginalConstructor() + ->getMock(); + $this->_httpClientMock = $this->getMockBuilder('Magento\Framework\HTTP\ZendClient')->setMethods([]) + ->disableOriginalConstructor()->getMock(); + $this->_httpClientMock->expects($this->any())->method('setUri')->will($this->returnSelf()); + $this->_httpClientMock->expects($this->any())->method('setConfig')->will($this->returnSelf()); + $this->_httpClientMock->expects($this->any())->method('setMethod')->will($this->returnSelf()); + $this->_httpClientMock->expects($this->any())->method('setParameterPost')->will($this->returnSelf()); + $this->_httpClientMock->expects($this->any())->method('setHeaders')->will($this->returnSelf()); + $this->_httpClientMock->expects($this->any())->method('setUrlEncodeBody')->will($this->returnSelf()); + + $httpClientFactoryMock->expects($this->any())->method('create') + ->will($this->returnValue($this->_httpClientMock)); + + $this->_model = $this->_objectManager->create( + 'Magento\Paypal\Model\Payflowpro', + ['httpClientFactory' => $httpClientFactoryMock] + ); + } + + /** + * @magentoDataFixture Magento/Sales/_files/order_paid_with_payflowpro.php + */ + public function testReviewPaymentNullResponce() + { + /** @var \Magento\Sales\Model\Order $order */ + $order = $this->_objectManager->create('Magento\Sales\Model\Order'); + $order->loadByIncrementId('100000001'); + + $this->_httpClientMock->expects($this->any())->method('request') + ->will($this->returnValue(new \Magento\Framework\Object(['body' => 'RESULTval=12&val2=34']))); + $expectedResult = ['resultval' => '12', 'val2' => '34', 'result_code' => null, 'respmsg' => null]; + + $this->assertEquals($expectedResult, $this->_model->acceptPayment($order->getPayment())); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Paypal/Model/VoidTest.php b/dev/tests/integration/testsuite/Magento/Paypal/Model/VoidTest.php index 35a37a47b00187d7f64548e49f3777a1568edf87..00de2fc305a6fa6de728edae3dc7e23be243264a 100644 --- a/dev/tests/integration/testsuite/Magento/Paypal/Model/VoidTest.php +++ b/dev/tests/integration/testsuite/Magento/Paypal/Model/VoidTest.php @@ -43,6 +43,10 @@ class VoidTest extends \PHPUnit_Framework_TestCase $storeManager = $objectManager->get('Magento\Store\Model\StoreManagerInterface'); $configFactory = $objectManager->get('Magento\Paypal\Model\ConfigFactory'); $mathRandom = $objectManager->get('Magento\Framework\Math\Random'); + $httpClientFactoryMock = $this->getMockBuilder('Magento\Framework\HTTP\ZendClientFactory') + ->setMethods(['create']) + ->disableOriginalConstructor() + ->getMock(); /** @var $order \Magento\Sales\Model\Order */ $order = $objectManager->create('Magento\Sales\Model\Order'); @@ -64,7 +68,8 @@ class VoidTest extends \PHPUnit_Framework_TestCase $centinelService, $storeManager, $configFactory, - $mathRandom + $mathRandom, + $httpClientFactoryMock ) ); diff --git a/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/CreateTest.php b/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/CreateTest.php index 53d0573346a934b6d7b8ec6f16446be8c28096d1..d18c0c11578f9d6dfc697bab8f2e932ce2c2d75d 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/CreateTest.php +++ b/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/CreateTest.php @@ -107,12 +107,13 @@ class CreateTest extends \Magento\Backend\Utility\Controller $order->addProducts(array(1 => array('qty' => 1))); $this->dispatch('backend/sales/order_create/index'); $html = $this->getResponse()->getBody(); - $this->assertContains('<div id="order-customer-selector"', $html); - $this->assertContains('<div id="sales_order_create_customer_grid">', $html); - $this->assertContains('<div id="order-billing_method_form">', $html); - $this->assertContains('id="shipping-method-overlay"', $html); - $this->assertContains('<div id="sales_order_create_search_grid">', $html); - $this->assertContains('id="coupons:code"', $html); + + $this->assertSelectCount('div#order-customer-selector', true, $html); + $this->assertSelectCount('[data-grid-id=sales_order_create_customer_grid]', true, $html); + $this->assertSelectCount('div#order-billing_method_form', true, $html); + $this->assertSelectCount('#shipping-method-overlay', true, $html); + $this->assertSelectCount('div#sales_order_create_search_grid', true, $html); + $this->assertSelectCount('#coupons:code', true, $html); } /** diff --git a/dev/tests/integration/testsuite/Magento/Sales/Model/Resource/Report/Bestsellers/CollectionTest.php b/dev/tests/integration/testsuite/Magento/Sales/Model/Resource/Report/Bestsellers/CollectionTest.php index b47c2f127e85e83970a7af82bc8a37932627de01..ad8874a03aab6bf7085bb1ae7ad431a60b890fc4 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/Model/Resource/Report/Bestsellers/CollectionTest.php +++ b/dev/tests/integration/testsuite/Magento/Sales/Model/Resource/Report/Bestsellers/CollectionTest.php @@ -52,4 +52,89 @@ class CollectionTest extends \PHPUnit_Framework_TestCase } $this->assertEquals($expectedResult, $actualResult); } + + /** + * @dataProvider tableForPeriodDataProvider + * + * @param $period + * @param $expectedTable + * @param $dateFrom + * @param $dateTo + */ + public function testTableSelection($period, $expectedTable, $dateFrom, $dateTo) + { + $dbTableName = $this->_collection->getTable($expectedTable); + $this->_collection->setPeriod($period); + $this->_collection->setDateRange($dateFrom, $dateTo); + $this->_collection->load(); + $from = $this->_collection->getSelect()->getPart('from'); + + $this->assertArrayHasKey($dbTableName, $from); + + $this->assertArrayHasKey('tableName', $from[$dbTableName]); + $actualTable = $from[$dbTableName]['tableName']; + + $this->assertEquals($dbTableName, $actualTable); + } + + /** + * Data provider for testTableSelection + * + * @return array + */ + public function tableForPeriodDataProvider() + { + $dateNow = date('Y-m-d', time()); + $dateYearAgo = date('Y-m-d', strtotime($dateNow . ' -1 year')); + return array( + [ + 'period' => 'year', + 'table' => 'sales_bestsellers_aggregated_yearly', + 'date_from' => null, + 'date_to' => null + ], + [ + 'period' => 'month', + 'table' => 'sales_bestsellers_aggregated_monthly', + 'date_from' => null, + 'date_to' => null + ], + [ + 'period' => 'day', + 'table' => 'sales_bestsellers_aggregated_daily', + 'date_from' => null, + 'date_to' => null + ], + [ + 'period' => 'undefinedPeriod', + 'table' => 'sales_bestsellers_aggregated_daily', + 'date_from' => null, + 'date_to' => null + ], + [ + 'period' => null, + 'table' => 'sales_bestsellers_aggregated_daily', + 'date_from' => $dateYearAgo, + 'date_to' => $dateNow + ], + [ + 'period' => null, + 'table' => 'sales_bestsellers_aggregated_daily', + 'date_from' => $dateNow, + 'date_to' => $dateNow + ], + [ + 'period' => null, + 'table' => 'sales_bestsellers_aggregated_daily', + 'date_from' => $dateYearAgo, + 'date_to' => $dateYearAgo + ], + [ + 'period' => null, + 'table' => 'sales_bestsellers_aggregated_yearly', + 'date_from' => null, + 'date_to' => null + ], + ); + } } diff --git a/dev/tests/integration/testsuite/Magento/Tax/Pricing/Price/Plugin/AttributePriceTest.php b/dev/tests/integration/testsuite/Magento/Tax/Pricing/Price/Plugin/AttributePriceTest.php new file mode 100644 index 0000000000000000000000000000000000000000..f1ae5b55957db737217535299d9a3676b6dc7ac4 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Tax/Pricing/Price/Plugin/AttributePriceTest.php @@ -0,0 +1,208 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Tax\Pricing\Price\Plugin; + +use Magento\Tax\Model\ClassModel; +use Magento\Tax\Service\V1\TaxRuleFixtureFactory; +use Magento\Store\Model\ScopeInterface; +use Magento\Tax\Model\Config; + +/** + * @magentoDataFixture Magento/Customer/_files/customer.php + * @magentoDataFixture Magento/Customer/_files/customer_address.php + * @magentoDataFixture Magento/ConfigurableProduct/_files/product_configurable.php + */ +class AttributePriceTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Framework\ObjectManager + */ + private $objectManager; + + /** + * Array of default tax classes ids + * + * Key is class name + * + * @var int[] + */ + private $taxClasses; + + /** + * Array of default tax rates ids. + * + * Key is rate percentage as string. + * + * @var int[] + */ + private $taxRates; + + /** + * Array of default tax rules ids. + * + * Key is rule code. + * + * @var int[] + */ + private $taxRules; + + /** + * Helps in creating required tax rules. + * + * @var \Magento\Tax\Service\V1\TaxRuleFixtureFactory + */ + private $taxRuleFixtureFactory; + + public function setUp() + { + $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $this->taxRuleFixtureFactory = new \Magento\Tax\Service\V1\TaxRuleFixtureFactory(); + } + + public function tearDown() + { + $this->tearDownDefaultRules(); + } + + /** + * Tests that the plugin's adjustment config behavior with different tax config. + * + * @param bool $isTaxIncludeInBasePrice + * @param int $priceDisplayType + * @param bool $isProductTaxClassIdSet + * @dataProvider getTaxConfigData + */ + public function testPrepareAdjustmentConfig($isTaxIncludedInBasePrice, $priceDisplayType, $isProductTaxClassIdSet) + { + $this->setupDefaultRules(); + + $scopeConfig = $this->objectManager->get('Magento\Framework\App\MutableScopeConfig'); + $scopeConfig->setValue( + Config::CONFIG_XML_PATH_PRICE_INCLUDES_TAX, + $isTaxIncludedInBasePrice, + ScopeInterface::SCOPE_STORE, + 'default' + ); + $scopeConfig->setValue( + Config::CONFIG_XML_PATH_PRICE_DISPLAY_TYPE, + $priceDisplayType, + ScopeInterface::SCOPE_STORE, + 'default' + ); + + $product = $this->objectManager->get('Magento\Catalog\Model\Product')->load(1); + if ($isProductTaxClassIdSet) { + $product->setTaxClassId($this->taxClasses['DefaultProductClass']); + } + + $customerId = 1; + $attributePrice = $this->objectManager->create( + 'Magento\ConfigurableProduct\Pricing\Price\AttributePrice', + [ + 'saleableItem' => $product, + 'quantity' => 1, + ] + ); + + $result = $attributePrice->prepareAdjustmentConfig($customerId); + if ($isProductTaxClassIdSet) { + $this->assertEquals(7.5, $result['defaultTax']); + $this->assertEquals(6.5, $result['currentTax']); + } else { + $this->assertEquals(0, $result['defaultTax']); + $this->assertEquals(0, $result['currentTax']); + } + $this->assertEquals($isTaxIncludedInBasePrice, $result['includeTax']); + $this->assertEquals($priceDisplayType === Config::DISPLAY_TYPE_INCLUDING_TAX, $result['showIncludeTax']); + $this->assertEquals($priceDisplayType === Config::DISPLAY_TYPE_BOTH, $result['showBothPrices']); + $this->assertEquals($customerId, $result['customerId']); + } + + public function getTaxConfigData() + { + return [ + 'default behavior' => [ + false, + Config::DISPLAY_TYPE_EXCLUDING_TAX, + null + ], + 'include tax in base, show include tax in display, no product tax class' => [ + true, + Config::DISPLAY_TYPE_INCLUDING_TAX, + null + ], + 'include tax in base, show both include and exclude tax in display, no product tax class' => [ + true, + Config::DISPLAY_TYPE_BOTH, + null + ], + 'include tax in base, show both include and exclude tax in display, set product tax class' => [ + true, + Config::DISPLAY_TYPE_BOTH, + true + ], + ]; + } + + private function setUpDefaultRules() + { + $this->taxClasses = $this->taxRuleFixtureFactory->createTaxClasses([ + ['name' => 'DefaultCustomerClass', 'type' => ClassModel::TAX_CLASS_TYPE_CUSTOMER], + ['name' => 'DefaultProductClass', 'type' => ClassModel::TAX_CLASS_TYPE_PRODUCT], + ]); + + $this->taxRates = $this->taxRuleFixtureFactory->createTaxRates([ + ['percentage' => 6.5, 'country' => 'US', 'region' => 1], + ['percentage' => 7.5, 'country' => 'US', 'region' => 12], // Default store rate + ]); + + $this->taxRules = $this->taxRuleFixtureFactory->createTaxRules([ + [ + 'code' => 'Default Rule', + 'customer_tax_class_ids' => [$this->taxClasses['DefaultCustomerClass'], 3], + 'product_tax_class_ids' => [$this->taxClasses['DefaultProductClass']], + 'tax_rate_ids' => array_values($this->taxRates), + 'sort_order' => 0, + 'priority' => 0, + ], + ]); + } + + /** + * Helper function that tears down some default rules + */ + private function tearDownDefaultRules() + { + if ($this->taxRules) { + $this->taxRuleFixtureFactory->deleteTaxRules(array_values($this->taxRules)); + } + if ($this->taxRates) { + $this->taxRuleFixtureFactory->deleteTaxRates(array_values($this->taxRates)); + } + if ($this->taxClasses) { + $this->taxRuleFixtureFactory->deleteTaxClasses(array_values($this->taxClasses)); + } + } +} diff --git a/dev/tests/integration/testsuite/Magento/Tax/Service/V1/Data/QuoteDetails/ItemBuilderTest.php b/dev/tests/integration/testsuite/Magento/Tax/Service/V1/Data/QuoteDetails/ItemBuilderTest.php new file mode 100644 index 0000000000000000000000000000000000000000..7b418c0423847c7e233469ce3942637d7b43167c --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Tax/Service/V1/Data/QuoteDetails/ItemBuilderTest.php @@ -0,0 +1,213 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Tax\Service\V1\Data\QuoteDetails; + +use Magento\Tax\Service\V1\Data\TaxClassKey; + +class ItemBuilderTest extends \PHPUnit_Framework_TestCase +{ + /** + * Object manager + * + * @var \Magento\Framework\ObjectManager + */ + private $objectManager; + + /** + * TaxClassKey data object builder + * + * @var \Magento\Tax\Service\V1\Data\TaxClassKeyBuilder + */ + private $taxClassKeyBuilder; + + /** + * Quote Details Item data object builder + * + * @var \Magento\Tax\Service\V1\Data\QuoteDetails\ItemBuilder + */ + private $quoteDetailsItemBuilder; + + protected function setUp() + { + $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $this->taxClassKeyBuilder = $this->objectManager + ->create('Magento\Tax\Service\V1\Data\TaxClassKeyBuilder'); + $this->quoteDetailsItemBuilder = $this->objectManager + ->create('Magento\Tax\Service\V1\Data\QuoteDetails\ItemBuilder'); + } + + /** + * @param array $dataArray Array with data for item + * @dataProvider createDataProvider + */ + public function testPopulateWithArray($dataArray) + { + $itemFromPopulate = $this->quoteDetailsItemBuilder->populateWithArray($dataArray)->create(); + $itemFromSetters = $this->generateItemWithSetters($dataArray); + $this->assertInstanceOf('\Magento\Tax\Service\V1\Data\QuoteDetails\Item', $itemFromPopulate); + $this->assertInstanceOf('\Magento\Tax\Service\V1\Data\QuoteDetails\Item', $itemFromSetters); + $this->assertEquals($itemFromSetters, $itemFromPopulate); + $this->assertEquals($dataArray, $itemFromPopulate->__toArray()); + $this->assertEquals($dataArray, $itemFromSetters->__toArray()); + } + + /** + * @param array $dataArray Array with data for item + * @dataProvider createDataProvider + */ + public function testPopulate($dataArray) + { + $itemFromSetters = $this->generateItemWithSetters($dataArray); + $itemFromPopulate = $this->quoteDetailsItemBuilder->populate($itemFromSetters)->create(); + $this->assertEquals($itemFromSetters, $itemFromPopulate); + } + + public function createDataProvider() + { + return[ + 'empty' => [[]], + 'case1' => [$this->getData()['data1']], + 'case2' => [$this->getData()['data2']], + ]; + } + + public function testMergeDataObjects() + { + $data = $this->getData(); + $itemExpected = $this->quoteDetailsItemBuilder->populateWithArray($data['dataMerged'])->create(); + $itemSomeFields = $this->quoteDetailsItemBuilder->populateWithArray($data['data1'])->create(); + $itemMoreFields = $this->quoteDetailsItemBuilder->populateWithArray($data['data2'])->create(); + $itemMerged = $this->quoteDetailsItemBuilder->mergeDataObjects($itemSomeFields, $itemMoreFields); + $this->assertEquals($itemExpected->__toArray(), $itemMerged->__toArray()); + } + + public function testMergeDataObjectsWithArray() + { + $data = $this->getData(); + $itemExpected = $this->quoteDetailsItemBuilder->populateWithArray($data['dataMerged'])->create(); + $itemSomeFields = $this->quoteDetailsItemBuilder->populateWithArray($data['data1'])->create(); + $itemMerged = $this->quoteDetailsItemBuilder->mergeDataObjectWithArray($itemSomeFields, $data['data2']); + $this->assertEquals($itemExpected->__toArray(), $itemMerged->__toArray()); + } + + /** + * Creates a QuoteDetails item data object by calling setters. + * + * @param array $dataArray + * @return Item + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * @SuppressWarnings(PHPMD.NPathComplexity) + */ + private function generateItemWithSetters($dataArray) + { + $this->quoteDetailsItemBuilder->populateWithArray([]); + if (array_key_exists(Item::KEY_CODE, $dataArray)) { + $this->quoteDetailsItemBuilder->setCode($dataArray[Item::KEY_CODE]); + } + if (array_key_exists(Item::KEY_TYPE, $dataArray)) { + $this->quoteDetailsItemBuilder->setType($dataArray[Item::KEY_TYPE]); + } + if (array_key_exists(Item::KEY_TAX_CLASS_KEY, $dataArray)) { + $this->quoteDetailsItemBuilder->setTaxClassKey( + $this->taxClassKeyBuilder->setType($dataArray[Item::KEY_TAX_CLASS_KEY][TaxClassKey::KEY_TYPE]) + ->setValue($dataArray[Item::KEY_TAX_CLASS_KEY][TaxClassKey::KEY_VALUE]) + ->create() + ); + } + if (array_key_exists(Item::KEY_DISCOUNT_AMOUNT, $dataArray)) { + $this->quoteDetailsItemBuilder->setDiscountAmount($dataArray[Item::KEY_DISCOUNT_AMOUNT]); + } + if (array_key_exists(Item::KEY_QUANTITY, $dataArray)) { + $this->quoteDetailsItemBuilder->setQuantity($dataArray[Item::KEY_QUANTITY]); + } + if (array_key_exists(Item::KEY_PARENT_CODE, $dataArray)) { + $this->quoteDetailsItemBuilder->setParentCode($dataArray[Item::KEY_PARENT_CODE]); + } + if (array_key_exists(Item::KEY_SHORT_DESCRIPTION, $dataArray)) { + $this->quoteDetailsItemBuilder->setShortDescription($dataArray[Item::KEY_SHORT_DESCRIPTION]); + } + if (array_key_exists(Item::KEY_UNIT_PRICE, $dataArray)) { + $this->quoteDetailsItemBuilder->setUnitPrice($dataArray[Item::KEY_UNIT_PRICE]); + } + if (array_key_exists(Item::KEY_TAX_INCLUDED, $dataArray)) { + $this->quoteDetailsItemBuilder->setTaxIncluded($dataArray[Item::KEY_TAX_INCLUDED]); + } + return $this->quoteDetailsItemBuilder->create(); + } + + /** + * Get item data + * + * @return array + */ + protected function getData() + { + $data1 = [ + Item::KEY_CODE => 'item code', + Item::KEY_TYPE => 'shipping', + Item::KEY_TAX_CLASS_KEY => [ + TaxClassKey::KEY_TYPE => TaxClassKey::TYPE_ID, + TaxClassKey::KEY_VALUE => 1, + ], + Item::KEY_UNIT_PRICE => 10, + Item::KEY_DISCOUNT_AMOUNT => 2.6, + ]; + + $data2 = [ + Item::KEY_CODE => 'another code', + Item::KEY_TYPE => 'product', + Item::KEY_DISCOUNT_AMOUNT => 5, + Item::KEY_QUANTITY => 2, + Item::KEY_TAX_INCLUDED => false, + Item::KEY_SHORT_DESCRIPTION => 'product', + Item::KEY_PARENT_CODE => 'parent', + Item::KEY_TAX_CLASS_KEY => [ + TaxClassKey::KEY_TYPE => TaxClassKey::TYPE_NAME, + TaxClassKey::KEY_VALUE => 'tax class name', + ], + ]; + + $data = [ + 'data1' => $data1, + 'data2' => $data2, + 'dataMerged' => [ + Item::KEY_CODE => 'another code', + Item::KEY_TYPE => 'product', + Item::KEY_DISCOUNT_AMOUNT => 5, + Item::KEY_QUANTITY => 2, + Item::KEY_TAX_INCLUDED => false, + Item::KEY_SHORT_DESCRIPTION => 'product', + Item::KEY_PARENT_CODE => 'parent', + Item::KEY_UNIT_PRICE => 10, + Item::KEY_TAX_CLASS_KEY => [ + TaxClassKey::KEY_TYPE => TaxClassKey::TYPE_NAME, + TaxClassKey::KEY_VALUE => 'tax class name', + ], + ] + ]; + + return $data; + } +} diff --git a/dev/tests/integration/testsuite/Magento/Tax/Service/V1/Data/QuoteDetailsBuilderTest.php b/dev/tests/integration/testsuite/Magento/Tax/Service/V1/Data/QuoteDetailsBuilderTest.php index d7513b5f4a516c4774ccb6557480f4549933d2d5..10138b0ca3a99a0354da15a5a2ab871e401d7f05 100644 --- a/dev/tests/integration/testsuite/Magento/Tax/Service/V1/Data/QuoteDetailsBuilderTest.php +++ b/dev/tests/integration/testsuite/Magento/Tax/Service/V1/Data/QuoteDetailsBuilderTest.php @@ -158,10 +158,15 @@ class QuoteDetailsBuilderTest extends \PHPUnit_Framework_TestCase ] ]; + $taxClassKeyId = [ + 'type' => 'id', + 'value' => 1, + ]; + $data = [ 'data1' => [ QuoteDetails::KEY_BILLING_ADDRESS => $addressData, - QuoteDetails::KEY_CUSTOMER_TAX_CLASS_ID => 1, + QuoteDetails::KEY_CUSTOMER_TAX_CLASS_KEY => $taxClassKeyId, QuoteDetails::KEY_CUSTOMER_ID => 1 ], 'data2' => [ @@ -171,8 +176,8 @@ class QuoteDetailsBuilderTest extends \PHPUnit_Framework_TestCase 'dataMerged' => [ QuoteDetails::KEY_BILLING_ADDRESS => $addressData, QuoteDetails::KEY_SHIPPING_ADDRESS => $addressData, - QuoteDetails::KEY_CUSTOMER_TAX_CLASS_ID => 1, QuoteDetails::KEY_CUSTOMER_ID => 1, + QuoteDetails::KEY_CUSTOMER_TAX_CLASS_KEY => $taxClassKeyId, QuoteDetails::KEY_ITEMS => $items ] ]; diff --git a/dev/tests/integration/testsuite/Magento/Tax/Service/V1/TaxCalculationServiceTest.php b/dev/tests/integration/testsuite/Magento/Tax/Service/V1/TaxCalculationServiceTest.php index 1638d8bc15b40424b9211e25a5652488513beb26..491a0d9d3f5ac11061cd8ca574b43c8a95aecb62 100644 --- a/dev/tests/integration/testsuite/Magento/Tax/Service/V1/TaxCalculationServiceTest.php +++ b/dev/tests/integration/testsuite/Magento/Tax/Service/V1/TaxCalculationServiceTest.php @@ -26,6 +26,7 @@ namespace Magento\Tax\Service\V1; use Magento\Tax\Model\ClassModel; use Magento\TestFramework\Helper\Bootstrap; +use Magento\Tax\Service\V1\Data\TaxClassKey; /** * @magentoDbIsolation enabled @@ -67,7 +68,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase * * @var int[] */ - private $taxClasses; + private $taxClassIds; /** * Array of default tax rates ids. @@ -137,7 +138,10 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase 'type' => 'product', 'quantity' => 2, 'unit_price' => 10, - 'tax_class_id' => 'DefaultProductClass', + 'tax_class_key' => [ + TaxClassKey::KEY_TYPE => TaxClassKey::TYPE_NAME, + TaxClassKey::KEY_VALUE => 'DefaultProductClass', + ], ]; $oneProductResults = [ 'subtotal' => 20, @@ -168,6 +172,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase 'type' => 'product', 'tax_percent' => 7.5, 'discount_tax_compensation_amount' => 0, + 'associated_item_code' => null, 'applied_taxes' => [ 'US - 42 - 7.5' => [ 'amount' => 1.5, @@ -192,7 +197,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase 'type' => 'product', 'quantity' => 2, 'unit_price' => 10.75, - 'tax_class_id' => 'DefaultProductClass', + 'tax_class_key' => 'DefaultProductClass', 'tax_included' => true, ]; $oneProductInclTaxResults = $oneProductResults; @@ -203,7 +208,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase 'type' => 'product', 'quantity' => 2, 'unit_price' => 11, - 'tax_class_id' => 'HigherProductClass', + 'tax_class_key' => 'HigherProductClass', 'tax_included' => true, ]; $oneProductInclTaxDiffRateResults = [ @@ -235,6 +240,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase 'type' => 'product', 'tax_percent' => 22.0, 'discount_tax_compensation_amount' => 0, + 'associated_item_code' => null, 'applied_taxes' => [ 'US - 42 - 22' => [ 'amount' => 4.4, @@ -260,14 +266,14 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase 'type' => 'product', 'quantity' => 2, 'unit_price' => 10, - 'tax_class_id' => 'DefaultProductClass', + 'tax_class_key' => 'DefaultProductClass', ], [ 'code' => 'sku_2', 'type' => 'product', 'quantity' => 20, 'unit_price' => 11, - 'tax_class_id' => 'DefaultProductClass', + 'tax_class_key' => 'DefaultProductClass', ] ]; $twoProductsResults = [ @@ -299,6 +305,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase 'type' => 'product', 'tax_percent' => 7.5, 'discount_tax_compensation_amount' => 0, + 'associated_item_code' => null, 'applied_taxes' => [ 'US - 42 - 7.5' => [ 'amount' => 1.5, @@ -324,6 +331,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase 'type' => 'product', 'tax_percent' => 7.5, 'discount_tax_compensation_amount' => 0, + 'associated_item_code' => null, 'applied_taxes' => [ 'US - 42 - 7.5' => [ 'amount' => 16.6, @@ -350,7 +358,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase 'quantity' => 2, 'unit_price' => 10.75, 'row_total' => 21.5, - 'tax_class_id' => 'DefaultProductClass', + 'tax_class_key' => 'DefaultProductClass', 'tax_included' => true, ], [ @@ -359,7 +367,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase 'quantity' => 20, 'unit_price' => 11.83, 'row_total' => 236.6, - 'tax_class_id' => 'DefaultProductClass', + 'tax_class_key' => 'DefaultProductClass', 'tax_included' => true, ] ]; @@ -371,7 +379,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase 'type' => 'product', 'quantity' => 1, 'unit_price' => 10, - 'tax_class_id' => 'DefaultProductClass', + 'tax_class_key' => 'DefaultProductClass', 'parent_code' => 'bundle', ]; $bundleProduct['items'][] = [ @@ -379,7 +387,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase 'type' => 'product', 'quantity' => 2, 'unit_price' => 0, - 'tax_class_id' => 'DefaultProductClass', + 'tax_class_key' => 'DefaultProductClass', ]; $bundleProductResults = [ 'subtotal' => 20, @@ -410,6 +418,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase 'type' => 'product', 'tax_percent' => 7.5, 'discount_tax_compensation_amount' => 0, + 'associated_item_code' => null, 'applied_taxes' => [ 'US - 42 - 7.5' => [ 'amount' => 1.5, @@ -510,7 +519,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase 'tax_included' => false, ], ], - 'customer_tax_class_id' => 'DefaultCustomerClass' + 'customer_tax_class_key' => 'DefaultCustomerClass' ], 'expected_tax_details' => [ 'subtotal' => 10.0, @@ -561,7 +570,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase ]; $quoteDetailItemWithDefaultProductTaxClass = $prodQuoteDetailItemBase; - $quoteDetailItemWithDefaultProductTaxClass['tax_class_id'] = 'DefaultProductClass'; + $quoteDetailItemWithDefaultProductTaxClass['tax_class_key'] = 'DefaultProductClass'; $prodExpectedItemWithNoProductTaxClass = [ 'code' => [ @@ -574,6 +583,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase 'type' => 'type', 'tax_percent' => 0, 'discount_tax_compensation_amount' => 0, + 'associated_item_code' => null, 'applied_taxes' => [], ], ]; @@ -590,6 +600,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase 'type' => 'type', 'tax_percent' => 7.5, 'discount_tax_compensation_amount' => 0, + 'associated_item_code' => null, 'applied_taxes' => $itemAppliedTaxes, ], ]; @@ -651,7 +662,10 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase 'tax_included' => true, ], ], - 'customer_tax_class_id' => 'DefaultCustomerClass' + 'customer_tax_class_key' => [ + TaxClassKey::KEY_TYPE => TaxClassKey::TYPE_NAME, + TaxClassKey::KEY_VALUE => 'DefaultCustomerClass', + ], ], 'expected_tax_details' => [ 'subtotal' => 10.0, @@ -672,7 +686,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase ]; $quoteDetailTaxInclItemWithDefaultProductTaxClass = $productTaxInclQuoteDetailItemBase; - $quoteDetailTaxInclItemWithDefaultProductTaxClass['tax_class_id'] = 'DefaultProductClass'; + $quoteDetailTaxInclItemWithDefaultProductTaxClass['tax_class_key'] = 'DefaultProductClass'; $productTaxInclExpectedItemWithNoProductTaxClass = [ 'code' => [ @@ -685,6 +699,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase 'type' => 'type', 'tax_percent' => 0, 'discount_tax_compensation_amount' => 0, + 'associated_item_code' => null, 'applied_taxes' => [], ], ]; @@ -715,6 +730,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase 'type' => 'type', 'tax_percent' => 7.5, 'discount_tax_compensation_amount' => 0, + 'associated_item_code' => null, 'applied_taxes' => [ 'US - 42 - 7.5' => [ 'amount' => 0.7, @@ -795,7 +811,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase 'tax_included' => false, ], ], - 'customer_tax_class_id' => 'DefaultCustomerClass' + 'customer_tax_class_key' => 'DefaultCustomerClass' ], 'expected_tax_details' => [ 'subtotal' => 15.94, @@ -816,7 +832,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase ]; $quoteDetailItemWithDefaultProductTaxClass = $prodQuoteDetailItemBase; - $quoteDetailItemWithDefaultProductTaxClass['tax_class_id'] = 'DefaultProductClass'; + $quoteDetailItemWithDefaultProductTaxClass['tax_class_key'] = 'DefaultProductClass'; $quoteDetailAppliedTaxesBase = [ @@ -845,6 +861,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase 'type' => 'type', 'tax_percent' => 0, 'discount_tax_compensation_amount' => 0, + 'associated_item_code' => null, 'applied_taxes' => [], ], ]; @@ -860,6 +877,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase 'type' => 'type', 'tax_percent' => 7.5, 'discount_tax_compensation_amount' => 0, + 'associated_item_code' => null, 'applied_taxes' => [ 'US - 42 - 7.5' => [ 'amount' => 1.2, @@ -943,7 +961,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase 'type' => 'product', 'quantity' => 10, 'unit_price' => 1, - 'tax_class_id' => 'DefaultProductClass', + 'tax_class_key' => 'DefaultProductClass', ]; $oneProductResults = [ 'subtotal' => 10, @@ -974,6 +992,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase 'type' => 'product', 'tax_percent' => 7.5, 'discount_tax_compensation_amount' => 0, + 'associated_item_code' => null, 'applied_taxes' => [ 'US - 42 - 7.5' => [ 'amount' => 0.75, @@ -998,7 +1017,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase 'type' => 'product', 'quantity' => 10, 'unit_price' => 1.0, - 'tax_class_id' => 'DefaultProductClass', + 'tax_class_key' => 'DefaultProductClass', 'tax_included' => true, ]; $oneProductInclTaxResults = [ @@ -1030,6 +1049,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase 'type' => 'product', 'tax_percent' => 7.5, 'discount_tax_compensation_amount' => 0, + 'associated_item_code' => null, 'applied_taxes' => [ 'US - 42 - 7.5' => [ 'amount' => 0.7, @@ -1054,7 +1074,10 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase 'type' => 'product', 'quantity' => 9, 'unit_price' => 0.33, // this is including the store tax of 10%. Pre tax is 0.3 - 'tax_class_id' => 'HigherProductClass', + 'tax_class_key' => [ + TaxClassKey::KEY_TYPE => TaxClassKey::TYPE_NAME, + TaxClassKey::KEY_VALUE => 'HigherProductClass', + ], 'tax_included' => true, ]; $oneProductInclTaxDiffRateResults = [ @@ -1086,6 +1109,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase 'type' => 'product', 'tax_percent' => 22.0, 'discount_tax_compensation_amount' => 0, + 'associated_item_code' => null, 'applied_taxes' => [ 'US - 42 - 22' => [ 'amount' => 0.6, @@ -1111,14 +1135,14 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase 'type' => 'product', 'quantity' => 10, 'unit_price' => 1, - 'tax_class_id' => 'DefaultProductClass', + 'tax_class_key' => 'DefaultProductClass', ], [ 'code' => 'sku_2', 'type' => 'product', 'quantity' => 20, 'unit_price' => 11, - 'tax_class_id' => 'DefaultProductClass', + 'tax_class_key' => 'DefaultProductClass', ] ]; $twoProductsResults = [ @@ -1150,6 +1174,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase 'type' => 'product', 'tax_percent' => 7.5, 'discount_tax_compensation_amount' => 0, + 'associated_item_code' => null, 'applied_taxes' => [ 'US - 42 - 7.5' => [ 'amount' => 0.75, @@ -1175,6 +1200,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase 'type' => 'product', 'tax_percent' => 7.5, 'discount_tax_compensation_amount' => 0, + 'associated_item_code' => null, 'applied_taxes' => [ 'US - 42 - 7.5' => [ 'amount' => 16.5, @@ -1200,7 +1226,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase 'type' => 'product', 'quantity' => 10, 'unit_price' => 0.98, - 'tax_class_id' => 'DefaultProductClass', + 'tax_class_key' => 'DefaultProductClass', 'tax_included' => true, ], [ @@ -1208,7 +1234,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase 'type' => 'product', 'quantity' => 20, 'unit_price' => 11.99, - 'tax_class_id' => 'DefaultProductClass', + 'tax_class_key' => 'DefaultProductClass', 'tax_included' => true, ] ]; @@ -1241,6 +1267,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase 'type' => 'product', 'tax_percent' => 7.5, 'discount_tax_compensation_amount' => 0, + 'associated_item_code' => null, 'applied_taxes' => [ 'US - 42 - 7.5' => [ 'amount' => 0.68, @@ -1266,6 +1293,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase 'type' => 'product', 'tax_percent' => 7.5, 'discount_tax_compensation_amount' => 0, + 'associated_item_code' => null, 'applied_taxes' => [ 'US - 42 - 7.5' => [ 'amount' => 16.73, @@ -1291,7 +1319,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase 'type' => 'product', 'quantity' => 2, 'unit_price' => 12.34, - 'tax_class_id' => 'DefaultProductClass', + 'tax_class_key' => 'DefaultProductClass', 'parent_code' => 'parent_sku', ], [ @@ -1299,14 +1327,14 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase 'type' => 'product', 'quantity' => 10, 'unit_price' => 0, - 'tax_class_id' => 'DefaultProductClass', + 'tax_class_key' => 'DefaultProductClass', ], [ 'code' => 'child_2_sku', 'type' => 'product', 'quantity' => 2, 'unit_price' => 1.99, - 'tax_class_id' => 'HigherProductClass', + 'tax_class_key' => 'HigherProductClass', 'parent_code' => 'parent_sku', ], ]; @@ -1351,6 +1379,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase 'type' => 'product', 'tax_percent' => 7.5, 'discount_tax_compensation_amount' => 0, + 'associated_item_code' => null, 'applied_taxes' => [ 'US - 42 - 7.5' => [ 'amount' => 18.51, @@ -1376,6 +1405,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase 'type' => 'product', 'tax_percent' => 22, 'discount_tax_compensation_amount' => 0, + 'associated_item_code' => null, 'applied_taxes' => [ 'US - 42 - 22' => [ 'amount' => 8.76, @@ -1446,7 +1476,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase 'type' => 'product', 'quantity' => 10, 'unit_price' => 1.89, - 'tax_class_id' => 'MultipleRulesProductClass', + 'tax_class_key' => 'MultipleRulesProductClass', 'tax_included' => true, 'discount_amount' => 5, ]; @@ -1455,7 +1485,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase 'type' => 'product', 'quantity' => 5, 'unit_price' => 14.99, - 'tax_class_id' => 'MultipleRulesProductClass', + 'tax_class_key' => 'MultipleRulesProductClass', 'tax_included' => true, 'discount_amount' => 10, ]; @@ -1464,7 +1494,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase 'type' => 'product', 'quantity' => 1, 'unit_price' => 99.99, - 'tax_class_id' => 'MultipleRulesProductClass', + 'tax_class_key' => 'MultipleRulesProductClass', 'tax_included' => false, 'discount_amount' => 5, ]; @@ -1526,6 +1556,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase 'type' => 'product', 'tax_percent' => 25.7075, 'discount_tax_compensation_amount' => 1.03, + 'associated_item_code' => null, 'applied_taxes' => [ 'US - 42 - 8.25US - 42 - 5 - 55555' => [ 'amount' => 1.71, @@ -1568,6 +1599,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase 'type' => 'product', 'tax_percent' => 25.7075, 'discount_tax_compensation_amount' => 2.05, + 'associated_item_code' => null, 'applied_taxes' => [ 'US - 42 - 8.25US - 42 - 5 - 55555' => [ 'amount' => 7.8, @@ -1610,6 +1642,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase 'type' => 'product', 'tax_percent' => 25.7075, 'discount_tax_compensation_amount' => 0, + 'associated_item_code' => null, 'applied_taxes' => [ 'US - 42 - 8.25US - 42 - 5 - 55555' => [ 'amount' => 12.59, @@ -1780,10 +1813,13 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase array_walk_recursive( $data, function (&$value, $key) { - if ( ($key === 'tax_class_id' || $key === 'customer_tax_class_id') + if ( ($key === 'tax_class_key' || $key === 'customer_tax_class_key') && is_string($value) ) { - $value = $this->taxClasses[$value]; + $value = [ + TaxClassKey::KEY_TYPE => TaxClassKey::TYPE_ID, + TaxClassKey::KEY_VALUE => $this->taxClassIds[$value], + ]; } } ); @@ -1796,7 +1832,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase */ private function setUpDefaultRules() { - $this->taxClasses = $this->taxRuleFixtureFactory->createTaxClasses([ + $this->taxClassIds = $this->taxRuleFixtureFactory->createTaxClasses([ ['name' => 'DefaultCustomerClass', 'type' => ClassModel::TAX_CLASS_TYPE_CUSTOMER], ['name' => 'DefaultProductClass', 'type' => ClassModel::TAX_CLASS_TYPE_PRODUCT], ['name' => 'HigherProductClass', 'type' => ClassModel::TAX_CLASS_TYPE_PRODUCT], @@ -1829,40 +1865,40 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase $this->taxRules = $this->taxRuleFixtureFactory->createTaxRules([ [ 'code' => 'Default Rule', - 'customer_tax_class_ids' => [$this->taxClasses['DefaultCustomerClass'], 3], - 'product_tax_class_ids' => [$this->taxClasses['DefaultProductClass']], + 'customer_tax_class_ids' => [$this->taxClassIds['DefaultCustomerClass'], 3], + 'product_tax_class_ids' => [$this->taxClassIds['DefaultProductClass']], 'tax_rate_ids' => array_values($this->taxRates), 'sort_order' => 0, 'priority' => 0, ], [ 'code' => 'Higher Rate Rule', - 'customer_tax_class_ids' => [$this->taxClasses['DefaultCustomerClass'], 3], - 'product_tax_class_ids' => [$this->taxClasses['HigherProductClass']], + 'customer_tax_class_ids' => [$this->taxClassIds['DefaultCustomerClass'], 3], + 'product_tax_class_ids' => [$this->taxClassIds['HigherProductClass']], 'tax_rate_ids' => array_values($higherRates), 'sort_order' => 0, 'priority' => 0, ], [ 'code' => 'MultiRule-1', - 'customer_tax_class_ids' => [$this->taxClasses['DefaultCustomerClass'], 3], - 'product_tax_class_ids' => [$this->taxClasses['MultipleRulesProductClass']], + 'customer_tax_class_ids' => [$this->taxClassIds['DefaultCustomerClass'], 3], + 'product_tax_class_ids' => [$this->taxClassIds['MultipleRulesProductClass']], 'tax_rate_ids' => array_values($multiTaxRates1), 'sort_order' => 0, 'priority' => 0, ], [ 'code' => 'MultiRule-2', - 'customer_tax_class_ids' => [$this->taxClasses['DefaultCustomerClass'], 3], - 'product_tax_class_ids' => [$this->taxClasses['MultipleRulesProductClass']], + 'customer_tax_class_ids' => [$this->taxClassIds['DefaultCustomerClass'], 3], + 'product_tax_class_ids' => [$this->taxClassIds['MultipleRulesProductClass']], 'tax_rate_ids' => array_values($multiTaxRatesSamePriority), 'sort_order' => 0, 'priority' => 0, ], [ 'code' => 'MultiRule-3', - 'customer_tax_class_ids' => [$this->taxClasses['DefaultCustomerClass'], 3], - 'product_tax_class_ids' => [$this->taxClasses['MultipleRulesProductClass']], + 'customer_tax_class_ids' => [$this->taxClassIds['DefaultCustomerClass'], 3], + 'product_tax_class_ids' => [$this->taxClassIds['MultipleRulesProductClass']], 'tax_rate_ids' => array_values($multiTaxRatesDifferentPriority), 'sort_order' => 0, 'priority' => 1, @@ -1883,7 +1919,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase { $this->taxRuleFixtureFactory->deleteTaxRules(array_values($this->taxRules)); $this->taxRuleFixtureFactory->deleteTaxRates(array_values($this->taxRates)); - $this->taxRuleFixtureFactory->deleteTaxClasses(array_values($this->taxClasses)); + $this->taxRuleFixtureFactory->deleteTaxClasses(array_values($this->taxClassIds)); } /** @@ -1905,7 +1941,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase 'region' => ['region_id' => 42], ], 'items' => [], - 'customer_tax_class_id' => 'DefaultCustomerClass', + 'customer_tax_class_key' => 'DefaultCustomerClass', ]; return $baseQuote; } diff --git a/dev/tests/integration/testsuite/Magento/Tax/Service/V1/TaxClassServiceTest.php b/dev/tests/integration/testsuite/Magento/Tax/Service/V1/TaxClassServiceTest.php index 594c97b52702793dc106c5d5de02a3498bf7a41f..e693a437546bef80832e120199f4deacac296094 100644 --- a/dev/tests/integration/testsuite/Magento/Tax/Service/V1/TaxClassServiceTest.php +++ b/dev/tests/integration/testsuite/Magento/Tax/Service/V1/TaxClassServiceTest.php @@ -27,6 +27,7 @@ namespace Magento\Tax\Service\V1; use Magento\Framework\Exception\InputException; use Magento\Tax\Model\ClassModel as TaxClassModel; use Magento\Tax\Service\V1\Data\TaxClassBuilder; +use Magento\Tax\Service\V1\Data\TaxClassKey; use Magento\TestFramework\Helper\Bootstrap; class TaxClassServiceTest extends \PHPUnit_Framework_TestCase @@ -254,4 +255,44 @@ class TaxClassServiceTest extends \PHPUnit_Framework_TestCase $this->taxClassService->updateTaxClass($taxClassId, $taxClassDataObject); } + + /** + * @magentoDbIsolation enabled + */ + public function testGetTaxClassId() + { + $taxClassName = 'Get Me'; + $taxClassDataObject = $this->taxClassBuilder + ->setClassName($taxClassName) + ->setClassType(TaxClassServiceInterface::TYPE_CUSTOMER) + ->create(); + $taxClassId = $this->taxClassService->createTaxClass($taxClassDataObject); + /** @var \Magento\Tax\Service\V1\Data\TaxClassKeyBuilder $taxClassKeyBuilder */ + $taxClassKeyBuilder = $this->objectManager->create('Magento\Tax\Service\V1\Data\TaxClassKeyBuilder'); + $taxClassKeyTypeId = $taxClassKeyBuilder->populateWithArray( + [ + TaxClassKey::KEY_TYPE => TaxClassKey::TYPE_ID, + TaxClassKey::KEY_VALUE => $taxClassId, + ] + )->create(); + $this->assertEquals( + $taxClassId, + $this->taxClassService->getTaxClassId($taxClassKeyTypeId, TaxClassServiceInterface::TYPE_CUSTOMER) + ); + $taxClassKeyTypeName = $taxClassKeyBuilder->populateWithArray( + [ + TaxClassKey::KEY_TYPE => TaxClassKey::TYPE_NAME, + TaxClassKey::KEY_VALUE => $taxClassName, + ] + )->create(); + $this->assertEquals( + $taxClassId, + $this->taxClassService->getTaxClassId($taxClassKeyTypeId, TaxClassServiceInterface::TYPE_CUSTOMER) + ); + $this->assertNull($this->taxClassService->getTaxClassId(null)); + $this->assertEquals( + null, + $this->taxClassService->getTaxClassId($taxClassKeyTypeName, TaxClassServiceInterface::TYPE_PRODUCT) + ); + } } diff --git a/dev/tests/integration/testsuite/Magento/Tax/Service/V1/TaxRateServiceTest.php b/dev/tests/integration/testsuite/Magento/Tax/Service/V1/TaxRateServiceTest.php index 77a23de151170a11c92c6f619f9c3cce5db48b68..0331c269cfb163d2631afa28f0c823d36c768a93 100644 --- a/dev/tests/integration/testsuite/Magento/Tax/Service/V1/TaxRateServiceTest.php +++ b/dev/tests/integration/testsuite/Magento/Tax/Service/V1/TaxRateServiceTest.php @@ -317,11 +317,12 @@ class TaxRateServiceTest extends \PHPUnit_Framework_TestCase /** * @magentoDbIsolation enabled * @expectedException \Magento\Framework\Exception\InputException - * @expectedExceptionMessage country_id + * @expectedExceptionMessage postcode */ public function testUpdateTaxRateMissingRequiredFields() { $taxRate = $this->taxRateBuilder + ->setCountryId('US') ->setRegionId(42) ->setPercentageRate(8.25) ->setCode('UpdateTaxRates') diff --git a/dev/tests/integration/testsuite/Magento/Tax/Service/V1/TaxRuleServiceTest.php b/dev/tests/integration/testsuite/Magento/Tax/Service/V1/TaxRuleServiceTest.php index 2e6af1e6a42ec127f97a85a86803889deb620fb7..b3455a2a334e94c2bc236a203e3f60f299e6b1c0 100644 --- a/dev/tests/integration/testsuite/Magento/Tax/Service/V1/TaxRuleServiceTest.php +++ b/dev/tests/integration/testsuite/Magento/Tax/Service/V1/TaxRuleServiceTest.php @@ -92,10 +92,18 @@ class TaxRuleServiceTest extends \PHPUnit_Framework_TestCase */ private $taxRules; + /** + * TaxRateService + * + * @var \Magento\Tax\Service\V1\TaxRateServiceInterface + */ + private $taxRateService; + protected function setUp() { $this->objectManager = Bootstrap::getObjectManager(); $this->taxRuleService = $this->objectManager->get('Magento\Tax\Service\V1\TaxRuleServiceInterface'); + $this->taxRateService = $this->objectManager->get('Magento\Tax\Service\V1\TaxRateServiceInterface'); $this->taxRuleBuilder = $this->objectManager->create('Magento\Tax\Service\V1\Data\TaxRuleBuilder'); $this->taxRuleFixtureFactory = new TaxRuleFixtureFactory(); } @@ -339,6 +347,27 @@ class TaxRuleServiceTest extends \PHPUnit_Framework_TestCase $this->tearDownDefaultRules(); } + /** + * + * @magentoDbIsolation enabled + */ + public function testGetRatesByCustomerAndProductTaxClassId() + { + $this->setUpDefaultRules(); + $taxRateIds = $this->taxRuleService->getTaxRule(current($this->taxRules))->getTaxRateIds(); + $expectedRates = []; + foreach ($taxRateIds as $rateId) { + $expectedRates[] = $this->taxRateService->getTaxRate($rateId); + } + $rates = $this->taxRuleService->getRatesByCustomerAndProductTaxClassId( + $this->taxClasses['DefaultCustomerClass'], + $this->taxClasses['DefaultProductClass'] + ); + + $this->assertCount(2, $rates); + $this->assertEquals($expectedRates, $rates); + } + public function searchTaxRulesDataProvider() { $filterBuilder = Bootstrap::getObjectManager()->create('\Magento\Framework\Service\V1\Data\FilterBuilder'); @@ -349,9 +378,9 @@ class TaxRuleServiceTest extends \PHPUnit_Framework_TestCase null, ['Default Rule'] ], - 'sort_order eq 0 AND priority eq 0' => [ + 'customer_tax_class_ids eq 3 AND priority eq 0' => [ [ - $filterBuilder->setField(TaxRule::SORT_ORDER)->setValue('0')->create(), + $filterBuilder->setField(TaxRule::CUSTOMER_TAX_CLASS_IDS)->setValue(3)->create(), $filterBuilder->setField(TaxRule::PRIORITY)->setValue('0')->create(), ], [], diff --git a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_apply_tax_after_discount_discount_tax.php b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_apply_tax_after_discount_discount_tax.php new file mode 100644 index 0000000000000000000000000000000000000000..644fa071b27ade483fdf42f6443334a29dfcfd39 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_apply_tax_after_discount_discount_tax.php @@ -0,0 +1,143 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +use Magento\Tax\Model\Config; +use Magento\Tax\Model\Sales\Total\Quote\SetupUtil; + +$taxCalculationData['excluding_tax_apply_tax_after_discount_discount_tax'] = [ + 'config_data' => [ + SetupUtil::CONFIG_OVERRIDES => [ + Config::CONFIG_XML_PATH_APPLY_AFTER_DISCOUNT => 1, + Config::CONFIG_XML_PATH_SHIPPING_TAX_CLASS => SetupUtil::SHIPPING_TAX_CLASS, + Config::CONFIG_XML_PATH_DISCOUNT_TAX => 1, + ], + SetupUtil::TAX_RATE_OVERRIDES => [ + SetupUtil::TAX_RATE_TX => 20, + ], + SetupUtil::TAX_RULE_OVERRIDES => [ + [ + //tax rule for product + 'code' => 'Product Tax Rule', + 'tax_product_class' => [SetupUtil::PRODUCT_TAX_CLASS_1], + ], + [ + //tax rule for shipping + 'code' => 'Shipping Tax Rule', + 'tax_product_class' => [SetupUtil::SHIPPING_TAX_CLASS], + 'tax_rate' => [SetupUtil::TAX_RATE_SHIPPING], + ], + ], + ], + 'quote_data' => [ + 'billing_address' => [ + 'region_id' => SetupUtil::REGION_TX, + ], + 'shipping_address' => [ + 'region_id' => SetupUtil::REGION_TX, + ], + 'items' => [ + [ + 'sku' => 'simple1', + 'price' => 10, + 'qty' => 2, + ], + ], + 'shipping_method' => 'flatrate_flatrate', + 'shopping_cart_rules' => [ + [ + 'discount_amount' => 50, + ], + ], + ], + 'expected_results' => [ + 'address_data' => [ + 'subtotal' => 20, + 'base_subtotal' => 20, + 'subtotal_incl_tax' => 24, + 'base_subtotal_incl_tax' => 24, + 'tax_amount' => 2.35, + 'base_tax_amount' => 2.35, + 'shipping_amount' => 10, + 'base_shipping_amount' => 10, + 'shipping_incl_tax' => 10.75, + 'base_shipping_incl_tax' => 10.75, + 'shipping_tax_amount' => 0.75, + 'base_shipping_tax_amount' => 0.75, + 'discount_amount' => -12, + 'base_discount_amount' => -12, + 'hidden_tax_amount' => 0, + 'base_hidden_tax_amount' => 0, + 'shipping_hidden_tax_amount' => 0, + 'base_shipping_hidden_tax_amount' => 0, + 'grand_total' => 20.35, + 'base_grand_total' => 20.35, + 'applied_taxes' => [ + SetupUtil::TAX_RATE_TX => [ + 'percent' => 20, + 'amount' => 1.6, + 'base_amount' => 1.6, + 'rates' => [ + [ + 'code' => SetupUtil::TAX_RATE_TX, + 'title' => SetupUtil::TAX_RATE_TX, + 'percent' => 20, + ], + ], + ], + SetupUtil::TAX_RATE_SHIPPING => [ + 'percent' => 7.5, + 'amount' => 0.75, + 'base_amount' => 0.75, + 'rates' => [ + [ + 'code' => SetupUtil::TAX_RATE_SHIPPING, + 'title' => SetupUtil::TAX_RATE_SHIPPING, + 'percent' => 7.5, + ], + ], + ], + ], + ], + 'items_data' => [ + 'simple1' => [ + 'row_total' => 20, + 'base_row_total' => 20, + 'tax_percent' => 20, + 'price' => 10, + 'base_price' => 10, + 'price_incl_tax' => 12, + 'base_price_incl_tax' => 12, + 'row_total_incl_tax' => 24, + 'base_row_total_incl_tax' => 24, + 'tax_amount' => 1.6, + 'base_tax_amount' => 1.6, + 'discount_amount' => 12, + 'base_discount_amount' => 12, + 'discount_percent' => 50, + 'hidden_tax_amount' => 0, + 'base_hidden_tax_amount' => 0, + ], + ], + ], +]; \ No newline at end of file diff --git a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/multi_tax_rule_two_row_calculate_subtotal_yes_row.php b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/multi_tax_rule_two_row_calculate_subtotal_yes_row.php index 8b18adbb1126af1f46c2028d6ea721c80cbb952a..82435beca6d279a651d35c853d32bec9cd39b42a 100644 --- a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/multi_tax_rule_two_row_calculate_subtotal_yes_row.php +++ b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/multi_tax_rule_two_row_calculate_subtotal_yes_row.php @@ -162,6 +162,9 @@ $taxCalculationData['multi_tax_rule_two_row_calculate_subtotal_yes_row'] = [ 'title' => SetupUtil::TAX_RATE_TX, ], ], + 'item_id' => null, + 'item_type' => 'product', + 'associated_item_id' => null, ], [ 'amount' => 0.5, @@ -175,6 +178,9 @@ $taxCalculationData['multi_tax_rule_two_row_calculate_subtotal_yes_row'] = [ 'title' => SetupUtil::TAX_RATE_AUSTIN, ], ], + 'item_id' => null, + 'item_type' => 'product', + 'associated_item_id' => null, ], ], ], @@ -208,6 +214,9 @@ $taxCalculationData['multi_tax_rule_two_row_calculate_subtotal_yes_row'] = [ 'title' => SetupUtil::TAX_RATE_TX, ], ], + 'item_id' => null, + 'item_type' => 'product', + 'associated_item_id' => null, ], [ 'amount' => 0.52, @@ -221,6 +230,9 @@ $taxCalculationData['multi_tax_rule_two_row_calculate_subtotal_yes_row'] = [ 'title' => SetupUtil::TAX_RATE_AUSTIN, ], ], + 'item_id' => null, + 'item_type' => 'product', + 'associated_item_id' => null, ], ], ], diff --git a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/multi_tax_rule_two_row_calculate_subtotal_yes_total.php b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/multi_tax_rule_two_row_calculate_subtotal_yes_total.php index d0d85808d2cd888e87bbd9131ba0a8252c7478ba..8586e95a4e6c91a50407f11a369c3550cd9e5861 100644 --- a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/multi_tax_rule_two_row_calculate_subtotal_yes_total.php +++ b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/multi_tax_rule_two_row_calculate_subtotal_yes_total.php @@ -162,6 +162,9 @@ $taxCalculationData['multi_tax_rule_two_row_calculate_subtotal_yes_total'] = [ 'title' => SetupUtil::TAX_RATE_TX, ], ], + 'item_id' => null, + 'item_type' => 'product', + 'associated_item_id' => null, ], [ 'amount' => 0.5, @@ -175,6 +178,9 @@ $taxCalculationData['multi_tax_rule_two_row_calculate_subtotal_yes_total'] = [ 'percent' => 5, ], ], + 'item_id' => null, + 'item_type' => 'product', + 'associated_item_id' => null, ], ], ], @@ -208,6 +214,9 @@ $taxCalculationData['multi_tax_rule_two_row_calculate_subtotal_yes_total'] = [ 'title' => SetupUtil::TAX_RATE_TX, ], ], + 'item_id' => null, + 'item_type' => 'product', + 'associated_item_id' => null, ], [ 'amount' => 0.53, @@ -221,6 +230,9 @@ $taxCalculationData['multi_tax_rule_two_row_calculate_subtotal_yes_total'] = [ 'title' => SetupUtil::TAX_RATE_AUSTIN, ], ], + 'item_id' => null, + 'item_type' => 'product', + 'associated_item_id' => null, ], ], ], diff --git a/dev/tests/integration/testsuite/Magento/Tax/_files/tax_calculation_data_aggregated.php b/dev/tests/integration/testsuite/Magento/Tax/_files/tax_calculation_data_aggregated.php index 452752b9baaf076c3abfdcd39e6b2a6ec74a00fb..080fefd9f6f052abfd8ac6c3656cd6f173fbca1d 100644 --- a/dev/tests/integration/testsuite/Magento/Tax/_files/tax_calculation_data_aggregated.php +++ b/dev/tests/integration/testsuite/Magento/Tax/_files/tax_calculation_data_aggregated.php @@ -30,6 +30,7 @@ $taxCalculationData = []; require_once __DIR__ . '/scenarios/excluding_tax_apply_tax_after_discount.php'; +require_once __DIR__ . '/scenarios/excluding_tax_apply_tax_after_discount_discount_tax.php'; require_once __DIR__ . '/scenarios/excluding_tax_apply_tax_before_discount.php'; require_once __DIR__ . '/scenarios/excluding_tax_unit.php'; require_once __DIR__ . '/scenarios/excluding_tax_row.php'; diff --git a/dev/tests/integration/testsuite/Magento/Test/Integrity/LayoutTest.php b/dev/tests/integration/testsuite/Magento/Test/Integrity/LayoutTest.php index cc97ae4ea17c41f14170f3b07653332a3adbdd27..1feef2c21fa6c920612ba11fc38ceb970f669407 100644 --- a/dev/tests/integration/testsuite/Magento/Test/Integrity/LayoutTest.php +++ b/dev/tests/integration/testsuite/Magento/Test/Integrity/LayoutTest.php @@ -76,9 +76,6 @@ class LayoutTest extends \PHPUnit_Framework_TestCase if ($refName) { $refNode = $xml->xpath("/layouts/{$refName}"); if (!$refNode) { - if ($refName == 'checkout_cart_configure' || $refName == 'checkout_cart_configurefailed') { - $this->markTestIncomplete('MAGETWO-9182'); - } $errors[$name][] = "Node '{$refName}', referenced in hierarchy, does not exist"; } } diff --git a/dev/tests/integration/testsuite/Magento/Test/Integrity/Theme/TemplateFilesTest.php b/dev/tests/integration/testsuite/Magento/Test/Integrity/Theme/TemplateFilesTest.php index 7f27f901c9a36d2b074c47f7029d6fd7d2571655..27d7874280831f076976085d69074f15c991052c 100644 --- a/dev/tests/integration/testsuite/Magento/Test/Integrity/Theme/TemplateFilesTest.php +++ b/dev/tests/integration/testsuite/Magento/Test/Integrity/Theme/TemplateFilesTest.php @@ -33,19 +33,6 @@ class TemplateFilesTest extends \Magento\TestFramework\TestCase\AbstractIntegrit $invalidTemplates = array(); foreach ($this->templatesDataProvider() as $template) { list($area, $themeId, $module, $file, $xml) = $template; - - if ($area === 'frontend' && in_array( - $module . '::' . $file, - array( - 'Magento_Reports::Magento_Catalog::product/list/items.phtml', - 'Magento_Review::redirect.phtml', - 'Magento_Theme::blank.phtml' - ) - ) - ) { - continue; // $this->markTestIncomplete('MAGETWO-9806'); - } - $params = array('area' => $area, 'themeId' => $themeId, 'module' => $module); try { $templateFilename = \Magento\TestFramework\Helper\Bootstrap::getObjectmanager() diff --git a/dev/tests/integration/testsuite/Magento/Weee/Model/ObserverTest.php b/dev/tests/integration/testsuite/Magento/Weee/Model/ObserverTest.php index 2a1b20179716bf7665996d22748e794292c1404d..0521f1e57be97ca6276323054120b05cf00f23aa 100644 --- a/dev/tests/integration/testsuite/Magento/Weee/Model/ObserverTest.php +++ b/dev/tests/integration/testsuite/Magento/Weee/Model/ObserverTest.php @@ -59,7 +59,7 @@ class ObserverTest extends \PHPUnit_Framework_TestCase \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( 'Magento\Framework\App\Config\MutableScopeConfigInterface' )->setValue( - 'tax/weee/display', + Config::XML_PATH_FPT_DISPLAY_PRODUCT_VIEW, $mode, \Magento\Store\Model\ScopeInterface::SCOPE_STORE ); @@ -78,7 +78,7 @@ class ObserverTest extends \PHPUnit_Framework_TestCase \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( 'Magento\Framework\App\Config\MutableScopeConfigInterface' )->setValue( - 'tax/weee/display', + Config::XML_PATH_FPT_DISPLAY_PRODUCT_VIEW, $mode, \Magento\Store\Model\ScopeInterface::SCOPE_STORE ); diff --git a/dev/tests/js/testsuite/mage/form/form-test.js b/dev/tests/js/testsuite/mage/form/form-test.js index 328586b50badac5afaf562b0676f2e5aaecbef77..df04f03911ea951b37d4f547caa2414034106dc2 100644 --- a/dev/tests/js/testsuite/mage/form/form-test.js +++ b/dev/tests/js/testsuite/mage/form/form-test.js @@ -69,9 +69,9 @@ FormTest.prototype.testGetHandlers = function() { FormTest.prototype.testStoreAttribute = function() { var form = jQuery('#form').form(), initialFormAttrs = { - action: form.prop('action'), - target: form.prop('target'), - method: form.prop('method') + action: form.attr('action'), + target: form.attr('target'), + method: form.attr('method') }; form.data("form")._storeAttribute('action'); form.data("form")._storeAttribute('target'); @@ -100,7 +100,7 @@ FormTest.prototype.testBind = function() { }; FormTest.prototype.testGetActionUrl = function() { var form = jQuery('#form').form(), - action = form.prop('action'), + action = form.attr('action'), testUrl = 'new/action/url', testArgs = { args: {arg: 'value'} @@ -114,9 +114,9 @@ FormTest.prototype.testGetActionUrl = function() { FormTest.prototype.testProcessData = function() { var form = jQuery('#form').form(), initialFormAttrs = { - action: form.prop('action'), - target: form.prop('target'), - method: form.prop('method') + action: form.attr('action'), + target: form.attr('target'), + method: form.attr('method') }, testSimpleData = { action: 'new/action/url', @@ -224,9 +224,9 @@ FormTest.prototype.testSubmit = function() { form.data("form")._submit({type: 'save'}); - assertEquals(form.prop('action'), form.data("form").oldAttributes.action); - assertEquals(form.prop('target'), form.data("form").oldAttributes.target); - assertEquals(form.prop('method'), form.data("form").oldAttributes.method); + assertEquals(form.attr('action'), form.data("form").oldAttributes.action); + assertEquals(form.attr('target'), form.data("form").oldAttributes.target); + assertEquals(form.attr('method'), form.data("form").oldAttributes.method); assertTrue(formSubmitted); form.off('submit'); }; diff --git a/dev/tests/js/testsuite/mage/validation/test-validation.js b/dev/tests/js/testsuite/mage/validation/test-validation.js index 5f3258896db7e224c06e266fd745ed91c60b6b32..2bde1bc8126fd2be55a2a0a41833879a58088bcf 100644 --- a/dev/tests/js/testsuite/mage/validation/test-validation.js +++ b/dev/tests/js/testsuite/mage/validation/test-validation.js @@ -219,14 +219,14 @@ test( "testValidateSsn", function() { test( "testValidateZip", function() { expect(8); - equal(true, $.validator.methods['validate-zip'].call(this, "")); - equal(true, $.validator.methods['validate-zip'].call(this, null)); - equal(true, $.validator.methods['validate-zip'].call(this, undefined)); - equal(false, $.validator.methods['validate-zip'].call(this, " ")); - equal(true, $.validator.methods['validate-zip'].call(this, "12345-1234")); - equal(true, $.validator.methods['validate-zip'].call(this, "02345")); - equal(false, $.validator.methods['validate-zip'].call(this, "1234")); - equal(false, $.validator.methods['validate-zip'].call(this, "1234-1234")); + equal(true, $.validator.methods['validate-zip-us'].call(this, "")); + equal(true, $.validator.methods['validate-zip-us'].call(this, null)); + equal(true, $.validator.methods['validate-zip-us'].call(this, undefined)); + equal(false, $.validator.methods['validate-zip-us'].call(this, " ")); + equal(true, $.validator.methods['validate-zip-us'].call(this, "12345-1234")); + equal(true, $.validator.methods['validate-zip-us'].call(this, "02345")); + equal(false, $.validator.methods['validate-zip-us'].call(this, "1234")); + equal(false, $.validator.methods['validate-zip-us'].call(this, "1234-1234")); }); test( "testValidateDateAu", function() { diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/App/Language/CircularDependencyTest.php b/dev/tests/static/testsuite/Magento/Test/Integrity/App/Language/CircularDependencyTest.php new file mode 100644 index 0000000000000000000000000000000000000000..7386046e7bd573cbe1361ca9e907dacc8c34b1e2 --- /dev/null +++ b/dev/tests/static/testsuite/Magento/Test/Integrity/App/Language/CircularDependencyTest.php @@ -0,0 +1,90 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Test\Integrity\App\Language; + +use \Magento\Framework\App\Language\Config; + +class CircularDependencyTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var Config[][] + */ + private $packs; + + /** + * Test circular dependencies between languages + */ + public function testCircularDependencies() + { + $package = new Package(); + $rootDirectory = \Magento\TestFramework\Utility\Files::init()->getPathToSource(); + $declaredLanguages = $package->readDeclarationFiles($rootDirectory); + $packs = []; + foreach ($declaredLanguages as $language) { + $filePath = reset($language); + $languageConfig = new Config(file_get_contents($filePath)); + $this->packs[$languageConfig->getVendor()][$languageConfig->getPackage()] = $languageConfig; + $packs[] = $languageConfig; + } + + /** @var $languageConfig Config */ + foreach ($packs as $languageConfig) { + $languages = []; + /** @var $config Config */ + foreach ($this->collectCircularInheritance($languageConfig) as $config) { + $languages[] = $config->getVendor() . '/' . $config->getPackage(); + } + if (!empty($languages)) { + $this->fail("Circular dependency detected:\n" . implode(' -> ', $languages)); + } + } + } + + /** + * @param Config $languageConfig + * @param array $languageList + * @param bool $isCircular + * @return array|null + */ + private function collectCircularInheritance(Config $languageConfig, &$languageList = [], &$isCircular = false) + { + $packKey = implode('|', [$languageConfig->getVendor(), $languageConfig->getPackage()]); + if (isset($languageList[$packKey])) { + $isCircular = true; + } else { + $languageList[$packKey] = $languageConfig; + foreach ($languageConfig->getUses() as $reuse) { + if (isset($this->packs[$reuse['vendor']][$reuse['package']])) { + $this->collectCircularInheritance( + $this->packs[$reuse['vendor']][$reuse['package']], + $languageList, + $isCircular + ); + } + } + } + return $isCircular ? $languageList : []; + } +} diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/App/Language/ConfigTest.php b/dev/tests/static/testsuite/Magento/Test/Integrity/App/Language/ConfigTest.php index f36bad617a18d2b44a2f8f6e5fe17e2e106a0efc..2576b0e265bf052ec64e36551ade9e7bea2e435a 100644 --- a/dev/tests/static/testsuite/Magento/Test/Integrity/App/Language/ConfigTest.php +++ b/dev/tests/static/testsuite/Magento/Test/Integrity/App/Language/ConfigTest.php @@ -31,9 +31,9 @@ class ConfigTest extends \Magento\TestFramework\Integrity\AbstractConfig $expectedErrors = array( "Element 'code': [facet 'pattern'] The value 'e_GB' is not accepted by the pattern", "Element 'code': 'e_GB' is not a valid value of the atomic type 'codeType'", - "Element 'vendor': [facet 'pattern'] The value 'agento' is not accepted by the pattern", - "Element 'vendor': 'agento' is not a valid value of the atomic type", - "Element 'sort_odrer': This element is not expected. Expected is one of", + "Element 'vendor': [facet 'pattern'] The value 'Magento' is not accepted by the pattern", + "Element 'vendor': 'Magento' is not a valid value of the atomic type", + "Element 'sort_odrer': This element is not expected. Expected is", ); parent::testSchemaUsingInvalidXml($expectedErrors); } diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/App/Language/PackageTest.php b/dev/tests/static/testsuite/Magento/Test/Integrity/App/Language/PackageTest.php index 4ff37b870bb5cad5dfdf1b6aea69fe2e146dbf00..181254ab9fcee7d62ec49bce83faa7a1188113ec 100644 --- a/dev/tests/static/testsuite/Magento/Test/Integrity/App/Language/PackageTest.php +++ b/dev/tests/static/testsuite/Magento/Test/Integrity/App/Language/PackageTest.php @@ -32,16 +32,14 @@ class PackageTest extends \PHPUnit_Framework_TestCase /** * @param string $file * @param string $expectedVendor - * @param string $expectedCode + * @param string $expectedPackage * @dataProvider declaredConsistentlyDataProvider */ - public function testDeclaredConsistently($file, $expectedVendor, $expectedCode) + public function testDeclaredConsistently($file, $expectedVendor, $expectedPackage) { - $dom = new \DOMDocument(); - $dom->load($file); - $root = $dom->documentElement; - \Magento\Framework\App\Language\Dictionary::assertVendor($expectedVendor, $root); - \Magento\Framework\App\Language\Dictionary::assertCode($expectedCode, $root); + $languageConfig = new \Magento\Framework\App\Language\Config(file_get_contents($file)); + $this->assertEquals($expectedVendor, $languageConfig->getVendor()); + $this->assertEquals($expectedPackage, $languageConfig->getPackage()); } /** diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/App/Language/TranslationFiles.php b/dev/tests/static/testsuite/Magento/Test/Integrity/App/Language/TranslationFiles.php index c58642f9063300dd739414e9fc22891f3c73e2c6..bf3b5085d43ae5af24043713e9c569dfb861a9a8 100644 --- a/dev/tests/static/testsuite/Magento/Test/Integrity/App/Language/TranslationFiles.php +++ b/dev/tests/static/testsuite/Magento/Test/Integrity/App/Language/TranslationFiles.php @@ -96,13 +96,13 @@ class TranslationFiles extends \PHPUnit_Framework_TestCase */ protected function printMessage($failures, $message = '') { - $message .= "\n"; + $message .= PHP_EOL; foreach ($failures as $locale => $localeErrors) { - $message .= $locale . "\n"; + $message .= $locale . PHP_EOL; foreach ($localeErrors as $typeError => $error) { - $message .= "\t" . $typeError . "\n"; + $message .= PHP_EOL . "##########" . PHP_EOL . ucfirst($typeError) . ':' . PHP_EOL; foreach ($error as $phrase) { - $message .= "\t\t" . $phrase . "\n"; + $message .= '"' . $phrase . '","' . $phrase . '"' . PHP_EOL; } } } diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/App/Language/_files/known_invalid.xml b/dev/tests/static/testsuite/Magento/Test/Integrity/App/Language/_files/known_invalid.xml index 9366bbeedcfb54c7dbe17db6dfe31e89ac5b29bd..e86fff00763647c3fed796cebf0770fbfec9bf87 100644 --- a/dev/tests/static/testsuite/Magento/Test/Integrity/App/Language/_files/known_invalid.xml +++ b/dev/tests/static/testsuite/Magento/Test/Integrity/App/Language/_files/known_invalid.xml @@ -25,7 +25,7 @@ --> <language xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../../../lib/internal/Magento/Framework/App/Language/package.xsd"> <code>e_GB</code> - <vendor>agento</vendor> + <vendor>Magento</vendor> <sort_odrer>100</sort_odrer> <use code="en_GB"/> </language> diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/App/Language/_files/known_valid.xml b/dev/tests/static/testsuite/Magento/Test/Integrity/App/Language/_files/known_valid.xml index d13de1dd866bcdc5a9bbb387c573ce1a62d83a2e..04363d89ad421db85a8dfd8d82456cdda23ddea8 100644 --- a/dev/tests/static/testsuite/Magento/Test/Integrity/App/Language/_files/known_valid.xml +++ b/dev/tests/static/testsuite/Magento/Test/Integrity/App/Language/_files/known_valid.xml @@ -25,7 +25,9 @@ --> <language xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../../../lib/internal/Magento/Framework/App/Language/package.xsd"> <code>en_GB</code> - <vendor>Magento</vendor> + <vendor>magento</vendor> + <package>en_gb</package> <sort_order>100</sort_order> - <use vendor="OxfordUniversity" code="en_GB"/> + <use vendor="oxford-university" package="en_us"/> + <use vendor="oxford-university" package="en_gb"/> </language> diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php index 7f0b60616a16406524001ce631432b4b7894ed09..0feded3cb23129449e1a33130bc04d6257c4d8fa 100644 --- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php +++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php @@ -665,8 +665,7 @@ return array( '\Magento\ConfigurableProduct\Block\Adminhtml\Product\Edit\Tab\Super\Config\Matrix' ), array( - 'Magento\Catalog\Block\Adminhtml\Product\Edit\Tab\Super\Config\Simple', - 'Magento\ConfigurableProduct\Block\Adminhtml\Product\Edit\Tab\Super\Config\Simple' + 'Magento\Catalog\Block\Adminhtml\Product\Edit\Tab\Super\Config\Simple' ), array( 'Magento\Catalog\Block\Adminhtml\Product\Edit\Tab\Super\Config', @@ -1376,6 +1375,7 @@ return array( array('Magento\Framework\HTTP\HandlerInterface'), array('Magento\Backend\Model\Request\PathInfoProcessor'), array('Magento\Backend\Model\Router\NoRouteHandler'), + array('Magento\ConfigurableProduct\Block\Adminhtml\Product\Edit\Tab\Super\Config\Simple'), array('Magento\Core\Model\Request\PathInfoProcessor', 'Magento\Store\App\Request\PathInfoProcessor'), array('Magento\Core\Model\Request\RewriteService'), array('Magento\Core\Model\Router\NoRouteHandler'), diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php index dc21a5b7b0b5f209cf15b32521e312d2168e988a..fd30dd301cd457ed4f7bc6b01dd28f59aa465aeb 100644 --- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php +++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php @@ -389,6 +389,7 @@ return array( array('getAllOrderEntityIds', 'Magento\Rss\Model\Resource\Order'), array('getAllOrderEntityTypeIds', 'Magento\Rss\Model\Resource\Order'), array('getAnonSuffix'), + ['getAttributesById', 'Magento\Eav\Model\Entity\AbstractEntity'], array('getAttributeDataModelFactory', 'Magento\Eav\Model\Validator\Attribute\Data'), array('getAttributes', 'Magento\Customer\Helper\Address'), array('getAttributesJson', 'Magento\Backend\Block\Catalog\Product\Edit\Tab\Super\Config', 'getAttributes'), @@ -1792,6 +1793,14 @@ return array( ['reset', 'Magento\CatalogInventory\Model\Stock\Item'], ['prepareValueForDuplicate', 'Magento\Catalog\Model\Product\Option\Value'], ['prepareOptionForDuplicate', '\Magento\Catalog\Model\Product\Option'], + [ + 'getFlatColums', + 'Magento\Eav\Model\Entity\Attribute\Source\AbstractSource', + 'Magento\Eav\Model\Entity\Attribute\Source\AbstractSource::getFlatColumns' + ], ['addProductAdvanced', '\Magento\Sales\Model\Quote'], ['translateArray', 'Magento\Framework\App\Helper\AbstractHelper'], + ['getCalculator', '\Magento\Tax\Helper\Data'], + ['getRatesForAllProductTaxClasses', 'Magento\Tax\Model\Calculation'], + ['getRatesForAllCustomerTaxClasses', 'Magento\Tax\Model\Calculation'] ); diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_properties.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_properties.php index 330062a24478d82b30a63b1d519ec87f1d07acff..fa620e572b00cde146d396d7214341701197ea25 100644 --- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_properties.php +++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_properties.php @@ -340,4 +340,8 @@ return array( ['_productInstance', 'Magento\CatalogInventory\Model\Stock\Item'], ['_regionBuilder', 'Magento\Customer\Model\Address\Converter'], ['_scopeConfig', 'Magento\CatalogInventory\Helper\Minsaleqty', 'scopeConfig'], + ['_stopFurtherRules', 'Magento\SalesRule\Model\Validator'], + ['_usageFactory', 'Magento\SalesRule\Model\Validator', 'Magento\SalesRule\Model\Validator\Utility'], + ['_couponFactory', 'Magento\SalesRule\Model\Validator', 'Magento\SalesRule\Model\Validator\Utility'], + ['_customerFactory', 'Magento\SalesRule\Model\Validator', 'Magento\SalesRule\Model\Validator\Utility'], ); diff --git a/dev/tests/static/testsuite/Magento/Test/Php/LiveCodeTest.php b/dev/tests/static/testsuite/Magento/Test/Php/LiveCodeTest.php index 7099d66c0369a230c53d049b9ca8693fb750fc7f..273663ecf30ef6c605044db1ec56f74c28190410 100644 --- a/dev/tests/static/testsuite/Magento/Test/Php/LiveCodeTest.php +++ b/dev/tests/static/testsuite/Magento/Test/Php/LiveCodeTest.php @@ -141,7 +141,6 @@ class LiveCodeTest extends PHPUnit_Framework_TestCase public function testAnnotationStandard() { $reportFile = self::$reportDir . '/phpcs_annotations_report.xml'; - $warningSeverity = 5; $wrapper = new Wrapper(); $codeSniffer = new CodeSniffer( realpath(__DIR__ . '/../../../../framework/Magento/ruleset.xml'), @@ -152,14 +151,11 @@ class LiveCodeTest extends PHPUnit_Framework_TestCase $this->markTestSkipped('PHP Code Sniffer is not installed.'); } self::setupFileLists('phpcs'); - // Scan for error amount - $result = $codeSniffer->run(self::$whiteList, self::$blackList, array('php'), 0); - // Rescan to generate report with warnings. - $codeSniffer->run(self::$whiteList, self::$blackList, array('php'), $warningSeverity); - // Fail if there are errors in report. + + $severity = 0; // Change to 5 to see the warnings $this->assertEquals( 0, - $result, + $result = $codeSniffer->run(self::$whiteList, self::$blackList, array('php'), $severity), "PHP Code Sniffer has found {$result} error(s): See detailed report in {$reportFile}" ); } diff --git a/dev/tests/static/testsuite/Magento/Test/Php/_files/blacklist/common.txt b/dev/tests/static/testsuite/Magento/Test/Php/_files/blacklist/common.txt index f9f4ce6856d861ab56e36b7485d0142190b534c2..54ea92a6e2f4ebd8ba0705310f5cc131498a7c44 100644 --- a/dev/tests/static/testsuite/Magento/Test/Php/_files/blacklist/common.txt +++ b/dev/tests/static/testsuite/Magento/Test/Php/_files/blacklist/common.txt @@ -16,6 +16,7 @@ app/code/Magento/User/view app/code/Magento/Webapi/view app/code/Magento/GroupedProduct/view app/code/Magento/RecurringPayment/view +app/code/Magento/UrlRedirect/view dev/tests/integration/framework/Magento/TestFramework/Db/Mysql.php dev/tests/integration/framework/Magento/TestFramework/Db/Adapter/Mysql.php dev/tests/integration/framework/Magento/TestFramework/Db/ConnectionAdapter.php diff --git a/dev/tests/static/testsuite/Magento/Test/Php/_files/phpcpd/blacklist/common.txt b/dev/tests/static/testsuite/Magento/Test/Php/_files/phpcpd/blacklist/common.txt index 40be27df10932f32ce172b37712ad69222e70e87..f33297f898b91182cb7fa2300d6470bdcd75ca25 100644 --- a/dev/tests/static/testsuite/Magento/Test/Php/_files/phpcpd/blacklist/common.txt +++ b/dev/tests/static/testsuite/Magento/Test/Php/_files/phpcpd/blacklist/common.txt @@ -1,4 +1,3 @@ -Find/Feed/Block/Adminhtml Magento/Adminhtml Magento/Authorizenet/Model Magento/Backend @@ -126,3 +125,4 @@ Magento/Usps/Model/Carrier Magento/Dhl/Model Magento/Shipping/Model Magento/Catalog/Service/V1/Category +Magento/UrlRedirect/Model diff --git a/dev/tests/static/testsuite/Magento/Test/Php/_files/whitelist/common.txt b/dev/tests/static/testsuite/Magento/Test/Php/_files/whitelist/common.txt index e97a5303a151b1fb35b38c6732421ef546026492..63ed5b003a15bf6696db75fb448d89c7c40d94d4 100644 --- a/dev/tests/static/testsuite/Magento/Test/Php/_files/whitelist/common.txt +++ b/dev/tests/static/testsuite/Magento/Test/Php/_files/whitelist/common.txt @@ -116,6 +116,7 @@ app/code/Magento/Shipping/Model/Resource/Order app/code/Magento/Theme app/code/Magento/Webapi app/code/Magento/GroupedProduct +app/code/Magento/UrlRedirect app/code/Magento/Wishlist/Block/Link.php dev/shell dev/tests/functional diff --git a/dev/tests/unit/filename b/dev/tests/unit/filename deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/dev/tests/unit/filename.csv b/dev/tests/unit/filename.csv deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/dev/tests/unit/filename.invalid_type b/dev/tests/unit/filename.invalid_type deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/dev/tests/unit/framework/Magento/TestFramework/Helper/ObjectManager.php b/dev/tests/unit/framework/Magento/TestFramework/Helper/ObjectManager.php index 36507e50baeeb2dccabb6f44628e57c3fc42706b..5a2ff33df0f2e597add3c6b5aaccd48aabc5272f 100644 --- a/dev/tests/unit/framework/Magento/TestFramework/Helper/ObjectManager.php +++ b/dev/tests/unit/framework/Magento/TestFramework/Helper/ObjectManager.php @@ -198,6 +198,12 @@ class ObjectManager $reflectionClass = new \ReflectionClass($className); $builderObject = $reflectionClass->newInstanceArgs($constructArguments); + $objectFactory->expects($this->_testObject->any()) + ->method('populateWithArray') + ->will($this->_testObject->returnSelf()); + $objectFactory->expects($this->_testObject->any()) + ->method('populate') + ->will($this->_testObject->returnSelf()); $objectFactory->expects($this->_testObject->any()) ->method('create') ->will($this->_testObject->returnCallback( @@ -243,7 +249,7 @@ class ObjectManager if ($parameter->getClass()) { $argClassName = $parameter->getClass()->getName(); } - $object = $this->_createArgumentMock($argClassName, $arguments); + $object = $this->_getMockObject($argClassName, $arguments); } catch (\ReflectionException $e) { $parameterString = $parameter->__toString(); $firstPosition = strpos($parameterString, '<required>'); @@ -285,4 +291,24 @@ class ObjectManager ); return $mock; } + + /** + * Helper function that creates a mock object for a given class name. + * + * Will return a real object in some cases to assist in testing. + * + * @param string $argClassName + * @param array $arguments + * @return null|object|\PHPUnit_Framework_MockObject_MockObject + */ + private function _getMockObject($argClassName, array $arguments) + { + if (is_subclass_of($argClassName, '\Magento\Framework\Service\Data\AbstractObjectBuilder')) { + $object = $this->getBuilder($argClassName, $arguments); + return $object; + } else { + $object = $this->_createArgumentMock($argClassName, $arguments); + return $object; + } + } } diff --git a/dev/tests/unit/testsuite/Magento/Backend/Controller/Adminhtml/System/Config/SaveTest.php b/dev/tests/unit/testsuite/Magento/Backend/Controller/Adminhtml/System/Config/SaveTest.php index fd073c45107cd59530c9c4caa473fbf17585fdfd..33960d51babc74deeadb6feed37147d3eabe4e91 100644 --- a/dev/tests/unit/testsuite/Magento/Backend/Controller/Adminhtml/System/Config/SaveTest.php +++ b/dev/tests/unit/testsuite/Magento/Backend/Controller/Adminhtml/System/Config/SaveTest.php @@ -70,6 +70,14 @@ class SaveTest extends \PHPUnit_Framework_TestCase */ protected $_responseMock; + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $_sectionCheckerMock; + + /** + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ protected function setUp() { $this->_requestMock = $this->getMock('Magento\Framework\App\Request\Http', array(), array(), '', false, false); @@ -151,6 +159,14 @@ class SaveTest extends \PHPUnit_Framework_TestCase 'messageManager' => $this->messageManagerMock ); + $this->_sectionCheckerMock = $this->getMock( + 'Magento\Backend\Controller\Adminhtml\System\ConfigSectionChecker', + array(), + array(), + '', + false + ); + $context = $helper->getObject('Magento\Backend\App\Action\Context', $arguments); $this->_controller = $this->getMock( 'Magento\Backend\Controller\Adminhtml\System\Config\Save', @@ -158,6 +174,7 @@ class SaveTest extends \PHPUnit_Framework_TestCase array( $context, $configStructureMock, + $this->_sectionCheckerMock, $this->_configFactoryMock, $this->_cacheMock, new \Magento\Framework\Stdlib\String() @@ -167,7 +184,7 @@ class SaveTest extends \PHPUnit_Framework_TestCase public function testIndexActionWithAllowedSection() { - $this->_sectionMock->expects($this->any())->method('isAllowed')->will($this->returnValue(true)); + $this->_sectionCheckerMock->expects($this->any())->method('isSectionAllowed')->will($this->returnValue(true)); $this->messageManagerMock->expects($this->once())->method('addSuccess')->with('You saved the configuration.'); $groups = array('some_key' => 'some_value'); @@ -204,30 +221,9 @@ class SaveTest extends \PHPUnit_Framework_TestCase $this->_controller->execute(); } - public function testIndexActionWithNotAllowedSection() - { - $this->_sectionMock->expects($this->any())->method('isAllowed')->will($this->returnValue(false)); - - $backendConfigMock = $this->getMock('Magento\Backend\Model\Config', array(), array(), '', false, false); - $backendConfigMock->expects($this->never())->method('save'); - $this->_eventManagerMock->expects($this->never())->method('dispatch'); - $this->messageManagerMock->expects($this->never())->method('addSuccess'); - $this->messageManagerMock->expects($this->once())->method('addException'); - - $this->_configFactoryMock->expects( - $this->any() - )->method( - 'create' - )->will( - $this->returnValue($backendConfigMock) - ); - - $this->_controller->execute(); - } - public function testIndexActionSaveState() { - $this->_sectionMock->expects($this->any())->method('isAllowed')->will($this->returnValue(false)); + $this->_sectionCheckerMock->expects($this->any())->method('isSectionAllowed')->will($this->returnValue(false)); $data = array('some_key' => 'some_value'); $userMock = $this->getMock('Magento\User\Model\User', array(), array(), '', false, false); @@ -248,7 +244,7 @@ class SaveTest extends \PHPUnit_Framework_TestCase public function testIndexActionGetGroupForSave() { - $this->_sectionMock->expects($this->any())->method('isAllowed')->will($this->returnValue(true)); + $this->_sectionCheckerMock->expects($this->any())->method('isSectionAllowed')->will($this->returnValue(true)); $fixturePath = __DIR__ . '/_files/'; $groups = require_once $fixturePath . 'groups_array.php'; @@ -299,7 +295,7 @@ class SaveTest extends \PHPUnit_Framework_TestCase public function testIndexActionSaveAdvanced() { - $this->_sectionMock->expects($this->any())->method('isAllowed')->will($this->returnValue(true)); + $this->_sectionCheckerMock->expects($this->any())->method('isSectionAllowed')->will($this->returnValue(true)); $requestParamMap = array( array('section', null, 'advanced'), diff --git a/dev/tests/unit/testsuite/Magento/Backend/Model/ConfigTest.php b/dev/tests/unit/testsuite/Magento/Backend/Model/ConfigTest.php index 16a334ed1f4133d74a10284044aac63858b0a6b6..e3f89ef42253a0c49a056527c97aff85d92ce3e8 100644 --- a/dev/tests/unit/testsuite/Magento/Backend/Model/ConfigTest.php +++ b/dev/tests/unit/testsuite/Magento/Backend/Model/ConfigTest.php @@ -242,6 +242,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase ); $website = $this->getMock('Magento\Store\Model\Website', array(), array(), '', false); + $website->expects($this->any())->method('getCode')->will($this->returnValue('website_code')); $this->_storeManager->expects($this->any())->method('getWebsite')->will($this->returnValue($website)); $this->_storeManager->expects($this->any())->method('getWebsites')->will($this->returnValue(array($website))); $this->_storeManager->expects($this->any())->method('isSingleStoreMode')->will($this->returnValue(true)); @@ -268,7 +269,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase 'group_id' => null, 'scope' => 'websites', 'scope_id' => 0, - 'scope_code' => 'website', + 'scope_code' => 'website_code', 'field_config' => null, 'fieldset_data' => array('key' => null) ) diff --git a/dev/tests/unit/testsuite/Magento/Bundle/Block/Adminhtml/Catalog/Product/Composite/Fieldset/Options/Type/CheckboxTest.php b/dev/tests/unit/testsuite/Magento/Bundle/Block/Adminhtml/Catalog/Product/Composite/Fieldset/Options/Type/CheckboxTest.php new file mode 100644 index 0000000000000000000000000000000000000000..0a310bba02bf29114331ffa61c6aeac54f8011dd --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Bundle/Block/Adminhtml/Catalog/Product/Composite/Fieldset/Options/Type/CheckboxTest.php @@ -0,0 +1,51 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Bundle\Block\Adminhtml\Catalog\Product\Composite\Fieldset\Options\Type; + +use Magento\TestFramework\Helper\ObjectManager; + +class CheckboxTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Bundle\Block\Adminhtml\Catalog\Product\Composite\Fieldset\Options\Type\Checkbox + */ + protected $block; + + public function setUp() + { + $this->block = (new ObjectManager($this)) + ->getObject('Magento\Bundle\Block\Adminhtml\Catalog\Product\Composite\Fieldset\Options\Type\Checkbox'); + } + + public function testSetValidationContainer() + { + $elementId = 'element-id'; + $containerId = 'container-id'; + + $result = $this->block->setValidationContainer($elementId, $containerId); + + $this->assertContains($elementId, $result); + $this->assertContains($containerId, $result); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Bundle/Block/Adminhtml/Catalog/Product/Composite/Fieldset/Options/Type/MultiTest.php b/dev/tests/unit/testsuite/Magento/Bundle/Block/Adminhtml/Catalog/Product/Composite/Fieldset/Options/Type/MultiTest.php new file mode 100644 index 0000000000000000000000000000000000000000..c4346248329086710bce6adc24d792bff4ab7123 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Bundle/Block/Adminhtml/Catalog/Product/Composite/Fieldset/Options/Type/MultiTest.php @@ -0,0 +1,51 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Bundle\Block\Adminhtml\Catalog\Product\Composite\Fieldset\Options\Type; + +use Magento\TestFramework\Helper\ObjectManager; + +class MultiTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Bundle\Block\Adminhtml\Catalog\Product\Composite\Fieldset\Options\Type\Multi + */ + protected $block; + + public function setUp() + { + $this->block = (new ObjectManager($this)) + ->getObject('Magento\Bundle\Block\Adminhtml\Catalog\Product\Composite\Fieldset\Options\Type\Multi'); + } + + public function testSetValidationContainer() + { + $elementId = 'element-id'; + $containerId = 'container-id'; + + $result = $this->block->setValidationContainer($elementId, $containerId); + + $this->assertContains($elementId, $result); + $this->assertContains($containerId, $result); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Bundle/Block/Adminhtml/Catalog/Product/Composite/Fieldset/Options/Type/RadioTest.php b/dev/tests/unit/testsuite/Magento/Bundle/Block/Adminhtml/Catalog/Product/Composite/Fieldset/Options/Type/RadioTest.php new file mode 100644 index 0000000000000000000000000000000000000000..609851d15f9df6ac6faf067254478fded6c41c60 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Bundle/Block/Adminhtml/Catalog/Product/Composite/Fieldset/Options/Type/RadioTest.php @@ -0,0 +1,51 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Bundle\Block\Adminhtml\Catalog\Product\Composite\Fieldset\Options\Type; + +use Magento\TestFramework\Helper\ObjectManager; + +class RadioTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Bundle\Block\Adminhtml\Catalog\Product\Composite\Fieldset\Options\Type\Radio + */ + protected $block; + + public function setUp() + { + $this->block = (new ObjectManager($this)) + ->getObject('Magento\Bundle\Block\Adminhtml\Catalog\Product\Composite\Fieldset\Options\Type\Radio'); + } + + public function testSetValidationContainer() + { + $elementId = 'element-id'; + $containerId = 'container-id'; + + $result = $this->block->setValidationContainer($elementId, $containerId); + + $this->assertContains($elementId, $result); + $this->assertContains($containerId, $result); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Bundle/Block/Adminhtml/Catalog/Product/Composite/Fieldset/Options/Type/SelectTest.php b/dev/tests/unit/testsuite/Magento/Bundle/Block/Adminhtml/Catalog/Product/Composite/Fieldset/Options/Type/SelectTest.php new file mode 100644 index 0000000000000000000000000000000000000000..f24fe781bcd3e7db507698443fcd3665c121e7c2 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Bundle/Block/Adminhtml/Catalog/Product/Composite/Fieldset/Options/Type/SelectTest.php @@ -0,0 +1,51 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Bundle\Block\Adminhtml\Catalog\Product\Composite\Fieldset\Options\Type; + +use Magento\TestFramework\Helper\ObjectManager; + +class SelectTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Bundle\Block\Adminhtml\Catalog\Product\Composite\Fieldset\Options\Type\Select + */ + protected $block; + + public function setUp() + { + $this->block = (new ObjectManager($this)) + ->getObject('Magento\Bundle\Block\Adminhtml\Catalog\Product\Composite\Fieldset\Options\Type\Select'); + } + + public function testSetValidationContainer() + { + $elementId = 'element-id'; + $containerId = 'container-id'; + + $result = $this->block->setValidationContainer($elementId, $containerId); + + $this->assertContains($elementId, $result); + $this->assertContains($containerId, $result); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Bundle/Block/Adminhtml/Sales/Order/Items/RendererTest.php b/dev/tests/unit/testsuite/Magento/Bundle/Block/Adminhtml/Sales/Order/Items/RendererTest.php new file mode 100644 index 0000000000000000000000000000000000000000..4f1278e2cf3dd480c0f9c7048bc9c84192e6d949 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Bundle/Block/Adminhtml/Sales/Order/Items/RendererTest.php @@ -0,0 +1,265 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Bundle\Block\Adminhtml\Sales\Order\Items; + +class RendererTest extends \PHPUnit_Framework_TestCase +{ + /** @var \Magento\Sales\Model\Order\Item|\PHPUnit_Framework_MockObject_MockObject */ + protected $orderItem; + + /** @var \Magento\Bundle\Block\Adminhtml\Sales\Order\Items\Renderer $model */ + protected $model; + + protected function setUp() + { + $this->orderItem = $this->getMock( + 'Magento\Sales\Model\Order\Item', + ['getProductOptions', '__wakeup', 'getParentItem', 'getOrderItem', 'getOrderItemId', 'getId'], + [], + '', + false + ); + + $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this); + $this->model = $objectManager->getObject('Magento\Bundle\Block\Adminhtml\Sales\Order\Items\Renderer'); + } + + /** + * @dataProvider getChildrenEmptyItemsDataProvider + */ + public function testGetChildrenEmptyItems($class, $method, $returnClass) + { + $salesModel = $this->getMock($returnClass, ['getAllItems', '__wakeup'], [], '', false); + $salesModel->expects($this->once())->method('getAllItems')->will($this->returnValue([])); + + $item = $this->getMock($class, [$method, 'getOrderItem', '__wakeup'], [], '', false); + $item->expects($this->once())->method($method)->will($this->returnValue($salesModel)); + $item->expects($this->once())->method('getOrderItem')->will($this->returnValue($this->orderItem)); + $this->orderItem->expects($this->any())->method('getId')->will($this->returnValue(1)); + + $this->assertSame(null, $this->model->getChilds($item)); + } + + public function getChildrenEmptyItemsDataProvider() + { + return [ + ['Magento\Sales\Model\Order\Invoice\Item', 'getInvoice', 'Magento\Sales\Model\Order\Invoice'], + ['Magento\Sales\Model\Order\Shipment\Item', 'getShipment', 'Magento\Sales\Model\Order\Shipment'], + ['Magento\Sales\Model\Order\Creditmemo\Item', 'getCreditmemo', 'Magento\Sales\Model\Order\Creditmemo'] + ]; + } + + /** + * @dataProvider getChildrenDataProvider + */ + public function testGetChildren($parentItem) + { + if ($parentItem) { + $parentItem = $this->getMock('Magento\Sales\Model\Order\Item', ['getId', '__wakeup'], [], '', false); + $parentItem->expects($this->any())->method('getId')->will($this->returnValue(1)); + } + $this->orderItem->expects($this->any())->method('getOrderItem')->will($this->returnSelf()); + $this->orderItem->expects($this->any())->method('getParentItem')->will($this->returnValue($parentItem)); + $this->orderItem->expects($this->any())->method('getOrderItemId')->will($this->returnValue(2)); + $this->orderItem->expects($this->any())->method('getId')->will($this->returnValue(1)); + + $salesModel = $this->getMock('Magento\Sales\Model\Order\Invoice', ['getAllItems', '__wakeup'], [], '', false); + $salesModel->expects($this->once())->method('getAllItems')->will($this->returnValue([$this->orderItem])); + + $item = $this->getMock( + 'Magento\Sales\Model\Order\Invoice\Item', + ['getInvoice', 'getOrderItem', '__wakeup'], + [], + '', + false + ); + $item->expects($this->once())->method('getInvoice')->will($this->returnValue($salesModel)); + $item->expects($this->any())->method('getOrderItem')->will($this->returnValue($this->orderItem)); + + $this->assertSame([2 => $this->orderItem], $this->model->getChilds($item)); + } + + public function getChildrenDataProvider() + { + return [ + [true], + [false], + ]; + } + + /** + * @dataProvider isShipmentSeparatelyWithoutItemDataProvider + */ + public function testIsShipmentSeparatelyWithoutItem($productOptions, $result) + { + $this->model->setItem($this->orderItem); + $this->orderItem->expects($this->any())->method('getProductOptions')->will($this->returnValue($productOptions)); + + $this->assertSame($result, $this->model->isShipmentSeparately()); + } + + public function isShipmentSeparatelyWithoutItemDataProvider() + { + return [ + [['shipment_type' => 1], true], + [['shipment_type' => 0], false], + [[], false] + ]; + } + + /** + * @dataProvider isShipmentSeparatelyWithItemDataProvider + */ + public function testIsShipmentSeparatelyWithItem($productOptions, $result, $parentItem) + { + if ($parentItem) { + $parentItem = + $this->getMock('Magento\Sales\Model\Order\Item', ['getProductOptions', '__wakeup'], [], '', false); + $parentItem->expects($this->any())->method('getProductOptions')->will($this->returnValue($productOptions)); + } else { + $this->orderItem->expects($this->any())->method('getProductOptions') + ->will($this->returnValue($productOptions)); + } + $this->orderItem->expects($this->any())->method('getParentItem')->will($this->returnValue($parentItem)); + $this->orderItem->expects($this->any())->method('getOrderItem')->will($this->returnSelf()); + + $this->assertSame($result, $this->model->isShipmentSeparately($this->orderItem)); + } + + public function isShipmentSeparatelyWithItemDataProvider() + { + return [ + [['shipment_type' => 1], false, false], + [['shipment_type' => 0], true, false], + [['shipment_type' => 1], true, true], + [['shipment_type' => 0], false, true], + ]; + } + + /** + * @dataProvider isChildCalculatedWithoutItemDataProvider + */ + public function testIsChildCalculatedWithoutItem($productOptions, $result) + { + $this->model->setItem($this->orderItem); + $this->orderItem->expects($this->any())->method('getProductOptions')->will($this->returnValue($productOptions)); + + $this->assertSame($result, $this->model->isChildCalculated()); + } + + public function isChildCalculatedWithoutItemDataProvider() + { + return [ + [['product_calculations' => 0], true], + [['product_calculations' => 1], false], + [[], false], + ]; + } + + /** + * @dataProvider isChildCalculatedWithItemDataProvider + */ + public function testIsChildCalculatedWithItem($productOptions, $result, $parentItem) + { + if ($parentItem) { + $parentItem = + $this->getMock('Magento\Sales\Model\Order\Item', ['getProductOptions', '__wakeup'], [], '', false); + $parentItem->expects($this->any())->method('getProductOptions')->will($this->returnValue($productOptions)); + } else { + $this->orderItem->expects($this->any())->method('getProductOptions') + ->will($this->returnValue($productOptions)); + } + $this->orderItem->expects($this->any())->method('getParentItem')->will($this->returnValue($parentItem)); + $this->orderItem->expects($this->any())->method('getOrderItem')->will($this->returnSelf()); + + $this->assertSame($result, $this->model->isChildCalculated($this->orderItem)); + } + + public function isChildCalculatedWithItemDataProvider() + { + return [ + [['product_calculations' => 0], false, false], + [['product_calculations' => 1], true, false], + [['product_calculations' => 0], true, true], + [['product_calculations' => 1], false, true], + ]; + } + + /** + * @dataProvider getSelectionAttributesDataProvider + */ + public function testGetSelectionAttributes($productOptions, $result) + { + $this->orderItem->expects($this->any())->method('getProductOptions')->will($this->returnValue($productOptions)); + $this->assertSame($result, $this->model->getSelectionAttributes($this->orderItem)); + } + + public function getSelectionAttributesDataProvider() + { + return [ + [[], null], + [['bundle_selection_attributes' => 'a:1:{i:0;i:1;}'], [0 => 1]], + ]; + } + + public function testGetOrderOptions() + { + $productOptions = [ + 'options' => ['options'], + 'additional_options' => ['additional_options'], + 'attributes_info' => ['attributes_info'] + ]; + $this->model->setItem($this->orderItem); + $this->orderItem->expects($this->any())->method('getProductOptions')->will($this->returnValue($productOptions)); + $this->assertEquals(['attributes_info', 'options', 'additional_options'], $this->model->getOrderOptions()); + } + + public function testGetOrderItem() + { + $this->model->setItem($this->orderItem); + $this->assertSame($this->orderItem, $this->model->getOrderItem()); + } + + /** + * @dataProvider canShowPriceInfoDataProvider + */ + public function testCanShowPriceInfo($parentItem, $productOptions, $result) + { + $this->model->setItem($this->orderItem); + $this->orderItem->expects($this->any())->method('getOrderItem')->will($this->returnSelf()); + $this->orderItem->expects($this->any())->method('getParentItem')->will($this->returnValue($parentItem)); + $this->orderItem->expects($this->any())->method('getProductOptions')->will($this->returnValue($productOptions)); + + $this->assertSame($result, $this->model->canShowPriceInfo($this->orderItem)); + } + + public function canShowPriceInfoDataProvider() + { + return [ + [true, ['product_calculations' => 0], true], + [false, [], true], + [false, ['product_calculations' => 0], false], + ]; + } +} diff --git a/dev/tests/unit/testsuite/Magento/Bundle/Block/Adminhtml/Sales/Order/View/Items/RendererTest.php b/dev/tests/unit/testsuite/Magento/Bundle/Block/Adminhtml/Sales/Order/View/Items/RendererTest.php new file mode 100644 index 0000000000000000000000000000000000000000..c3c0d11001d4e3cc1feac7d15b81f79115da492f --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Bundle/Block/Adminhtml/Sales/Order/View/Items/RendererTest.php @@ -0,0 +1,196 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Bundle\Block\Adminhtml\Sales\Order\View\Items; + +class RendererTest extends \PHPUnit_Framework_TestCase +{ + /** @var \Magento\Sales\Model\Order\Item|\PHPUnit_Framework_MockObject_MockObject */ + protected $orderItem; + + /** @var \Magento\Bundle\Block\Adminhtml\Sales\Order\View\Items\Renderer $model */ + protected $model; + + protected function setUp() + { + $this->orderItem = $this->getMock( + 'Magento\Sales\Model\Order\Item', + ['getProductOptions', '__wakeup', 'getParentItem', 'getOrderItem'], + [], + '', + false + ); + + $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this); + $this->model = $objectManager->getObject('Magento\Bundle\Block\Adminhtml\Sales\Order\View\Items\Renderer'); + } + + /** + * @dataProvider isShipmentSeparatelyWithoutItemDataProvider + */ + public function testIsShipmentSeparatelyWithoutItem($productOptions, $result) + { + $this->model->setItem($this->orderItem); + $this->orderItem->expects($this->any())->method('getProductOptions')->will($this->returnValue($productOptions)); + + $this->assertSame($result, $this->model->isShipmentSeparately()); + } + + public function isShipmentSeparatelyWithoutItemDataProvider() + { + return [ + [['shipment_type' => 1], true], + [['shipment_type' => 0], false], + [[], false] + ]; + } + + /** + * @dataProvider isShipmentSeparatelyWithItemDataProvider + */ + public function testIsShipmentSeparatelyWithItem($productOptions, $result, $parentItem) + { + if ($parentItem) { + $parentItem = + $this->getMock('Magento\Sales\Model\Order\Item', ['getProductOptions', '__wakeup'], [], '', false); + $parentItem->expects($this->any())->method('getProductOptions')->will($this->returnValue($productOptions)); + } else { + $this->orderItem->expects($this->any())->method('getProductOptions') + ->will($this->returnValue($productOptions)); + } + $this->orderItem->expects($this->any())->method('getParentItem')->will($this->returnValue($parentItem)); + $this->orderItem->expects($this->any())->method('getOrderItem')->will($this->returnSelf()); + + $this->assertSame($result, $this->model->isShipmentSeparately($this->orderItem)); + } + + public function isShipmentSeparatelyWithItemDataProvider() + { + return [ + [['shipment_type' => 1], false, false], + [['shipment_type' => 0], true, false], + [['shipment_type' => 1], true, true], + [['shipment_type' => 0], false, true], + ]; + } + + /** + * @dataProvider isChildCalculatedWithoutItemDataProvider + */ + public function testIsChildCalculatedWithoutItem($productOptions, $result) + { + $this->model->setItem($this->orderItem); + $this->orderItem->expects($this->any())->method('getProductOptions')->will($this->returnValue($productOptions)); + + $this->assertSame($result, $this->model->isChildCalculated()); + } + + public function isChildCalculatedWithoutItemDataProvider() + { + return [ + [['product_calculations' => 0], true], + [['product_calculations' => 1], false], + [[], false], + ]; + } + + /** + * @dataProvider isChildCalculatedWithItemDataProvider + */ + public function testIsChildCalculatedWithItem($productOptions, $result, $parentItem) + { + if ($parentItem) { + $parentItem = + $this->getMock('Magento\Sales\Model\Order\Item', ['getProductOptions', '__wakeup'], [], '', false); + $parentItem->expects($this->any())->method('getProductOptions')->will($this->returnValue($productOptions)); + } else { + $this->orderItem->expects($this->any())->method('getProductOptions') + ->will($this->returnValue($productOptions)); + } + $this->orderItem->expects($this->any())->method('getParentItem')->will($this->returnValue($parentItem)); + $this->orderItem->expects($this->any())->method('getOrderItem')->will($this->returnSelf()); + + $this->assertSame($result, $this->model->isChildCalculated($this->orderItem)); + } + + public function isChildCalculatedWithItemDataProvider() + { + return [ + [['product_calculations' => 0], false, false], + [['product_calculations' => 1], true, false], + [['product_calculations' => 0], true, true], + [['product_calculations' => 1], false, true], + ]; + } + + /** + * @dataProvider getSelectionAttributesDataProvider + */ + public function testGetSelectionAttributes($productOptions, $result) + { + $this->orderItem->expects($this->any())->method('getProductOptions')->will($this->returnValue($productOptions)); + $this->assertSame($result, $this->model->getSelectionAttributes($this->orderItem)); + } + + public function getSelectionAttributesDataProvider() + { + return [ + [[], null], + [['bundle_selection_attributes' => 'a:1:{i:0;i:1;}'], [0 => 1]], + ]; + } + + public function testGetOrderOptions() + { + $productOptions = [ + 'options' => ['options'], + 'additional_options' => ['additional_options'], + 'attributes_info' => ['attributes_info'] + ]; + $this->model->setItem($this->orderItem); + $this->orderItem->expects($this->any())->method('getProductOptions')->will($this->returnValue($productOptions)); + $this->assertEquals(['attributes_info', 'options', 'additional_options'], $this->model->getOrderOptions()); + } + + /** + * @dataProvider canShowPriceInfoDataProvider + */ + public function testCanShowPriceInfo($parentItem, $productOptions, $result) + { + $this->model->setItem($this->orderItem); + $this->orderItem->expects($this->any())->method('getOrderItem')->will($this->returnSelf()); + $this->orderItem->expects($this->any())->method('getParentItem')->will($this->returnValue($parentItem)); + $this->orderItem->expects($this->any())->method('getProductOptions')->will($this->returnValue($productOptions)); + + $this->assertSame($result, $this->model->canShowPriceInfo($this->orderItem)); + } + + public function canShowPriceInfoDataProvider() + { + return [ + [true, ['product_calculations' => 0], true], + [false, [], true], + [false, ['product_calculations' => 0], false], + ]; + } +} \ No newline at end of file diff --git a/dev/tests/unit/testsuite/Magento/Bundle/Block/Sales/Order/Items/RendererTest.php b/dev/tests/unit/testsuite/Magento/Bundle/Block/Sales/Order/Items/RendererTest.php new file mode 100644 index 0000000000000000000000000000000000000000..b1a89097ae81a56fd502ee47207547ce8177a432 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Bundle/Block/Sales/Order/Items/RendererTest.php @@ -0,0 +1,247 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Bundle\Block\Sales\Order\Items; + +class RendererTest extends \PHPUnit_Framework_TestCase +{ + /** @var \Magento\Sales\Model\Order\Item|\PHPUnit_Framework_MockObject_MockObject */ + protected $orderItem; + + /** @var \Magento\Bundle\Block\Sales\Order\Items\Renderer $model */ + protected $model; + + protected function setUp() + { + $this->orderItem = $this->getMock( + 'Magento\Sales\Model\Order\Item', + ['getProductOptions', '__wakeup', 'getParentItem', 'getOrderItem', 'getOrderItemId', 'getId'], + [], + '', + false + ); + + $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this); + $this->model = $objectManager->getObject('Magento\Bundle\Block\Sales\Order\Items\Renderer'); + } + + /** + * @dataProvider getChildrenEmptyItemsDataProvider + */ + public function testGetChildrenEmptyItems($class, $method, $returnClass) + { + $salesModel = $this->getMock($returnClass, ['getAllItems', '__wakeup'], [], '', false); + $salesModel->expects($this->once())->method('getAllItems')->will($this->returnValue([])); + + $item = $this->getMock($class, [$method, 'getOrderItem', '__wakeup'], [], '', false); + $item->expects($this->once())->method($method)->will($this->returnValue($salesModel)); + $item->expects($this->once())->method('getOrderItem')->will($this->returnValue($this->orderItem)); + $this->orderItem->expects($this->any())->method('getId')->will($this->returnValue(1)); + + $this->assertSame(null, $this->model->getChilds($item)); + } + + public function getChildrenEmptyItemsDataProvider() + { + return [ + ['Magento\Sales\Model\Order\Invoice\Item', 'getInvoice', 'Magento\Sales\Model\Order\Invoice'], + ['Magento\Sales\Model\Order\Shipment\Item', 'getShipment', 'Magento\Sales\Model\Order\Shipment'], + ['Magento\Sales\Model\Order\Creditmemo\Item', 'getCreditmemo', 'Magento\Sales\Model\Order\Creditmemo'] + ]; + } + + /** + * @dataProvider getChildrenDataProvider + */ + public function testGetChildren($parentItem) + { + if ($parentItem) { + $parentItem = $this->getMock('Magento\Sales\Model\Order\Item', ['getId', '__wakeup'], [], '', false); + $parentItem->expects($this->any())->method('getId')->will($this->returnValue(1)); + } + $this->orderItem->expects($this->any())->method('getOrderItem')->will($this->returnSelf()); + $this->orderItem->expects($this->any())->method('getParentItem')->will($this->returnValue($parentItem)); + $this->orderItem->expects($this->any())->method('getOrderItemId')->will($this->returnValue(2)); + $this->orderItem->expects($this->any())->method('getId')->will($this->returnValue(1)); + + $salesModel = $this->getMock('Magento\Sales\Model\Order\Invoice', ['getAllItems', '__wakeup'], [], '', false); + $salesModel->expects($this->once())->method('getAllItems')->will($this->returnValue([$this->orderItem])); + + $item = $this->getMock( + 'Magento\Sales\Model\Order\Invoice\Item', + ['getInvoice', 'getOrderItem', '__wakeup'], + [], + '', + false + ); + $item->expects($this->once())->method('getInvoice')->will($this->returnValue($salesModel)); + $item->expects($this->any())->method('getOrderItem')->will($this->returnValue($this->orderItem)); + + $this->assertSame([2 => $this->orderItem], $this->model->getChilds($item)); + } + + public function getChildrenDataProvider() + { + return [ + [true], + [false], + ]; + } + + /** + * @dataProvider isShipmentSeparatelyWithoutItemDataProvider + */ + public function testIsShipmentSeparatelyWithoutItem($productOptions, $result) + { + $this->model->setItem($this->orderItem); + $this->orderItem->expects($this->any())->method('getProductOptions')->will($this->returnValue($productOptions)); + + $this->assertSame($result, $this->model->isShipmentSeparately()); + } + + public function isShipmentSeparatelyWithoutItemDataProvider() + { + return [ + [['shipment_type' => 1], true], + [['shipment_type' => 0], false], + [[], false] + ]; + } + + /** + * @dataProvider isShipmentSeparatelyWithItemDataProvider + */ + public function testIsShipmentSeparatelyWithItem($productOptions, $result, $parentItem) + { + if ($parentItem) { + $parentItem = + $this->getMock('Magento\Sales\Model\Order\Item', ['getProductOptions', '__wakeup'], [], '', false); + $parentItem->expects($this->any())->method('getProductOptions')->will($this->returnValue($productOptions)); + } else { + $this->orderItem->expects($this->any())->method('getProductOptions') + ->will($this->returnValue($productOptions)); + } + $this->orderItem->expects($this->any())->method('getParentItem')->will($this->returnValue($parentItem)); + $this->orderItem->expects($this->any())->method('getOrderItem')->will($this->returnSelf()); + + $this->assertSame($result, $this->model->isShipmentSeparately($this->orderItem)); + } + + public function isShipmentSeparatelyWithItemDataProvider() + { + return [ + [['shipment_type' => 1], false, false], + [['shipment_type' => 0], true, false], + [['shipment_type' => 1], true, true], + [['shipment_type' => 0], false, true], + ]; + } + + /** + * @dataProvider isChildCalculatedWithoutItemDataProvider + */ + public function testIsChildCalculatedWithoutItem($productOptions, $result) + { + $this->model->setItem($this->orderItem); + $this->orderItem->expects($this->any())->method('getProductOptions')->will($this->returnValue($productOptions)); + + $this->assertSame($result, $this->model->isChildCalculated()); + } + + public function isChildCalculatedWithoutItemDataProvider() + { + return [ + [['product_calculations' => 0], true], + [['product_calculations' => 1], false], + [[], false], + ]; + } + + /** + * @dataProvider isChildCalculatedWithItemDataProvider + */ + public function testIsChildCalculatedWithItem($productOptions, $result, $parentItem) + { + if ($parentItem) { + $parentItem = + $this->getMock('Magento\Sales\Model\Order\Item', ['getProductOptions', '__wakeup'], [], '', false); + $parentItem->expects($this->any())->method('getProductOptions')->will($this->returnValue($productOptions)); + } else { + $this->orderItem->expects($this->any())->method('getProductOptions') + ->will($this->returnValue($productOptions)); + } + $this->orderItem->expects($this->any())->method('getParentItem')->will($this->returnValue($parentItem)); + $this->orderItem->expects($this->any())->method('getOrderItem')->will($this->returnSelf()); + + $this->assertSame($result, $this->model->isChildCalculated($this->orderItem)); + } + + public function isChildCalculatedWithItemDataProvider() + { + return [ + [['product_calculations' => 0], false, false], + [['product_calculations' => 1], true, false], + [['product_calculations' => 0], true, true], + [['product_calculations' => 1], false, true], + ]; + } + + /** + * @dataProvider getSelectionAttributesDataProvider + */ + public function testGetSelectionAttributes($productOptions, $result) + { + $this->orderItem->expects($this->any())->method('getProductOptions')->will($this->returnValue($productOptions)); + $this->assertSame($result, $this->model->getSelectionAttributes($this->orderItem)); + } + + public function getSelectionAttributesDataProvider() + { + return [ + [[], null], + [['bundle_selection_attributes' => 'a:1:{i:0;i:1;}'], [0 => 1]], + ]; + } + + /** + * @dataProvider canShowPriceInfoDataProvider + */ + public function testCanShowPriceInfo($parentItem, $productOptions, $result) + { + $this->model->setItem($this->orderItem); + $this->orderItem->expects($this->any())->method('getOrderItem')->will($this->returnSelf()); + $this->orderItem->expects($this->any())->method('getParentItem')->will($this->returnValue($parentItem)); + $this->orderItem->expects($this->any())->method('getProductOptions')->will($this->returnValue($productOptions)); + + $this->assertSame($result, $this->model->canShowPriceInfo($this->orderItem)); + } + + public function canShowPriceInfoDataProvider() + { + return [ + [true, ['product_calculations' => 0], true], + [false, [], true], + [false, ['product_calculations' => 0], false], + ]; + } +} \ No newline at end of file diff --git a/dev/tests/unit/testsuite/Magento/Bundle/Helper/Catalog/Product/ConfigurationTest.php b/dev/tests/unit/testsuite/Magento/Bundle/Helper/Catalog/Product/ConfigurationTest.php new file mode 100644 index 0000000000000000000000000000000000000000..151a87c78ff21d9c721c108c8ca0fb77a216f3e8 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Bundle/Helper/Catalog/Product/ConfigurationTest.php @@ -0,0 +1,220 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Bundle\Helper\Catalog\Product; + +use Magento\TestFramework\Helper\ObjectManager; + +class ConfigurationTest extends \PHPUnit_Framework_TestCase +{ + /** @var \Magento\Core\Helper\Data|\PHPUnit_Framework_MockObject_MockObject */ + protected $coreData; + + /** @var \Magento\Catalog\Helper\Product\Configuration|\PHPUnit_Framework_MockObject_MockObject */ + protected $productConfiguration; + + /** @var \Magento\Framework\Escaper|\PHPUnit_Framework_MockObject_MockObject */ + protected $escaper; + + /** @var \Magento\Bundle\Helper\Catalog\Product\Configuration */ + protected $helper; + + /** @var \Magento\Catalog\Model\Product\Configuration\Item\ItemInterface|\PHPUnit_Framework_MockObject_MockObject */ + protected $item; + + protected function setUp() + { + $this->coreData = $this->getMock('Magento\Core\Helper\Data', ['currency'], [], '', false); + $this->productConfiguration = $this->getMock('Magento\Catalog\Helper\Product\Configuration', [], [], '', false); + $this->escaper = $this->getMock('Magento\Framework\Escaper', ['escapeHtml'], [], '', false); + $this->item = $this->getMock( + 'Magento\Catalog\Model\Product\Configuration\Item\ItemInterface', + ['getQty', 'getProduct', 'getOptionByCode', 'getFileDownloadParams'] + ); + + $this->helper = (new ObjectManager($this))->getObject( + 'Magento\Bundle\Helper\Catalog\Product\Configuration', + [ + 'coreData' => $this->coreData, + 'productConfiguration' => $this->productConfiguration, + 'escaper' => $this->escaper, + ] + ); + } + + public function testGetSelectionQty() + { + $selectionId = 15; + $selectionQty = 35; + $product = $this->getMock('Magento\Catalog\Model\Product', [], [], '', false); + $option = $this->getMock('Magento\Catalog\Model\Product\Option', ['__wakeup', 'getValue'], [], '', false); + + $product->expects($this->once())->method('getCustomOption')->with('selection_qty_' . $selectionId) + ->will($this->returnValue($option)); + $option->expects($this->once())->method('getValue')->will($this->returnValue($selectionQty)); + + $this->assertEquals($selectionQty, $this->helper->getSelectionQty($product, $selectionId)); + } + + public function testGetSelectionQtyIfCustomOptionIsNotSet() + { + $selectionId = 15; + $product = $this->getMock('Magento\Catalog\Model\Product', [], [], '', false); + + $product->expects($this->once())->method('getCustomOption')->with('selection_qty_' . $selectionId) + ->will($this->returnValue(null)); + + $this->assertEquals(0, $this->helper->getSelectionQty($product, $selectionId)); + } + + /** + * @covers \Magento\Bundle\Helper\Catalog\Product\Configuration::getSelectionFinalPrice + */ + public function testGetSelectionFinalPrice() + { + $itemQty = 2; + + $product = $this->getMock('Magento\Catalog\Model\Product', [], [], '', false); + $price = $this->getMock('Magento\Bundle\Model\Product\Price', [], [], '', false); + $selectionProduct = $this->getMock('Magento\Catalog\Model\Product', [], [], '', false); + + $selectionProduct->expects($this->once())->method('unsetData')->with('final_price'); + $this->item->expects($this->once())->method('getProduct')->will($this->returnValue($product)); + $this->item->expects($this->once())->method('getQty')->will($this->returnValue($itemQty)); + $product->expects($this->once())->method('getPriceModel')->will($this->returnValue($price)); + $price->expects($this->once())->method('getSelectionFinalTotalPrice') + ->with($product, $selectionProduct, $itemQty, 0, false, true); + + $this->helper->getSelectionFinalPrice($this->item, $selectionProduct); + } + + public function testGetBundleOptionsEmptyBundleOptionsIds() + { + $typeInstance = $this->getMock('Magento\Bundle\Model\Product\Type', [], [], '', false); + $product = $this->getMock('Magento\Catalog\Model\Product', ['getTypeInstance', '__wakeup'], [], '', false); + + $product->expects($this->once())->method('getTypeInstance')->will($this->returnValue($typeInstance)); + $this->item->expects($this->once())->method('getProduct')->will($this->returnValue($product)); + $this->item->expects($this->once())->method('getOptionByCode')->with('bundle_option_ids') + ->will($this->returnValue(null)); + + $this->assertEquals([], $this->helper->getBundleOptions($this->item)); + } + + public function testGetBundleOptionsEmptyBundleSelectionIds() + { + $optionIds = 'a:1:{i:0;i:1;}'; + + $collection = $this->getMock('Magento\Bundle\Model\Resource\Option\Collection', [], [], '', false); + $product = $this->getMock('Magento\Catalog\Model\Product', ['getTypeInstance', '__wakeup'], [], '', false); + $typeInstance = $this->getMock('Magento\Bundle\Model\Product\Type', ['getOptionsByIds'], [], '', false); + $selectionOption = + $this->getMock('\Magento\Catalog\Model\Product\Configuration\Item\Option\OptionInterface', ['getValue']); + $itemOption = + $this->getMock('\Magento\Catalog\Model\Product\Configuration\Item\Option\OptionInterface', ['getValue']); + + $selectionOption->expects($this->once())->method('getValue')->will($this->returnValue('')); + $itemOption->expects($this->once())->method('getValue')->will($this->returnValue($optionIds)); + $typeInstance->expects($this->once())->method('getOptionsByIds')->with(unserialize($optionIds), $product) + ->will($this->returnValue($collection)); + $product->expects($this->once())->method('getTypeInstance')->will($this->returnValue($typeInstance)); + $this->item->expects($this->once())->method('getProduct')->will($this->returnValue($product)); + $this->item->expects($this->at(1))->method('getOptionByCode')->with('bundle_option_ids') + ->will($this->returnValue($itemOption)); + $this->item->expects($this->at(2))->method('getOptionByCode')->with('bundle_selection_ids') + ->will($this->returnValue($selectionOption)); + + $this->assertEquals([], $this->helper->getBundleOptions($this->item)); + } + + public function testGetOptions() + { + $optionIds = 'a:1:{i:0;i:1;}'; + $selectionIds = 'a:1:{i:0;s:1:"2";}'; + $selectionId = '2'; + $product = $this->getMock( + 'Magento\Catalog\Model\Product', + ['getTypeInstance', '__wakeup', 'getCustomOption', 'getSelectionId', 'getName', 'getPriceModel'], + [], + '', + false + ); + $typeInstance = $this->getMock( + 'Magento\Bundle\Model\Product\Type', + ['getOptionsByIds', 'getSelectionsByIds'], + [], + '', + false + ); + $priceModel = + $this->getMock('Magento\Bundle\Model\Product\Price', ['getSelectionFinalTotalPrice'], [], '', false); + $selectionQty = + $this->getMock('Magento\Sales\Model\Quote\Item\Option', ['getValue', '__wakeup'], [], '', false); + $bundleOption = + $this->getMock('Magento\Bundle\Model\Option', ['getSelections', 'getTitle', '__wakeup'], [], '', false); + $selectionOption = + $this->getMock('\Magento\Catalog\Model\Product\Configuration\Item\Option\OptionInterface', ['getValue']); + $collection = + $this->getMock('Magento\Bundle\Model\Resource\Option\Collection', ['appendSelections'], [], '', false); + $itemOption = + $this->getMock('\Magento\Catalog\Model\Product\Configuration\Item\Option\OptionInterface', ['getValue']); + $collection2 = $this->getMock('Magento\Bundle\Model\Resource\Selection\Collection', [], [], '', false); + + $this->escaper->expects($this->once())->method('escapeHtml')->with('name')->will($this->returnValue('name')); + $this->coreData->expects($this->once())->method('currency')->with(15) + ->will($this->returnValue('<span class="price">$15.00</span>')); + $priceModel->expects($this->once())->method('getSelectionFinalTotalPrice')->will($this->returnValue(15)); + $selectionQty->expects($this->any())->method('getValue')->will($this->returnValue(1)); + $bundleOption->expects($this->any())->method('getSelections')->will($this->returnValue([$product])); + $bundleOption->expects($this->once())->method('getTitle')->will($this->returnValue('title')); + $selectionOption->expects($this->once())->method('getValue')->will($this->returnValue($selectionIds)); + $collection->expects($this->once())->method('appendSelections')->with($collection2, true) + ->will($this->returnValue([$bundleOption])); + $itemOption->expects($this->once())->method('getValue')->will($this->returnValue($optionIds)); + $typeInstance->expects($this->once())->method('getOptionsByIds')->with(unserialize($optionIds), $product) + ->will($this->returnValue($collection)); + $typeInstance->expects($this->once())->method('getSelectionsByIds')->with(unserialize($selectionIds), $product) + ->will($this->returnValue($collection2)); + $product->expects($this->once())->method('getTypeInstance')->will($this->returnValue($typeInstance)); + $product->expects($this->any())->method('getCustomOption')->with('selection_qty_' . $selectionId) + ->will($this->returnValue($selectionQty)); + $product->expects($this->any())->method('getSelectionId')->will($this->returnValue($selectionId)); + $product->expects($this->once())->method('getName')->will($this->returnValue('name')); + $product->expects($this->once())->method('getPriceModel')->will($this->returnValue($priceModel)); + $this->item->expects($this->any())->method('getProduct')->will($this->returnValue($product)); + $this->item->expects($this->at(1))->method('getOptionByCode')->with('bundle_option_ids') + ->will($this->returnValue($itemOption)); + $this->item->expects($this->at(2))->method('getOptionByCode')->with('bundle_selection_ids') + ->will($this->returnValue($selectionOption)); + $this->productConfiguration->expects($this->once())->method('getCustomOptions')->with($this->item) + ->will($this->returnValue([0 => ['label' => 'title', 'value' => 'value']])); + + $this->assertEquals( + [ + 0 => ['label' => 'title', 'value' => [0 => '1 x name <span class="price">$15.00</span>']], + 1 => ['label' => 'title', 'value' => 'value'] + ], + $this->helper->getOptions($this->item) + ); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Bundle/Helper/DataTest.php b/dev/tests/unit/testsuite/Magento/Bundle/Helper/DataTest.php new file mode 100644 index 0000000000000000000000000000000000000000..d668cb5ed3b226305832c08ecf3bd1c27a1f83de --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Bundle/Helper/DataTest.php @@ -0,0 +1,66 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Bundle\Helper; + +use Magento\TestFramework\Helper\ObjectManager; + +class DataTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Catalog\Model\ProductTypes\ConfigInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $config; + + /** + * @var \Magento\Bundle\Helper\Data + */ + protected $helper; + + protected function setUp() + { + $this->config = $this->getMock('Magento\Catalog\Model\ProductTypes\ConfigInterface'); + $this->helper = (new ObjectManager($this))->getObject( + 'Magento\Bundle\Helper\Data', + ['config' => $this->config] + ); + } + + public function testGetAllowedSelectionTypes() + { + $configData = ['allowed_selection_types' => ['foo', 'bar', 'baz']]; + $this->config->expects($this->once())->method('getType')->with('bundle')->will($this->returnValue($configData)); + + $this->assertEquals($configData['allowed_selection_types'], $this->helper->getAllowedSelectionTypes()); + } + + public function testGetAllowedSelectionTypesIfTypesIsNotSet() + { + $configData = []; + $this->config->expects($this->once())->method('getType') + ->with(\Magento\Catalog\Model\Product\Type::TYPE_BUNDLE) + ->will($this->returnValue($configData)); + + $this->assertEquals([], $this->helper->getAllowedSelectionTypes()); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Bundle/Model/OptionTest.php b/dev/tests/unit/testsuite/Magento/Bundle/Model/OptionTest.php new file mode 100644 index 0000000000000000000000000000000000000000..355a033db2dbbf7622c5f0fe741d9e2662294f63 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Bundle/Model/OptionTest.php @@ -0,0 +1,181 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Bundle\Model; + +use Magento\TestFramework\Helper\ObjectManager; + +class OptionTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject + */ + protected $selectionFirst; + + /** + * @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject + */ + protected $selectionSecond; + + /** + * @var \Magento\Framework\Model\Resource\AbstractResource|\PHPUnit_Framework_MockObject_MockObject + */ + protected $resource; + + /** + * @var \Magento\Bundle\Model\Option + */ + protected $model; + + protected function setUp() + { + $this->selectionFirst = $this->getMock( + 'Magento\Catalog\Model\Product', + ['__wakeup', 'isSaleable', 'getIsDefault', 'getSelectionId'], + [], + '', + false + ); + $this->selectionSecond = $this->getMock( + 'Magento\Catalog\Model\Product', + ['__wakeup', 'isSaleable', 'getIsDefault', 'getSelectionId'], + [], + '', + false + ); + $this->resource = $this->getMock( + 'Magento\Framework\Model\Resource\AbstractResource', + ['_construct', '_getReadAdapter', '_getWriteAdapter', 'getIdFieldName', 'getSearchableData'], + [], + '', + false + ); + $this->model = (new ObjectManager($this))->getObject('Magento\Bundle\Model\Option', [ + 'resource' => $this->resource, + ]); + } + + /** + * @covers \Magento\Bundle\Model\Option::addSelection + */ + public function testAddSelection() + { + $this->model->addSelection($this->selectionFirst); + + $this->assertContains($this->selectionFirst, $this->model->getSelections()); + } + + public function testIsSaleablePositive() + { + $this->selectionFirst->expects($this->any())->method('isSaleable')->will($this->returnValue(true)); + $this->selectionSecond->expects($this->any())->method('isSaleable')->will($this->returnValue(false)); + + $this->model->setSelections([$this->selectionFirst, $this->selectionSecond]); + $this->assertTrue($this->model->isSaleable()); + } + + public function testIsSaleableNegative() + { + $this->selectionFirst->expects($this->any())->method('isSaleable')->will($this->returnValue(false)); + $this->selectionSecond->expects($this->any())->method('isSaleable')->will($this->returnValue(false)); + + $this->model->setSelections([$this->selectionFirst, $this->selectionSecond]); + $this->assertFalse($this->model->isSaleable()); + } + + public function testGetDefaultSelection() + { + $this->selectionFirst->expects($this->any())->method('getIsDefault')->will($this->returnValue(true)); + $this->selectionSecond->expects($this->any())->method('getIsDefault')->will($this->returnValue(false)); + + $this->model->setSelections([$this->selectionFirst, $this->selectionSecond]); + $this->assertEquals($this->selectionFirst, $this->model->getDefaultSelection()); + } + + public function testGetDefaultSelectionNegative() + { + $this->selectionFirst->expects($this->any())->method('getIsDefault')->will($this->returnValue(false)); + $this->selectionSecond->expects($this->any())->method('getIsDefault')->will($this->returnValue(false)); + + $this->model->setSelections([$this->selectionFirst, $this->selectionSecond]); + $this->assertNull($this->model->getDefaultSelection()); + } + + /** + * @param string $type + * @param bool $expectedValue + * @dataProvider dataProviderForIsMultiSelection + */ + public function testIsMultiSelection($type, $expectedValue) + { + $this->model->setType($type); + + $this->assertEquals($expectedValue, $this->model->isMultiSelection()); + } + + /** + * @return array + */ + public function dataProviderForIsMultiSelection() + { + return [ + ['checkbox', true], + ['multi', true], + ['some_type', false], + ]; + } + + public function testGetSearchableData() + { + $productId = 15; + $storeId = 1; + $data = 'data'; + + $this->resource->expects($this->any())->method('getSearchableData')->with($productId, $storeId) + ->will($this->returnValue($data)); + + $this->assertEquals($data, $this->model->getSearchableData($productId, $storeId)); + } + + public function testGetSelectionById() + { + $selectionId = 15; + + $this->selectionFirst->expects($this->any())->method('getSelectionId')->will($this->returnValue($selectionId)); + $this->selectionSecond->expects($this->any())->method('getSelectionId')->will($this->returnValue(16)); + + $this->model->setSelections([$this->selectionFirst, $this->selectionSecond]); + $this->assertEquals($this->selectionFirst, $this->model->getSelectionById($selectionId)); + } + + public function testGetSelectionByIdNegative() + { + $selectionId = 15; + + $this->selectionFirst->expects($this->any())->method('getSelectionId')->will($this->returnValue(16)); + $this->selectionSecond->expects($this->any())->method('getSelectionId')->will($this->returnValue(17)); + + $this->model->setSelections([$this->selectionFirst, $this->selectionSecond]); + $this->assertNull($this->model->getSelectionById($selectionId)); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Bundle/Model/Plugin/PriceBackendTest.php b/dev/tests/unit/testsuite/Magento/Bundle/Model/Plugin/PriceBackendTest.php new file mode 100644 index 0000000000000000000000000000000000000000..6f306983a2d7786d3e70c4c3303872c919a4a90a --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Bundle/Model/Plugin/PriceBackendTest.php @@ -0,0 +1,97 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Bundle\Model\Plugin; + + +use Magento\Bundle\Model\Product\Price; +use Magento\Catalog\Model\Product\Type; +use Magento\TestFramework\Helper\ObjectManager; + + +class PriceBackendTest extends \PHPUnit_Framework_TestCase +{ + const CLOSURE_VALUE = 'CLOSURE'; + /** @var PriceBackend */ + private $priceBackendPlugin; + /** @var \PHPUnit_Framework_MockObject_MockObject */ + private $priceAttributeMock; + /** @var \Closure */ + private $closure; + /** @var \PHPUnit_Framework_MockObject_MockObject */ + private $productMock; + + protected function setUp() + { + $objectManager = new ObjectManager($this); + $this->priceBackendPlugin = $objectManager->getObject('\Magento\Bundle\Model\Plugin\PriceBackend'); + + $this->closure = function () { + return static::CLOSURE_VALUE; + }; + $this->priceAttributeMock = $this->getMockBuilder('Magento\Catalog\Model\Product\Attribute\Backend\Price') + ->disableOriginalConstructor() + ->getMock(); + $this->productMock = $this->getMockBuilder('Magento\Catalog\Model\Product') + ->disableOriginalConstructor() + ->setMethods(['getTypeId', 'getPriceType', '__wakeUp']) + ->getMock(); + } + + /** + * @dataProvider aroundValidateDataProvider + * + * @param $typeId + * @param $priceType + * @param $expectedResult + */ + public function testAroundValidate($typeId, $priceType, $expectedResult) + { + $this->productMock->expects($this->any())->method('getTypeId')->will($this->returnValue($typeId)); + $this->productMock->expects($this->any())->method('getPriceType')->will($this->returnValue($priceType)); + $result = $this->priceBackendPlugin->aroundValidate( + $this->priceAttributeMock, + $this->closure, + $this->productMock + ); + $this->assertEquals($expectedResult, $result); + } + + /** + * Data provider for testAroundValidate + * + * @return array + */ + public function aroundValidateDataProvider() + { + return array( + ['type' => Type::TYPE_SIMPLE, 'priceType' => Price::PRICE_TYPE_FIXED, 'result' => static::CLOSURE_VALUE], + ['type' => Type::TYPE_SIMPLE, 'priceType' => Price::PRICE_TYPE_DYNAMIC, 'result' => static::CLOSURE_VALUE], + ['type' => Type::TYPE_BUNDLE, 'priceType' => Price::PRICE_TYPE_FIXED, 'result' => static::CLOSURE_VALUE], + ['type' => Type::TYPE_BUNDLE, 'priceType' => Price::PRICE_TYPE_DYNAMIC, 'result' => true], + ['type' => Type::TYPE_VIRTUAL, 'priceType' => Price::PRICE_TYPE_FIXED, 'result' => static::CLOSURE_VALUE], + ['type' => Type::TYPE_VIRTUAL, 'priceType' => Price::PRICE_TYPE_DYNAMIC, 'result' => static::CLOSURE_VALUE], + ); + } +} \ No newline at end of file diff --git a/dev/tests/unit/testsuite/Magento/Bundle/Model/Product/Attribute/Source/Price/ViewTest.php b/dev/tests/unit/testsuite/Magento/Bundle/Model/Product/Attribute/Source/Price/ViewTest.php index 5220ab8755d063684eb7394d680587f5a0f6ccce..7d560eda3678d1b24410882df967bf749013fdc3 100644 --- a/dev/tests/unit/testsuite/Magento/Bundle/Model/Product/Attribute/Source/Price/ViewTest.php +++ b/dev/tests/unit/testsuite/Magento/Bundle/Model/Product/Attribute/Source/Price/ViewTest.php @@ -30,39 +30,98 @@ class ViewTest extends \PHPUnit_Framework_TestCase /** * @var \Magento\Bundle\Model\Product\Attribute\Source\Price\View */ - protected $_model; + protected $model; + + /** + * @var \Magento\Eav\Model\Resource\Entity\Attribute\Option|\PHPUnit_Framework_MockObject_MockObject + */ + protected $option; + + /** + * @var \Magento\Eav\Model\Resource\Entity\Attribute\OptionFactory|\PHPUnit_Framework_MockObject_MockObject + */ + protected $optionFactory; + + /** + * @var \Magento\Eav\Model\Entity\Attribute\AbstractAttribute|\PHPUnit_Framework_MockObject_MockObject + */ + protected $attribute; public function setUp() { - $objectManager = new ObjectManager($this); - $this->_model = $objectManager->getObject('Magento\Bundle\Model\Product\Attribute\Source\Price\View'); + $this->option = $this->getMock('Magento\Eav\Model\Resource\Entity\Attribute\Option', [], [], '', false); + $this->optionFactory = $this->getMock('Magento\Eav\Model\Resource\Entity\Attribute\OptionFactory', ['create']); + $this->optionFactory->expects($this->any())->method('create')->will($this->returnValue($this->option)); + $this->attribute = $this->getMock('Magento\Eav\Model\Entity\Attribute\AbstractAttribute', [], [], '', false); + + $this->model = (new ObjectManager($this)) + ->getObject('Magento\Bundle\Model\Product\Attribute\Source\Price\View', [ + 'optionFactory' => $this->optionFactory, + ]); + $this->model->setAttribute($this->attribute); + } + + public function testGetAllOptions() + { + $options = $this->model->getAllOptions(); + + $this->assertInternalType('array', $options); + $this->assertNotEmpty($options); + + foreach ($options as $option) { + $this->assertArrayHasKey('label', $option); + $this->assertArrayHasKey('value', $option); + } + } + + /** + * @covers \Magento\Bundle\Model\Product\Attribute\Source\Price\View::getOptionText + */ + public function testGetOptionTextForExistLabel() + { + $existValue = 1; + + $this->assertInternalType('string', $this->model->getOptionText($existValue)); + } + + /** + * @covers \Magento\Bundle\Model\Product\Attribute\Source\Price\View::getOptionText + */ + public function testGetOptionTextForNotExistLabel() + { + $notExistValue = -1; + + $this->assertFalse($this->model->getOptionText($notExistValue)); } - public function testGetFlatColums() + public function testGetFlatColumns() { - $abstractAttributeMock = $this->getMock( - '\Magento\Eav\Model\Entity\Attribute\AbstractAttribute', - array('getAttributeCode', '__wakeup'), - array(), - '', - false - ); - - $abstractAttributeMock->expects($this->any())->method('getAttributeCode')->will($this->returnValue('code')); - - $this->_model->setAttribute($abstractAttributeMock); - - $flatColums = $this->_model->getFlatColums(); - - $this->assertTrue(is_array($flatColums), 'FlatColums must be an array value'); - $this->assertTrue(!empty($flatColums), 'FlatColums must be not empty'); - foreach ($flatColums as $result) { - $this->assertArrayHasKey('unsigned', $result, 'FlatColums must have "unsigned" column'); - $this->assertArrayHasKey('default', $result, 'FlatColums must have "default" column'); - $this->assertArrayHasKey('extra', $result, 'FlatColums must have "extra" column'); - $this->assertArrayHasKey('type', $result, 'FlatColums must have "type" column'); - $this->assertArrayHasKey('nullable', $result, 'FlatColums must have "nullable" column'); - $this->assertArrayHasKey('comment', $result, 'FlatColums must have "comment" column'); + $code = 'attribute-code'; + $this->attribute->expects($this->any())->method('getAttributeCode')->will($this->returnValue($code)); + + $columns = $this->model->getFlatColumns(); + + $this->assertInternalType('array', $columns); + $this->assertArrayHasKey($code, $columns); + + foreach ($columns as $column) { + $this->assertArrayHasKey('unsigned', $column); + $this->assertArrayHasKey('default', $column); + $this->assertArrayHasKey('extra', $column); + $this->assertArrayHasKey('type', $column); + $this->assertArrayHasKey('nullable', $column); + $this->assertArrayHasKey('comment', $column); } } + + public function testGetFlatUpdateSelect() + { + $store = 1; + $select = 'select'; + + $this->option->expects($this->once())->method('getFlatUpdateSelect')->with($this->attribute, $store, false) + ->will($this->returnValue($select)); + + $this->assertEquals($select, $this->model->getFlatUpdateSelect($store)); + } } diff --git a/dev/tests/unit/testsuite/Magento/Bundle/Model/Sales/Order/Pdf/Items/AbstractItemsTest.php b/dev/tests/unit/testsuite/Magento/Bundle/Model/Sales/Order/Pdf/Items/AbstractItemsTest.php new file mode 100644 index 0000000000000000000000000000000000000000..703601a015bf4c62435cad4d0cbe0026632d612c --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Bundle/Model/Sales/Order/Pdf/Items/AbstractItemsTest.php @@ -0,0 +1,283 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Bundle\Model\Sales\Order\Pdf\Items; + +class AbstractItemsTest extends \PHPUnit_Framework_TestCase +{ + /** @var \Magento\Sales\Model\Order\Item|\PHPUnit_Framework_MockObject_MockObject */ + protected $orderItem; + + /** @var \Magento\Bundle\Model\Sales\Order\Pdf\Items\Shipment $model */ + protected $model; + + protected function setUp() + { + $this->orderItem = $this->getMock( + 'Magento\Sales\Model\Order\Item', + ['getProductOptions', '__wakeup', 'getParentItem', 'getOrderItem', 'getOrderItemId', 'getId'], + [], + '', + false + ); + + $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this); + $this->model = $objectManager->getObject('Magento\Bundle\Model\Sales\Order\Pdf\Items\Shipment'); + } + + /** + * @dataProvider getChildrenEmptyItemsDataProvider + */ + public function testGetChildrenEmptyItems($class, $method, $returnClass) + { + $salesModel = $this->getMock($returnClass, ['getAllItems', '__wakeup'], [], '', false); + $salesModel->expects($this->once())->method('getAllItems')->will($this->returnValue([])); + + $item = $this->getMock($class, [$method, 'getOrderItem', '__wakeup'], [], '', false); + $item->expects($this->once())->method($method)->will($this->returnValue($salesModel)); + $item->expects($this->once())->method('getOrderItem')->will($this->returnValue($this->orderItem)); + $this->orderItem->expects($this->any())->method('getId')->will($this->returnValue(1)); + + $this->assertSame(null, $this->model->getChilds($item)); + } + + public function getChildrenEmptyItemsDataProvider() + { + return [ + ['Magento\Sales\Model\Order\Invoice\Item', 'getInvoice', 'Magento\Sales\Model\Order\Invoice'], + ['Magento\Sales\Model\Order\Shipment\Item', 'getShipment', 'Magento\Sales\Model\Order\Shipment'], + ['Magento\Sales\Model\Order\Creditmemo\Item', 'getCreditmemo', 'Magento\Sales\Model\Order\Creditmemo'] + ]; + } + + /** + * @dataProvider getChildrenDataProvider + */ + public function testGetChildren($parentItem) + { + if ($parentItem) { + $parentItem = $this->getMock('Magento\Sales\Model\Order\Item', ['getId', '__wakeup'], [], '', false); + $parentItem->expects($this->any())->method('getId')->will($this->returnValue(1)); + } + $this->orderItem->expects($this->any())->method('getOrderItem')->will($this->returnSelf()); + $this->orderItem->expects($this->any())->method('getParentItem')->will($this->returnValue($parentItem)); + $this->orderItem->expects($this->any())->method('getOrderItemId')->will($this->returnValue(2)); + $this->orderItem->expects($this->any())->method('getId')->will($this->returnValue(1)); + + $salesModel = $this->getMock('Magento\Sales\Model\Order\Invoice', ['getAllItems', '__wakeup'], [], '', false); + $salesModel->expects($this->once())->method('getAllItems')->will($this->returnValue([$this->orderItem])); + + $item = $this->getMock( + 'Magento\Sales\Model\Order\Invoice\Item', + ['getInvoice', 'getOrderItem', '__wakeup'], + [], + '', + false + ); + $item->expects($this->once())->method('getInvoice')->will($this->returnValue($salesModel)); + $item->expects($this->any())->method('getOrderItem')->will($this->returnValue($this->orderItem)); + + $this->assertSame([2 => $this->orderItem], $this->model->getChilds($item)); + } + + public function getChildrenDataProvider() + { + return [ + [true], + [false], + ]; + } + + /** + * @dataProvider isShipmentSeparatelyWithoutItemDataProvider + */ + public function testIsShipmentSeparatelyWithoutItem($productOptions, $result) + { + $this->model->setItem($this->orderItem); + $this->orderItem->expects($this->any())->method('getProductOptions')->will($this->returnValue($productOptions)); + + $this->assertSame($result, $this->model->isShipmentSeparately()); + } + + public function isShipmentSeparatelyWithoutItemDataProvider() + { + return [ + [['shipment_type' => 1], true], + [['shipment_type' => 0], false], + [[], false] + ]; + } + + /** + * @dataProvider isShipmentSeparatelyWithItemDataProvider + */ + public function testIsShipmentSeparatelyWithItem($productOptions, $result, $parentItem) + { + if ($parentItem) { + $parentItem = + $this->getMock('Magento\Sales\Model\Order\Item', ['getProductOptions', '__wakeup'], [], '', false); + $parentItem->expects($this->any())->method('getProductOptions')->will($this->returnValue($productOptions)); + } else { + $this->orderItem->expects($this->any())->method('getProductOptions') + ->will($this->returnValue($productOptions)); + } + $this->orderItem->expects($this->any())->method('getParentItem')->will($this->returnValue($parentItem)); + $this->orderItem->expects($this->any())->method('getOrderItem')->will($this->returnSelf()); + + $this->assertSame($result, $this->model->isShipmentSeparately($this->orderItem)); + } + + public function isShipmentSeparatelyWithItemDataProvider() + { + return [ + [['shipment_type' => 1], false, false], + [['shipment_type' => 0], true, false], + [['shipment_type' => 1], true, true], + [['shipment_type' => 0], false, true], + ]; + } + + /** + * @dataProvider isChildCalculatedWithoutItemDataProvider + */ + public function testIsChildCalculatedWithoutItem($productOptions, $result) + { + $this->model->setItem($this->orderItem); + $this->orderItem->expects($this->any())->method('getProductOptions')->will($this->returnValue($productOptions)); + + $this->assertSame($result, $this->model->isChildCalculated()); + } + + public function isChildCalculatedWithoutItemDataProvider() + { + return [ + [['product_calculations' => 0], true], + [['product_calculations' => 1], false], + [[], false], + ]; + } + + /** + * @dataProvider isChildCalculatedWithItemDataProvider + */ + public function testIsChildCalculatedWithItem($productOptions, $result, $parentItem) + { + if ($parentItem) { + $parentItem = + $this->getMock('Magento\Sales\Model\Order\Item', ['getProductOptions', '__wakeup'], [], '', false); + $parentItem->expects($this->any())->method('getProductOptions')->will($this->returnValue($productOptions)); + } else { + $this->orderItem->expects($this->any())->method('getProductOptions') + ->will($this->returnValue($productOptions)); + } + $this->orderItem->expects($this->any())->method('getParentItem')->will($this->returnValue($parentItem)); + $this->orderItem->expects($this->any())->method('getOrderItem')->will($this->returnSelf()); + + $this->assertSame($result, $this->model->isChildCalculated($this->orderItem)); + } + + public function isChildCalculatedWithItemDataProvider() + { + return [ + [['product_calculations' => 0], false, false], + [['product_calculations' => 1], true, false], + [['product_calculations' => 0], true, true], + [['product_calculations' => 1], false, true], + ]; + } + + /** + * @dataProvider getBundleOptionsDataProvider + */ + public function testGetBundleOptions($productOptions, $result) + { + $this->model->setItem($this->orderItem); + $this->orderItem->expects($this->any())->method('getProductOptions')->will($this->returnValue($productOptions)); + $this->assertSame($result, $this->model->getBundleOptions()); + } + + public function getBundleOptionsDataProvider() + { + return [ + [['bundle_options' => 'result'], 'result'], + [[], []], + ]; + } + + /** + * @dataProvider getSelectionAttributesDataProvider + */ + public function testGetSelectionAttributes($productOptions, $result) + { + $this->orderItem->expects($this->any())->method('getProductOptions')->will($this->returnValue($productOptions)); + $this->assertSame($result, $this->model->getSelectionAttributes($this->orderItem)); + } + + public function getSelectionAttributesDataProvider() + { + return [ + [[], null], + [['bundle_selection_attributes' => 'a:1:{i:0;i:1;}'], [0 => 1]], + ]; + } + + public function testGetOrderOptions() + { + $productOptions = [ + 'options' => ['options'], + 'additional_options' => ['additional_options'], + 'attributes_info' => ['attributes_info'] + ]; + $this->model->setItem($this->orderItem); + $this->orderItem->expects($this->any())->method('getProductOptions')->will($this->returnValue($productOptions)); + $this->assertEquals(['attributes_info', 'options', 'additional_options'], $this->model->getOrderOptions()); + } + + public function testGetOrderItem() + { + $this->model->setItem($this->orderItem); + $this->assertSame($this->orderItem, $this->model->getOrderItem()); + } + + /** + * @dataProvider canShowPriceInfoDataProvider + */ + public function testCanShowPriceInfo($parentItem, $productOptions, $result) + { + $this->model->setItem($this->orderItem); + $this->orderItem->expects($this->any())->method('getOrderItem')->will($this->returnSelf()); + $this->orderItem->expects($this->any())->method('getParentItem')->will($this->returnValue($parentItem)); + $this->orderItem->expects($this->any())->method('getProductOptions')->will($this->returnValue($productOptions)); + + $this->assertSame($result, $this->model->canShowPriceInfo($this->orderItem)); + } + + public function canShowPriceInfoDataProvider() + { + return [ + [true, ['product_calculations' => 0], true], + [false, [], true], + [false, ['product_calculations' => 0], false], + ]; + } +} diff --git a/dev/tests/unit/testsuite/Magento/Bundle/Service/V1/Product/Link/ReadServiceTest.php b/dev/tests/unit/testsuite/Magento/Bundle/Service/V1/Product/Link/ReadServiceTest.php new file mode 100644 index 0000000000000000000000000000000000000000..2f262ccd0ac3e7234658da5bac5dbc7eb10e8a5c --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Bundle/Service/V1/Product/Link/ReadServiceTest.php @@ -0,0 +1,194 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Bundle\Service\V1\Product\Link; + + +use Magento\TestFramework\Helper\ObjectManager; + +class ReadServiceTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Bundle\Service\V1\Product\Link\ReadService + */ + private $model; + + /** + * @var \Magento\Catalog\Model\ProductRepository|\PHPUnit_Framework_MockObject_MockObject + */ + private $productRepository; + + /** + * @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject + */ + private $product; + + /** + * @var \Magento\Bundle\Service\V1\Data\Product\Link\MetadataConverter|\PHPUnit_Framework_MockObject_MockObject + */ + private $metadataConverter; + + /** + * @var \Magento\Bundle\Model\Product\Type\Interceptor|\PHPUnit_Framework_MockObject_MockObject + */ + private $productType; + + /** + * @var \Magento\Bundle\Model\Resource\Option\Collection|\PHPUnit_Framework_MockObject_MockObject + */ + private $optionCollection; + + /** + * @var \Magento\Bundle\Model\Resource\Selection\Collection|\PHPUnit_Framework_MockObject_MockObject + */ + private $selectionCollection; + + /** + * @var \Magento\Bundle\Model\Option|\PHPUnit_Framework_MockObject_MockObject + */ + private $option; + + /** + * @var \Magento\Bundle\Service\V1\Data\Product\Link\Metadata|\PHPUnit_Framework_MockObject_MockObject + */ + private $metadata; + + private $storeId = 2; + + private $optionIds = [1, 2, 3]; + + protected function setUp() + { + $helper = new ObjectManager($this); + + $this->productRepository = $this->getMockBuilder('Magento\Catalog\Model\ProductRepository') + ->setMethods(['get']) + ->disableOriginalConstructor() + ->getMock(); + + $this->productType = $this->getMockBuilder('Magento\Bundle\Model\Product\Type\Interceptor') + ->setMethods(['getOptionsCollection', 'setStoreFilter', 'getSelectionsCollection', 'getOptionsIds']) + ->disableOriginalConstructor() + ->getMock(); + + $this->option = $this->getMockBuilder('Magento\Bundle\Model\Option') + ->setMethods(['getSelections', '__wakeup']) + ->disableOriginalConstructor() + ->getMock(); + + $this->optionCollection = $this->getMockBuilder('Magento\Bundle\Model\Resource\Option\Collection') + ->setMethods(['appendSelections']) + ->disableOriginalConstructor() + ->getMock(); + + $this->selectionCollection = $this->getMockBuilder('Magento\Bundle\Model\Resource\Selection\Collection') + ->disableOriginalConstructor() + ->getMock(); + + $this->product = $this->getMockBuilder('Magento\Catalog\Model\Product') + ->setMethods(['getTypeInstance', 'getStoreId', 'getTypeId', '__wakeup']) + ->disableOriginalConstructor() + ->getMock(); + + $this->metadata = $this->getMockBuilder('Magento\Bundle\Service\V1\Data\Product\Link\Metadata') + ->disableOriginalConstructor() + ->getMock(); + + $this->metadataConverter = $this->getMockBuilder( + 'Magento\Bundle\Service\V1\Data\Product\Link\MetadataConverter' + ) + ->setMethods(['createDataFromModel']) + ->disableOriginalConstructor() + ->getMock(); + + $this->model = $helper->getObject( + 'Magento\Bundle\Service\V1\Product\Link\ReadService', + [ + 'productRepository' => $this->productRepository, + 'metadataConverter' => $this->metadataConverter + ] + ); + } + + public function testGetChildren() + { + $productSku = 'productSku'; + + $this->getOptions(); + + $this->productRepository->expects($this->any())->method('get')->with($this->equalTo($productSku)) + ->will($this->returnValue($this->product)); + + $this->product->expects($this->once())->method('getTypeId')->will($this->returnValue('bundle')); + + $this->productType->expects($this->once())->method('setStoreFilter')->with( + $this->equalTo($this->storeId), + $this->product + ); + $this->productType->expects($this->once())->method('getSelectionsCollection') + ->with($this->equalTo($this->optionIds), $this->equalTo($this->product)) + ->will($this->returnValue($this->selectionCollection)); + $this->productType->expects($this->once())->method('getOptionsIds')->with($this->equalTo($this->product)) + ->will($this->returnValue($this->optionIds)); + + $this->optionCollection->expects($this->once())->method('appendSelections') + ->with($this->equalTo($this->selectionCollection)) + ->will($this->returnValue([$this->option])); + + $this->option->expects($this->any())->method('getSelections')->will($this->returnValue([$this->product])); + + $this->metadataConverter->expects($this->once())->method('createDataFromModel') + ->with($this->equalTo($this->product), $this->equalTo($this->product)) + ->will($this->returnValue($this->metadata)); + + $this->assertEquals([$this->metadata], $this->model->getChildren($productSku)); + } + + /** + * @expectedException \Magento\Webapi\Exception + * @expectedExceptionCode 403 + */ + public function testGetChildrenException() + { + $productSku = 'productSku'; + + $this->productRepository->expects($this->once())->method('get')->with($this->equalTo($productSku)) + ->will($this->returnValue($this->product)); + + $this->product->expects($this->once())->method('getTypeId')->will($this->returnValue('simple')); + + $this->assertEquals([$this->metadata], $this->model->getChildren($productSku)); + } + + private function getOptions() + { + $this->product->expects($this->once())->method('getStoreId')->will($this->returnValue($this->storeId)); + $this->product->expects($this->any())->method('getTypeInstance')->will($this->returnValue($this->productType)); + + $this->productType->expects($this->once())->method('setStoreFilter') + ->with($this->equalTo($this->storeId), $this->equalTo($this->product)); + $this->productType->expects($this->once())->method('getOptionsCollection') + ->with($this->equalTo($this->product)) + ->will($this->returnValue($this->optionCollection)); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Bundle/Service/V1/Product/Link/WriteServiceTest.php b/dev/tests/unit/testsuite/Magento/Bundle/Service/V1/Product/Link/WriteServiceTest.php new file mode 100644 index 0000000000000000000000000000000000000000..58dcca446fcb9496cdde0b302aff52b3a4e607c2 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Bundle/Service/V1/Product/Link/WriteServiceTest.php @@ -0,0 +1,626 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Bundle\Service\V1\Product\Link; + +class WriteServiceTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var WriteService + */ + protected $service; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Catalog\Model\ProductRepository + */ + protected $productRepositoryMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Bundle\Model\SelectionFactory + */ + protected $bundleSelectionMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Bundle\Model\Resource\BundleFactory + */ + protected $bundleFactoryMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Bundle\Model\Resource\Option\CollectionFactory + */ + protected $optionCollectionFactoryMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Store\Model\StoreManagerInterface + */ + protected $storeManagerMock; + + /** + * @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject + */ + private $product; + + /** + * @var \Magento\Bundle\Model\Product\Type\Interceptor|\PHPUnit_Framework_MockObject_MockObject + */ + private $productType; + + /** + * @var \Magento\Bundle\Model\Resource\Option\Collection|\PHPUnit_Framework_MockObject_MockObject + */ + private $optionCollection; + + /** + * @var \Magento\Bundle\Model\Option|\PHPUnit_Framework_MockObject_MockObject + */ + private $option; + + protected function setUp() + { + $helper = new \Magento\TestFramework\Helper\ObjectManager($this); + + $this->productRepositoryMock = $this->getMock( + '\Magento\Catalog\Model\ProductRepository', array(), array(), '', false + ); + + $this->bundleSelectionMock = $this->getMock( + '\Magento\Bundle\Model\SelectionFactory', array('create'), array(), '', false + ); + + $this->bundleFactoryMock = $this->getMock( + '\Magento\Bundle\Model\Resource\BundleFactory', array('create'), array(), '', false + ); + + $this->optionCollectionFactoryMock = $this->getMock( + '\Magento\Bundle\Model\Resource\Option\CollectionFactory', array('create'), array(), '', false + ); + + $this->storeManagerMock = $this->getMock( + '\Magento\Store\Model\StoreManagerInterface', array(), array(), '', false + ); + + $this->product = $this->getMockBuilder('Magento\Catalog\Model\Product') + ->setMethods(['getTypeInstance', 'getStoreId', 'getTypeId', 'getId', '__wakeup']) + ->disableOriginalConstructor() + ->getMock(); + + $this->productType = $this->getMockBuilder('Magento\Bundle\Model\Product\Type\Interceptor') + ->setMethods(['getOptionsCollection', 'setStoreFilter', 'getSelectionsCollection', 'getOptionsIds']) + ->disableOriginalConstructor() + ->getMock(); + + $this->option = $this->getMockBuilder('Magento\Bundle\Model\Option') + ->setMethods(['getSelections', '__wakeup']) + ->disableOriginalConstructor() + ->getMock(); + + $this->optionCollection = $this->getMockBuilder('Magento\Bundle\Model\Resource\Option\Collection') + ->setMethods(['appendSelections']) + ->disableOriginalConstructor() + ->getMock(); + + $this->service = $helper->getObject('Magento\Bundle\Service\V1\Product\Link\WriteService', + [ + 'productRepository' => $this->productRepositoryMock, + 'bundleSelection' => $this->bundleSelectionMock, + 'bundleFactory' => $this->bundleFactoryMock, + 'optionCollection' => $this->optionCollectionFactoryMock, + 'storeManager' => $this->storeManagerMock + ] + ); + } + + /** + * @expectedException \Magento\Framework\Exception\InputException + */ + public function testAddChildToNotBundleProduct() + { + $productLink = $this->getMock( + 'Magento\Bundle\Service\V1\Product\Link\Data\ProductLink', array(), array(), '', false + ); + + $productMock = $this->getMock('\Magento\Catalog\Model\Product', array(), array(), '', false); + $productMock->expects($this->once())->method('getTypeId')->will($this->returnValue( + \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE + )); + $this->productRepositoryMock + ->expects($this->once()) + ->method('get') + ->with('product_sku') + ->will($this->returnValue($productMock)); + $this->service->addChild('product_sku', 1, $productLink); + } + + /** + * @expectedException \Magento\Framework\Exception\InputException + */ + public function testAddChildNonExistingOption() + { + $productLink = $this->getMock( + 'Magento\Bundle\Service\V1\Product\Link\Data\ProductLink', array(), array(), '', false + ); + + $productMock = $this->getMock('\Magento\Catalog\Model\Product', array(), array(), '', false); + $productMock->expects($this->once())->method('getTypeId')->will($this->returnValue( + \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE + )); + $productMock->expects($this->once())->method('getId')->will($this->returnValue('product_id')); + $this->productRepositoryMock + ->expects($this->once()) + ->method('get') + ->with('product_sku') + ->will($this->returnValue($productMock)); + + $store = $this->getMock('\Magento\Store\Model\Store', array(), array(), '', false); + $this->storeManagerMock->expects($this->any())->method('getStore')->will($this->returnValue($store)); + $store->expects($this->any())->method('getId')->will($this->returnValue(0)); + + $option = $this->getMockBuilder('\Magento\Bundle\Model\Option')->disableOriginalConstructor() + ->setMethods(['getOptionId', '__wakeup']) + ->getMock(); + $option->expects($this->once())->method('getOptionId')->will($this->returnValue(2)); + + $optionsCollectionMock = $this->getMock( + '\Magento\Bundle\Model\Resource\Option\Collection', array(), array(), '', false + ); + $optionsCollectionMock->expects($this->once()) + ->method('setProductIdFilter') + ->with($this->equalTo('product_id')) + ->will($this->returnSelf()); + $optionsCollectionMock->expects($this->once()) + ->method('joinValues') + ->with($this->equalTo(0)) + ->will($this->returnSelf()); + $optionsCollectionMock->expects($this->any())->method('getIterator')->will( + $this->returnValue(new \ArrayIterator([$option])) + ); + $this->optionCollectionFactoryMock->expects($this->any())->method('create')->will( + $this->returnValue($optionsCollectionMock) + ); + $this->service->addChild('product_sku', 1, $productLink); + } + + /** + * @expectedException \Magento\Framework\Exception\InputException + * @expectedExceptionMessage Bundle product could not contain another composite product + */ + public function testAddChildLinkedProductIsComposite() + { + $productLink = $this->getMock( + 'Magento\Bundle\Service\V1\Product\Link\Data\ProductLink', array(), array(), '', false + ); + $productLink->expects($this->any())->method('getSku')->will($this->returnValue('linked_product_sku')); + + $productMock = $this->getMock('\Magento\Catalog\Model\Product', array(), array(), '', false); + $productMock->expects($this->once())->method('getTypeId')->will($this->returnValue( + \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE + )); + $productMock->expects($this->any())->method('getId')->will($this->returnValue('product_id')); + + $linkedProductMock = $this->getMock('\Magento\Catalog\Model\Product', array(), array(), '', false); + $linkedProductMock->expects($this->any())->method('getId')->will($this->returnValue(13)); + $linkedProductMock->expects($this->once())->method('isComposite')->will($this->returnValue(true)); + $this->productRepositoryMock + ->expects($this->at(0)) + ->method('get') + ->with('product_sku') + ->will($this->returnValue($productMock)); + $this->productRepositoryMock + ->expects($this->at(1)) + ->method('get') + ->with('linked_product_sku') + ->will($this->returnValue($linkedProductMock)); + + $store = $this->getMock('\Magento\Store\Model\Store', array(), array(), '', false); + $this->storeManagerMock->expects($this->any())->method('getStore')->will($this->returnValue($store)); + $store->expects($this->any())->method('getId')->will($this->returnValue(0)); + + $option = $this->getMockBuilder('\Magento\Bundle\Model\Option')->disableOriginalConstructor() + ->setMethods(['getOptionId', '__wakeup']) + ->getMock(); + $option->expects($this->once())->method('getOptionId')->will($this->returnValue(1)); + + $optionsCollectionMock = $this->getMock( + '\Magento\Bundle\Model\Resource\Option\Collection', array(), array(), '', false + ); + $optionsCollectionMock->expects($this->once()) + ->method('setProductIdFilter') + ->with($this->equalTo('product_id')) + ->will($this->returnSelf()); + $optionsCollectionMock->expects($this->once()) + ->method('joinValues') + ->with($this->equalTo(0)) + ->will($this->returnSelf()); + $optionsCollectionMock->expects($this->any())->method('getIterator')->will( + $this->returnValue(new \ArrayIterator([$option])) + ); + $this->optionCollectionFactoryMock->expects($this->any())->method('create')->will( + $this->returnValue($optionsCollectionMock) + ); + + $bundle = $this->getMock('\Magento\Bundle\Model\Resource\Bundle', array(), array(), '', false); + $bundle->expects($this->once())->method('getSelectionsData') + ->with('product_id') + ->will($this->returnValue([])); + $this->bundleFactoryMock->expects($this->once())->method('create')->will($this->returnValue($bundle)); + + $this->service->addChild('product_sku', 1, $productLink); + } + + /** + * @expectedException \Magento\Framework\Exception\CouldNotSaveException + */ + public function testAddChildProductAlreadyExistsInOption() + { + $productLink = $this->getMock( + 'Magento\Bundle\Service\V1\Product\Link\Data\ProductLink', array(), array(), '', false + ); + $productLink->expects($this->any())->method('getSku')->will($this->returnValue('linked_product_sku')); + + $productMock = $this->getMock('\Magento\Catalog\Model\Product', array(), array(), '', false); + $productMock->expects($this->once())->method('getTypeId')->will($this->returnValue( + \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE + )); + $productMock->expects($this->any())->method('getId')->will($this->returnValue('product_id')); + + $linkedProductMock = $this->getMock('\Magento\Catalog\Model\Product', array(), array(), '', false); + $linkedProductMock->expects($this->any())->method('getId')->will($this->returnValue(13)); + $linkedProductMock->expects($this->once())->method('isComposite')->will($this->returnValue(false)); + $this->productRepositoryMock + ->expects($this->at(0)) + ->method('get') + ->with('product_sku') + ->will($this->returnValue($productMock)); + $this->productRepositoryMock + ->expects($this->at(1)) + ->method('get') + ->with('linked_product_sku') + ->will($this->returnValue($linkedProductMock)); + + $store = $this->getMock('\Magento\Store\Model\Store', array(), array(), '', false); + $this->storeManagerMock->expects($this->any())->method('getStore')->will($this->returnValue($store)); + $store->expects($this->any())->method('getId')->will($this->returnValue(0)); + + $option = $this->getMockBuilder('\Magento\Bundle\Model\Option')->disableOriginalConstructor() + ->setMethods(['getOptionId', '__wakeup']) + ->getMock(); + $option->expects($this->once())->method('getOptionId')->will($this->returnValue(1)); + + $optionsCollectionMock = $this->getMock( + '\Magento\Bundle\Model\Resource\Option\Collection', array(), array(), '', false + ); + $optionsCollectionMock->expects($this->once()) + ->method('setProductIdFilter') + ->with($this->equalTo('product_id')) + ->will($this->returnSelf()); + $optionsCollectionMock->expects($this->once()) + ->method('joinValues') + ->with($this->equalTo(0)) + ->will($this->returnSelf()); + $optionsCollectionMock->expects($this->any())->method('getIterator')->will( + $this->returnValue(new \ArrayIterator([$option])) + ); + $this->optionCollectionFactoryMock->expects($this->any())->method('create')->will( + $this->returnValue($optionsCollectionMock) + ); + + $selections = [ + ['option_id' => 1, 'product_id' => 12], + ['option_id' => 1, 'product_id' => 13], + ]; + $bundle = $this->getMock('\Magento\Bundle\Model\Resource\Bundle', array(), array(), '', false); + $bundle->expects($this->once())->method('getSelectionsData') + ->with('product_id') + ->will($this->returnValue($selections)); + $this->bundleFactoryMock->expects($this->once())->method('create')->will($this->returnValue($bundle)); + + $this->service->addChild('product_sku', 1, $productLink); + } + + /** + * @expectedException \Magento\Framework\Exception\CouldNotSaveException + */ + public function testAddChildCouldNotSave() + { + $productLink = $this->getMock( + 'Magento\Bundle\Service\V1\Product\Link\Data\ProductLink', array(), array(), '', false + ); + $productLink->expects($this->any())->method('getSku')->will($this->returnValue('linked_product_sku')); + + $productMock = $this->getMock('\Magento\Catalog\Model\Product', array(), array(), '', false); + $productMock->expects($this->once())->method('getTypeId')->will($this->returnValue( + \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE + )); + $productMock->expects($this->any())->method('getId')->will($this->returnValue('product_id')); + + $linkedProductMock = $this->getMock('\Magento\Catalog\Model\Product', array(), array(), '', false); + $linkedProductMock->expects($this->any())->method('getId')->will($this->returnValue(13)); + $linkedProductMock->expects($this->once())->method('isComposite')->will($this->returnValue(false)); + $this->productRepositoryMock + ->expects($this->at(0)) + ->method('get') + ->with('product_sku') + ->will($this->returnValue($productMock)); + $this->productRepositoryMock + ->expects($this->at(1)) + ->method('get') + ->with('linked_product_sku') + ->will($this->returnValue($linkedProductMock)); + + $store = $this->getMock('\Magento\Store\Model\Store', array(), array(), '', false); + $this->storeManagerMock->expects($this->any())->method('getStore')->will($this->returnValue($store)); + $store->expects($this->any())->method('getId')->will($this->returnValue(0)); + + $option = $this->getMockBuilder('\Magento\Bundle\Model\Option')->disableOriginalConstructor() + ->setMethods(['getOptionId', '__wakeup']) + ->getMock(); + $option->expects($this->once())->method('getOptionId')->will($this->returnValue(1)); + + $optionsCollectionMock = $this->getMock( + '\Magento\Bundle\Model\Resource\Option\Collection', array(), array(), '', false + ); + $optionsCollectionMock->expects($this->once()) + ->method('setProductIdFilter') + ->with($this->equalTo('product_id')) + ->will($this->returnSelf()); + $optionsCollectionMock->expects($this->once()) + ->method('joinValues') + ->with($this->equalTo(0)) + ->will($this->returnSelf()); + $optionsCollectionMock->expects($this->any())->method('getIterator')->will( + $this->returnValue(new \ArrayIterator([$option])) + ); + $this->optionCollectionFactoryMock->expects($this->any())->method('create')->will( + $this->returnValue($optionsCollectionMock) + ); + + $selections = [ + ['option_id' => 1, 'product_id' => 11], + ['option_id' => 1, 'product_id' => 12], + ]; + $bundle = $this->getMock('\Magento\Bundle\Model\Resource\Bundle', array(), array(), '', false); + $bundle->expects($this->once())->method('getSelectionsData') + ->with('product_id') + ->will($this->returnValue($selections)); + $this->bundleFactoryMock->expects($this->once())->method('create')->will($this->returnValue($bundle)); + + $selection = $this->getMock('\Magento\Framework\Object', array('save'), array(), '', false); + $selection->expects($this->once())->method('save') + ->will( + $this->returnCallback( + function () { + throw new \Exception('message'); + } + ) + ); + $this->bundleSelectionMock->expects($this->once())->method('create')->will($this->returnValue($selection)); + $this->service->addChild('product_sku', 1, $productLink); + } + + public function testAddChild() + { + $productLink = $this->getMock( + 'Magento\Bundle\Service\V1\Product\Link\Data\ProductLink', array(), array(), '', false + ); + $productLink->expects($this->any())->method('getSku')->will($this->returnValue('linked_product_sku')); + + $productMock = $this->getMock('\Magento\Catalog\Model\Product', array(), array(), '', false); + $productMock->expects($this->once())->method('getTypeId')->will($this->returnValue( + \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE + )); + $productMock->expects($this->any())->method('getId')->will($this->returnValue('product_id')); + + $linkedProductMock = $this->getMock('\Magento\Catalog\Model\Product', array(), array(), '', false); + $linkedProductMock->expects($this->any())->method('getId')->will($this->returnValue(13)); + $linkedProductMock->expects($this->once())->method('isComposite')->will($this->returnValue(false)); + $this->productRepositoryMock + ->expects($this->at(0)) + ->method('get') + ->with('product_sku') + ->will($this->returnValue($productMock)); + $this->productRepositoryMock + ->expects($this->at(1)) + ->method('get') + ->with('linked_product_sku') + ->will($this->returnValue($linkedProductMock)); + + $store = $this->getMock('\Magento\Store\Model\Store', array(), array(), '', false); + $this->storeManagerMock->expects($this->any())->method('getStore')->will($this->returnValue($store)); + $store->expects($this->any())->method('getId')->will($this->returnValue(0)); + + $option = $this->getMockBuilder('\Magento\Bundle\Model\Option')->disableOriginalConstructor() + ->setMethods(['getOptionId', '__wakeup']) + ->getMock(); + $option->expects($this->once())->method('getOptionId')->will($this->returnValue(1)); + + $optionsCollectionMock = $this->getMock( + '\Magento\Bundle\Model\Resource\Option\Collection', array(), array(), '', false + ); + $optionsCollectionMock->expects($this->once()) + ->method('setProductIdFilter') + ->with($this->equalTo('product_id')) + ->will($this->returnSelf()); + $optionsCollectionMock->expects($this->once()) + ->method('joinValues') + ->with($this->equalTo(0)) + ->will($this->returnSelf()); + $optionsCollectionMock->expects($this->any())->method('getIterator')->will( + $this->returnValue(new \ArrayIterator([$option])) + ); + $this->optionCollectionFactoryMock->expects($this->any())->method('create')->will( + $this->returnValue($optionsCollectionMock) + ); + + $selections = [ + ['option_id' => 1, 'product_id' => 11], + ['option_id' => 1, 'product_id' => 12], + ]; + $bundle = $this->getMock('\Magento\Bundle\Model\Resource\Bundle', array(), array(), '', false); + $bundle->expects($this->once())->method('getSelectionsData') + ->with('product_id') + ->will($this->returnValue($selections)); + $this->bundleFactoryMock->expects($this->once())->method('create')->will($this->returnValue($bundle)); + + $selection = $this->getMock('\Magento\Framework\Object', array('save', 'getId'), array(), '', false); + $selection->expects($this->once())->method('save'); + $selection->expects($this->once())->method('getId')->will($this->returnValue(42)); + $this->bundleSelectionMock->expects($this->once())->method('create')->will($this->returnValue($selection)); + $result = $this->service->addChild('product_sku', 1, $productLink); + $this->assertEquals(42, $result); + } + + + public function testRemoveChild() + { + $this->productRepositoryMock->expects($this->any())->method('get')->will($this->returnValue($this->product)); + $bundle = $this->getMock('\Magento\Bundle\Model\Resource\Bundle', array(), array(), '', false); + $this->bundleFactoryMock->expects($this->once())->method('create')->will($this->returnValue($bundle)); + $productSku = 'productSku'; + $optionId = 1; + $childSku = 'childSku'; + + $this->product + ->expects($this->any()) + ->method('getTypeId') + ->will($this->returnValue(\Magento\Catalog\Model\Product\Type::TYPE_BUNDLE)); + + $this->getOptions(); + + $selection = $this->getMockBuilder('\Magento\Bundle\Model\Selection') + ->setMethods(['getSku', 'getOptionId', 'getSelectionId', 'getProductId', '__wakeup']) + ->disableOriginalConstructor() + ->getMock(); + $selection->expects($this->any())->method('getSku')->will($this->returnValue($childSku)); + $selection->expects($this->any())->method('getOptionId')->will($this->returnValue($optionId)); + $selection->expects($this->any())->method('getSelectionId')->will($this->returnValue(55)); + $selection->expects($this->any())->method('getProductId')->will($this->returnValue(1)); + + $this->option->expects($this->any())->method('getSelections')->will($this->returnValue([$selection])); + $this->product->expects($this->any())->method('getId')->will($this->returnValue(3)); + + $bundle->expects($this->once())->method('dropAllUnneededSelections')->with(3, array()); + $bundle->expects($this->once())->method('saveProductRelations')->with(3, array()); + $this->assertTrue($this->service->removeChild($productSku, $optionId, $childSku)); + } + + /** + * @expectedException \Magento\Webapi\Exception + * @expectedExceptionCode 403 + */ + public function testRemoveChildForbidden() + { + $this->productRepositoryMock->expects($this->any())->method('get')->will($this->returnValue($this->product)); + $productSku = 'productSku'; + $optionId = 1; + $childSku = 'childSku'; + + $this->product + ->expects($this->any()) + ->method('getTypeId') + ->will($this->returnValue(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE)); + + $this->service->removeChild($productSku, $optionId, $childSku); + } + + /** + * @expectedException \Magento\Framework\Exception\NoSuchEntityException + */ + public function testRemoveChildInvalidOptionId() + { + $this->productRepositoryMock->expects($this->any())->method('get')->will($this->returnValue($this->product)); + $productSku = 'productSku'; + $optionId = 1; + $childSku = 'childSku'; + + $this->product + ->expects($this->any()) + ->method('getTypeId') + ->will($this->returnValue(\Magento\Catalog\Model\Product\Type::TYPE_BUNDLE)); + + $this->getOptions(); + + $selection = $this->getMockBuilder('\Magento\Bundle\Model\Selection') + ->setMethods(['getSku', 'getOptionId', 'getSelectionId', 'getProductId', '__wakeup']) + ->disableOriginalConstructor() + ->getMock(); + $selection->expects($this->any())->method('getSku')->will($this->returnValue($childSku)); + $selection->expects($this->any())->method('getOptionId')->will($this->returnValue($optionId + 1)); + $selection->expects($this->any())->method('getSelectionId')->will($this->returnValue(55)); + $selection->expects($this->any())->method('getProductId')->will($this->returnValue(1)); + + $this->option->expects($this->any())->method('getSelections')->will($this->returnValue([$selection])); + $this->service->removeChild($productSku, $optionId, $childSku); + } + + /** + * @expectedException \Magento\Framework\Exception\NoSuchEntityException + */ + public function testRemoveChildInvalidChildSku() + { + $this->productRepositoryMock->expects($this->any())->method('get')->will($this->returnValue($this->product)); + $productSku = 'productSku'; + $optionId = 1; + $childSku = 'childSku'; + + $this->product + ->expects($this->any()) + ->method('getTypeId') + ->will($this->returnValue(\Magento\Catalog\Model\Product\Type::TYPE_BUNDLE)); + + $this->getOptions(); + + $selection = $this->getMockBuilder('\Magento\Bundle\Model\Selection') + ->setMethods(['getSku', 'getOptionId', 'getSelectionId', 'getProductId', '__wakeup']) + ->disableOriginalConstructor() + ->getMock(); + $selection->expects($this->any())->method('getSku')->will($this->returnValue($childSku . '_invalid')); + $selection->expects($this->any())->method('getOptionId')->will($this->returnValue($optionId)); + $selection->expects($this->any())->method('getSelectionId')->will($this->returnValue(55)); + $selection->expects($this->any())->method('getProductId')->will($this->returnValue(1)); + + $this->option->expects($this->any())->method('getSelections')->will($this->returnValue([$selection])); + $this->service->removeChild($productSku, $optionId, $childSku); + } + + public function getOptions() + { + $this->product->expects($this->any())->method('getTypeInstance')->will($this->returnValue($this->productType)); + $this->product->expects($this->once())->method('getStoreId')->will($this->returnValue(1)); + + $this->productType->expects($this->once())->method('setStoreFilter'); + $this->productType->expects($this->once())->method('getOptionsCollection') + ->with($this->equalTo($this->product)) + ->will($this->returnValue($this->optionCollection)); + + $this->productType->expects($this->once())->method('getOptionsIds')->with($this->equalTo($this->product)) + ->will($this->returnValue([1, 2, 3])); + + $this->productType->expects($this->once())->method('getSelectionsCollection') + ->will($this->returnValue([])); + + $this->optionCollection->expects($this->any())->method('appendSelections') + ->with($this->equalTo([])) + ->will($this->returnValue([$this->option])); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/ActionTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/ActionTest.php new file mode 100644 index 0000000000000000000000000000000000000000..b79481348a6413e3a9631cf520b5b5ac8e7ed55d --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/ActionTest.php @@ -0,0 +1,233 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Catalog\Model\Product; + +class ActionTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Catalog\Model\Product\Action + */ + protected $model; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $productWebsiteFactory; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $resource; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $productWebsite; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $indexIndexer; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $categoryIndexer; + + /** + * @var \Magento\Eav\Model\Config|\PHPUnit_Framework_MockObject_MockObject + */ + protected $eavConfig; + + /** + * @var \Magento\Catalog\Model\Resource\Eav\Attribute|\PHPUnit_Framework_MockObject_MockObject + */ + protected $eavAttribute; + + public function setUp() + { + $eventManagerMock = $this->getMock('Magento\Framework\Event\ManagerInterface'); + $this->productWebsiteFactory = $this->getMock( + '\Magento\Catalog\Model\Product\WebsiteFactory', + ['create'], + [], + '', + false + ); + $this->resource = $this->getMock( + '\Magento\Framework\Model\Resource\AbstractResource', + ['updateAttributes', '_getWriteAdapter', '_getReadAdapter', '_construct', 'getIdFieldName'], + [], + '', + false + ); + $this->productWebsite = $this->getMock( + '\Magento\Catalog\Model\Product\Website', + ['addProducts', 'removeProducts', '__wakeup'], + [], + '', + false + ); + $this->productWebsiteFactory + ->expects($this->any()) + ->method('create') + ->will($this->returnValue($this->productWebsite)); + $this->indexIndexer = $this->getMock( + '\Magento\Index\Model\Indexer', + ['processEntityAction', '__wakeup'], + [], + '', + false + ); + $this->categoryIndexer = $this->getMock( + '\Magento\Indexer\Model\Indexer', + ['getId', 'load', 'isScheduled', 'reindexList'], + [], + '', + false + ); + $this->eavConfig = $this->getMock( + '\Magento\Eav\Model\Config', + ['__wakeup', 'getAttribute'], + [], + '', + false + ); + $this->eavAttribute = $this->getMock( + '\Magento\Catalog\Model\Resource\Eav\Attribute', + ['__wakeup', 'isIndexable'], + [], + '', + false + ); + $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this); + $this->model = $objectManager->getObject( + '\Magento\Catalog\Model\Product\Action', + [ + 'eventDispatcher' => $eventManagerMock, + 'resource' => $this->resource, + 'productWebsiteFactory' => $this->productWebsiteFactory, + 'indexIndexer' => $this->indexIndexer, + 'categoryIndexer' => $this->categoryIndexer, + 'eavConfig' => $this->eavConfig + ] + ); + } + + public function testUpdateAttributes() + { + $productIds = [1, 2, 2, 4]; + $productIdsUnique = [0 => 1, 1 => 2, 3 => 4]; + $attrData = [1]; + $storeId = 1; + $this->resource + ->expects($this->any()) + ->method('updateAttributes') + ->with($productIds, $attrData, $storeId) + ->will($this->returnSelf()); + $this->indexIndexer + ->expects($this->any()) + ->method('processEntityAction') + ->with($this->model, 'catalog_product', 'mass_action'); + $this->categoryIndexer + ->expects($this->any()) + ->method('getId') + ->will($this->returnValue(false)); + $this->categoryIndexer + ->expects($this->any()) + ->method('load') + ->with('catalog_product_category') + ->will($this->returnSelf()); + $this->categoryIndexer + ->expects($this->any()) + ->method('isScheduled') + ->will($this->returnValue(false)); + $this->categoryIndexer + ->expects($this->any()) + ->method('reindexList') + ->will($this->returnValue($productIds)); + $this->eavConfig + ->expects($this->any()) + ->method('getAttribute') + ->will($this->returnValue($this->eavAttribute)); + $this->eavAttribute + ->expects($this->any()) + ->method('isIndexable') + ->will($this->returnValue(false)); + $this->assertEquals($this->model, $this->model->updateAttributes($productIds, $attrData, $storeId)); + $this->assertEquals($this->model->getDataByKey('product_ids'), $productIdsUnique); + $this->assertEquals($this->model->getDataByKey('attributes_data'), $attrData); + $this->assertEquals($this->model->getDataByKey('store_id'), $storeId); + } + + /** + * @param $type + * @param $methodName + * @dataProvider updateWebsitesDataProvider + */ + public function testUpdateWebsites($type, $methodName) + { + $productIds = [1, 2, 2, 4]; + $productIdsUnique = [0 => 1, 1 => 2, 3 => 4]; + $websiteIds = [1]; + $this->productWebsite + ->expects($this->any()) + ->method($methodName) + ->with($websiteIds, $productIds) + ->will($this->returnSelf()); + $this->indexIndexer + ->expects($this->any()) + ->method('processEntityAction') + ->with($this->model, 'catalog_product', 'mass_action'); + $this->categoryIndexer + ->expects($this->any()) + ->method('getId') + ->will($this->returnValue(false)); + $this->categoryIndexer + ->expects($this->any()) + ->method('load') + ->with('catalog_product_category') + ->will($this->returnSelf()); + $this->categoryIndexer + ->expects($this->any()) + ->method('isScheduled') + ->will($this->returnValue(false)); + $this->categoryIndexer + ->expects($this->any()) + ->method('reindexList') + ->will($this->returnValue($productIds)); + $this->model->updateWebsites($productIds, $websiteIds, $type); + $this->assertEquals($this->model->getDataByKey('product_ids'), $productIdsUnique); + $this->assertEquals($this->model->getDataByKey('website_ids'), $websiteIds); + $this->assertEquals($this->model->getDataByKey('action_type'), $type); + } + + public function updateWebsitesDataProvider() + { + return [ + ['$type' => 'add', '$methodName' => 'addProducts'], + ['$type' => 'remove', '$methodName' => 'removeProducts'] + ]; + } +} diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Attribute/Backend/MediaTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Attribute/Backend/MediaTest.php index 821ab44fee3ac603e8590fdd061fddc5de8f8018..1250a1a6254f800f7c513ada2a77518eb28cfcff 100644 --- a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Attribute/Backend/MediaTest.php +++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Attribute/Backend/MediaTest.php @@ -75,7 +75,8 @@ class MediaTest extends \PHPUnit_Framework_TestCase 'insertGallery', 'deleteGalleryValueInStore', 'insertGalleryValueInStore', - 'deleteGallery' + 'deleteGallery', + 'loadGallery' ], [], '', @@ -113,7 +114,7 @@ class MediaTest extends \PHPUnit_Framework_TestCase ); $this->dataObject = $this->getMockBuilder('Magento\Framework\Object') ->disableOriginalConstructor() - ->setMethods(['getIsDuplicate', 'isLockedAttribute']) + ->setMethods(['getIsDuplicate', 'isLockedAttribute', 'getMediaAttributes']) ->getMock(); } @@ -123,7 +124,7 @@ class MediaTest extends \PHPUnit_Framework_TestCase $attributeId = 345345; $attribute = $this->getMock( - 'Magento\Eav\Model\Entity\Attribute\AbstractAttribute', + 'Magento\Eav\Model\Entity\Attribute', ['getBackendTable', 'isStatic', 'getAttributeId', 'getName', '__wakeup'], [], '', @@ -259,4 +260,163 @@ class MediaTest extends \PHPUnit_Framework_TestCase $this->model->setAttribute($attributeMock); $this->assertNull($this->model->afterSave($this->dataObject)); } + + /** + * @dataProvider afterLoadDataProvider + * @param array $image + */ + public function testAfterLoad($image) + { + $attributeCode = 'attr_code'; + $attribute = $this->getMock( + 'Magento\Eav\Model\Entity\Attribute', + ['getAttributeCode', '__wakeup'], + [], + '', + false + ); + $attribute->expects($this->any())->method('getAttributeCode')->will($this->returnValue($attributeCode)); + $this->resourceModel->expects($this->any())->method('loadGallery')->will($this->returnValue([$image])); + + $this->model->setAttribute($attribute); + $this->model->afterLoad($this->dataObject); + $this->assertEquals([$image], $this->dataObject->getAttrCode('images')); + } + + public function afterLoadDataProvider() + { + return [ + [ + [ + 'label' => 'label_1', + 'position' => 'position_1', + 'disabled' => 'true' + ], + [ + 'label' => 'label_2', + 'position' => 'position_2', + 'disabled' => 'true' + ] + ], + [ + [ + 'label' => null, + 'position' => null, + 'disabled' => null + ], + [ + 'label' => null, + 'position' => null, + 'disabled' => null + ] + ] + ]; + } + + /** + * @dataProvider validateDataProvider + * @param bool $value + */ + public function testValidate($value) + { + $attributeCode = 'attr_code'; + $attribute = $this->getMock( + 'Magento\Eav\Model\Entity\Attribute', + ['getAttributeCode', 'getIsRequired', 'isValueEmpty', 'getIsUnique', 'getEntityType', '__wakeup'], + [], + '', + false + ); + $attributeEntity = $this->getMock( + '\Magento\Framework\Model\Resource\AbstractResourceAbstractEntity', + ['checkAttributeUniqueValue'] + ); + $attribute->expects($this->any())->method('getAttributeCode')->will($this->returnValue($attributeCode)); + $attribute->expects($this->any())->method('getIsRequired')->will($this->returnValue(true)); + $attribute->expects($this->any())->method('isValueEmpty')->will($this->returnValue($value)); + $attribute->expects($this->any())->method('getIsUnique')->will($this->returnValue(true)); + $attribute->expects($this->any())->method('getEntityType')->will($this->returnValue($attributeEntity)); + $attributeEntity->expects($this->any())->method('checkAttributeUniqueValue')->will($this->returnValue(true)); + + $this->model->setAttribute($attribute); + $this->dataObject->setData(['attr_code' => 'attribute data']); + $this->assertEquals(!$value, $this->model->validate($this->dataObject)); + } + + public function validateDataProvider() + { + return [ + [true], + [false] + ]; + } + + /** + * @dataProvider beforeSaveDataProvider + * @param array $value + */ + public function testBeforeSave($value) + { + $attributeCode = 'attr_code'; + $attribute = $this->getMock( + 'Magento\Eav\Model\Entity\Attribute', + ['getAttributeCode', 'getIsRequired', 'isValueEmpty', 'getIsUnique', 'getEntityType', '__wakeup'], + [], + '', + false + ); + $mediaAttributes = [ + 'image' => $attribute, + 'small_image' => $attribute, + 'thumbnail' => $attribute + ]; + $attribute->expects($this->any())->method('getAttributeCode')->will($this->returnValue($attributeCode)); + $this->dataObject->expects($this->any())->method('getIsDuplicate')->will($this->returnValue(false)); + $this->model->setAttribute($attribute); + $this->dataObject->setData(['attr_code' => ['images' => $value]]); + $this->dataObject->expects($this->any())->method('getMediaAttributes') + ->will(($this->returnValue($mediaAttributes))); + $this->model->beforeSave($this->dataObject); + foreach ($this->dataObject['attr_code']['images'] as $imageType => $imageData) { + if (isset($imageData['new_file'])) { + $value[$imageType]['file'] = $imageData['file']; + $value[$imageType]['new_file'] = $imageData['new_file']; + } + $this->assertEquals($value[$imageType], $imageData); + } + } + + public function beforeSaveDataProvider() + { + return [ + [ + [ + 'image_1' => [ + 'position' => '1', + 'file' => '/m/y/mydrawing1.jpg.tmp', + 'value_id' => '', + 'label' => 'image 1', + 'disableed' => '0', + 'removed' => '' + ], + 'image_2' => [ + 'position' => '1', + 'file' => '/m/y/mydrawing2.jpg.tmp', + 'value_id' => '', + 'label' => 'image 2', + 'disableed' => '0', + 'removed' => '' + ], + 'image_removed' => [ + 'position' => '1', + 'file' => '/m/y/mydrawing3.jpg.tmp', + 'value_id' => '', + 'label' => 'image 3', + 'disableed' => '0', + 'removed' => '1' + ] + ] + ] + ]; + } } diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Attribute/Source/InputtypeTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Attribute/Source/InputtypeTest.php new file mode 100644 index 0000000000000000000000000000000000000000..96c24b9627a52c071fd3bd4072226d86b5527448 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Attribute/Source/InputtypeTest.php @@ -0,0 +1,70 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Model\Product\Attribute\Source; + +use Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper; + +class InputtypeTest extends \PHPUnit_Framework_TestCase +{ + /** @var \Magento\Catalog\Model\Product\Attribute\Source\Inputtype */ + protected $inputtypeModel; + + /** @var ObjectManagerHelper */ + protected $objectManagerHelper; + + /** @var \Magento\Framework\Registry|\PHPUnit_Framework_MockObject_MockObject */ + protected $registry; + + protected function setUp() + { + $this->registry = $this->getMock('Magento\Framework\Registry'); + + $this->objectManagerHelper = new ObjectManagerHelper($this); + $this->inputtypeModel = $this->objectManagerHelper->getObject( + 'Magento\Catalog\Model\Product\Attribute\Source\Inputtype', + [ + 'coreRegistry' => $this->registry + ] + ); + } + + public function testToOptionArray() + { + $inputTypesSet = array( + array('value' => 'text', 'label' => 'Text Field'), + array('value' => 'textarea', 'label' => 'Text Area'), + array('value' => 'date', 'label' => 'Date'), + array('value' => 'boolean', 'label' => 'Yes/No'), + array('value' => 'multiselect', 'label' => 'Multiple Select'), + array('value' => 'select', 'label' => 'Dropdown'), + array('value' => 'price', 'label' => 'Price'), + array('value' => 'media_image', 'label' => 'Media Image') + ); + + $this->registry->expects($this->once())->method('registry'); + $this->registry->expects($this->once())->method('register'); + $this->assertEquals($inputTypesSet, $this->inputtypeModel->toOptionArray()); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Attribute/Source/LayoutTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Attribute/Source/LayoutTest.php new file mode 100644 index 0000000000000000000000000000000000000000..a8dc938f62d429a75082bf1ab8b20679ad489359 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Attribute/Source/LayoutTest.php @@ -0,0 +1,72 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Model\Product\Attribute\Source; + +use Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper; + +class LayoutTest extends \PHPUnit_Framework_TestCase +{ + /** @var \Magento\Catalog\Model\Product\Attribute\Source\Layout */ + protected $layoutModel; + + /** @var ObjectManagerHelper */ + protected $objectManagerHelper; + + /** @var \Magento\Theme\Model\Layout\Source\Layout|\PHPUnit_Framework_MockObject_MockObject */ + protected $layoutSourceModel; + + protected function setUp() + { + $this->layoutSourceModel = $this->getMock( + 'Magento\Theme\Model\Layout\Source\Layout', + array( + 'toOptionArray' + ), + array(), + '', + false + ); + + $this->objectManagerHelper = new ObjectManagerHelper($this); + $this->layoutModel = $this->objectManagerHelper->getObject( + 'Magento\Catalog\Model\Product\Attribute\Source\Layout', + array( + 'pageSourceLayout' => $this->layoutSourceModel + ) + ); + } + + public function testGetAllOptions() + { + $expectedOptions = array( + '0' => array('value' => '', 'label' => 'No layout updates'), + '1' => array('value' => 'option_value', 'label' => 'option_label') + ); + $this->layoutSourceModel->expects($this->once())->method('toOptionArray') + ->will($this->returnValue(array('0' => $expectedOptions['1']))); + $layoutOptions = $this->layoutModel->getAllOptions(); + $this->assertEquals($expectedOptions, $layoutOptions); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Attribute/Source/Msrp/Type/EnabledTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Attribute/Source/Msrp/Type/EnabledTest.php index 1f06fb62afb7a2564e28c9e3b81f219719959044..e0cf332202c6ee537b1c95819b3de74918aadbea 100644 --- a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Attribute/Source/Msrp/Type/EnabledTest.php +++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Attribute/Source/Msrp/Type/EnabledTest.php @@ -38,7 +38,7 @@ class EnabledTest extends \PHPUnit_Framework_TestCase $this->_model = $objectManager->getObject('Magento\Catalog\Model\Product\Attribute\Source\Msrp\Type\Enabled'); } - public function testGetFlatColums() + public function testGetFlatColumns() { $abstractAttributeMock = $this->getMock( '\Magento\Eav\Model\Entity\Attribute\AbstractAttribute', @@ -52,18 +52,18 @@ class EnabledTest extends \PHPUnit_Framework_TestCase $this->_model->setAttribute($abstractAttributeMock); - $flatColums = $this->_model->getFlatColums(); + $flatColumns = $this->_model->getFlatColumns(); - $this->assertTrue(is_array($flatColums), 'FlatColums must be an array value'); - $this->assertTrue(!empty($flatColums), 'FlatColums must be not empty'); - foreach ($flatColums as $result) { - $this->assertArrayHasKey('unsigned', $result, 'FlatColums must have "unsigned" column'); - $this->assertArrayHasKey('default', $result, 'FlatColums must have "default" column'); - $this->assertArrayHasKey('extra', $result, 'FlatColums must have "extra" column'); - $this->assertArrayHasKey('type', $result, 'FlatColums must have "type" column'); - $this->assertArrayHasKey('nullable', $result, 'FlatColums must have "nullable" column'); - $this->assertArrayHasKey('comment', $result, 'FlatColums must have "comment" column'); - $this->assertArrayHasKey('length', $result, 'FlatColums must have "length" column'); + $this->assertTrue(is_array($flatColumns), 'FlatColumns must be an array value'); + $this->assertTrue(!empty($flatColumns), 'FlatColumns must be not empty'); + foreach ($flatColumns as $result) { + $this->assertArrayHasKey('unsigned', $result, 'FlatColumns must have "unsigned" column'); + $this->assertArrayHasKey('default', $result, 'FlatColumns must have "default" column'); + $this->assertArrayHasKey('extra', $result, 'FlatColumns must have "extra" column'); + $this->assertArrayHasKey('type', $result, 'FlatColumns must have "type" column'); + $this->assertArrayHasKey('nullable', $result, 'FlatColumns must have "nullable" column'); + $this->assertArrayHasKey('comment', $result, 'FlatColumns must have "comment" column'); + $this->assertArrayHasKey('length', $result, 'FlatColumns must have "length" column'); } } } diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Attribute/Source/Msrp/Type/PriceTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Attribute/Source/Msrp/Type/PriceTest.php index 0295201caa55d10b2e507e3958fcbb1815fed0b9..cbef25f0bc895ccd8d58b3b1479249c57316e79d 100644 --- a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Attribute/Source/Msrp/Type/PriceTest.php +++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Attribute/Source/Msrp/Type/PriceTest.php @@ -38,7 +38,7 @@ class PriceTest extends \PHPUnit_Framework_TestCase $this->_model = $objectManager->getObject('Magento\Catalog\Model\Product\Attribute\Source\Msrp\Type\Price'); } - public function testGetFlatColums() + public function testGetFlatColumns() { $abstractAttributeMock = $this->getMock( '\Magento\Eav\Model\Entity\Attribute\AbstractAttribute', @@ -52,16 +52,16 @@ class PriceTest extends \PHPUnit_Framework_TestCase $this->_model->setAttribute($abstractAttributeMock); - $flatColums = $this->_model->getFlatColums(); + $flatColumns = $this->_model->getFlatColumns(); - $this->assertTrue(is_array($flatColums), 'FlatColums must be an array value'); - $this->assertTrue(!empty($flatColums), 'FlatColums must be not empty'); - foreach ($flatColums as $result) { - $this->assertArrayHasKey('unsigned', $result, 'FlatColums must have "unsigned" column'); - $this->assertArrayHasKey('default', $result, 'FlatColums must have "default" column'); - $this->assertArrayHasKey('extra', $result, 'FlatColums must have "extra" column'); - $this->assertArrayHasKey('type', $result, 'FlatColums must have "type" column'); - $this->assertArrayHasKey('nullable', $result, 'FlatColums must have "nullable" column'); + $this->assertTrue(is_array($flatColumns), 'FlatColumns must be an array value'); + $this->assertTrue(!empty($flatColumns), 'FlatColumns must be not empty'); + foreach ($flatColumns as $result) { + $this->assertArrayHasKey('unsigned', $result, 'FlatColumns must have "unsigned" column'); + $this->assertArrayHasKey('default', $result, 'FlatColumns must have "default" column'); + $this->assertArrayHasKey('extra', $result, 'FlatColumns must have "extra" column'); + $this->assertArrayHasKey('type', $result, 'FlatColumns must have "type" column'); + $this->assertArrayHasKey('nullable', $result, 'FlatColumns must have "nullable" column'); } } } diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Attribute/Source/StatusTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Attribute/Source/StatusTest.php new file mode 100644 index 0000000000000000000000000000000000000000..62df524b9b0fa61c3a71837d2bbb389b901d45fc --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Attribute/Source/StatusTest.php @@ -0,0 +1,171 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Model\Product\Attribute\Source; + +use Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper; + +class StatusTest extends \PHPUnit_Framework_TestCase +{ + /** @var \Magento\Catalog\Model\Product\Attribute\Source\Status */ + protected $status; + + /** @var ObjectManagerHelper */ + protected $objectManagerHelper; + + /** @var \Magento\Eav\Model\Entity\Collection\AbstractCollection|\PHPUnit_Framework_MockObject_MockObject */ + protected $collection; + + /** @var \Magento\Eav\Model\Entity\Attribute\AbstractAttribute|\PHPUnit_Framework_MockObject_MockObject */ + protected $attributeModel; + + /** @var \Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend|\PHPUnit_Framework_MockObject_MockObject */ + protected $backendAttributeModel; + + protected function setUp() + { + + $this->objectManagerHelper = new ObjectManagerHelper($this); + $this->collection = $this->getMock( + '\Magento\Catalog\Model\Resource\Product\Collection', + array( + '__wakeup', + 'getSelect', + 'joinLeft', + 'order', + 'getStoreId', + 'getConnection', + 'getCheckSql' + ), + array(), + '', + false + ); + $this->attributeModel = $this->getMock( + '\Magento\Catalog\Model\Entity\Attributee', + array( + '__wakeup', + 'getAttributeCode', + 'getBackend', + 'getId', + 'isScopeGlobal', + ), + array(), + '', + false + ); + $this->backendAttributeModel = $this->getMock( + '\Magento\Catalog\Model\Product\Attribute\Backend\Sku', array('__wakeup', 'getTable'), array(), '', false); + $this->status = $this->objectManagerHelper->getObject( + 'Magento\Catalog\Model\Product\Attribute\Source\Status' + ); + + $this->attributeModel->expects($this->any())->method('getAttribute') + ->will($this->returnSelf()); + $this->attributeModel->expects($this->any())->method('getAttributeCode') + ->will($this->returnValue('attribute_code')); + $this->attributeModel->expects($this->any())->method('getId') + ->will($this->returnValue('1')); + $this->attributeModel->expects($this->any())->method('getBackend') + ->will($this->returnValue($this->backendAttributeModel)); + $this->collection->expects($this->any())->method('getSelect') + ->will($this->returnSelf()); + $this->collection->expects($this->any())->method('joinLeft') + ->will($this->returnSelf()); + $this->backendAttributeModel->expects($this->any())->method('getTable') + ->will($this->returnValue('table_name')); + } + + public function testAddValueSortToCollectionGlobal() + { + + $this->attributeModel->expects($this->any())->method('isScopeGlobal') + ->will($this->returnValue(true)); + $this->collection->expects($this->once())->method('order')->with('attribute_code_t.value asc') + ->will($this->returnSelf()); + + $this->status->setAttribute($this->attributeModel); + $this->status->addValueSortToCollection($this->collection); + } + + public function testAddValueSortToCollectionNotGlobal() + { + $this->attributeModel->expects($this->any())->method('isScopeGlobal') + ->will($this->returnValue(false)); + + $this->collection->expects($this->once())->method('order')->with('check_sql asc') + ->will($this->returnSelf()); + $this->collection->expects($this->once())->method('getStoreId') + ->will($this->returnValue(1)); + $this->collection->expects($this->any())->method('getConnection') + ->will($this->returnSelf()); + $this->collection->expects($this->any())->method('getCheckSql') + ->will($this->returnValue('check_sql')); + + $this->status->setAttribute($this->attributeModel); + $this->status->addValueSortToCollection($this->collection); + } + + public function testGetVisibleStatusIds() + { + $this->assertEquals(array(0 => 1), $this->status->getVisibleStatusIds()); + } + + public function testGetSaleableStatusIds() + { + $this->assertEquals(array(0 => 1), $this->status->getSaleableStatusIds()); + } + + public function testGetOptionArray() + { + $this->assertEquals(array(1 => 'Enabled', 2 => 'Disabled'), $this->status->getOptionArray()); + } + + /** + * @dataProvider getOptionTextDataProvider + * @param string $text + * @param string $id + */ + public function testGetOptionText($text, $id) + { + $this->assertEquals($text, $this->status->getOptionText($id)); + } + + /** + * @return array + */ + public function getOptionTextDataProvider() + { + return array( + array( + 'text' => 'Enabled', + 'id' => '1' + ), + array( + 'text' => 'Disabled', + 'id' => '2' + ) + ); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/VisibilityTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/VisibilityTest.php index 0f1b303fe60103bbca16a835c33b6515113e58d3..07d1a7855ec36d80d6b01e0210e6549f58d6dbfc 100644 --- a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/VisibilityTest.php +++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/VisibilityTest.php @@ -38,7 +38,7 @@ class VisibilityTest extends \PHPUnit_Framework_TestCase $this->_model = $objectManager->getObject('Magento\Catalog\Model\Product\Visibility'); } - public function testGetFlatColums() + public function testGetFlatColumns() { $abstractAttributeMock = $this->getMock( '\Magento\Eav\Model\Entity\Attribute\AbstractAttribute', @@ -52,17 +52,17 @@ class VisibilityTest extends \PHPUnit_Framework_TestCase $this->_model->setAttribute($abstractAttributeMock); - $flatColums = $this->_model->getFlatColums(); + $flatColumns = $this->_model->getFlatColumns(); - $this->assertTrue(is_array($flatColums), 'FlatColums must be an array value'); - $this->assertTrue(!empty($flatColums), 'FlatColums must be not empty'); - foreach ($flatColums as $result) { - $this->assertArrayHasKey('unsigned', $result, 'FlatColums must have "unsigned" column'); - $this->assertArrayHasKey('default', $result, 'FlatColums must have "default" column'); - $this->assertArrayHasKey('extra', $result, 'FlatColums must have "extra" column'); - $this->assertArrayHasKey('type', $result, 'FlatColums must have "type" column'); - $this->assertArrayHasKey('nullable', $result, 'FlatColums must have "nullable" column'); - $this->assertArrayHasKey('comment', $result, 'FlatColums must have "comment" column'); + $this->assertTrue(is_array($flatColumns), 'FlatColumns must be an array value'); + $this->assertTrue(!empty($flatColumns), 'FlatColumns must be not empty'); + foreach ($flatColumns as $result) { + $this->assertArrayHasKey('unsigned', $result, 'FlatColumns must have "unsigned" column'); + $this->assertArrayHasKey('default', $result, 'FlatColumns must have "default" column'); + $this->assertArrayHasKey('extra', $result, 'FlatColumns must have "extra" column'); + $this->assertArrayHasKey('type', $result, 'FlatColumns must have "type" column'); + $this->assertArrayHasKey('nullable', $result, 'FlatColumns must have "nullable" column'); + $this->assertArrayHasKey('comment', $result, 'FlatColumns must have "comment" column'); } } } diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/ProductRepositoryTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/ProductRepositoryTest.php index b73e577eff08f56a71d7faaa13e2887803c3b5d1..bb769ece2d1e0e1e8b7e666d4e84e19ec448f656 100644 --- a/dev/tests/unit/testsuite/Magento/Catalog/Model/ProductRepositoryTest.php +++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/ProductRepositoryTest.php @@ -39,7 +39,11 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase protected function setUp() { $productFactoryMock = $this->getMock( - 'Magento\Catalog\Model\ProductFactory', array('create'), array(), '', false + 'Magento\Catalog\Model\ProductFactory', + array('create'), + array(), + '', + false ); $this->productMock = $this->getMock('Magento\Catalog\Model\Product', array(), array(), '', false); $productFactoryMock->expects($this->once())->method('create')->will($this->returnValue($this->productMock)); diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Data/ConverterTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Data/ConverterTest.php index bd29d60303e98d5cd65dc85b2349eac11b0fd8bd..2a403a9e9c5ecea984145e17cee4b4f120e29b89 100644 --- a/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Data/ConverterTest.php +++ b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Data/ConverterTest.php @@ -54,15 +54,29 @@ class ConverterTest extends \PHPUnit_Framework_TestCase $productModelMock = $this->getMockBuilder('\Magento\Catalog\Model\Product') ->disableOriginalConstructor() ->getMock(); - $attrCodes = ['sku', 'price', 'status', 'updatedAt', 'entity_id']; - $this->productBuilder->expects($this->once()) - ->method('getCustomAttributesCodes') - ->will($this->returnValue($attrCodes)); + + $attrMock = $this->getMockBuilder('\Magento\Catalog\Model\Resource\Eav\Attribute') + ->disableOriginalConstructor() + ->getMock(); + + $attrMock->expects($this->at(0))->method('getAttributeCode')->will($this->returnValue('sku')); + $attrMock->expects($this->at(1))->method('getAttributeCode')->will($this->returnValue('price')); + $attrMock->expects($this->at(2))->method('getAttributeCode')->will($this->returnValue('status')); + $attrMock->expects($this->at(3))->method('getAttributeCode')->will($this->returnValue('updatedAt')); + $attrMock->expects($this->at(4))->method('getAttributeCode')->will($this->returnValue('entity_id')); + $attrMock->expects($this->at(5))->method('getAttributeCode')->will($this->returnValue('store_id')); + + $attrList = [$attrMock, $attrMock, $attrMock, $attrMock, $attrMock, $attrMock]; + + $productModelMock->expects($this->once()) + ->method('getAttributes') + ->will($this->returnValue($attrList)); $attributes = [ ProductDataObject::SKU => ProductDataObject::SKU . 'value', ProductDataObject::PRICE => ProductDataObject::PRICE . 'value', - ProductDataObject::STATUS => ProductDataObject::STATUS . 'dataValue' + ProductDataObject::STATUS => ProductDataObject::STATUS . 'dataValue', + ProductDataObject::STORE_ID => ProductDataObject::STORE_ID . 'value' ]; $this->productBuilder->expects($this->once()) ->method('populateWithArray') @@ -84,10 +98,14 @@ class ConverterTest extends \PHPUnit_Framework_TestCase return null; } ); - $productModelMock->expects($this->exactly(count($attrCodes))) + $productModelMock->expects($this->exactly(count($attrList))) ->method('getDataUsingMethod') ->will($dataUsingMethodCallback); + $productModelMock->expects($this->once()) + ->method('getStoreId') + ->will($this->returnValue(ProductDataObject::STORE_ID . 'value')); + $dataCallback = $this->returnCallback( function ($attrCode) { if ($attrCode == 'status') { @@ -96,7 +114,7 @@ class ConverterTest extends \PHPUnit_Framework_TestCase return null; } ); - $productModelMock->expects($this->exactly(2)) + $productModelMock->expects($this->exactly(3)) ->method('getData') ->will($dataCallback); @@ -105,6 +123,7 @@ class ConverterTest extends \PHPUnit_Framework_TestCase $this->assertEquals(ProductDataObject::SKU . 'value', $productData->getSku()); $this->assertEquals(ProductDataObject::PRICE . 'value', $productData->getPrice()); $this->assertEquals(ProductDataObject::STATUS . 'dataValue', $productData->getStatus()); + $this->assertEquals(ProductDataObject::STORE_ID . 'value', $productData->getStoreId()); $this->assertEquals(null, $productData->getUpdatedAt()); } } diff --git a/dev/tests/unit/testsuite/Magento/CheckoutAgreements/Model/AgreementTest.php b/dev/tests/unit/testsuite/Magento/CheckoutAgreements/Model/AgreementTest.php new file mode 100644 index 0000000000000000000000000000000000000000..4dbdafbd74763a598d2feb8acc8b0dddd2098110 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/CheckoutAgreements/Model/AgreementTest.php @@ -0,0 +1,91 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\CheckoutAgreements\Model; + +class AgreementTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\CheckoutAgreements\Model\Agreement + */ + protected $model; + + protected function setUp() + { + $this->objectManager = new \Magento\TestFramework\Helper\ObjectManager($this); + $this->model = $this->objectManager->getObject('\Magento\CheckoutAgreements\Model\Agreement'); + } + + /** + * @covers \Magento\CheckoutAgreements\Model\Agreement::validateData + * + * @dataProvider validateDataDataProvider + * @param \Magento\Framework\Object $inputData + * @param array|bool $expectedResult + */ + public function testValidateData($inputData, $expectedResult) + { + $this->assertEquals($expectedResult, $this->model->validateData($inputData)); + } + + /** + * @return array + */ + public function validateDataDataProvider() + { + return [ + [ + 'inputData' => (new \Magento\Framework\Object())->setContentHeight('1px'), + 'expectedResult' => true + ], + [ + 'inputData' => (new \Magento\Framework\Object())->setContentHeight('1.1px'), + 'expectedResult' => true + ], + [ + 'inputData' => (new \Magento\Framework\Object())->setContentHeight('0.1in'), + 'expectedResult' => true + ], + [ + 'inputData' => (new \Magento\Framework\Object())->setContentHeight('5%'), + 'expectedResult' => true + ], + [ + 'inputData' => (new \Magento\Framework\Object())->setContentHeight('5'), + 'expectedResult' => true + ], + [ + 'inputData' => (new \Magento\Framework\Object())->setContentHeight('px'), + 'expectedResult' => [ + "Please input a valid CSS-height. For example 100px or 77pt or 20em or .5ex or 50%." + ] + ], + [ + 'inputData' => (new \Magento\Framework\Object())->setContentHeight('abracadabra'), + 'expectedResult' => [ + "Please input a valid CSS-height. For example 100px or 77pt or 20em or .5ex or 50%." + ] + ], + ]; + } +} diff --git a/dev/tests/unit/testsuite/Magento/Cms/Model/Resource/Block/Grid/CollectionTest.php b/dev/tests/unit/testsuite/Magento/Cms/Model/Resource/Block/Grid/CollectionTest.php new file mode 100644 index 0000000000000000000000000000000000000000..4f757d8e1f5bb377fb30385197a298cf538a2bd4 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Cms/Model/Resource/Block/Grid/CollectionTest.php @@ -0,0 +1,105 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Cms\Model\Resource\Block\Grid; + +class CollectionTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var Collection|\PHPUnit_Framework_MockObject_MockObject + */ + protected $collection; + + /** + * @var \Magento\Framework\DB\Select|\PHPUnit_Framework_MockObject_MockObject + */ + protected $select; + + protected function setUp() + { + $this->select = $this->getMockBuilder('Magento\Framework\DB\Select') + ->disableOriginalConstructor() + ->getMock(); + + $connection = $this->getMockBuilder('Magento\Framework\DB\Adapter\Pdo\Mysql') + ->disableOriginalConstructor() + ->getMock(); + $connection->expects($this->any()) + ->method('select') + ->will($this->returnValue($this->select)); + + $resource = $this->getMockBuilder('Magento\Framework\Model\Resource\Db\AbstractDb') + ->disableOriginalConstructor() + ->setMethods(['__wakeup', 'getReadConnection']) + ->getMockForAbstractClass(); + $resource->expects($this->any()) + ->method('getReadConnection') + ->will($this->returnValue($connection)); + + $objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this); + $arguments = $objectManagerHelper->getConstructArguments( + 'Magento\Cms\Model\Resource\Block\Grid\Collection', + ['resource' => $resource, 'connection' => $connection] + ); + + $this->collection = $this->getMockBuilder('Magento\Cms\Model\Resource\Block\Grid\Collection') + ->setConstructorArgs($arguments) + ->setMethods(['addFilter', '_translateCondition', 'getMainTable']) + ->getMock(); + } + + public function testAddFieldToFilterSore() + { + $storeId = 1; + $this->collection->expects($this->once()) + ->method('addFilter') + ->with( + $this->equalTo('store'), + $this->equalTo(array('in' => [$storeId])), + $this->equalTo('public') + ); + $this->collection->addFieldToFilter('store_id', $storeId); + } + + public function testAddFieldToFilter() + { + $field = 'title'; + $value = 'test_filter'; + $searchSql = 'sql query'; + + $this->collection->expects($this->once()) + ->method('_translateCondition') + ->with($field, $value) + ->will($this->returnValue($searchSql)); + + $this->select->expects($this->once()) + ->method('where') + ->with( + $this->equalTo($searchSql), + $this->equalTo(null), + $this->equalTo(\Magento\Framework\DB\Select::TYPE_CONDITION) + ); + + $this->collection->addFieldToFilter($field, $value); + } +} diff --git a/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Model/Product/Type/ConfigurableTest.php b/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Model/Product/Type/ConfigurableTest.php index 7912f69c35eb94858d06ca2e1ef7e7f4e9be80f5..ffc5ba421f75a8bf17c068d6777b3ae8267acc9e 100644 --- a/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Model/Product/Type/ConfigurableTest.php +++ b/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Model/Product/Type/ConfigurableTest.php @@ -31,7 +31,7 @@ namespace Magento\ConfigurableProduct\Model\Product\Type; class ConfigurableTest extends \PHPUnit_Framework_TestCase { /** - * @var \Magento\ConfigurableProduct\Model\Product\Type\Configurable + * @var Configurable */ protected $_model; @@ -50,6 +50,11 @@ class ConfigurableTest extends \PHPUnit_Framework_TestCase */ protected $_attributeCollectionFactory; + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $_productCollectionFactory; + /** * @var \Magento\TestFramework\Helper\ObjectManager */ @@ -90,9 +95,9 @@ class ConfigurableTest extends \PHPUnit_Framework_TestCase '', false ); - $productColFactory = $this->getMock( + $this->_productCollectionFactory = $this->getMock( 'Magento\ConfigurableProduct\Model\Resource\Product\Type\Configurable\Product\CollectionFactory', - array(), + array('create'), array(), '', false @@ -113,7 +118,7 @@ class ConfigurableTest extends \PHPUnit_Framework_TestCase 'attributeSetFactory' => $setFactoryMock, 'eavAttributeFactory' => $attributeFactoryMock, 'configurableAttributeFactory' => $this->_configurableAttributeFactoryMock, - 'productCollectionFactory' => $productColFactory, + 'productCollectionFactory' => $this->_productCollectionFactory, 'attributeCollectionFactory' => $this->_attributeCollectionFactory, 'eventManager' => $eventManager, 'coreData' => $coreDataMock, @@ -233,4 +238,56 @@ class ConfigurableTest extends \PHPUnit_Framework_TestCase $this->assertTrue($this->_model->canUseAttribute($attribute)); } -} + + public function testgetUsedProducts() + { + $attributeCollection = $this->getMockBuilder( + '\Magento\ConfigurableProduct\Model\Resource\Product\Type\Configurable\Attribute\Collection' + )->setMethods(['setProductFilter', 'addFieldToFilter', 'walk'])->disableOriginalConstructor() + ->getMock(); + $attributeCollection->expects($this->any())->method('setProductFilter')->will($this->returnSelf()); + $this->_attributeCollectionFactory->expects($this->any())->method('create') + ->will($this->returnValue($attributeCollection)); + $product = $this->getMockBuilder('\Magento\Catalog\Model\Product') + ->setMethods(['dataHasChangedFor', 'getConfigurableAttributesData', 'getStoreId', + 'getId', 'getData', 'hasData', 'getAssociatedProductIds', '__wakeup', '__sleep' + ])->disableOriginalConstructor() + ->getMock(); + $attributeData = [1 => [ + 'id' => 1, + 'code' => 'someattr', + 'attribute_id' => 111, + 'position' => 0, + 'label' => 'Some Super Attribute', + 'values' => [] + ]]; + $product->expects($this->any())->method('getConfigurableAttributesData') + ->will($this->returnValue($attributeData)); + $product->expects($this->any())->method('getStoreId')->will($this->returnValue(5)); + $product->expects($this->any())->method('getId')->will($this->returnValue(1)); + $product->expects($this->any())->method('getAssociatedProductIds')->will($this->returnValue([2])); + $product->expects($this->any())->method('hasData') + ->will($this->returnValueMap([ + ['_cache_instance_used_product_attribute_ids', 1], + ['_cache_instance_products', 0], + ['_cache_instance_configurable_attributes', 1], + ])); + $product->expects($this->any())->method('getData') + ->will($this->returnValue(1)); + $productCollection = $this->getMockBuilder( + 'Magento\ConfigurableProduct\Model\Resource\Product\Type\Configurable\Product\Collection' + )->setMethods( + ['setFlag', 'setProductFilter', 'addStoreFilter', 'addAttributeToSelect', 'addFilterByRequiredOptions', + 'setStoreId'] + )->disableOriginalConstructor() + ->getMock(); + $productCollection->expects($this->any())->method('addAttributeToSelect')->will($this->returnSelf()); + $productCollection->expects($this->any())->method('setProductFilter')->will($this->returnSelf()); + $productCollection->expects($this->any())->method('setFlag')->will($this->returnSelf()); + $productCollection->expects($this->any())->method('addFilterByRequiredOptions')->will($this->returnSelf()); + $productCollection->expects($this->any())->method('setStoreId')->with(5)->will($this->returnValue([])); + $this->_productCollectionFactory->expects($this->any())->method('create') + ->will($this->returnValue($productCollection)); + $this->_model->getUsedProducts($product); + } +} \ No newline at end of file diff --git a/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Service/V1/Product/Link/ReadServiceTest.php b/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Service/V1/Product/Link/ReadServiceTest.php new file mode 100644 index 0000000000000000000000000000000000000000..075de0e2d3b6a1d87873a491fdc20812c26f769f --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Service/V1/Product/Link/ReadServiceTest.php @@ -0,0 +1,120 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\ConfigurableProduct\Service\V1\Product\Link; + +class ReadServiceTest extends \PHPUnit_Framework_TestCase +{ + /** @var \Magento\Catalog\Model\ProductRepository|\PHPUnit_Framework_MockObject_MockObject */ + protected $productRepository; + /** @var \Magento\Catalog\Service\V1\Data\Converter|\PHPUnit_Framework_MockObject_MockObject */ + protected $productConverter; + /** @var \Magento\TestFramework\Helper\ObjectManager */ + protected $objectManagerHelper; + /** @var \Magento\ConfigurableProduct\Service\V1\Product\Link\ReadService */ + protected $object; + + public function setUp() + { + $this->productRepository = $this->getMockBuilder('Magento\\Catalog\\Model\\ProductRepository') + ->disableOriginalConstructor()->getMock(); + $this->productConverter = $this->getMockBuilder('Magento\\Catalog\\Service\\V1\\Data\\Converter') + ->disableOriginalConstructor() + ->getMock(); + + $this->objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this); + $this->object = $this->objectManagerHelper->getObject( + 'Magento\\ConfigurableProduct\\Service\\V1\\Product\\Link\\ReadService', + ['productRepository' => $this->productRepository, 'productConverter' => $this->productConverter] + ); + } + + public function testGetChildren() + { + $productId = 'sadasd'; + + $product = $this->getMockBuilder('Magento\Catalog\Model\Product') + ->disableOriginalConstructor() + ->getMock(); + + $productTypeInstance = $this->getMockBuilder('Magento\ConfigurableProduct\Model\Product\Type\Configurable') + ->disableOriginalConstructor() + ->getMock(); + + $product->expects($this->any())->method('getTypeId')->will( + $this->returnValue(\Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE) + ); + + $product->expects($this->any())->method('getTypeInstance')->will( + $this->returnValue($productTypeInstance) + ); + + $productTypeInstance->expects($this->once())->method('setStoreFilter') + ->with(null, $product); + + $childProduct = $this->getMockBuilder('Magento\Catalog\Model\Product') + ->disableOriginalConstructor() + ->getMock(); + + $productTypeInstance->expects($this->any())->method('getUsedProducts') + ->with($product)->will($this->returnValue([$childProduct])); + + $this->productRepository->expects($this->any()) + ->method('get')->with($productId) + ->will( + $this->returnValue($product) + ); + + $productDto = $this->getMockBuilder('Magento\Catalog\Service\V1\Data\Product') + ->disableOriginalConstructor() + ->getMock(); + + $this->productConverter->expects($this->any()) + ->method('createProductDataFromModel')->with($childProduct) + ->will( + $this->returnValue($productDto) + ); + + $products = $this->object->getChildren($productId); + $this->assertCount(1, $products); + $this->assertEquals($productDto, $products[0]); + } + + public function testGetChildrenException() + { + $product = $this->getMockBuilder('Magento\Catalog\Model\Product') + ->disableOriginalConstructor() + ->getMock(); + + $product->expects($this->any())->method('getTypeId')->will( + $this->returnValue('same') + ); + + $this->productRepository->expects($this->any()) + ->method('get')->with('sd') + ->will( + $this->returnValue($product) + ); + $this->assertCount(0, $this->object->getChildren('sd')); + } +} \ No newline at end of file diff --git a/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Service/V1/Product/Link/WriteServiceTest.php b/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Service/V1/Product/Link/WriteServiceTest.php new file mode 100644 index 0000000000000000000000000000000000000000..e2c582fbba3ed5b077fb5583bc1b0a9b16b973cd --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Service/V1/Product/Link/WriteServiceTest.php @@ -0,0 +1,189 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\ConfigurableProduct\Service\V1\Product\Link; + + +use Magento\TestFramework\Helper\ObjectManager; + +class WriteServiceTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\ConfigurableProduct\Service\V1\Product\Link\WriteService + */ + private $service; + + /** + * @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject + */ + private $product; + + /** + * @var \Magento\ConfigurableProduct\Model\Product\Type\Configurable|\PHPUnit_Framework_MockObject_MockObject + */ + private $productType; + + /** @var \Magento\Catalog\Model\ProductRepository|\PHPUnit_Framework_MockObject_MockObject */ + protected $productRepository; + + /** @var Configurable|\PHPUnit_Framework_MockObject_MockObject */ + protected $configurableType; + + protected function setUp() + { + $this->productType = $this->getMockBuilder('Magento\ConfigurableProduct\Model\Product\Type\Configurable') + ->setMethods(['getUsedProducts']) + ->disableOriginalConstructor() + ->getMock(); + + $this->product = $this->getMockBuilder('Magento\Catalog\Model\Product') + ->setMethods(['getTypeInstance', 'save', 'getTypeId', 'addData', '__wakeup']) + ->disableOriginalConstructor() + ->getMock(); + + $this->product + ->expects($this->any()) + ->method('getTypeInstance') + ->will($this->returnValue($this->productType)); + + $this->productRepository = $this->getMockBuilder('Magento\Catalog\Model\ProductRepository') + ->setMethods(['get']) + ->disableOriginalConstructor() + ->getMock(); + + $this->configurableType = + $this->getMockBuilder('Magento\\ConfigurableProduct\\Model\\Resource\\Product\\Type\\Configurable') + ->disableOriginalConstructor()->getMock(); + + $this->service = (new ObjectManager($this))->getObject( + 'Magento\ConfigurableProduct\Service\V1\Product\Link\WriteService', + [ + 'productRepository' => $this->productRepository, + 'configurableType' => $this->configurableType + ] + ); + } + + public function testRemoveChild() + { + $productSku = 'configurable'; + $childSku = 'simple_10'; + + $this->product + ->expects($this->any()) + ->method('getTypeId') + ->will($this->returnValue(\Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE)); + $this->productRepository->expects($this->any())->method('get')->will($this->returnValue($this->product)); + + $option = $this->getMockBuilder('\Magento\Catalog\Model\Product') + ->setMethods(['getSku', 'getId', '__wakeup']) + ->disableOriginalConstructor() + ->getMock(); + $option->expects($this->any())->method('getSku')->will($this->returnValue($childSku)); + $option->expects($this->any())->method('getId')->will($this->returnValue(10)); + $this->productType->expects($this->once())->method('getUsedProducts') + ->will($this->returnValue([$option])); + + $this->product->expects($this->once())->method('addData')->with(['associated_product_ids' => array()]); + $this->product->expects($this->once())->method('save'); + $this->assertTrue($this->service->removeChild($productSku, $childSku)); + } + + /** + * @expectedException \Magento\Webapi\Exception + * @expectedExceptionCode 403 + */ + public function testRemoveChildForbidden() + { + $productSku = 'configurable'; + $childSku = 'simple_10'; + + $this->product + ->expects($this->any()) + ->method('getTypeId') + ->will($this->returnValue(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE)); + $this->productRepository->expects($this->any())->method('get')->will($this->returnValue($this->product)); + $this->service->removeChild($productSku, $childSku); + } + + /** + * @expectedException \Magento\Framework\Exception\NoSuchEntityException + */ + public function testRemoveChildInvalidChildSku() + { + $productSku = 'configurable'; + $childSku = 'simple_10'; + + $this->product + ->expects($this->any()) + ->method('getTypeId') + ->will($this->returnValue(\Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE)); + $this->productRepository->expects($this->any())->method('get')->will($this->returnValue($this->product)); + + $option = $this->getMockBuilder('\Magento\Catalog\Model\Product') + ->setMethods(['getSku', 'getId', '__wakeup']) + ->disableOriginalConstructor() + ->getMock(); + $option->expects($this->any())->method('getSku')->will($this->returnValue($childSku . '_invalid')); + $option->expects($this->any())->method('getId')->will($this->returnValue(10)); + $this->productType->expects($this->once())->method('getUsedProducts') + ->will($this->returnValue([$option])); + + $this->service->removeChild($productSku, $childSku); + } + + public function testAddChild() + { + $productSku = 'configurable-sku'; + $childSku = 'simple-sku'; + + $configurable = $this->getMockBuilder('Magento\Catalog\Model\Product') + ->disableOriginalConstructor() + ->getMock(); + + $configurable->expects($this->any())->method('getId')->will($this->returnValue(666)); + + $simplee = $this->getMockBuilder('Magento\Catalog\Model\Product') + ->disableOriginalConstructor() + ->getMock(); + + $simplee->expects($this->any())->method('getId')->will($this->returnValue(999)); + + $this->productRepository->expects($this->at(0))->method('get')->with($productSku)->will( + $this->returnValue($configurable) + ); + + $this->productRepository->expects($this->at(1))->method('get')->with($childSku)->will( + $this->returnValue($simplee) + ); + + $this->configurableType->expects($this->once())->method('getChildrenIds')->with(666) + ->will( + $this->returnValue([0 => [1, 2, 3]]) + ); + $configurable->expects($this->once())->method('__call')->with('setAssociatedProductIds', [[1, 2, 3, 999]]); + $configurable->expects($this->once())->method('save'); + + $this->assertTrue(true, $this->service->addChild($productSku, $childSku)); + } +} diff --git a/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Service/V1/ReadServiceTest.php b/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Service/V1/ReadServiceTest.php new file mode 100644 index 0000000000000000000000000000000000000000..6e3c86f66799ea77e5bfcc32a39e4705e0459958 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Service/V1/ReadServiceTest.php @@ -0,0 +1,188 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\ConfigurableProduct\Service\V1; + +use Magento\Catalog\Service\V1\Data\Product; +use Magento\Catalog\Service\V1\Data\ProductBuilder; +use Magento\Catalog\Service\V1\Product\Attribute\ReadServiceInterface; +use Magento\ConfigurableProduct\Model\Product\Type\VariationMatrix; +use Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper; + +class ReadServiceTest extends \PHPUnit_Framework_TestCase +{ + /** @var ReadService */ + protected $object; + + /** @var ObjectManagerHelper */ + protected $objectManagerHelper; + + /** @var ReadServiceInterface|\PHPUnit_Framework_MockObject_MockObject */ + protected $attributeReadService; + + /** + * @var VariationMatrix|\PHPUnit_Framework_MockObject_MockObject + */ + private $variationMatrix; + + /** + * @var ProductBuilder|\PHPUnit_Framework_MockObject_MockObject + */ + private $productBuilder; + + protected function setUp() + { + $this->attributeReadService = $this->getMockBuilder( + 'Magento\Catalog\Service\V1\Product\Attribute\ReadServiceInterface' + )->disableOriginalConstructor()->getMock(); + + $this->variationMatrix = $this->getMockBuilder( + 'Magento\ConfigurableProduct\Model\Product\Type\VariationMatrix' + )->disableOriginalConstructor()->getMock(); + + $this->productBuilder = $this->getMockBuilder( + 'Magento\Catalog\Service\V1\Data\ProductBuilder' + )->disableOriginalConstructor()->getMock(); + + + $this->objectManagerHelper = new ObjectManagerHelper($this); + $this->object = $this->objectManagerHelper->getObject( + 'Magento\ConfigurableProduct\Service\V1\ReadService', + [ + 'attributeReadService' => $this->attributeReadService, + 'variationMatrix' => $this->variationMatrix, + 'productBuilder' => $this->productBuilder, + ] + ); + } + + /** + * @param array $configurableAttributeData + * @dataProvider productVariationDataProvider + */ + public function testGenerateVariation($configurableAttributeData) + { + $attributeCode = 'code'; + $attribute = $this->getMockBuilder('Magento\Catalog\Service\V1\Data\Eav\AttributeMetadata') + ->disableOriginalConstructor() + ->getMock(); + $attribute->expects($this->any()) + ->method('getAttributeCode') + ->will($this->returnValue($attributeCode)); + + + $this->attributeReadService->expects($this->once()) + ->method('info') + ->with($configurableAttributeData['attribute_id']) + ->will($this->returnValue($attribute)); + + $options = null; + $this->variationMatrix->expects($this->any()) + ->method('getVariations') + ->with( + [ + $configurableAttributeData['attribute_id'] => [ + "attribute_id" => $configurableAttributeData['attribute_id'], + "values" => $configurableAttributeData['values'], + "options" => $options, + "attribute_code" => $attributeCode, + ] + ] + ) + ->will( + $this->returnValue( + [ + [ + $configurableAttributeData['attribute_id'] => [ + 'value' => '14', + 'label' => 'dd', + 'price' => [ + 'value_index' => 14, + 'pricing_value' => 10, + ], + ], + ], + ] + ) + ); + + $product = $this->getMockBuilder('Magento\Catalog\Service\V1\Data\Product') + ->disableOriginalConstructor() + ->getMock(); + $product->expects($this->any()) + ->method('getPrice') + ->will($this->returnValue(100)); + + $configurableAttribute = $this->getMockBuilder( + 'Magento\ConfigurableProduct\Service\V1\Data\ConfigurableAttribute' + ) + ->disableOriginalConstructor() + ->getMock(); + $configurableAttribute->expects($this->any()) + ->method('__toArray') + ->will($this->returnValue($configurableAttributeData)); + $configurableAttribute->expects($this->any()) + ->method('getAttributeId') + ->will($this->returnValue($configurableAttributeData['attribute_id'])); + + $this->productBuilder->expects($this->any()) + ->method('populute') + ->with($product); + + $this->productBuilder->expects($this->once()) + ->method('setCustomAttribute') + ->with($attributeCode, 14); + $this->productBuilder->expects($this->once()) + ->method('setPrice') + ->with(110); + + $this->productBuilder->expects($this->once()) + ->method('create') + ->will($this->returnValue($product)); + + $result = $this->object->generateVariation($product, [$configurableAttribute]); + $this->assertCount(1, $result); + $this->assertEquals([$product], $result); + + } + + /** + * @return array + */ + public function productVariationDataProvider() + { + return [ + [ + [ + "attribute_id" => 174, + "values" => [ + [ + "index" => 14, + "price" => 100.0 + ] + ] + ] + ] + ]; + } +} diff --git a/dev/tests/unit/testsuite/Magento/Customer/Block/Adminhtml/From/Element/ImageTest.php b/dev/tests/unit/testsuite/Magento/Customer/Block/Adminhtml/From/Element/ImageTest.php new file mode 100644 index 0000000000000000000000000000000000000000..72bdfe972f4030c6144e71f018559d99ddcdc1c3 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Customer/Block/Adminhtml/From/Element/ImageTest.php @@ -0,0 +1,76 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Customer\Block\Adminhtml\From\Element; + +/** + * Test class for \Magento\Customer\Block\Adminhtml\From\Element\Image + */ +class ImageTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Customer\Block\Adminhtml\Form\Element\Image + */ + protected $image; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $backendHelperMock; + + protected function setUp() + { + $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this); + $this->backendHelperMock = $this->getMockBuilder('Magento\Backend\Helper\Data') + ->setMethods([]) + ->disableOriginalConstructor() + ->getMock(); + $this->image = $objectManager->getObject( + 'Magento\Customer\Block\Adminhtml\Form\Element\Image', + ['adminhtmlData' => $this->backendHelperMock] + ); + } + + public function testGetPreviewFile() + { + $value = 'image.jpg'; + $url = 'http://example.com/backend/customer/index/viewfile/' . $value; + $formMock = $this->getMockBuilder('Magento\Framework\Data\Form') + ->disableOriginalConstructor() + ->setMethods([]) + ->getMock(); + $this->image->setForm($formMock); + $this->image->setValue($value); + + $this->backendHelperMock->expects($this->once()) + ->method('urlEncode') + ->with($value) + ->will($this->returnArgument(0)); + $this->backendHelperMock->expects($this->once()) + ->method('getUrl') + ->with('customer/index/viewfile', ['image' => $value]) + ->will($this->returnValue($url)); + + $this->assertContains($url, $this->image->getElementHtml()); + } +} diff --git a/dev/tests/unit/testsuite/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/FirstEntranceTest.php b/dev/tests/unit/testsuite/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/FirstEntranceTest.php index 2fb597f357a1ec4a9393ccc45df65eb38f48e4d3..a6840d0e39fb18a47752ce4856e44f164ed342ae 100644 --- a/dev/tests/unit/testsuite/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/FirstEntranceTest.php +++ b/dev/tests/unit/testsuite/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/FirstEntranceTest.php @@ -32,16 +32,16 @@ class FirstEntranceTest extends \PHPUnit_Framework_TestCase /** * @var \Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor */ - protected $_model; + protected $model; /** * @var \PHPUnit_Framework_MockObject_MockObject */ - protected $_objectManagerMock; + protected $objectManagerMock; protected function setUp() { - $this->_objectManagerMock = $this->getMock('Magento\Framework\ObjectManager'); + $this->objectManagerMock = $this->getMock('Magento\Framework\ObjectManager'); $request = $this->getMock('Magento\Framework\App\Request\Http', array(), array(), '', false); $request->expects($this->any())->method('setActionName')->will($this->returnSelf()); @@ -70,10 +70,10 @@ class FirstEntranceTest extends \PHPUnit_Framework_TestCase $layoutMock->expects( $this->any() )->method( - 'getNode' - )->will( - $this->returnValue(new \Magento\Framework\Simplexml\Element('<root />')) - ); + 'getNode' + )->will( + $this->returnValue(new \Magento\Framework\Simplexml\Element('<root />')) + ); $blockMessage = $this->getMock( 'Magento\Framework\View\Element\Messages', array('addMessages', 'setEscapeMessageFlag', 'addStorageType'), @@ -100,7 +100,7 @@ class FirstEntranceTest extends \PHPUnit_Framework_TestCase 'Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor', array( 'request' => $request, - 'objectManager' => $this->_objectManagerMock, + 'objectManager' => $this->objectManagerMock, 'layout' => $layoutMock, 'invokeArgs' => array( 'helper' => $this->getMock('Magento\Backend\Helper\Data', array(), array(), '', false), @@ -109,7 +109,7 @@ class FirstEntranceTest extends \PHPUnit_Framework_TestCase ) ); - $this->_model = $objectManagerHelper->getObject( + $this->model = $objectManagerHelper->getObject( 'Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor\FirstEntrance', $constructArguments ); @@ -121,23 +121,23 @@ class FirstEntranceTest extends \PHPUnit_Framework_TestCase * @param int $countCustomization * @return \Magento\Core\Model\Resource\Theme\CollectionFactory */ - protected function _getThemeCollectionFactory($countCustomization) + protected function getThemeCollectionFactory($countCustomization) { $themeCollectionMock = $this->getMockBuilder( 'Magento\Core\Model\Resource\Theme\Collection' )->disableOriginalConstructor()->setMethods( - array('addTypeFilter', 'getSize') - )->getMock(); + array('addTypeFilter', 'getSize') + )->getMock(); $themeCollectionMock->expects( $this->once() )->method( - 'addTypeFilter' - )->with( - \Magento\Framework\View\Design\ThemeInterface::TYPE_VIRTUAL - )->will( - $this->returnValue($themeCollectionMock) - ); + 'addTypeFilter' + )->with( + \Magento\Framework\View\Design\ThemeInterface::TYPE_VIRTUAL + )->will( + $this->returnValue($themeCollectionMock) + ); $themeCollectionMock->expects($this->once())->method('getSize')->will($this->returnValue($countCustomization)); @@ -155,19 +155,18 @@ class FirstEntranceTest extends \PHPUnit_Framework_TestCase } /** - * @covers \Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor::firstEntranceAction * @dataProvider firstEntranceActionDataProvider */ public function testFirstEntranceAction($countCustomization) { - $this->_objectManagerMock->expects( + $this->objectManagerMock->expects( $this->any() )->method( - 'get' - )->will( - $this->returnValueMap($this->_getObjectManagerMap($countCustomization)) - ); - $this->assertNull($this->_model->execute()); + 'get' + )->will( + $this->returnValueMap($this->getObjectManagerMap($countCustomization)) + ); + $this->assertNull($this->model->execute()); } /** @@ -182,7 +181,7 @@ class FirstEntranceTest extends \PHPUnit_Framework_TestCase * @param int $countCustomization * @return array */ - protected function _getObjectManagerMap($countCustomization) + protected function getObjectManagerMap($countCustomization) { $translate = $this->getMock('Magento\Framework\TranslateInterface', array(), array(), '', false); $translate->expects($this->any())->method('translate')->will($this->returnSelf()); @@ -210,10 +209,10 @@ class FirstEntranceTest extends \PHPUnit_Framework_TestCase $backendSession->expects( $this->any() )->method( - 'getMessages' - )->will( - $this->returnValue($this->getMock('Magento\Framework\Message\Collection', array(), array(), '', false)) - ); + 'getMessages' + )->will( + $this->returnValue($this->getMock('Magento\Framework\Message\Collection', array(), array(), '', false)) + ); $inlineMock = $this->getMock('Magento\Framework\Translate\Inline', array(), array(), '', false); $aclFilterMock = $this->getMock('Magento\Backend\Model\Layout\Filter\Acl', array(), array(), '', false); @@ -221,7 +220,7 @@ class FirstEntranceTest extends \PHPUnit_Framework_TestCase return array( array( 'Magento\Core\Model\Resource\Theme\CollectionFactory', - $this->_getThemeCollectionFactory($countCustomization) + $this->getThemeCollectionFactory($countCustomization) ), array('Magento\Framework\TranslateInterface', $translate), array('Magento\Framework\App\Config\ScopeConfigInterface', $configMock), diff --git a/dev/tests/unit/testsuite/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/IndexTest.php b/dev/tests/unit/testsuite/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/IndexTest.php index cba4f9fe60233a8f38f6776eb7c5dbe5b8d05184..39372f5e57276815b0a6016402ff949c36b1bfbd 100644 --- a/dev/tests/unit/testsuite/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/IndexTest.php +++ b/dev/tests/unit/testsuite/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/IndexTest.php @@ -32,16 +32,16 @@ class IndexTest extends \PHPUnit_Framework_TestCase /** * @var \Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor */ - protected $_model; + protected $model; /** * @var \PHPUnit_Framework_MockObject_MockObject */ - protected $_objectManagerMock; + protected $objectManagerMock; protected function setUp() { - $this->_objectManagerMock = $this->getMock('Magento\Framework\ObjectManager'); + $this->objectManagerMock = $this->getMock('Magento\Framework\ObjectManager'); $request = $this->getMock('Magento\Framework\App\Request\Http', array(), array(), '', false); $request->expects($this->any())->method('setActionName')->will($this->returnSelf()); @@ -100,7 +100,7 @@ class IndexTest extends \PHPUnit_Framework_TestCase 'Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor', array( 'request' => $request, - 'objectManager' => $this->_objectManagerMock, + 'objectManager' => $this->objectManagerMock, 'layout' => $layoutMock, 'invokeArgs' => array( 'helper' => $this->getMock('Magento\Backend\Helper\Data', array(), array(), '', false), @@ -109,7 +109,7 @@ class IndexTest extends \PHPUnit_Framework_TestCase ) ); - $this->_model = $objectManagerHelper->getObject( + $this->model = $objectManagerHelper->getObject( 'Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor\Index', $constructArguments ); @@ -121,7 +121,7 @@ class IndexTest extends \PHPUnit_Framework_TestCase * @param int $countCustomization * @return \Magento\Core\Model\Resource\Theme\CollectionFactory */ - protected function _getThemeCollectionFactory($countCustomization) + protected function getThemeCollectionFactory($countCustomization) { $themeCollectionMock = $this->getMockBuilder( 'Magento\Core\Model\Resource\Theme\Collection' @@ -155,19 +155,18 @@ class IndexTest extends \PHPUnit_Framework_TestCase } /** - * @covers \Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor::indexAction * @dataProvider indexActionDataProvider */ public function testIndexAction($countCustomization) { - $this->_objectManagerMock->expects( + $this->objectManagerMock->expects( $this->any() )->method( 'get' )->will( - $this->returnValueMap($this->_getObjectManagerMap($countCustomization, 'index')) + $this->returnValueMap($this->getObjectManagerMap($countCustomization, 'index')) ); - $this->assertNull($this->_model->execute()); + $this->assertNull($this->model->execute()); } /** @@ -182,7 +181,7 @@ class IndexTest extends \PHPUnit_Framework_TestCase * @param int $countCustomization * @return array */ - protected function _getObjectManagerMap($countCustomization) + protected function getObjectManagerMap($countCustomization) { $translate = $this->getMock('Magento\Framework\TranslateInterface', array(), array(), '', false); $translate->expects($this->any())->method('translate')->will($this->returnSelf()); @@ -221,7 +220,7 @@ class IndexTest extends \PHPUnit_Framework_TestCase return array( array( 'Magento\Core\Model\Resource\Theme\CollectionFactory', - $this->_getThemeCollectionFactory($countCustomization) + $this->getThemeCollectionFactory($countCustomization) ), array('Magento\Framework\TranslateInterface', $translate), array('Magento\Framework\App\Config\ScopeConfigInterface', $configMock), diff --git a/dev/tests/unit/testsuite/Magento/Eav/Model/Entity/AbstractTest.php b/dev/tests/unit/testsuite/Magento/Eav/Model/Entity/AbstractTest.php index 1718e6be150c71e12e00ed05e64c704b292d8546..c815194b56ba3c18f8f3cc3d1348eb2f6452e903 100644 --- a/dev/tests/unit/testsuite/Magento/Eav/Model/Entity/AbstractTest.php +++ b/dev/tests/unit/testsuite/Magento/Eav/Model/Entity/AbstractTest.php @@ -31,13 +31,18 @@ class AbstractTest extends \PHPUnit_Framework_TestCase */ protected $_model; + /** @var \Magento\Eav\Model\Config */ + protected $eavConfig; + protected function setUp() { + + $this->eavConfig = $this->getMock('Magento\Eav\Model\Config', array(), array(), '', false); $this->_model = $this->getMockForAbstractClass( 'Magento\Eav\Model\Entity\AbstractEntity', array( $this->getMock('Magento\Framework\App\Resource', array(), array(), '', false), - $this->getMock('Magento\Eav\Model\Config', array(), array(), '', false), + $this->eavConfig, $this->getMock('Magento\Eav\Model\Entity\Attribute\Set', array(), array(), '', false), $this->getMock('\Magento\Framework\Locale\FormatInterface'), $this->getMock('Magento\Eav\Model\Resource\Helper', array(), array(), '', false), @@ -282,32 +287,38 @@ class AbstractTest extends \PHPUnit_Framework_TestCase $backendModel->setAttribute($attribute); $attribute->expects($this->any())->method('getBackend')->will($this->returnValue($backendModel)); + $attribute->setId(222); $attributes[$attributeCode] = $attribute; + $eavConfig = $this->getMockBuilder('Magento\Eav\Model\Config') + ->disableOriginalConstructor() + ->getMock(); + $data = array( $this->getMock('Magento\Framework\App\Resource', array(), array(), '', false), - $this->getMock('Magento\Eav\Model\Config', array(), array(), '', false), + $eavConfig, $this->getMock('Magento\Eav\Model\Entity\Attribute\Set', array(), array(), '', false), $this->getMock('Magento\Framework\Locale\FormatInterface'), $this->getMock('Magento\Eav\Model\Resource\Helper', array(), array(), '', false), $this->getMock('Magento\Framework\Validator\UniversalFactory', array(), array(), '', false), array('type' => $entityType, 'entityTable' => 'entityTable', 'attributesByCode' => $attributes) ); - /** @var $model \PHPUnit_Framework_MockObject_MockObject */ - $model = $this->getMockForAbstractClass( - 'Magento\Eav\Model\Entity\AbstractEntity', - $data, - '', - true, - true, - true, - array('_getValue') + /** @var $model \Magento\Framework\Model\AbstractModel|\PHPUnit_Framework_MockObject_MockObject */ + $model = $this->getMockBuilder('Magento\Eav\Model\Entity\AbstractEntity') + ->setConstructorArgs($data) + ->setMethods(['_getValue']) + ->getMock(); + + $model->expects($this->any())->method('_getValue')->will($this->returnValue($eavConfig)); + $eavConfig->expects($this->any())->method('getAttribute')->will( + $this->returnCallback( + function ($entityType, $attributeCode) use ($attributes) { + return $entityType && isset($attributes[$attributeCode]) ? $attributes[$attributeCode] : null; + } + ) ); - $configMock = $this->getMock('Magento\Eav\Model\Config', array(), array(), '', false); - $model->expects($this->any())->method('_getValue')->will($this->returnValue($configMock)); - $model->setConnection($this->_getAdapterMock()); $model->isPartialSave(true); diff --git a/dev/tests/unit/testsuite/Magento/Eav/Model/Entity/Attribute/Source/BooleanTest.php b/dev/tests/unit/testsuite/Magento/Eav/Model/Entity/Attribute/Source/BooleanTest.php index 1eb6d9c32218b2a882261b92d4d3e41da5376a3f..502ce4926bbe73d6b9d88cadfae20edc99b737c1 100644 --- a/dev/tests/unit/testsuite/Magento/Eav/Model/Entity/Attribute/Source/BooleanTest.php +++ b/dev/tests/unit/testsuite/Magento/Eav/Model/Entity/Attribute/Source/BooleanTest.php @@ -38,7 +38,7 @@ class BooleanTest extends \PHPUnit_Framework_TestCase $this->_model = $objectManager->getObject('Magento\Eav\Model\Entity\Attribute\Source\Boolean'); } - public function testGetFlatColums() + public function testGetFlatColumns() { $abstractAttributeMock = $this->getMock( '\Magento\Eav\Model\Entity\Attribute\AbstractAttribute', @@ -52,18 +52,153 @@ class BooleanTest extends \PHPUnit_Framework_TestCase $this->_model->setAttribute($abstractAttributeMock); - $flatColums = $this->_model->getFlatColums(); - - $this->assertTrue(is_array($flatColums), 'FlatColums must be an array value'); - $this->assertTrue(!empty($flatColums), 'FlatColums must be not empty'); - foreach ($flatColums as $result) { - $this->assertArrayHasKey('unsigned', $result, 'FlatColums must have "unsigned" column'); - $this->assertArrayHasKey('default', $result, 'FlatColums must have "default" column'); - $this->assertArrayHasKey('extra', $result, 'FlatColums must have "extra" column'); - $this->assertArrayHasKey('type', $result, 'FlatColums must have "type" column'); - $this->assertArrayHasKey('nullable', $result, 'FlatColums must have "nullable" column'); - $this->assertArrayHasKey('comment', $result, 'FlatColums must have "comment" column'); - $this->assertArrayHasKey('length', $result, 'FlatColums must have "length" column'); + $flatColumns = $this->_model->getFlatColumns(); + + $this->assertTrue(is_array($flatColumns), 'FlatColumns must be an array value'); + $this->assertTrue(!empty($flatColumns), 'FlatColumns must be not empty'); + foreach ($flatColumns as $result) { + $this->assertArrayHasKey('unsigned', $result, 'FlatColumns must have "unsigned" column'); + $this->assertArrayHasKey('default', $result, 'FlatColumns must have "default" column'); + $this->assertArrayHasKey('extra', $result, 'FlatColumns must have "extra" column'); + $this->assertArrayHasKey('type', $result, 'FlatColumns must have "type" column'); + $this->assertArrayHasKey('nullable', $result, 'FlatColumns must have "nullable" column'); + $this->assertArrayHasKey('comment', $result, 'FlatColumns must have "comment" column'); + $this->assertArrayHasKey('length', $result, 'FlatColumns must have "length" column'); + } + } + + /** + * @covers \Magento\Eav\Model\Entity\Attribute\Source\Boolean::addValueSortToCollection + * + * @dataProvider addValueSortToCollectionDataProvider + * @param string $direction + * @param bool $isScopeGlobal + * @param array $expectedJoinCondition + * @param string $expectedOrder + */ + public function testAddValueSortToCollection( + $direction, $isScopeGlobal, $expectedJoinCondition, $expectedOrder + ) { + $attributeMock = $this->getAttributeMock(); + $attributeMock->expects($this->any())->method('isScopeGlobal')->will($this->returnValue($isScopeGlobal)); + + $selectMock = $this->getMock('\Magento\Framework\DB\Select', [], [], '', false); + + $collectionMock = $this->getCollectionMock(); + $collectionMock->expects($this->any())->method('getSelect')->will($this->returnValue($selectMock)); + + foreach ($expectedJoinCondition as $step => $data) { + $selectMock->expects($this->at($step))->method('joinLeft') + ->with($data['requisites'], $data['condition'], [])->will($this->returnSelf()); } + + $selectMock->expects($this->once())->method('order')->with($expectedOrder); + + $this->_model->setAttribute($attributeMock); + $this->_model->addValueSortToCollection($collectionMock, $direction); + } + + /** + * @return array + */ + public function addValueSortToCollectionDataProvider() + { + return [ + [ + 'direction' => 'ASC', + 'isScopeGlobal' => false, + 'expectedJoinCondition' => [ + 0 => [ + 'requisites' => ['code_t1' => "table"], + 'condition' => + "e.entity_id=code_t1.entity_id AND code_t1.attribute_id='123' AND code_t1.store_id='0'", + ], + 1 => [ + 'requisites' => ['code_t2' => "table"], + 'condition' => + "e.entity_id=code_t2.entity_id AND code_t2.attribute_id='123' AND code_t2.store_id='12'" + ] + ], + 'expectedOrder' => 'IF(code_t2.value_id > 0, code_t2.value, code_t1.value) ASC', + ], + [ + 'direction' => 'DESC', + 'isScopeGlobal' => false, + 'expectedJoinCondition' => [ + 0 => [ + 'requisites' => ['code_t1' => "table"], + 'condition' => + "e.entity_id=code_t1.entity_id AND code_t1.attribute_id='123' AND code_t1.store_id='0'", + ], + 1 => [ + 'requisites' => ['code_t2' => "table"], + 'condition' => + "e.entity_id=code_t2.entity_id AND code_t2.attribute_id='123' AND code_t2.store_id='12'" + ] + ], + 'expectedOrder' => 'IF(code_t2.value_id > 0, code_t2.value, code_t1.value) DESC', + ], + [ + 'direction' => 'DESC', + 'isScopeGlobal' => true, + 'expectedJoinCondition' => [ + 0 => [ + 'requisites' => ['code_t' => "table"], + 'condition' => + "e.entity_id=code_t.entity_id AND code_t.attribute_id='123' AND code_t.store_id='0'", + ] + ], + 'expectedOrder' => 'code_t.value DESC', + ], + [ + 'direction' => 'ASC', + 'isScopeGlobal' => true, + 'expectedJoinCondition' => [ + 0 => [ + 'requisites' => ['code_t' => "table"], + 'condition' => + "e.entity_id=code_t.entity_id AND code_t.attribute_id='123' AND code_t.store_id='0'", + ] + ], + 'expectedOrder' => 'code_t.value ASC', + ], + ]; + } + + /** + * @return \PHPUnit_Framework_MockObject_MockObject + */ + protected function getCollectionMock() + { + $collectionMethods = ['getSelect', 'getStoreId', 'getConnection']; + $collectionMock = $this->getMock( + '\Magento\Eav\Model\Entity\Collection\AbstractCollection', $collectionMethods, [], '', false + ); + + $connectionMock = $this->getMock('\Magento\Framework\DB\Adapter\Pdo\Mysql', ['method'], [], '', false); + + $collectionMock->expects($this->any())->method('getConnection')->will($this->returnValue($connectionMock)); + $collectionMock->expects($this->any())->method('getStoreId')->will($this->returnValue('12')); + + return $collectionMock; + } + + /** + * @return \PHPUnit_Framework_MockObject_MockObject + */ + protected function getAttributeMock() + { + $attributeMockMethods = ['getAttributeCode', 'getId', 'getBackend', 'isScopeGlobal', '__wakeup']; + $attributeMock = $this->getMock( + '\Magento\Eav\Model\Entity\Attribute\AbstractAttribute', $attributeMockMethods, [], '', false + ); + $backendMock = $this->getMock('\Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend', [], [], '', false); + + $attributeMock->expects($this->any())->method('getAttributeCode')->will($this->returnValue('code')); + $attributeMock->expects($this->any())->method('getId')->will($this->returnValue('123')); + $attributeMock->expects($this->any())->method('getBackend')->will($this->returnValue($backendMock)); + $backendMock->expects($this->any())->method('getTable')->will($this->returnValue('table')); + + return $attributeMock; } } diff --git a/dev/tests/unit/testsuite/Magento/Eav/Model/Entity/Attribute/Source/TableTest.php b/dev/tests/unit/testsuite/Magento/Eav/Model/Entity/Attribute/Source/TableTest.php index 2d6531d79743a721141f76a972f2fe0f5f8ef8aa..2e26b78c295119b0a1b22dae71453a9a8f627be0 100644 --- a/dev/tests/unit/testsuite/Magento/Eav/Model/Entity/Attribute/Source/TableTest.php +++ b/dev/tests/unit/testsuite/Magento/Eav/Model/Entity/Attribute/Source/TableTest.php @@ -38,7 +38,7 @@ class TableTest extends \PHPUnit_Framework_TestCase $this->_model = $objectManager->getObject('Magento\Eav\Model\Entity\Attribute\Source\Table'); } - public function testGetFlatColums() + public function testGetFlatColumns() { $abstractFrontendMock = $this->getMock( 'Magento\Eav\Model\Entity\Attribute\Frontend\AbstractFrontend', @@ -68,19 +68,19 @@ class TableTest extends \PHPUnit_Framework_TestCase $this->_model->setAttribute($abstractAttributeMock); - $flatColums = $this->_model->getFlatColums(); + $flatColumns = $this->_model->getFlatColumns(); - $this->assertTrue(is_array($flatColums), 'FlatColums must be an array value'); - $this->assertTrue(!empty($flatColums), 'FlatColums must be not empty'); + $this->assertTrue(is_array($flatColumns), 'FlatColumns must be an array value'); + $this->assertTrue(!empty($flatColumns), 'FlatColumns must be not empty'); - foreach ($flatColums as $result) { - $this->assertArrayHasKey('unsigned', $result, 'FlatColums must have "unsigned" column'); - $this->assertArrayHasKey('default', $result, 'FlatColums must have "default" column'); - $this->assertArrayHasKey('extra', $result, 'FlatColums must have "extra" column'); - $this->assertArrayHasKey('type', $result, 'FlatColums must have "type" column'); - $this->assertArrayHasKey('nullable', $result, 'FlatColums must have "nullable" column'); - $this->assertArrayHasKey('comment', $result, 'FlatColums must have "comment" column'); - $this->assertArrayHasKey('length', $result, 'FlatColums must have "length" column'); + foreach ($flatColumns as $result) { + $this->assertArrayHasKey('unsigned', $result, 'FlatColumns must have "unsigned" column'); + $this->assertArrayHasKey('default', $result, 'FlatColumns must have "default" column'); + $this->assertArrayHasKey('extra', $result, 'FlatColumns must have "extra" column'); + $this->assertArrayHasKey('type', $result, 'FlatColumns must have "type" column'); + $this->assertArrayHasKey('nullable', $result, 'FlatColumns must have "nullable" column'); + $this->assertArrayHasKey('comment', $result, 'FlatColumns must have "comment" column'); + $this->assertArrayHasKey('length', $result, 'FlatColumns must have "length" column'); } } } diff --git a/dev/tests/unit/testsuite/Magento/Framework/App/Language/ConfigTest.php b/dev/tests/unit/testsuite/Magento/Framework/App/Language/ConfigTest.php new file mode 100644 index 0000000000000000000000000000000000000000..01cbf21eab5a586600c774b75d589e90e7372a29 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Framework/App/Language/ConfigTest.php @@ -0,0 +1,48 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Framework\App\Language; + +/** + * Test for configuration of language + */ +class ConfigTest extends \PHPUnit_Framework_TestCase +{ + public function testConfiguration() + { + $languageXml = file_get_contents(__DIR__ . '/_files/language.xml'); + $languageConfig = new Config($languageXml); + $this->assertEquals('en_GB', $languageConfig->getCode()); + $this->assertEquals('magento', $languageConfig->getVendor()); + $this->assertEquals('en_gb', $languageConfig->getPackage()); + $this->assertEquals('100', $languageConfig->getSortOrder()); + $this->assertEquals( + [ + ['vendor' => 'oxford-university', 'package' => 'en_us'], + ['vendor' => 'oxford-university', 'package' => 'en_gb'] + ], + $languageConfig->getUses() + ); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Framework/App/Language/DictionaryTest.php b/dev/tests/unit/testsuite/Magento/Framework/App/Language/DictionaryTest.php index b1b939ae96e84ca5bb9954d31cdd932e2fc0fb27..0ba2fab53d11f985158cc74721c0464611767107 100644 --- a/dev/tests/unit/testsuite/Magento/Framework/App/Language/DictionaryTest.php +++ b/dev/tests/unit/testsuite/Magento/Framework/App/Language/DictionaryTest.php @@ -36,6 +36,11 @@ class DictionaryTest extends \PHPUnit_Framework_TestCase */ private $dir; + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $configFactory; + protected function setUp() { $this->dir = $this->getMockForAbstractClass('\Magento\Framework\Filesystem\Directory\ReadInterface'); @@ -43,99 +48,76 @@ class DictionaryTest extends \PHPUnit_Framework_TestCase $filesystem->expects($this->once()) ->method('getDirectoryRead') ->with(\Magento\Framework\App\Filesystem::LOCALE_DIR) - ->will($this->returnValue($this->dir)) - ; - $this->model = new Dictionary($filesystem); + ->will($this->returnValue($this->dir)); + $this->configFactory = $this->getMockBuilder('\Magento\Framework\App\Language\ConfigFactory') + ->setMethods(['create']) + ->disableOriginalConstructor() + ->getMock(); + $this->model = new Dictionary($filesystem, $this->configFactory); } - public function testGetDictionary() + /** + * @param array $languagesData + * @param array $csvMap + * @param array $dictionaryMap + * @param $languageCode + * @param array $expectation + * @dataProvider dictionaryDataProvider + */ + public function testDictionaryGetter($languagesData, $csvMap, $dictionaryMap, $languageCode, $expectation) { - $dir = [ - 'Foo/en_AU/language.xml', - 'Bar/en_GB/language.xml', - 'Baz/en_GB/language.xml', - 'Bar/en_US/language.xml' - ]; - $xmlMap = [ - [ - $dir[0], - null, - null, - '<?xml version="1.0"?> - <language> - <code>en_AU</code> - <vendor>Foo</vendor> - <use vendor="Bar" code="en_GB"/> - <use vendor="Baz" code="en_GB"/> - </language>' - ], - [ - $dir[1], - null, - null, - '<?xml version="1.0"?> - <language> - <code>en_GB</code> - <vendor>Bar</vendor> - <sort_order>100</sort_order> - <use vendor="Bar" code="en_US"/> - </language>' - ], - [ - $dir[2], - null, - null, - '<?xml version="1.0"?> - <language> - <code>en_GB</code> - <vendor>Baz</vendor> - <sort_order>50</sort_order> - </language>' - ], - [ - $dir[3], - null, - null, - '<?xml version="1.0"?> - <language> - <code>en_US</code> - <vendor>Bar</vendor> - </language>' - ], - ]; - $csvMap = [ - ['Bar/en_US/*.csv', null, ['Bar/en_US/b.csv', 'Bar/en_US/a.csv']], - ['Baz/en_GB/*.csv', null, ['Baz/en_GB/1.csv']], - ['Bar/en_GB/*.csv', null, ['Bar/en_GB/1.csv']], - ['Foo/en_AU/*.csv', null, ['Foo/en_AU/1.csv', 'Foo/en_AU/2.csv']], - ]; - $dictionaryMap = [ - ['Bar/en_US/a.csv', $this->getCsvMock([['one', '1'], ['two', '2']])], - ['Bar/en_US/b.csv', $this->getCsvMock([['three', '3'], ['four', '4']])], - ['Baz/en_GB/1.csv', $this->getCsvMock([['four and 5/10', '4.5']])], - ['Bar/en_GB/1.csv', $this->getCsvMock([['four and 75/100', '4.75'], ['four and 5/10', '4.50']])], - ['Foo/en_AU/1.csv', $this->getCsvMock([['one', '1.0'], ['five', '5.0']])], - ['Foo/en_AU/2.csv', $this->getCsvMock([['six', '6.0']])], - ]; + $languagePaths = array_keys($languagesData); $this->dir->expects($this->any())->method('search')->will($this->returnValueMap( - array_merge([['*/*/language.xml', null, $dir]], $csvMap) + array_merge([['*/*/language.xml', null, $languagePaths]], $csvMap) )); - $this->dir->expects($this->any())->method('readFile')->will($this->returnValueMap($xmlMap)); + + // Return first argument to mark content for configuration factory mock + $this->dir->expects($this->any())->method('readFile')->will($this->returnArgument(0)); + $configCallback = $this->returnCallback(function ($arguments) use ($languagesData) { + return $this->getLanguageConfigMock($languagesData[$arguments['source']]); + }); + $this->configFactory->expects($this->any())->method('create')->will($configCallback); + + // Covers data from dataProvider + $dictionaryMap = array_map(function ($data) { + list($path, $result) = $data; + return [$path, $this->getCsvMock($result)]; + }, $dictionaryMap); $this->dir->expects($this->any())->method('openFile')->will($this->returnValueMap($dictionaryMap)); - $result = $this->model->getDictionary('en_AU'); - $this->assertSame( - [ - 'one' => '1.0', - 'two' => '2', - 'three' => '3', - 'four' => '4', - 'four and 5/10' => '4.50', - 'four and 75/100' => '4.75', - 'five' => '5.0', - 'six' => '6.0' - ], - $result - ); + + $result = $this->model->getDictionary($languageCode); + $this->assertSame($expectation, $result); + } + + public function dictionaryDataProvider() + { + return [ + // First case with multiple inheritance, the obtained dictionary is en_AU + 'a case with multiple inheritance' => $this->getDataMultipleInheritance(), + // Second case with inheritance of package with the same language code + 'a case with inheritance similar language code' => $this->getDataInheritanceWitSimilarCode(), + // Third case with circular inheritance, when two packages depend on each other + 'a case with circular inheritance' => $this->getDataCircularInheritance() + ]; + } + + /** + * Create mock of language configuration model + * + * @param array $languageData + * @return \PHPUnit_Framework_MockObject_MockObject + */ + private function getLanguageConfigMock($languageData) + { + $languageConfig = $this->getMock('\Magento\Framework\App\Language\Config', [], [], '', false); + $languageConfig->expects($this->any())->method('getCode')->will($this->returnValue($languageData['code'])); + $languageConfig->expects($this->any())->method('getVendor')->will($this->returnValue($languageData['vendor'])); + $languageConfig->expects($this->any())->method('getPackage') + ->will($this->returnValue($languageData['package'])); + $languageConfig->expects($this->any())->method('getSortOrder') + ->will($this->returnValue($languageData['sort_order'])); + $languageConfig->expects($this->any())->method('getUses')->will($this->returnValue($languageData['use'])); + return $languageConfig; } /** @@ -153,4 +135,169 @@ class DictionaryTest extends \PHPUnit_Framework_TestCase $file->expects($this->at($i))->method('readCsv')->will($this->returnValue(false)); return $file; } + + /** + * @return array + */ + private function getDataMultipleInheritance() + { + return [ + 'languages' => [ + 'foo/en_au/language.xml' => [ + 'code' => 'en_AU', + 'vendor' => 'foo', + 'package' => 'en_au', + 'sort_order' => 0, + 'use' => [ + ['vendor' => 'bar', 'package' => 'en_gb'], + ['vendor' => 'baz', 'package' => 'en_gb'], + ] + ], + 'bar/en_gb/language.xml' => [ + 'code' => 'en_GB', + 'vendor' => 'bar', + 'package' => 'en_gb', + 'sort_order' => 100, + 'use' => [ + ['vendor' => 'bar', 'package' => 'en_us'], + ] + ], + 'baz/en_gb/language.xml' => [ + 'code' => 'en_GB', + 'vendor' => 'baz', + 'package' => 'en_gb', + 'sort_order' => 50, + 'use' => [] + ], + 'bar/en_us/language.xml' => [ + 'code' => 'en_US', + 'vendor' => 'bar', + 'package' => 'en_us', + 'sort_order' => 0, + 'use' => [] + ] + ], + // ValueMap for \Magento\Framework\Filesystem\Directory\ReadInterface::search($pattern, $path = null) + 'csv_map' => [ + ['bar/en_us/*.csv', null, ['bar/en_us/b.csv', 'bar/en_us/a.csv']], + ['baz/en_gb/*.csv', null, ['baz/en_gb/1.csv']], + ['bar/en_gb/*.csv', null, ['bar/en_gb/1.csv']], + ['foo/en_au/*.csv', null, ['foo/en_au/1.csv', 'foo/en_au/2.csv']], + ], + // ValueMap for \Magento\Framework\Filesystem\Directory\ReadInterface::openFile($path) + 'dictionary_map' => [ + ['bar/en_us/a.csv', [['one', '1'], ['two', '2']]], + ['bar/en_us/b.csv', [['three', '3'], ['four', '4']]], + ['baz/en_gb/1.csv', [['four and 5/10', '4.5']]], + ['bar/en_gb/1.csv', [['four and 75/100', '4.75'], ['four and 5/10', '4.50']]], + ['foo/en_au/1.csv', [['one', '1.0'], ['five', '5.0']]], + ['foo/en_au/2.csv', [['six', '6.0']]] + ], + // Dictionary that will be requested + 'language_code' => 'en_AU', + // Expected merged dictionary data + 'expectation' => [ + 'one' => '1.0', + 'two' => '2', + 'three' => '3', + 'four' => '4', + 'four and 5/10' => '4.50', + 'four and 75/100' => '4.75', + 'five' => '5.0', + 'six' => '6.0' + ] + ]; + } + + /** + * @return array + */ + private function getDataInheritanceWitSimilarCode() + { + return [ + 'languages' => [ + 'theirs/ru_ru/language.xml' => [ + 'code' => 'ru_RU', + 'vendor' => 'theirs', + 'package' => 'ru_ru', + 'sort_order' => 0, + 'use' => [] + ], + 'my/ru_ru/language.xml' => [ + 'code' => 'ru_RU', + 'vendor' => 'my', + 'package' => 'ru_ru', + 'sort_order' => 100, + 'use' => [ + ['vendor' => 'theirs', 'package' => 'ru_ru'], + ] + ], + ], + // ValueMap for \Magento\Framework\Filesystem\Directory\ReadInterface::search($pattern, $path = null) + 'csv_map' => [ + ['theirs/ru_ru/*.csv', null, ['theirs/ru_ru/1.csv']], + ['my/ru_ru/*.csv', null, ['my/ru_ru/1.csv']], + ], + // ValueMap for \Magento\Framework\Filesystem\Directory\ReadInterface::openFile($path) + 'dictionary_map' => [ + ['theirs/ru_ru/1.csv', [['one', '1'], ['two', '2']]], + ['my/ru_ru/1.csv', [['three', '3'], ['one', '1.0']]], + ], + // Dictionary that will be requested + 'language_code' => 'ru_RU', + // Expected merged dictionary data + 'expectation' => [ + 'one' => '1.0', + 'two' => '2', + 'three' => '3', + ] + ]; + } + + /** + * @return array + */ + private function getDataCircularInheritance() + { + return [ + 'languages' => [ + 'first/en_us/language.xml' => [ + 'code' => 'en_US', + 'vendor' => 'first', + 'package' => 'en_us', + 'sort_order' => 0, + 'use' => [ + ['vendor' => 'second', 'package' => 'en_gb'] + ] + ], + 'second/en_gb/language.xml' => [ + 'code' => 'en_GB', + 'vendor' => 'second', + 'package' => 'en_gb', + 'sort_order' => 0, + 'use' => [ + ['vendor' => 'first', 'package' => 'en_us'], + ] + ], + ], + // ValueMap for \Magento\Framework\Filesystem\Directory\ReadInterface::search($pattern, $path = null) + 'csv_map' => [ + ['first/en_us/*.csv', null, ['first/en_us/1.csv']], + ['second/en_gb/*.csv', null, ['second/en_gb/1.csv']], + ], + // ValueMap for \Magento\Framework\Filesystem\Directory\ReadInterface::openFile($path) + 'dictionary_map' => [ + ['first/en_us/1.csv', [['three', '3'], ['one', '1.0']]], + ['second/en_gb/1.csv', [['one', '1'], ['two', '2']]], + ], + // Dictionary that will be requested + 'language_code' => 'en_US', + // Expected merged dictionary data + 'expectation' => [ + 'one' => '1.0', + 'two' => '2', + 'three' => '3', + ] + ]; + } } diff --git a/dev/tests/unit/testsuite/Magento/Framework/App/Language/_files/language.xml b/dev/tests/unit/testsuite/Magento/Framework/App/Language/_files/language.xml new file mode 100644 index 0000000000000000000000000000000000000000..f438fb45df49191953caf569f9ecaf7587a71368 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Framework/App/Language/_files/language.xml @@ -0,0 +1,33 @@ +<?xml version="1.0"?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<language xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../../lib/internal/Magento/Framework/App/Language/package.xsd"> + <code>en_GB</code> + <vendor>magento</vendor> + <package>en_gb</package> + <sort_order>100</sort_order> + <use vendor="oxford-university" package="en_us"/> + <use vendor="oxford-university" package="en_gb"/> +</language> diff --git a/dev/tests/unit/testsuite/Magento/Framework/Data/FormTest.php b/dev/tests/unit/testsuite/Magento/Framework/Data/FormTest.php index fe9ecdb6f425748129db6dd82181d17524f9852b..1c6c0a812afba8fcce5f4950c6805c04c52c928d 100644 --- a/dev/tests/unit/testsuite/Magento/Framework/Data/FormTest.php +++ b/dev/tests/unit/testsuite/Magento/Framework/Data/FormTest.php @@ -44,15 +44,6 @@ class FormTest extends \PHPUnit_Framework_TestCase */ protected $_formKeyMock; - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $elementMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $allElementsMock; /** * @var \Magento\Framework\Data\Form */ @@ -62,11 +53,12 @@ class FormTest extends \PHPUnit_Framework_TestCase { $this->_factoryElementMock = $this->getMock( 'Magento\Framework\Data\Form\Element\Factory', - array('create'), + array(), array(), '', false ); + $this->_factoryCollectionMock = $this->getMock( 'Magento\Framework\Data\Form\Element\CollectionFactory', array('create'), @@ -74,8 +66,16 @@ class FormTest extends \PHPUnit_Framework_TestCase '', false ); - $this->allElementsMock = - $this->getMock('Magento\Framework\Data\Form\Element\Collection', [], [], '', false); + + $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this); + $collectionModel = $objectManager->getObject + ('Magento\Framework\Data\Form\Element\Collection'); + + $this->_factoryCollectionMock + ->expects($this->any()) + ->method('create') + ->will($this->returnValue($collectionModel)); + $this->_formKeyMock = $this->getMock( 'Magento\Framework\Data\Form\FormKey', array('getFormKey'), @@ -83,19 +83,12 @@ class FormTest extends \PHPUnit_Framework_TestCase '', false ); - $methods = ['getId', 'setValue', 'setName', 'getName', '_wakeup']; - $this->elementMock = - $this->getMock('Magento\Framework\Data\Form\Element\AbstractElement', $methods, [], '', false); $this->_form = new Form($this->_factoryElementMock, $this->_factoryCollectionMock, $this->_formKeyMock); } public function testFormKeyUsing() { - $this->_factoryCollectionMock - ->expects($this->any()) - ->method('create') - ->will($this->returnValue(array())); $formKey = 'form-key'; $this->_formKeyMock->expects($this->once())->method('getFormKey')->will($this->returnValue($formKey)); @@ -104,74 +97,86 @@ class FormTest extends \PHPUnit_Framework_TestCase $this->assertContains($formKey, $this->_form->toHtml()); } - public function testAddValue() + public function testSettersGetters() { - $this->_factoryCollectionMock - ->expects($this->once()) - ->method('create') - ->will($this->returnValue($this->allElementsMock)); - $this->_form = new Form($this->_factoryElementMock, $this->_factoryCollectionMock, $this->_formKeyMock); - $values = [ - 'element_id' => 'value_one' - ]; - $this->elementMock->expects($this->once())->method('getId')->will($this->returnValue('element_id')); - $this->allElementsMock->expects($this->once())->method('add')->with($this->elementMock); - $this->elementMock->expects($this->once())->method('setValue')->with('value_one'); - $this->_form->addElementToCollection($this->elementMock); - $this->_form->addValues($values); + $setElementRenderer = $this->getMockBuilder + ('Magento\Backend\Block\Widget\Form\Renderer\Element') + ->disableOriginalConstructor() + ->getMock(); + + // note: this results in setting a static variable in the Form class + $this->_form->setElementRenderer($setElementRenderer); + $getElementRenderer = $this->_form->getElementRenderer(); + $this->assertSame($setElementRenderer, $getElementRenderer); + // restore our Form to its earlier state + $this->_form->setElementRenderer(null); + + + $setFieldsetRenderer = $this->getMockBuilder + ('Magento\Backend\Block\Widget\Form\Renderer\Fieldset') + ->disableOriginalConstructor() + ->getMock(); + + $this->_form->setFieldsetRenderer($setFieldsetRenderer); + $getFieldsetRenderer = $this->_form->getFieldsetRenderer(); + $this->assertSame($setFieldsetRenderer, $getFieldsetRenderer); + + + $setFieldsetElementRenderer = $this->getMockBuilder + ('Magento\Backend\Block\Widget\Form\Renderer\Fieldset') + ->disableOriginalConstructor() + ->getMock(); + + $this->_form->setFieldsetElementRenderer($setFieldsetElementRenderer); + $getFieldsetElementRenderer = $this->_form->getFieldsetElementRenderer(); + $this->assertSame($setFieldsetElementRenderer, $getFieldsetElementRenderer); + + $this->assertSame($this->_form->getHtmlAttributes(), ['id', 'name', 'method', + 'action', 'enctype', 'class', 'onsubmit', 'target']); + + $this->_form->setFieldContainerIdPrefix('abc'); + $this->assertSame($this->_form->getFieldContainerIdPrefix(), 'abc'); + + $result = $this->_form->addSuffixToName('123', 'abc'); + $this->assertSame($result, 'abc[123]'); } /** - * @param int $number - * @param string $elementId - * @param string|null $value - * - * @dataProvider setValueDataProvider + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage Element with id "1" already exists */ - public function testSetValue($number, $elementId, $value) + public function testElementExistsException() { - $this->_factoryCollectionMock - ->expects($this->once()) - ->method('create') - ->will($this->returnValue(array($this->elementMock))); - $this->_form = new Form($this->_factoryElementMock, $this->_factoryCollectionMock, $this->_formKeyMock); - $values = [ - 'element_two' => 'value_two' - ]; - $this->elementMock->expects($this->exactly($number))->method('getId')->will($this->returnValue($elementId)); - $this->elementMock->expects($this->once())->method('setValue')->with($value); - $this->_form->setValues($values); - } + $buttonElement = $this->getMockBuilder + ('Magento\Framework\Data\Form\Element\Button') + ->disableOriginalConstructor() + ->getMock(); + $buttonElement->expects($this->any())->method('getId')->will($this->returnValue('1')); - public function setValueDataProvider() - { - return [ - 'value_exists' => [2, 'element_two', 'value_two'], - 'value_not_exist' => [1, 'element_one', null] - ]; - } + $this->_form->addElement($buttonElement); + $this->_form->addElementToCollection($buttonElement); - public function testAddFieldNameSuffix() - { - $this->_factoryCollectionMock - ->expects($this->once()) - ->method('create') - ->will($this->returnValue(array($this->elementMock))); - $this->_form = new Form($this->_factoryElementMock, $this->_factoryCollectionMock, $this->_formKeyMock); - $this->elementMock->expects($this->once())->method('getName')->will($this->returnValue('name')); - $this->elementMock->expects($this->once())->method('setName')->with('_suffix[name]'); - $this->_form->addFieldNameSuffix('_suffix'); + $this->_form->checkElementId($buttonElement->getId()); } - public function testAddEllement() + public function testElementOperations() { - $this->_factoryCollectionMock - ->expects($this->any()) - ->method('create') - ->will($this->returnValue($this->allElementsMock)); - $this->_form = new Form($this->_factoryElementMock, $this->_factoryCollectionMock, $this->_formKeyMock); - $this->elementMock->expects($this->any())->method('getId')->will($this->returnValue('element_id')); - $this->allElementsMock->expects($this->exactly(2))->method('add')->with($this->elementMock, false); - $this->_form->addElement($this->elementMock); + $buttonElement = $this->getMockBuilder + ('Magento\Framework\Data\Form\Element\Button') + ->disableOriginalConstructor() + ->getMock(); + $buttonElement->expects($this->any())->method('getId')->will($this->returnValue('1')); + $buttonElement->expects($this->any())->method('getName')->will($this->returnValue('Hero')); + + $this->_form->addElement($buttonElement); + $this->_form->addElementToCollection($buttonElement); + + $this->_form->addValues(['1', '2', '3']); + $this->_form->setValues(['4', '5', '6']); + + $this->_form->addFieldNameSuffix('abc123'); + + $this->_form->removeField($buttonElement->getId()); + $this->assertSame($this->_form->checkElementId($buttonElement->getId()), true); } } diff --git a/dev/tests/unit/testsuite/Magento/Framework/Data/Tree/Node/CollectionTest.php b/dev/tests/unit/testsuite/Magento/Framework/Data/Tree/Node/CollectionTest.php index afe8ae8c7df5a0a263fc21ce283ecf9f0e10d2c7..3b342a2b1fdb911e81629b023aac5e6959d11207 100644 --- a/dev/tests/unit/testsuite/Magento/Framework/Data/Tree/Node/CollectionTest.php +++ b/dev/tests/unit/testsuite/Magento/Framework/Data/Tree/Node/CollectionTest.php @@ -31,43 +31,77 @@ class CollectionTest extends \PHPUnit_Framework_TestCase */ protected $collection; - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $containerMock; + public function setUp() + { + $tree = new \Magento\Framework\Data\Tree(); + $node = new \Magento\Framework\Data\Tree\Node(['id' => 'root'], 'id', $tree); + $this->collection = new Collection($node); + } - protected function setUp() + public function testAdd() { - $this->containerMock = $this->getMock('Magento\Framework\Data\Tree\Node', [], [], '', false); - $this->collection = new \Magento\Framework\Data\Tree\Node\Collection($this->containerMock); + $tree = new \Magento\Framework\Data\Tree(); + $this->assertSame($this->collection->count(), 0); + $node = new \Magento\Framework\Data\Tree\Node(['id' => 'node1'], 'id', $tree); + $this->collection->add($node); + $this->assertSame($this->collection->count(), 1); } - /** - * @param int $number - * @param \PHPUnit_Framework_MockObject_MockObject|null $returnValue - * - * @dataProvider testAddDataProvider - */ - public function testAdd($number, $returnValue) + public function testOffsets() + { + $tree = new \Magento\Framework\Data\Tree(); + $this->assertSame($this->collection->count(), 0); + $node = new \Magento\Framework\Data\Tree\Node(['id' => 'node1'], 'id', $tree); + $this->collection->add($node); + $this->assertSame($this->collection->offsetExists('node1'), true); + $this->collection->offsetSet('node1', 'Hello'); + $this->assertSame($this->collection->offsetExists('node1'), true); + $this->assertSame($this->collection->offsetGet('node1'), 'Hello'); + $this->collection->offsetUnset('node1'); + $this->assertSame($this->collection->offsetExists('node1'), false); + } + + public function testDelete() { - $nodeMock = $this->getMock('Magento\Framework\Data\Tree\Node', [], [], '', false); - $nodeMock->expects($this->once())->method('setParent')->with($this->containerMock); - $this->containerMock - ->expects($this->exactly($number)) - ->method('getTree') - ->will($this->returnValue($returnValue)); - $nodeMock->expects($this->once())->method('getId')->will($this->returnValue('id_node')); - $this->assertEquals($nodeMock, $this->collection->add($nodeMock)); - $this->assertEquals(['id_node' => $nodeMock], $this->collection->getNodes()); - $this->assertEquals($nodeMock, $this->collection->searchById('id_node')); - $this->assertEquals(null, $this->collection->searchById('id_node_new')); + $tree = new \Magento\Framework\Data\Tree(); + $this->assertSame($this->collection->count(), 0); + $node = new \Magento\Framework\Data\Tree\Node(['id' => 'node1'], 'id', $tree); + $this->collection->add($node); + $this->assertSame($this->collection->count(), 1); + $this->collection->delete($node); + $this->assertSame($this->collection->count(), 0); } - public function testAddDataProvider() + public function testLastNode() { - return [ - 'tree_exists' => [2, $this->getMock('Magento\Framework\Data\Tree', [], [], '', false)], - 'tree_not_exist' => [1, null] - ]; + $tree = new \Magento\Framework\Data\Tree(); + $node1 = new \Magento\Framework\Data\Tree\Node(['id' => 'node1'], 'id', $tree); + $this->collection->add($node1); + $node2 = new \Magento\Framework\Data\Tree\Node(['id' => 'node2'], 'id', $tree); + $this->collection->add($node2); + $this->assertSame($this->collection->lastNode(), $node2); + $node3 = new \Magento\Framework\Data\Tree\Node(['id' => 'node3'], 'id', $tree); + $this->collection->add($node3); + + $this->assertSame($this->collection->lastNode(), $node3); + $this->assertSame($this->collection->lastNode(), $node3); + $this->collection->delete($node3); + $this->assertSame($this->collection->lastNode(), $node2); + $this->assertSame($this->collection->lastNode(), $node2); + } + + public function testSearchById() + { + $tree = new \Magento\Framework\Data\Tree(); + $node1 = new \Magento\Framework\Data\Tree\Node(['id' => 'node1'], 'id', $tree); + $this->collection->add($node1); + $node2 = new \Magento\Framework\Data\Tree\Node(['id' => 'node2'], 'id', $tree); + $this->collection->add($node2); + $this->assertSame($this->collection->lastNode(), $node2); + $node3 = new \Magento\Framework\Data\Tree\Node(['id' => 'node3'], 'id', $tree); + $this->collection->add($node3); + + $this->assertSame($this->collection->searchById('node2'), $node2); } } + \ No newline at end of file diff --git a/dev/tests/unit/testsuite/Magento/Framework/Data/TreeTest.php b/dev/tests/unit/testsuite/Magento/Framework/Data/TreeTest.php new file mode 100644 index 0000000000000000000000000000000000000000..e1080d1e801a5a0b438f5498e13aecc4f5832e17 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Framework/Data/TreeTest.php @@ -0,0 +1,63 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Framework\Data; + +/** + * Tests for \Magento\Framework\Data\FormFactory + * @SuppressWarnings(PHPMD.LongVariable) + */ +class TreeTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Framework\Data\Tree + */ + protected $_tree; + + public function setUp() + { + $this->_tree = new Tree(); + } + + public function testTreeOperations() + { + $newNode1 = new Tree\Node('abc', 'node1', $this->_tree); + $this->_tree->addNode($newNode1); + $newNode2 = new Tree\Node('def', 'node2', $this->_tree); + $this->_tree->addNode($newNode2, $newNode1); + $newNode3 = new Tree\Node('ghi', 'node3', $this->_tree); + $this->_tree->addNode($newNode3, $newNode1); + $data1 = ['j', 'k', 'l']; + $this->_tree->appendChild($data1, $newNode3); + $newNode4 = new Tree\Node('mno', 'node4', $this->_tree); + $this->_tree->appendChild($newNode4, $newNode3); + + $this->_tree->removeNode($newNode4); + $this->_tree->removeNode($newNode3); + $this->_tree->removeNode($newNode2); + $this->_tree->removeNode($newNode1); + + $this->assertEmpty($this->_tree->getNodes()->getNodes()); + } +} + \ No newline at end of file diff --git a/dev/tests/unit/testsuite/Magento/Framework/File/CsvTest.php b/dev/tests/unit/testsuite/Magento/Framework/File/CsvTest.php index c11e537bd3317bc768ea00f7adc42b83b7e5ad08..3993209ca419193d5a1c6e6e98a9afcb1bbea77e 100644 --- a/dev/tests/unit/testsuite/Magento/Framework/File/CsvTest.php +++ b/dev/tests/unit/testsuite/Magento/Framework/File/CsvTest.php @@ -70,11 +70,11 @@ class CsvTest extends \PHPUnit_Framework_TestCase /** * @expectedException \Exception - * @expectedExceptionMessage File "FileName" do not exists + * @expectedExceptionMessage File "FileNameThatShouldNotExist" do not exists */ public function testGetDataFileNonExistent() { - $file = 'FileName'; + $file = 'FileNameThatShouldNotExist'; $this->_model->getData($file); } } diff --git a/dev/tests/unit/testsuite/Magento/Framework/HTTP/Adapter/CurlTest.php b/dev/tests/unit/testsuite/Magento/Framework/HTTP/Adapter/CurlTest.php new file mode 100644 index 0000000000000000000000000000000000000000..c4d16ea847892c2e52438afcc5877605a5fdfc0b --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Framework/HTTP/Adapter/CurlTest.php @@ -0,0 +1,71 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Framework\HTTP\Adapter; + +class CurlTest extends \PHPUnit_Framework_TestCase +{ + /** @var Curl */ + protected $model; + + /** @var \Closure */ + public static $curlExectClosure; + + protected function setUp() + { + $this->model = new \Magento\Framework\HTTP\Adapter\Curl(); + } + + /** + * @param string $response + * @dataProvider readDataProvider + */ + public function testRead($response) + { + self::$curlExectClosure = function () use ($response) { + return $response; + }; + $this->assertEquals(file_get_contents(__DIR__ . '/_files/curl_response_expected.txt'), $this->model->read()); + } + + public function readDataProvider() + { + return [ + [file_get_contents(__DIR__ . '/_files/curl_response1.txt')], + [file_get_contents(__DIR__ . '/_files/curl_response2.txt')], + ]; + } +} + +/** + * Override global PHP function + * + * @SuppressWarnings("unused") + * @param mixed $resource + * @return string + */ +function curl_exec($resource) +{ + return call_user_func(CurlTest::$curlExectClosure); +} diff --git a/dev/tests/unit/testsuite/Magento/Framework/HTTP/Adapter/_files/curl_response1.txt b/dev/tests/unit/testsuite/Magento/Framework/HTTP/Adapter/_files/curl_response1.txt new file mode 100644 index 0000000000000000000000000000000000000000..74ebfb7b1b5b59a1c31e5bcf7e263c4505a5d3d5 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Framework/HTTP/Adapter/_files/curl_response1.txt @@ -0,0 +1,24 @@ +HTTP/1.1 100 Continue +Set-Cookie: ... + +HTTP/1.1 100 Continue +Set-Cookie: ... + +HTTP/1.1 101 Continue +Set-Cookie: ... + +HTTP/1.1 100 Continue +Set-Cookie: ... + +HTTP/1.1 200 OK +Server: Apache +X-Frame-Options: SAMEORIGIN +Strict-Transport-Security: max-age=14400 +Strict-Transport-Security: max-age=14400 +Content-Type: text/html; charset=UTF-8 +Date: Mon, 22 Apr 2013 09:52:36 GMT +Content-Length: 8 +Connection: keep-alive +Set-Cookie: ... + +VERIFIED \ No newline at end of file diff --git a/dev/tests/unit/testsuite/Magento/Framework/HTTP/Adapter/_files/curl_response2.txt b/dev/tests/unit/testsuite/Magento/Framework/HTTP/Adapter/_files/curl_response2.txt new file mode 100644 index 0000000000000000000000000000000000000000..a35904eb08dbcd82bcdc5042a2b6e061b6e6c143 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Framework/HTTP/Adapter/_files/curl_response2.txt @@ -0,0 +1,12 @@ +HTTP/1.1 200 OK +Server: Apache +X-Frame-Options: SAMEORIGIN +Strict-Transport-Security: max-age=14400 +Strict-Transport-Security: max-age=14400 +Content-Type: text/html; charset=UTF-8 +Date: Mon, 22 Apr 2013 09:52:36 GMT +Content-Length: 8 +Connection: keep-alive +Set-Cookie: ... + +VERIFIED \ No newline at end of file diff --git a/dev/tests/unit/testsuite/Magento/Framework/HTTP/Adapter/_files/curl_response_expected.txt b/dev/tests/unit/testsuite/Magento/Framework/HTTP/Adapter/_files/curl_response_expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..a35904eb08dbcd82bcdc5042a2b6e061b6e6c143 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Framework/HTTP/Adapter/_files/curl_response_expected.txt @@ -0,0 +1,12 @@ +HTTP/1.1 200 OK +Server: Apache +X-Frame-Options: SAMEORIGIN +Strict-Transport-Security: max-age=14400 +Strict-Transport-Security: max-age=14400 +Content-Type: text/html; charset=UTF-8 +Date: Mon, 22 Apr 2013 09:52:36 GMT +Content-Length: 8 +Connection: keep-alive +Set-Cookie: ... + +VERIFIED \ No newline at end of file diff --git a/dev/tests/unit/testsuite/Magento/Framework/Phrase/Renderer/TranslateTest.php b/dev/tests/unit/testsuite/Magento/Framework/Phrase/Renderer/TranslateTest.php index e614b0342818ca85c86da696b3ee5d24b68aad89..09f9e16065ba4e969368713c6648c880d403d78c 100644 --- a/dev/tests/unit/testsuite/Magento/Framework/Phrase/Renderer/TranslateTest.php +++ b/dev/tests/unit/testsuite/Magento/Framework/Phrase/Renderer/TranslateTest.php @@ -26,7 +26,7 @@ namespace Magento\Framework\Phrase\Renderer; class TranslateTest extends \PHPUnit_Framework_TestCase { /** - * @var \Magento\Framework\Translate|PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Framework\Translate|\PHPUnit_Framework_MockObject_MockObject */ protected $_translator; @@ -46,44 +46,17 @@ class TranslateTest extends \PHPUnit_Framework_TestCase ); } - public function testRenderByCode() + public function testRender() { - $text = 'original text'; - $result = 'rendered text'; + $text = 'text'; + $translatedText = 'translated text'; + $translate = 'translate'; - $this->_translator->expects( - $this->once() - )->method( - 'getTheme' - )->will( - $this->returnValue('theme') - ); - $this->_translator->expects( - $this->once() - )->method( - 'getData' - )->will( - $this->returnValue(['theme::' . $text => $result]) - ); - - $this->assertEquals($result, $this->_renderer->render([$text], [])); - } - - public function testRenderByText() - { - $text = 'original text'; - $result = 'rendered text'; - - $this->_translator->expects($this->once()) - ->method('getTheme') - ->will($this->returnValue('theme')); - $this->_translator->expects($this->once()) + $this->_translator->expects($this->exactly(2)) ->method('getData') - ->will($this->returnValue([ - 'theme::' . $text => $result, - $text => $result, - ])); + ->will($this->returnValue([$translatedText => $translate])); - $this->assertEquals($result, $this->_renderer->render([$text], [])); + $this->assertEquals($translate, $this->_renderer->render([$translatedText], [])); + $this->assertEquals($text, $this->_renderer->render([$text], [])); } } diff --git a/dev/tests/unit/testsuite/Magento/Framework/Simplexml/Config/Cache/AbstractCacheTest.php b/dev/tests/unit/testsuite/Magento/Framework/Simplexml/Config/Cache/AbstractCacheTest.php new file mode 100644 index 0000000000000000000000000000000000000000..d291a1166dba3b8342c1d3f6c65d881ccea81929 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Framework/Simplexml/Config/Cache/AbstractCacheTest.php @@ -0,0 +1,62 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Framework\Simplexml\Config\Cache; + +class AbstractCacheTest extends \PHPUnit_Framework_TestCase +{ + /** @var File */ + protected $cache; + + protected $file; + + protected function setUp() + { + $this->cache = new File(); + $this->file = realpath(__DIR__ . '/../../_files/data.xml'); + } + + public function testAddComponent() + { + $this->cache->addComponent('wrong_path'); + $this->assertSame([], $this->cache->getComponents()); + + $this->cache->addComponent($this->file); + $this->assertSame([$this->file => ['mtime' => filemtime($this->file)]], $this->cache->getComponents()); + } + + public function testValidateComponents() + { + $this->assertSame(false, $this->cache->validateComponents([])); + $this->assertSame(false, $this->cache->validateComponents('')); + $this->assertSame(false, $this->cache->validateComponents([$this->file => ['mtime' => '']])); + $this->assertSame(false, $this->cache->validateComponents([$this->file => ['mtime' => 1]])); + $this->assertSame(true, $this->cache->validateComponents([$this->file => ['mtime' => filemtime($this->file)]])); + } + + public function testGetComponentsHash() + { + $this->cache->addComponent($this->file); + $this->assertSame(md5(filemtime($this->file) . ':'), $this->cache->getComponentsHash()); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Framework/Simplexml/ConfigTest.php b/dev/tests/unit/testsuite/Magento/Framework/Simplexml/ConfigTest.php index dce22beb0ad65e102fe9e658ccc867f3cec98f1b..77a9cbd11c384f56ff5f72c2682c64395ce3e889 100644 --- a/dev/tests/unit/testsuite/Magento/Framework/Simplexml/ConfigTest.php +++ b/dev/tests/unit/testsuite/Magento/Framework/Simplexml/ConfigTest.php @@ -25,12 +25,213 @@ namespace Magento\Framework\Simplexml; class ConfigTest extends \PHPUnit_Framework_TestCase { + /** + * @var Config + */ + protected $config; + + protected function setUp() + { + $this->config = new Config(); + } + + public function testConstruct() + { + $xml = '<root><node1><node2/></node1><node3><node4/></node3></root>'; + $file = __DIR__ . '/_files/data.xml'; + + $config = new Config($xml); + $this->assertXmlStringEqualsXmlString($xml, $config->getXmlString()); + + $config = new Config($file); + $this->assertXmlStringEqualsXmlString($xml, $config->getXmlString()); + + /** @var Element $simpleXml */ + $simpleXml = simplexml_load_string(file_get_contents($file), 'Magento\Framework\Simplexml\Element'); + $config = new Config($simpleXml); + $this->assertXmlStringEqualsXmlString($xml, $config->getXmlString()); + } + public function testLoadString() { $xml = '<?xml version="1.0"?><config><node>1</node></config>'; - $config = new \Magento\Framework\Simplexml\Config(); - $this->assertFalse($config->loadString('')); - $this->assertTrue($config->loadString($xml)); - $this->assertXmlStringEqualsXmlString($xml, $config->getXmlString()); + $this->assertFalse($this->config->loadString('')); + $this->assertTrue($this->config->loadString($xml)); + $this->assertXmlStringEqualsXmlString($xml, $this->config->getXmlString()); + $this->setExpectedException( + 'PHPUnit_Framework_Error_Warning', + 'simplexml_load_string(): Entity: line 1: parser error : Start tag expected,' + ); + $this->assertFalse($this->config->loadString('wrong_path')); + } + + public function testLoadDom() + { + $this->config->loadString('<?xml version="1.0"?><config><node>1</node></config>'); + $this->assertTrue($this->config->loadDom($this->config->getNode())); + } + + public function testGetNode() + { + $this->assertFalse($this->config->getNode()); + $config = new Config(__DIR__ . '/_files/mixed_data.xml'); + $this->assertSame('Value 2.1', $config->getNode('node_2/node_2_1')->asArray()); + } + + public function testGetXpath() + { + $this->assertFalse($this->config->getXpath('wrong_xpath')); + $config = new Config(__DIR__ . '/_files/mixed_data.xml'); + $this->assertFalse($config->getXpath('wrong_xpath')); + $element = $config->getXpath('/root/node_2/node_2_1'); + $this->assertArrayHasKey(0, $element); + $this->assertInstanceOf('Magento\Framework\Simplexml\Element', $element[0]); + $this->assertSame('Value 2.1', $element[0]->asArray()); + } + + public function testLoadWrongFile() + { + $this->assertFalse($this->config->loadFile('wrong_file')); + } + + public function testSetCacheChecksum() + { + $this->config->setCacheChecksum(null); + $this->assertNull($this->config->getCacheChecksum()); + $this->config->setCacheChecksum(false); + $this->assertFalse($this->config->getCacheChecksum()); + $this->config->setCacheChecksum(0); + $this->assertFalse($this->config->getCacheChecksum()); + $this->config->setCacheChecksum('CacheChecksum'); + $this->assertSame('415a5472d4f94b71ff80fd1c8e9eca7f', $this->config->getCacheChecksum()); + } + + public function testUpdateCacheChecksum() + { + $this->config->setCacheChecksum('CacheChecksum'); + $this->config->updateCacheChecksum(false); + $this->assertFalse($this->config->getCacheChecksum()); + + $this->config->setCacheChecksum('CacheChecksum'); + $this->config->updateCacheChecksum(0); + $this->assertFalse($this->config->getCacheChecksum()); + + $this->config->setCacheChecksum('CacheChecksum'); + $this->config->updateCacheChecksum('UpdateCacheChecksum'); + $this->assertSame('894eb161d8e1e48f825d05fdac61afae', $this->config->getCacheChecksum()); + + $this->config->setCacheChecksum(false); + $this->config->updateCacheChecksum('UpdateCacheChecksum'); + $this->assertFalse($this->config->getCacheChecksum()); + } + + public function testValidateCacheChecksum() + { + $this->config->setCacheChecksum(false); + $this->assertFalse($this->config->validateCacheChecksum()); + + $this->config->setCacheChecksum(null); + $this->assertTrue($this->config->validateCacheChecksum()); + + $this->config->setCacheId('cacheId'); + $this->config->setCacheChecksum('CacheChecksum'); + $cache = $this->getMock('Magento\Framework\Simplexml\Config\Cache\File', ['load']); + $cache->expects($this->once())->method('load')->with('cacheId__CHECKSUM') + ->will($this->returnValue('415a5472d4f94b71ff80fd1c8e9eca7f')); + $this->config->setCache($cache); + $this->assertTrue($this->config->validateCacheChecksum()); + } + + public function testLoadCache() + { + $this->config->setCacheChecksum(false); + $this->assertFalse($this->config->loadCache()); + + $this->config->setCacheId('cacheId'); + $this->config->setCacheChecksum('CacheChecksum'); + $cache = $this->getMock('Magento\Framework\Simplexml\Config\Cache\File', ['load']); + $this->config->setCache($cache); + + $cache->expects($this->at(0))->method('load')->with('cacheId__CHECKSUM') + ->will($this->returnValue('415a5472d4f94b71ff80fd1c8e9eca7f')); + $cache->expects($this->at(1))->method('load')->with('cacheId') + ->will($this->returnValue('')); + $this->config->setCache($cache); + $cache->expects($this->at(2))->method('load')->with('cacheId__CHECKSUM') + ->will($this->returnValue('415a5472d4f94b71ff80fd1c8e9eca7f')); + $cache->expects($this->at(3))->method('load')->with('cacheId') + ->will($this->returnValue('<?xml version="1.0"?><config><node>1</node></config>')); + + $this->assertFalse($this->config->loadCache()); + $this->assertTrue($this->config->loadCache()); + } + + public function testSaveCache() + { + $xml = '<config><node>1</node></config>'; + + $cache = $this->getMock('Magento\Framework\Simplexml\Config\Cache\File', ['save']); + $cache->expects($this->at(0))->method('save') + ->with(null, 'cacheId__CHECKSUM', array('cacheTags'), 10) + ->will($this->returnValue(true)); + $cache->expects($this->at(1))->method('save') + ->with($xml, 'cacheId', array('cacheTags'), 10) + ->will($this->returnValue(true)); + $cache->expects($this->exactly(2))->method('save'); + + $this->config->loadString($xml); + $this->config->setCache($cache); + $this->config->setCacheChecksum(null); + $this->config->setCacheTags(array('cacheTags')); + $this->config->setCacheId('cacheId'); + $this->config->setCacheLifetime(10); + + $this->config->saveCache(); + $this->config->saveCache(); + $this->config->setCacheSaved(false); + $this->config->setCacheChecksum(false); + $this->config->saveCache(); + } + + public function testRemoveCache() + { + $cache = $this->getMock('Magento\Framework\Simplexml\Config\Cache\File', ['remove']); + $cache->expects($this->at(0))->method('remove') + ->with('cacheId') + ->will($this->returnValue(true)); + $cache->expects($this->at(1))->method('remove') + ->with('cacheId__CHECKSUM') + ->will($this->returnValue(true)); + $cache->expects($this->exactly(2))->method('remove'); + + $this->config->setCache($cache); + $this->config->setCacheId('cacheId'); + $this->config->removeCache(); + } + + public function testSetNode() + { + $config = new Config(__DIR__ . '/_files/mixed_data.xml'); + $config->setNode('node_2', 'new_value'); + $this->assertSame('new_value', $config->getNode('node_2')->asArray()); + } + + public function testApplyExtends() + { + $config = new Config(__DIR__ . '/_files/extend_data.xml'); + $config->applyExtends(); + $this->assertEquals( + $config->getNode('node_1/node_1_1')->asArray(), + $config->getNode('node_3/node_1_1')->asArray() + ); + $config = new Config(__DIR__ . '/_files/data.xml'); + $config->applyExtends(); + } + + public function testExtendNode() + { + $config = new Config(__DIR__ . '/_files/data.xml'); + $config->extend(new Config('<config><node>1</node></config>')); + $this->assertSame('1', $config->getNode('node')->asArray()); } -} +} \ No newline at end of file diff --git a/dev/tests/unit/testsuite/Magento/Framework/Simplexml/_files/extend_data.xml b/dev/tests/unit/testsuite/Magento/Framework/Simplexml/_files/extend_data.xml new file mode 100644 index 0000000000000000000000000000000000000000..2043ba099d82e20898239ee25ad5546d00dac6f7 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Framework/Simplexml/_files/extend_data.xml @@ -0,0 +1,38 @@ +<?xml version="1.0"?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<root> + <node_1 id='1'> + Value 1 + <node_1_1> + Value 1.1 + <node_1_1_1>Value 1.1.1</node_1_1_1> + </node_1_1> + </node_1> + <node_2> + <node_2_1>Value 2.1</node_2_1> + </node_2> + <node_3 extends="node_1"/> +</root> diff --git a/dev/tests/unit/testsuite/Magento/Framework/Stdlib/DateTime/DateTimeTest.php b/dev/tests/unit/testsuite/Magento/Framework/Stdlib/DateTime/DateTimeTest.php new file mode 100644 index 0000000000000000000000000000000000000000..fe7d96dcdf2cae92715de2eab05adc753dab6900 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Framework/Stdlib/DateTime/DateTimeTest.php @@ -0,0 +1,118 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Framework\Stdlib\DateTime; + +class DateTimeTest extends \PHPUnit_Framework_TestCase +{ + /** @var \Magento\Framework\Stdlib\DateTime\DateTime */ + protected $dateTime; + + /** @var \Magento\Framework\Stdlib\DateTime\Date */ + protected $date; + + /** @var \Magento\Framework\Stdlib\DateTime\Timezone|\PHPUnit_Framework_MockObject_MockObject */ + protected $localeDate; + + protected function setUp() + { + require_once __DIR__ . '/../_files/gmdate_mock.php'; + $this->date = new \Magento\Framework\Stdlib\DateTime\Date(1403832149); + + $this->localeDate = $this->getMock( + 'Magento\Framework\Stdlib\DateTime\Timezone', + array('getConfigTimezone', 'date'), + array(), + '', + false + ); + $this->localeDate->expects($this->any())->method('getConfigTimezone') + ->will($this->returnValue('America/Los_Angeles')); + $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this); + $this->dateTime = $objectManager->getObject( + 'Magento\Framework\Stdlib\DateTime\DateTime', + array('localeDate' => $this->localeDate) + ); + } + + public function testCalculateOffset() + { + $this->assertSame(-28800, $this->dateTime->calculateOffset()); + $this->assertSame(10800, $this->dateTime->calculateOffset('Europe/Kiev')); + } + + public function testGmtDate() + { + $time = 1403858418; + $this->localeDate->expects($this->any())->method('date')->with($time) + ->will($this->returnValue($this->date)); + $this->assertSame(false, $this->dateTime->gmtDate(null, 'tro-lo-lo')); + $this->assertSame('2014-06-27', $this->dateTime->gmtDate('Y-m-d', $time)); + } + + public function testDate() + { + $time = 1403858418; + $this->localeDate->expects($this->any())->method('date')->with($time) + ->will($this->returnValue($this->date)); + $this->assertSame('2014-06-26', $this->dateTime->date('Y-m-d', $time)); + $this->assertSame('2014-06-26 11:22:29', $this->dateTime->date(null, $time)); + } + + public function testGmtTimestamp() + { + $time = time(); + $this->localeDate->expects($this->at(0))->method('date')->with($time) + ->will($this->returnValue($this->date)); + $this->localeDate->expects($this->at(1))->method('date')->with(strtotime("10 September 2000")) + ->will($this->returnValue($this->date)); + + $this->assertSame(1403857349, $this->dateTime->gmtTimestamp($time)); + $this->assertSame(1403857349, $this->dateTime->gmtTimestamp("10 September 2000")); + $this->assertSame(false, $this->dateTime->gmtTimestamp("la-la-la")); + $this->assertSame(1404377188, $this->dateTime->gmtTimestamp()); + } + + public function testTimestamp() + { + $time = time(); + $this->localeDate->expects($this->at(0))->method('date')->with(1404377188) + ->will($this->returnValue($this->date)); + $this->localeDate->expects($this->at(1))->method('date')->with($time) + ->will($this->returnValue($this->date)); + $this->localeDate->expects($this->at(2))->method('date')->with(strtotime("10 September 2000")) + ->will($this->returnValue($this->date)); + + $this->assertSame(1403806949, $this->dateTime->timestamp()); + $this->assertSame(1403806949, $this->dateTime->timestamp($time)); + $this->assertSame(1403806949, $this->dateTime->timestamp("10 September 2000")); + } + + public function testGetGmtOffset() + { + $this->assertSame(-28800, $this->dateTime->getGmtOffset('seconds')); + $this->assertSame(-28800, $this->dateTime->getGmtOffset('seconds11')); + $this->assertSame(-480, $this->dateTime->getGmtOffset('minutes')); + $this->assertSame(-8, $this->dateTime->getGmtOffset('hours')); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Framework/Stdlib/DateTime/TimezoneTest.php b/dev/tests/unit/testsuite/Magento/Framework/Stdlib/DateTime/TimezoneTest.php new file mode 100644 index 0000000000000000000000000000000000000000..3b9e726bb7b21e055282fa3e74a9fe2c68f6561b --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Framework/Stdlib/DateTime/TimezoneTest.php @@ -0,0 +1,195 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Framework\Stdlib\DateTime; + +class TimezoneTest extends \PHPUnit_Framework_TestCase +{ + /** @var \Magento\Framework\Stdlib\DateTime\Timezone */ + protected $timezone; + + /** @var \Magento\Backend\Model\Locale\Resolver\Interceptor|\PHPUnit_Framework_MockObject_MockObject */ + protected $localeResolver; + + /** @var \Magento\Framework\Stdlib\DateTime\DateFactory|\PHPUnit_Framework_MockObject_MockObject */ + protected $dateFactory; + + /** @var \Magento\Framework\App\Config|\PHPUnit_Framework_MockObject_MockObject */ + protected $scopeConfig; + + /** @var \Magento\Framework\Locale|\PHPUnit_Framework_MockObject_MockObject */ + protected $locale; + + /** @var \Magento\Framework\Stdlib\DateTime|\PHPUnit_Framework_MockObject_MockObject */ + protected $dateTime; + + /** @var \Magento\Store\Model\Resolver\Store|\PHPUnit_Framework_MockObject_MockObject */ + protected $scopeResolver; + + protected function setUp() + { + $this->locale = $this->getMock('Magento\Framework\Locale', ['getTranslation', 'toString'], [], '', false); + $this->dateTime = $this->getMock('Magento\Framework\Stdlib\DateTime', ['isEmptyDate'], [], '', false); + $this->scopeConfig = $this->getMock('Magento\Framework\App\Config', ['getValue'], [], '', false); + $this->localeResolver = $this->getMock('Magento\Backend\Model\Locale\Resolver', ['getLocale'], [], '', false); + $this->dateFactory = $this->getMock('Magento\Framework\Stdlib\DateTime\DateFactory', ['create'], [], '', false); + $this->scopeResolver = $this->getMock('Magento\Store\Model\Resolver\Store', ['getScope'], [], '', false); + + $this->localeResolver->expects($this->any())->method('getLocale')->will($this->returnValue($this->locale)); + $this->scopeConfig->expects($this->any())->method('getValue')->with('general/locale/timezone', 'store') + ->will($this->returnValue('America/Los_Angeles')); + $this->locale->expects($this->any())->method('toString')->will($this->returnValue('en_US')); + + $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this); + $this->timezone = $objectManager->getObject( + 'Magento\Framework\Stdlib\DateTime\Timezone', + [ + 'scopeResolver' => $this->scopeResolver, + 'localeResolver' => $this->localeResolver, + 'dateTime' => $this->dateTime, + 'dateFactory' => $this->dateFactory, + 'scopeConfig' => $this->scopeConfig, + 'scopeType' => 'store', + 'defaultTimezonePath' => 'general/locale/timezone' + ] + ); + } + + public function testGetDateFormatWithLongYear() + { + $this->markTestIncomplete('MAGETWO-26166'); + $this->locale->staticExpects($this->once())->method('getTranslation')->with('short', 'date') + ->will($this->returnValue('M/d/yy')); + $this->assertSame('M/d/yyyy', $this->timezone->getDateFormatWithLongYear()); + } + + public function testDate() + { + $this->dateFactory->expects($this->any())->method('create') + ->with(['date' => null, 'part' => null, 'locale' => $this->locale]) + ->will($this->returnValue(new \Magento\Framework\Stdlib\DateTime\Date(null, null, $this->locale))); + $date = $this->timezone->date(); + $this->assertSame('America/Los_Angeles', $date->getTimezone()); + } + + public function testFormatDate() + { + $time = date('M j, Y'); + $date1 = new \Magento\Framework\Stdlib\DateTime\Date(1347260400, null, $this->locale); + $date2 = new \Magento\Framework\Stdlib\DateTime\Date(strtotime($time), null, $this->locale); + + $this->dateFactory->expects($this->at(0))->method('create') + ->will($this->returnValue($date1)); + $this->dateFactory->expects($this->at(1))->method('create') + ->will($this->returnValue($date1)); + $this->dateFactory->expects($this->at(2))->method('create') + ->will($this->returnValue($date2)); + $this->dateFactory->expects($this->exactly(3))->method('create'); + + $this->markTestIncomplete('MAGETWO-26166'); + $this->locale->staticExpects($this->at(0))->method('getTranslation') + ->with('medium', 'date', $this->locale) + ->will($this->returnValue('MMM d, y')); + $this->locale->staticExpects($this->at(1))->method('getTranslation') + ->with('medium', 'time', $this->locale) + ->will($this->returnValue('h:mm:ss a')); + $this->locale->staticExpects($this->at(2))->method('getTranslation') + ->with('medium', 'date', $this->locale) + ->will($this->returnValue('MMM d, y')); + $this->locale->staticExpects($this->at(3))->method('getTranslation') + ->with('medium', 'date', $this->locale) + ->will($this->returnValue('MMM d, y')); + $this->locale->staticExpects($this->exactly(4))->method('getTranslation'); + + $this->assertSame( + 'Sep 10, 2012 12:00:00 AM', + $this->timezone->formatDate("10 September 2012", 'medium', true) + ); + $this->assertSame( + 'Sep 10, 2012', + $this->timezone->formatDate("10 September 2012", 'medium') + ); + $this->assertSame( + $time, + $this->timezone->formatDate(null, 'medium') + ); + $this->assertSame('date', $this->timezone->formatDate('date', 'wrong')); + $this->assertSame('', $this->timezone->formatDate('date')); + } + + public function testFormatTime() + { + $time = date('M j, Y g:m:s A'); + $date1 = new \Magento\Framework\Stdlib\DateTime\Date(1347260470, null, $this->locale); + $date2 = new \Magento\Framework\Stdlib\DateTime\Date(strtotime($time), null, $this->locale); + + $this->dateFactory->expects($this->at(0))->method('create') + ->with(['date' => 1347260470, 'part' => null, 'locale' => $this->locale]) + ->will($this->returnValue($date1)); + $this->dateFactory->expects($this->at(1))->method('create')->will($this->returnValue($date2)); + $this->dateFactory->expects($this->exactly(2))->method('create'); + + $this->markTestIncomplete('MAGETWO-26166'); + $this->locale->staticExpects($this->at(0))->method('getTranslation') + ->with('medium', 'time', $this->locale) + ->will($this->returnValue('h:mm:ss a')); + $this->locale->staticExpects($this->at(1))->method('getTranslation') + ->with('medium', 'time', $this->locale) + ->will($this->returnValue('h:mm:ss a')); + $this->locale->staticExpects($this->at(2))->method('getTranslation') + ->with('medium', 'date', $this->locale) + ->will($this->returnValue('MMM d, y')); + $this->locale->staticExpects($this->at(3))->method('getTranslation') + ->with('medium', 'time', $this->locale) + ->will($this->returnValue('h:mm:ss a')); + $this->locale->staticExpects($this->exactly(4))->method('getTranslation'); + + $this->assertSame('10 September 2012', $this->timezone->formatTime('10 September 2012', 'wrong_type')); + $this->assertSame('12:01:10 AM', $this->timezone->formatTime('September 10, 2012 12:01:10 AM', 'medium')); + $this->assertSame('12:01:10 AM', $this->timezone->formatTime($date1, 'medium')); + $this->assertSame($time, $this->timezone->formatTime(null, 'medium', true)); + } + + public function testUtcDate() + { + $this->dateFactory->expects($this->any())->method('create') + ->with(['date' => 1347260470, 'part' => null, 'locale' => $this->locale]) + ->will($this->returnValue(new \Magento\Framework\Stdlib\DateTime\Date(1347260470, null, $this->locale))); + + $date = $this->timezone->utcDate('general/locale/timezone', 1347260470); + $this->assertSame('UTC', $date->getTimezone()); + } + + public function testIsScopeDateInInterval() + { + $scope = $this->getMock('Magento\Framework\App\ScopeInterface', ['getCode', 'getId']); + $this->scopeResolver->expects($this->any())->method('getScope')->will($this->returnValue($scope)); + $this->dateTime->expects($this->at(0))->method('isEmptyDate')->will($this->returnValue(false)); + $this->dateTime->expects($this->at(1))->method('isEmptyDate')->will($this->returnValue(false)); + $this->dateTime->expects($this->at(2))->method('isEmptyDate')->will($this->returnValue(true)); + $this->dateTime->expects($this->at(3))->method('isEmptyDate')->will($this->returnValue(true)); + + $this->assertFalse($this->timezone->isScopeDateInInterval('store')); + $this->assertTrue($this->timezone->isScopeDateInInterval('store', null, '10 September 2036')); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Framework/Stdlib/StringTest.php b/dev/tests/unit/testsuite/Magento/Framework/Stdlib/StringTest.php index 723d1514f96333bb804da91951ba9b3b1b5395dd..d584c6f8f74a82032c4c3f514ed15cc3ed962886 100644 --- a/dev/tests/unit/testsuite/Magento/Framework/Stdlib/StringTest.php +++ b/dev/tests/unit/testsuite/Magento/Framework/Stdlib/StringTest.php @@ -50,6 +50,10 @@ class StringTest extends \PHPUnit_Framework_TestCase array('12345', '123', '12345', '6789'), $this->_string->split('12345 123 123456789', 5, true, true) ); + $this->assertEquals( + array('1234', '5', '123', '1234', '5678', '9'), + $this->_string->split('12345 123 123456789', 4, true, true) + ); } /** @@ -70,6 +74,17 @@ class StringTest extends \PHPUnit_Framework_TestCase $this->assertEquals($string, $this->_string->cleanString($string)); } + public function testSubstr() + { + $this->assertSame('tring', $this->_string->substr('string', 1)); + } + + public function testStrrev() + { + $this->assertSame('0987654321', $this->_string->strrev('1234567890')); + $this->assertSame('', $this->_string->strrev('')); + } + /** * @covers \Magento\Framework\Stdlib\String::strpos */ diff --git a/dev/tests/unit/testsuite/Magento/Framework/Stdlib/_files/gmdate_mock.php b/dev/tests/unit/testsuite/Magento/Framework/Stdlib/_files/gmdate_mock.php new file mode 100644 index 0000000000000000000000000000000000000000..627e244e5b2fb6c2115994429ca3fda7cc804dd4 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Framework/Stdlib/_files/gmdate_mock.php @@ -0,0 +1,32 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Framework\Stdlib\DateTime; + +/** + * Override standard function + */ +function gmdate() +{ + return 1404377188; +} \ No newline at end of file diff --git a/dev/tests/unit/testsuite/Magento/Framework/TranslateTest.php b/dev/tests/unit/testsuite/Magento/Framework/TranslateTest.php index 2301ef7bb2ce322abde52d7ed8fabbdc4d32eca8..9c6296ef00dacff4cc08d1240009b77e5c1c3096 100644 --- a/dev/tests/unit/testsuite/Magento/Framework/TranslateTest.php +++ b/dev/tests/unit/testsuite/Magento/Framework/TranslateTest.php @@ -23,90 +23,88 @@ */ namespace Magento\Framework; -use Magento\TestFramework\Matcher\MethodInvokedAtIndex; - /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class TranslateTest extends \PHPUnit_Framework_TestCase { /** @var Translate */ - protected $_translate; + protected $translate; - /** @var \Magento\Framework\View\DesignInterface */ - protected $_viewDesign; + /** @var \Magento\Framework\View\DesignInterface|\PHPUnit_Framework_MockObject_MockObject */ + protected $viewDesign; - /** @var \Magento\Framework\Cache\FrontendInterface */ - protected $_cache; + /** @var \Magento\Framework\Cache\FrontendInterface|\PHPUnit_Framework_MockObject_MockObject */ + protected $cache; - /** @var \Magento\Framework\View\FileSystem */ - protected $_viewFileSystem; + /** @var \Magento\Framework\View\FileSystem|\PHPUnit_Framework_MockObject_MockObject */ + protected $viewFileSystem; - /** @var \Magento\Framework\Module\ModuleList */ - protected $_moduleList; + /** @var \Magento\Framework\Module\ModuleList|\PHPUnit_Framework_MockObject_MockObject */ + protected $moduleList; - /** @var \Magento\Framework\Module\Dir\Reader */ - protected $_modulesReader; + /** @var \Magento\Framework\Module\Dir\Reader|\PHPUnit_Framework_MockObject_MockObject */ + protected $modulesReader; - /** @var \Magento\Framework\App\ScopeResolverInterface */ - protected $_scopeResolver; + /** @var \Magento\Framework\App\ScopeResolverInterface|\PHPUnit_Framework_MockObject_MockObject */ + protected $scopeResolver; - /** @var \Magento\Framework\Translate\ResourceInterface */ - protected $_resource; + /** @var \Magento\Framework\Translate\ResourceInterface|\PHPUnit_Framework_MockObject_MockObject */ + protected $resource; - /** @var \Magento\Framework\Locale\ResolverInterface */ - protected $_locale; + /** @var \Magento\Framework\Locale\ResolverInterface|\PHPUnit_Framework_MockObject_MockObject */ + protected $locale; - /** @var \Magento\Framework\App\State */ - protected $_appState; + /** @var \Magento\Framework\App\State|\PHPUnit_Framework_MockObject_MockObject */ + protected $appState; - /** @var \Magento\Framework\App\Filesystem */ - protected $_filesystem; + /** @var \Magento\Framework\App\Filesystem|\PHPUnit_Framework_MockObject_MockObject */ + protected $filesystem; - /** @var \Magento\Framework\App\RequestInterface */ - protected $_request; + /** @var \Magento\Framework\App\RequestInterface|\PHPUnit_Framework_MockObject_MockObject */ + protected $request; - /** @var \Magento\Framework\File\Csv */ - protected $_csvParser; + /** @var \Magento\Framework\File\Csv|\PHPUnit_Framework_MockObject_MockObject */ + protected $csvParser; /** @var \Magento\Framework\App\Language\Dictionary|\PHPUnit_Framework_MockObject_MockObject */ - protected $_packDictionary; + protected $packDictionary; - /** @var \Magento\Framework\Filesystem\Directory\ReadInterface */ - protected $_directory; + /** @var \Magento\Framework\Filesystem\Directory\ReadInterface|\PHPUnit_Framework_MockObject_MockObject */ + protected $directory; public function setUp() { - $this->_viewDesign = $this->getMock('\Magento\Framework\View\DesignInterface', [], [], '', false); - $this->_cache = $this->getMock('\Magento\Framework\Cache\FrontendInterface', [], [], '', false); - $this->_viewFileSystem = $this->getMock('\Magento\Framework\View\FileSystem', [], [], '', false); - $this->_moduleList = $this->getMock('\Magento\Framework\Module\ModuleList', [], [], '', false); - $this->_modulesReader = $this->getMock('\Magento\Framework\Module\Dir\Reader', [], [], '', false); - $this->_scopeResolver = $this->getMock('\Magento\Framework\App\ScopeResolverInterface', [], [], '', false); - $this->_resource = $this->getMock('\Magento\Framework\Translate\ResourceInterface', [], [], '', false); - $this->_locale = $this->getMock('\Magento\Framework\Locale\ResolverInterface', [], [], '', false); - $this->_appState = $this->getMock('\Magento\Framework\App\State', [], [], '', false); - $this->_request = $this->getMock('\Magento\Framework\App\RequestInterface', [], [], '', false); - $this->_csvParser = $this->getMock('\Magento\Framework\File\Csv', [], [], '', false); - $this->_packDictionary = $this->getMock('\Magento\Framework\App\Language\Dictionary', [], [], '', false); - $this->_directory = $this->getMock('\Magento\Framework\Filesystem\Directory\ReadInterface', [], [], '', false); + $this->viewDesign = $this->getMock('\Magento\Framework\View\DesignInterface', [], [], '', false); + $this->cache = $this->getMock('\Magento\Framework\Cache\FrontendInterface', [], [], '', false); + $this->viewFileSystem = $this->getMock('\Magento\Framework\View\FileSystem', [], [], '', false); + $this->moduleList = $this->getMock('\Magento\Framework\Module\ModuleList', [], [], '', false); + $this->modulesReader = $this->getMock('\Magento\Framework\Module\Dir\Reader', [], [], '', false); + $this->scopeResolver = $this->getMock('\Magento\Framework\App\ScopeResolverInterface', [], [], '', false); + $this->resource = $this->getMock('\Magento\Framework\Translate\ResourceInterface', [], [], '', false); + $this->locale = $this->getMock('\Magento\Framework\Locale\ResolverInterface', [], [], '', false); + $this->appState = $this->getMock('\Magento\Framework\App\State', [], [], '', false); + $this->request = $this->getMock('\Magento\Framework\App\RequestInterface', [], [], '', false); + $this->csvParser = $this->getMock('\Magento\Framework\File\Csv', [], [], '', false); + $this->packDictionary = $this->getMock('\Magento\Framework\App\Language\Dictionary', [], [], '', false); + $this->directory = $this->getMock('\Magento\Framework\Filesystem\Directory\ReadInterface', [], [], '', false); $filesystem = $this->getMock('\Magento\Framework\App\Filesystem', [], [], '', false); - $filesystem->expects($this->once())->method('getDirectoryRead')->will($this->returnValue($this->_directory)); - - $this->_translate = new Translate( - $this->_viewDesign, - $this->_cache, - $this->_viewFileSystem, - $this->_moduleList, - $this->_modulesReader, - $this->_scopeResolver, - $this->_resource, - $this->_locale, - $this->_appState, + $filesystem->expects($this->once())->method('getDirectoryRead')->will($this->returnValue($this->directory)); + + $this->translate = new Translate( + $this->viewDesign, + $this->cache, + $this->viewFileSystem, + $this->moduleList, + $this->modulesReader, + $this->scopeResolver, + $this->resource, + $this->locale, + $this->appState, $filesystem, - $this->_request, - $this->_csvParser, - $this->_packDictionary + $this->request, + $this->csvParser, + $this->packDictionary ); } @@ -119,30 +117,37 @@ class TranslateTest extends \PHPUnit_Framework_TestCase */ public function testLoadData($area, $forceReload, $cachedData) { - $this->_expectsSetConfig('themeId'); + $this->expectsSetConfig('themeId'); - $this->_cache->expects($this->exactly($forceReload ? 0 : 1)) + $this->cache->expects($this->exactly($forceReload ? 0 : 1)) ->method('load') ->will($this->returnValue(serialize($cachedData))); if (!$forceReload && $cachedData !== false) { - $this->_translate->loadData($area, $forceReload); - $this->assertEquals($cachedData, $this->_translate->getData()); + $this->translate->loadData($area, $forceReload); + $this->assertEquals($cachedData, $this->translate->getData()); return; } - $this->_directory->expects($this->any())->method('isExist')->will($this->returnValue(true)); + $this->directory->expects($this->any())->method('isExist')->will($this->returnValue(true)); // _loadModuleTranslation() $modules = [['name' => 'module']]; - $this->_moduleList->expects($this->once())->method('getModules')->will($this->returnValue($modules)); + $this->moduleList->expects($this->once())->method('getModules')->will($this->returnValue($modules)); $moduleData = [ 'module original' => 'module translated', - 'module original2' => 'module original2' + 'module theme' => 'module-theme original translated', + 'module pack' => 'module-pack original translated', + 'module db' => 'module-db original translated', + ]; + $this->modulesReader->expects($this->any())->method('getModuleDir')->will($this->returnValue('/app/module')); + $themeData = [ + 'theme original' => 'theme translated', + 'module theme' => 'theme translated overwrite', + 'module pack' => 'theme-pack translated overwrite', + 'module db' => 'theme-db translated overwrite', ]; - $this->_modulesReader->expects($this->any())->method('getModuleDir')->will($this->returnValue('/app/module')); - $themeData = ['theme original' => 'theme translated']; - $this->_csvParser->expects($this->any()) + $this->csvParser->expects($this->any()) ->method('getDataPairs') ->will( $this->returnValueMap( @@ -155,30 +160,40 @@ class TranslateTest extends \PHPUnit_Framework_TestCase ); // _loadThemeTranslation() - $this->_viewFileSystem->expects($this->any()) + $this->viewFileSystem->expects($this->any()) ->method('getLocaleFileName') ->will($this->returnValue('/theme.csv')); // _loadPackTranslation - $packData = ['pack original' => 'pack translated']; - $this->_packDictionary->expects($this->once())->method('getDictionary')->will($this->returnValue($packData)); + $packData = [ + 'pack original' => 'pack translated', + 'module pack' => 'pack translated overwrite', + 'module db' => 'pack-db translated overwrite', + ]; + $this->packDictionary->expects($this->once())->method('getDictionary')->will($this->returnValue($packData)); // _loadDbTranslation() - $dbData = ['db original' => 'db translated']; - $this->_resource->expects($this->any())->method('getTranslationArray')->will($this->returnValue($dbData)); + $dbData = [ + 'db original' => 'db translated', + 'module db' => 'db translated overwrite', + ]; + $this->resource->expects($this->any())->method('getTranslationArray')->will($this->returnValue($dbData)); - $this->_cache->expects($this->exactly($forceReload ? 0 : 1)) + $this->cache->expects($this->exactly($forceReload ? 0 : 1)) ->method('save'); - $this->_translate->loadData($area, $forceReload); + $this->translate->loadData($area, $forceReload); $expected = [ 'module original' => 'module translated', + 'module theme' => 'theme translated overwrite', + 'module pack' => 'pack translated overwrite', + 'module db' => 'db translated overwrite', 'theme original' => 'theme translated', 'pack original' => 'pack translated', - 'db original' => 'db translated' + 'db original' => 'db translated', ]; - $this->assertEquals($expected, $this->_translate->getData()); + $this->assertEquals($expected, $this->translate->getData()); } public function dataProviderForTestLoadData() @@ -186,12 +201,17 @@ class TranslateTest extends \PHPUnit_Framework_TestCase $cachedData = ['cached 1' => 'translated 1', 'cached 2' => 'translated 2']; return [ ['adminhtml', true, false], + ['adminhtml', true, $cachedData], ['adminhtml', false, $cachedData], + ['adminhtml', false, false], ['frontend', true, false], + ['frontend', true, $cachedData], ['frontend', false, $cachedData], + ['frontend', false, false], [null, true, false], + [null, true, $cachedData], [null, false, $cachedData], - ['adminhtml', false, false] + [null, false, false] ]; } @@ -202,12 +222,12 @@ class TranslateTest extends \PHPUnit_Framework_TestCase */ public function testGetData($data, $result) { - $this->_cache->expects($this->once()) + $this->cache->expects($this->once()) ->method('load') ->will($this->returnValue(serialize($data))); - $this->_expectsSetConfig('themeId'); - $this->_translate->loadData('frontend'); - $this->assertEquals($result, $this->_translate->getData()); + $this->expectsSetConfig('themeId'); + $this->translate->loadData('frontend'); + $this->assertEquals($result, $this->translate->getData()); } public function dataProviderForTestGetData() @@ -221,56 +241,56 @@ class TranslateTest extends \PHPUnit_Framework_TestCase public function testGetLocale() { - $this->_locale->expects($this->once())->method('getLocaleCode')->will($this->returnValue('en_US')); - $this->assertEquals('en_US', $this->_translate->getLocale()); + $this->locale->expects($this->once())->method('getLocaleCode')->will($this->returnValue('en_US')); + $this->assertEquals('en_US', $this->translate->getLocale()); - $this->_locale->expects($this->never())->method('getLocaleCode'); - $this->assertEquals('en_US', $this->_translate->getLocale()); + $this->locale->expects($this->never())->method('getLocaleCode'); + $this->assertEquals('en_US', $this->translate->getLocale()); - $this->_locale->expects($this->never())->method('getLocaleCode'); - $this->_translate->setLocale('en_GB'); - $this->assertEquals('en_GB', $this->_translate->getLocale()); + $this->locale->expects($this->never())->method('getLocaleCode'); + $this->translate->setLocale('en_GB'); + $this->assertEquals('en_GB', $this->translate->getLocale()); } public function testSetLocale() { - $this->_translate->setLocale('en_GB'); - $this->_locale->expects($this->never())->method('getLocaleCode'); - $this->assertEquals('en_GB', $this->_translate->getLocale()); + $this->translate->setLocale('en_GB'); + $this->locale->expects($this->never())->method('getLocaleCode'); + $this->assertEquals('en_GB', $this->translate->getLocale()); } public function testGetTheme() { - $this->_request->expects($this->at(0))->method('getParam')->with('theme')->will($this->returnValue('')); + $this->request->expects($this->at(0))->method('getParam')->with('theme')->will($this->returnValue('')); $requestTheme = array('theme_title' => 'Theme Title'); - $this->_request->expects($this->at(1))->method('getParam')->with('theme') + $this->request->expects($this->at(1))->method('getParam')->with('theme') ->will($this->returnValue($requestTheme)); - $this->assertEquals('theme', $this->_translate->getTheme()); - $this->assertEquals('themeTheme Title', $this->_translate->getTheme()); + $this->assertEquals('theme', $this->translate->getTheme()); + $this->assertEquals('themeTheme Title', $this->translate->getTheme()); } public function testLoadDataNoTheme() { $forceReload = true; - $this->_expectsSetConfig(null, null); - $this->_moduleList->expects($this->once())->method('getModules')->will($this->returnValue([])); - $this->_appState->expects($this->once())->method('getAreaCode')->will($this->returnValue('frontend')); - $this->_packDictionary->expects($this->once())->method('getDictionary')->will($this->returnValue([])); - $this->_resource->expects($this->any())->method('getTranslationArray')->will($this->returnValue([])); - $this->assertEquals($this->_translate, $this->_translate->loadData(null, $forceReload)); + $this->expectsSetConfig(null, null); + $this->moduleList->expects($this->once())->method('getModules')->will($this->returnValue([])); + $this->appState->expects($this->once())->method('getAreaCode')->will($this->returnValue('frontend')); + $this->packDictionary->expects($this->once())->method('getDictionary')->will($this->returnValue([])); + $this->resource->expects($this->any())->method('getTranslationArray')->will($this->returnValue([])); + $this->assertEquals($this->translate, $this->translate->loadData(null, $forceReload)); } /** * Declare calls expectation for setConfig() method */ - protected function _expectsSetConfig($themeId, $localeCode = 'en_US') + protected function expectsSetConfig($themeId, $localeCode = 'en_US') { - $this->_locale->expects($this->any())->method('getLocaleCode')->will($this->returnValue($localeCode)); - $scope = new \Magento\Framework\Object(); - $scopeAdmin = new \Magento\Framework\Object(['code' => 'adminCode', 'id' => 1]); - $this->_scopeResolver->expects($this->any()) + $this->locale->expects($this->any())->method('getLocaleCode')->will($this->returnValue($localeCode)); + $scope = new \Magento\Framework\Object(['code' => 'frontendCode', 'id' => 1]); + $scopeAdmin = new \Magento\Framework\Object(['code' => 'adminCode', 'id' => 0]); + $this->scopeResolver->expects($this->any()) ->method('getScope') ->will( $this->returnValueMap( @@ -281,6 +301,6 @@ class TranslateTest extends \PHPUnit_Framework_TestCase ) ); $designTheme = new \Magento\Framework\Object(['id' => $themeId]); - $this->_viewDesign->expects($this->any())->method('getDesignTheme')->will($this->returnValue($designTheme)); + $this->viewDesign->expects($this->any())->method('getDesignTheme')->will($this->returnValue($designTheme)); } } diff --git a/dev/tests/unit/testsuite/Magento/Framework/View/BlockPoolTest.php b/dev/tests/unit/testsuite/Magento/Framework/View/BlockPoolTest.php new file mode 100644 index 0000000000000000000000000000000000000000..1bddc2cd7a028a0d3a3c9039ab8441ad4edf0830 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Framework/View/BlockPoolTest.php @@ -0,0 +1,96 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Framework\View; + +/** + * Test for view BlockPool model + */ +class BlockPoolTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var BlockPool + */ + protected $blockPool; + + /** + * Block factory + * @var \Magento\Framework\View\Element\BlockFactory|\PHPUnit_Framework_MockObject_MockObject + */ + protected $blockFactory; + + protected function setUp() + { + $this->blockFactory = $this->getMockBuilder('Magento\Framework\View\Element\BlockFactory') + ->disableOriginalConstructor() + ->setMethods(['createBlock']) + ->getMock(); + $this->blockPool = new BlockPool($this->blockFactory); + } + + public function testAdd() + { + $blockName = 'testName'; + $blockClass = '\Magento\Framework\View\BlockPoolTestBlock'; + $arguments = ['key' => 'value']; + + $block = $this->getMock('Magento\Framework\View\BlockPoolTestBlock'); + + $this->blockFactory->expects($this->atLeastOnce()) + ->method('createBlock') + ->with($blockClass, $arguments) + ->will($this->returnValue($block)); + + $this->assertEquals($this->blockPool, $this->blockPool->add($blockName, $blockClass, $arguments)); + + $this->assertEquals([$blockName => $block], $this->blockPool->get()); + $this->assertEquals($block, $this->blockPool->get($blockName)); + $this->assertNull($this->blockPool->get('someWrongName')); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage Invalid Block class name: NotExistingBlockClass + */ + public function testAddWithException() + { + $this->blockPool->add('BlockPoolTestBlock', 'NotExistingBlockClass'); + } +} + +/** + * Class BlockPoolTestBlock mock + */ +class BlockPoolTestBlock implements \Magento\Framework\View\Element\BlockInterface +{ + /** + * Produce and return block's html output + * + * @return string + */ + public function toHtml() + { + return ''; + } +} diff --git a/dev/tests/unit/testsuite/Magento/Framework/View/ConfigTest.php b/dev/tests/unit/testsuite/Magento/Framework/View/ConfigTest.php new file mode 100644 index 0000000000000000000000000000000000000000..81ec3b6d814bcb9e668cdb45e3d08c47536e145e --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Framework/View/ConfigTest.php @@ -0,0 +1,134 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Framework\View; + +use Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper; + +class ConfigTest extends \PHPUnit_Framework_TestCase +{ + /** @var \Magento\Framework\View\Config */ + protected $config; + + /** @var ObjectManagerHelper */ + protected $objectManagerHelper; + + /** @var \Magento\Framework\Module\Dir\Reader|\PHPUnit_Framework_MockObject_MockObject */ + protected $readerMock; + + /** @var \Magento\Framework\App\Filesystem|\PHPUnit_Framework_MockObject_MockObject */ + protected $filesystemMock; + + /** @var \Magento\Framework\View\Asset\Repository|\PHPUnit_Framework_MockObject_MockObject */ + protected $repositoryMock; + + /** @var \Magento\Framework\View\FileSystem|\PHPUnit_Framework_MockObject_MockObject */ + protected $fileSystemMock; + + /** @var \Magento\Framework\Config\FileIteratorFactory|\PHPUnit_Framework_MockObject_MockObject */ + protected $fileIteratorFactoryMock; + + /** @var \Magento\Framework\Filesystem\Directory\ReadInterface|\PHPUnit_Framework_MockObject_MockObject */ + protected $directoryReadMock; + + protected function setUp() + { + $this->readerMock = $this->getMock('Magento\Framework\Module\Dir\Reader', [], [], '', false); + $this->filesystemMock = $this->getMock('Magento\Framework\App\Filesystem', [], [], '', false); + $this->directoryReadMock = $this->getMock('Magento\Framework\Filesystem\Directory\ReadInterface'); + $this->filesystemMock->expects($this->once()) + ->method('getDirectoryRead') + ->with($this->equalTo(\Magento\Framework\App\Filesystem::ROOT_DIR)) + ->will($this->returnValue($this->directoryReadMock)); + $this->repositoryMock = $this->getMock('Magento\Framework\View\Asset\Repository', [], [], '', false); + $this->fileSystemMock = $this->getMock('Magento\Framework\View\FileSystem', [], [], '', false); + $this->fileIteratorFactoryMock = $this->getMock('Magento\Framework\Config\FileIteratorFactory'); + + $this->objectManagerHelper = new ObjectManagerHelper($this); + $this->config = $this->objectManagerHelper->getObject( + 'Magento\Framework\View\Config', + [ + 'moduleReader' => $this->readerMock, + 'filesystem' => $this->filesystemMock, + 'assetRepo' => $this->repositoryMock, + 'viewFileSystem' => $this->fileSystemMock, + 'fileIteratorFactory' => $this->fileIteratorFactoryMock + ] + ); + } + + public function testGetViewConfig() + { + $themeMock = $this->getMock( + 'Magento\Core\Model\Theme', + ['getId', 'getCustomization', 'getCustomViewConfigPath'], + [], + '', + false + ); + $themeMock->expects($this->atLeastOnce()) + ->method('getId') + ->will($this->returnValue(2)); + $themeMock->expects($this->once()) + ->method('getCustomization') + ->will($this->returnSelf()); + $themeMock->expects($this->once()) + ->method('getCustomViewConfigPath') + ->will($this->returnValue('')); + $params = ['themeModel' => $themeMock]; + $configFile = 'config.xml'; + $this->repositoryMock->expects($this->atLeastOnce()) + ->method('updateDesignParams') + ->with($this->equalTo($params)) + ->will($this->returnSelf()); + $iterator = $this->getMock('Magento\Framework\Config\FileIterator', [], [], '', false); + $iterator->expects($this->once()) + ->method('toArray') + ->will($this->returnValue([])); + $this->readerMock->expects($this->once()) + ->method('getConfigurationFiles') + ->with($this->equalTo(basename(\Magento\Framework\View\ConfigInterface::CONFIG_FILE_NAME))) + ->will($this->returnValue($iterator)); + $this->directoryReadMock->expects($this->once()) + ->method('isExist') + ->with($this->anything()) + ->will($this->returnValue(true)); + $this->fileSystemMock->expects($this->once()) + ->method('getFilename') + ->with($this->equalTo(\Magento\Framework\View\ConfigInterface::CONFIG_FILE_NAME), $params) + ->will($this->returnValue($configFile)); + $this->directoryReadMock->expects($this->any()) + ->method('getRelativePath') + ->with($this->equalTo($configFile)) + ->will($this->returnArgument(0)); + $xmlData = '<view><vars module="Magento_Catalog"><var name="test">1</var></vars></view>'; + $this->directoryReadMock->expects($this->once()) + ->method('readFile') + ->with($this->equalTo($configFile)) + ->will($this->returnValue($xmlData)); + $this->assertInstanceOf('Magento\Framework\Config\View', $this->config->getViewConfig($params)); + // lazy load test + $this->assertInstanceOf('Magento\Framework\Config\View', $this->config->getViewConfig($params)); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Framework/View/ContextTest.php b/dev/tests/unit/testsuite/Magento/Framework/View/ContextTest.php new file mode 100644 index 0000000000000000000000000000000000000000..b67be10a2b3ad6be29a658405dc9d789197e19d9 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Framework/View/ContextTest.php @@ -0,0 +1,330 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +/** + * Test for view Context model + */ +namespace Magento\Framework\View; + +class ContextTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var Context + */ + protected $context; + + /** + * @var \Magento\Framework\App\State|\PHPUnit_Framework_MockObject_MockObject + */ + protected $appState; + + /** + * @var \Magento\Framework\App\Request\Http|\PHPUnit_Framework_MockObject_MockObject + */ + protected $request; + + /** + * @var \Magento\Framework\View\DesignInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $design; + + protected function setUp() + { + $this->appState = $this->getMockBuilder('Magento\Framework\App\State') + ->disableOriginalConstructor() + ->getMock(); + + $this->request = $this->getMockBuilder('Magento\Framework\App\Request\Http') + ->disableOriginalConstructor() + ->getMock(); + + $this->design = $this->getMockBuilder('Magento\Framework\View\DesignInterface') + ->disableOriginalConstructor() + ->getMock(); + + $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this); + $this->context = $objectManager->getObject('Magento\Framework\View\Context', array( + 'appState' => $this->appState, + 'request' => $this->request, + 'design' => $this->design + )); + } + + public function testGetCache() + { + $this->assertInstanceOf('\Magento\Framework\App\CacheInterface', $this->context->getCache()); + } + + public function testGetDesignPackage() + { + $this->assertInstanceOf('\Magento\Framework\View\DesignInterface', $this->context->getDesignPackage()); + } + + public function testGetEventManager() + { + $this->assertInstanceOf('\Magento\Framework\Event\ManagerInterface', $this->context->getEventManager()); + } + + public function testGetFrontController() + { + $this->assertInstanceOf( + '\Magento\Framework\App\FrontControllerInterface', + $this->context->getFrontController() + ); + } + + public function testGetLayout() + { + $this->assertInstanceOf('\Magento\Framework\View\LayoutInterface', $this->context->getLayout()); + } + + public function testGetRequest() + { + $this->assertInstanceOf('\Magento\Framework\App\Request\Http', $this->context->getRequest()); + } + + public function testGetSession() + { + $this->assertInstanceOf('\Magento\Framework\Session\SessionManagerInterface', $this->context->getSession()); + } + + public function testGetScopeConfig() + { + $this->assertInstanceOf('\Magento\Framework\App\Config\ScopeConfigInterface', $this->context->getScopeConfig()); + } + + public function testGetTranslator() + { + $this->assertInstanceOf('\Magento\Framework\TranslateInterface', $this->context->getTranslator()); + } + + public function testGetUrlBuilder() + { + $this->assertInstanceOf('\Magento\Framework\UrlInterface', $this->context->getUrlBuilder()); + } + + public function testGetViewConfig() + { + $this->assertInstanceOf('\Magento\Framework\View\ConfigInterface', $this->context->getViewConfig()); + } + + public function testGetCacheState() + { + $this->assertInstanceOf('\Magento\Framework\App\Cache\StateInterface', $this->context->getCacheState()); + } + + public function testGetLogger() + { + $this->assertInstanceOf('\Magento\Framework\Logger', $this->context->getLogger()); + } + + public function testGetAppState() + { + $this->assertInstanceOf('\Magento\Framework\App\State', $this->context->getAppState()); + } + + public function testGetArea() + { + $area = 'frontendArea'; + + $this->appState->expects($this->once()) + ->method('getAreaCode') + ->will($this->returnValue($area)); + + $this->assertEquals($area, $this->context->getArea()); + } + + public function testGetModuleName() + { + $moduleName = 'testModuleName'; + + $this->request->expects($this->once()) + ->method('getModuleName') + ->will($this->returnValue($moduleName)); + + $this->assertEquals($moduleName, $this->context->getModuleName()); + } + + public function testGetFrontName() + { + $frontName = 'testFrontName'; + + $this->request->expects($this->once()) + ->method('getModuleName') + ->will($this->returnValue($frontName)); + + $this->assertEquals($frontName, $this->context->getFrontName()); + } + + public function testGetControllerName() + { + $controllerName = 'testControllerName'; + + $this->request->expects($this->once()) + ->method('getControllerName') + ->will($this->returnValue($controllerName)); + + $this->assertEquals($controllerName, $this->context->getControllerName()); + } + + public function testGetActionName() + { + $actionName = 'testActionName'; + + $this->request->expects($this->once()) + ->method('getActionName') + ->will($this->returnValue($actionName)); + + $this->assertEquals($actionName, $this->context->getActionName()); + } + + public function testGetFullActionName() + { + $frontName = 'testFrontName'; + $controllerName = 'testControllerName'; + $actionName = 'testActionName'; + $fullActionName = 'testfrontname_testcontrollername_testactionname'; + + $this->request->expects($this->once()) + ->method('getModuleName') + ->will($this->returnValue($frontName)); + + $this->request->expects($this->once()) + ->method('getControllerName') + ->will($this->returnValue($controllerName)); + + $this->request->expects($this->once()) + ->method('getActionName') + ->will($this->returnValue($actionName)); + + $this->assertEquals($fullActionName, $this->context->getFullActionName()); + } + + /** + * @param string $headerAccept + * @param string $acceptType + * + * @dataProvider getAcceptTypeDataProvider + */ + public function testGetAcceptType($headerAccept, $acceptType) + { + $this->request->expects($this->once()) + ->method('getHeader') + ->with('Accept') + ->will($this->returnValue($headerAccept)); + + $this->assertEquals($acceptType, $this->context->getAcceptType()); + } + + public function getAcceptTypeDataProvider() + { + return [ + ['json', 'json'], + ['testjson', 'json'], + ['soap', 'soap'], + ['testsoap', 'soap'], + ['text/html', 'html'], + ['testtext/html', 'html'], + ['xml', 'xml'], + ['someElse', 'xml'], + ]; + } + + public function testGetPost() + { + $key = 'getParamName'; + $default = 'defaultGetParamValue'; + $postValue = 'someGetParamValue'; + + $this->request->expects($this->once()) + ->method('getPost') + ->with($key, $default) + ->will($this->returnValue($postValue)); + + $this->assertEquals($postValue, $this->context->getPost($key, $default)); + } + + public function testGetQuery() + { + $key = 'getParamName'; + $default = 'defaultGetParamValue'; + $queryValue = 'someGetParamValue'; + + $this->request->expects($this->once()) + ->method('getPost') + ->with($key, $default) + ->will($this->returnValue($queryValue)); + + $this->assertEquals($queryValue, $this->context->getQuery($key, $default)); + } + + public function testGetParam() + { + $key = 'paramName'; + $default = 'defaultParamValue'; + $paramValue = 'someParamValue'; + + $this->request->expects($this->once()) + ->method('getParam') + ->with($key, $default) + ->will($this->returnValue($paramValue)); + + $this->assertEquals($paramValue, $this->context->getParam($key, $default)); + } + + public function testGetParams() + { + $params = ['paramName' => 'value']; + + $this->request->expects($this->once()) + ->method('getParams') + ->will($this->returnValue($params)); + + $this->assertEquals($params, $this->context->getParams()); + } + + public function testGetHeader() + { + $headerName = 'headerName'; + $headerValue = 'headerValue'; + + $this->request->expects($this->once()) + ->method('getHeader') + ->with($headerName) + ->will($this->returnValue($headerValue)); + + $this->assertEquals($headerValue, $this->context->getHeader($headerName)); + } + + public function testGetRawBody() + { + $rawBody = 'body string'; + + $this->request->expects($this->once()) + ->method('getRawBody') + ->will($this->returnValue($rawBody)); + + $this->assertEquals($rawBody, $this->context->getRawBody()); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Framework/View/DataSourcePoolTest.php b/dev/tests/unit/testsuite/Magento/Framework/View/DataSourcePoolTest.php new file mode 100644 index 0000000000000000000000000000000000000000..369314fec23f3c925c3255b182b02f39bce3f6f4 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Framework/View/DataSourcePoolTest.php @@ -0,0 +1,133 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Framework\View; + +/** + * Test for view Context model + */ +class DataSourcePoolTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var DataSourcePool + */ + protected $dataSourcePool; + + /** + * @var \Magento\Framework\View\Element\BlockFactory|\PHPUnit_Framework_MockObject_MockObject + */ + protected $blockFactory; + + protected function setUp() + { + $this->blockFactory = $this->getMockBuilder('Magento\Framework\View\Element\BlockFactory') + ->disableOriginalConstructor() + ->getMock(); + + $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this); + $this->dataSourcePool = $objectManager->getObject('Magento\Framework\View\DataSourcePool', [ + 'blockFactory' => $this->blockFactory + ]); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage Invalid Data Source class name: NotExistingBlockClass + */ + public function testAddWithException() + { + $this->dataSourcePool->add('DataSourcePoolTestBlock', 'NotExistingBlockClass'); + } + + protected function createBlock($blockClass) + { + $block = $this->getMock('Magento\Framework\View\Element\BlockInterface'); + + $this->blockFactory->expects($this->once()) + ->method('createBlock') + ->with($blockClass) + ->will($this->returnValue($block)); + return $block; + } + + public function testAdd() + { + $blockName = 'DataSourcePoolTestBlock'; + $blockClass = 'Magento\Framework\View\DataSourcePoolTestBlock'; + + $block = $this->createBlock($blockClass); + + $this->assertSame($block, $this->dataSourcePool->add($blockName, $blockClass)); + } + + public function testGet() + { + $blockName = 'DataSourcePoolTestBlock'; + $blockClass = 'Magento\Framework\View\DataSourcePoolTestBlock'; + + $block = $this->createBlock($blockClass); + $this->dataSourcePool->add($blockName, $blockClass); + + $this->assertSame($block, $this->dataSourcePool->get($blockName)); + $this->assertEquals([$blockName => $block], $this->dataSourcePool->get()); + $this->assertNull($this->dataSourcePool->get('WrongName')); + } + + public function testGetEmpty() + { + $this->assertEquals([], $this->dataSourcePool->get()); + } + + public function testAssignAndGetNamespaceData() + { + $blockName = 'DataSourcePoolTestBlock'; + $blockClass = 'Magento\Framework\View\DataSourcePoolTestBlock'; + + $block = $this->createBlock($blockClass); + $this->dataSourcePool->add($blockName, $blockClass); + + $namespace = 'namespace'; + $alias = 'alias'; + $this->dataSourcePool->assign($blockName, $namespace, $alias); + + $this->assertEquals(['alias' => $block], $this->dataSourcePool->getNamespaceData($namespace)); + $this->assertEquals([], $this->dataSourcePool->getNamespaceData('WrongNamespace')); + } +} + +/** + * Class DataSourcePoolTestBlock mock + */ +class DataSourcePoolTestBlock implements \Magento\Framework\View\Element\BlockInterface +{ + /** + * Produce and return block's html output + * + * @return string + */ + public function toHtml() + { + return ''; + } +} diff --git a/dev/tests/unit/testsuite/Magento/Framework/View/DesignExceptionsTest.php b/dev/tests/unit/testsuite/Magento/Framework/View/DesignExceptionsTest.php new file mode 100644 index 0000000000000000000000000000000000000000..773bf22d8e7c31aaf2e487335baa257049a4e0a1 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Framework/View/DesignExceptionsTest.php @@ -0,0 +1,102 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Framework\View; + +use Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper; + +class DesignExceptionsTest extends \PHPUnit_Framework_TestCase +{ + /** @var \Magento\Framework\View\DesignExceptions */ + protected $designExceptions; + + /** @var ObjectManagerHelper */ + protected $objectManagerHelper; + + /** @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject */ + protected $scopeConfigMock; + + /** @var \Magento\Framework\App\Request\Http|\PHPUnit_Framework_MockObject_MockObject */ + protected $requestMock; + + /** @var string */ + protected $exceptionConfigPath = 'exception_path'; + + /** @var string */ + protected $scopeType = 'scope_type'; + + protected function setUp() + { + $this->scopeConfigMock = $this->getMock('Magento\Framework\App\Config\ScopeConfigInterface'); + $this->requestMock = $this->getMock('Magento\Framework\App\Request\Http', [], [], '', false); + + $this->objectManagerHelper = new ObjectManagerHelper($this); + $this->designExceptions = $this->objectManagerHelper->getObject( + 'Magento\Framework\View\DesignExceptions', + [ + 'scopeConfig' => $this->scopeConfigMock, + 'exceptionConfigPath' => $this->exceptionConfigPath, + 'scopeType' => $this->scopeType + ] + ); + } + + /** + * @param string $userAgent + * @param bool $useConfig + * @param bool|string $result + * @param array $expressions + * @dataProvider getThemeByRequestDataProvider + */ + public function testGetThemeByRequest($userAgent, $useConfig, $result, $expressions = []) + { + $this->requestMock->expects($this->once()) + ->method('getServer') + ->with($this->equalTo('HTTP_USER_AGENT')) + ->will($this->returnValue($userAgent)); + + if ($useConfig) { + $this->scopeConfigMock->expects($this->once()) + ->method('getValue') + ->with($this->equalTo($this->exceptionConfigPath), $this->equalTo($this->scopeType)) + ->will($this->returnValue(serialize($expressions))); + } + + $this->assertSame($result, $this->designExceptions->getThemeByRequest($this->requestMock)); + } + + /** + * @return array + */ + public function getThemeByRequestDataProvider() + { + return [ + [false, false, false], + ['iphone', false, false], + ['iphone', true, false], + ['iphone', true, 'matched', [['regexp' => '/iphone/', 'value' => 'matched']]], + ['explorer', true, false, [['regexp' => '/iphone/', 'value' => 'matched']]], + ]; + } +} diff --git a/dev/tests/unit/testsuite/Magento/Framework/View/Element/BlockFactoryTest.php b/dev/tests/unit/testsuite/Magento/Framework/View/Element/BlockFactoryTest.php new file mode 100644 index 0000000000000000000000000000000000000000..cd42c5994545513fb918abda0119c19e7dba11b2 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Framework/View/Element/BlockFactoryTest.php @@ -0,0 +1,77 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Framework\View\Element; + +class BlockFactoryTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Framework\View\Element\BlockFactory + */ + protected $blockFactory; + + /** + * @var \Magento\Framework\ObjectManager|\PHPUnit_Framework_MockObject_MockObject + */ + protected $objectManagerMock; + + public function setUp() + { + $objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this); + + $this->objectManagerMock = $this->getMockBuilder('Magento\Framework\ObjectManager') + ->disableOriginalConstructor() + ->getMock(); + + $this->blockFactory = $objectManagerHelper->getObject('Magento\Framework\View\Element\BlockFactory', array( + 'objectManager' => $this->objectManagerMock + )); + } + + public function testCreateBlock() + { + $className = 'Magento\Framework\View\Element\Template'; + $argumentsResult = ['arg1', 'arg2']; + + $templateMock = $this->getMockBuilder('Magento\Framework\View\Element\Template') + ->disableOriginalConstructor()->getMock(); + + $this->objectManagerMock->expects($this->once()) + ->method('create') + ->with($className, $argumentsResult) + ->will($this->returnValue($templateMock)); + + $this->assertInstanceOf( + 'Magento\Framework\View\Element\BlockInterface', + $this->blockFactory->createBlock($className, $argumentsResult) + ); + } + + /** + * @expectedException \LogicException + */ + public function testCreateBlockWithException() + { + $this->blockFactory->createBlock('invalid_class_name'); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Framework/View/Element/FormKeyTest.php b/dev/tests/unit/testsuite/Magento/Framework/View/Element/FormKeyTest.php new file mode 100644 index 0000000000000000000000000000000000000000..979eb53377948e440262b102e6f99ff54d2cad30 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Framework/View/Element/FormKeyTest.php @@ -0,0 +1,62 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Framework\View\Element; + +class FormKeyTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Framework\View\Element\FormKey + */ + protected $formKeyElement; + + protected function setUp() + { + $objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this); + + $formKeyMock = $this->getMockBuilder('Magento\Framework\Data\Form\FormKey') + ->setMethods(['getFormKey'])->disableOriginalConstructor()->getMock(); + + $formKeyMock->expects($this->any()) + ->method('getFormKey') + ->will($this->returnValue('form_key')); + + $this->formKeyElement = $objectManagerHelper->getObject( + 'Magento\Framework\View\Element\FormKey', + ['formKey' => $formKeyMock] + ); + } + + public function testGetFormKey() + { + $this->assertEquals('form_key', $this->formKeyElement->getFormKey()); + } + + public function testToHtml() + { + $this->assertEquals( + '<input name="form_key" type="hidden" value="form_key" />', + $this->formKeyElement->toHtml() + ); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Framework/View/Element/Html/LinkTest.php b/dev/tests/unit/testsuite/Magento/Framework/View/Element/Html/LinkTest.php new file mode 100644 index 0000000000000000000000000000000000000000..69f1c6cf6b77d1251582e5af9f53287d276dabda --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Framework/View/Element/Html/LinkTest.php @@ -0,0 +1,111 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Framework\View\Element\Html; + +class LinkTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var array + */ + protected $allowedAttributes = [ + 'shape', + 'tabindex', + 'onfocus', + 'onblur', + 'id', + 'some_invalid_data' + ]; + + /** + * @var \Magento\Framework\View\Element\Html\Link + */ + protected $link; + + /** + * @param \Magento\Framework\View\Element\Html\Link $link + * @param string $expected + * + * @dataProvider getLinkAttributesDataProvider + */ + public function testGetLinkAttributes($link, $expected) + { + $this->assertEquals($expected, $link->getLinkAttributes()); + } + + public function getLinkAttributesDataProvider() + { + $objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this); + + $escaperMock = $this->getMockBuilder('Magento\Framework\Escaper') + ->setMethods(['escapeHtml'])->disableOriginalConstructor()->getMock(); + + $escaperMock->expects($this->any()) + ->method('escapeHtml') + ->will($this->returnArgument(0)); + + $urlBuilderMock = $this->getMockBuilder('Magento\Framework\UrlInterface') + ->setMethods(['getUrl'])->disableOriginalConstructor()->getMockForAbstractClass(); + + $urlBuilderMock->expects($this->any()) + ->method('getUrl') + ->will($this->returnArgument('http://site.com/link.html')); + + $contextMock = $this->getMockBuilder('Magento\Framework\View\Element\Template\Context') + ->setMethods(['getEscaper', 'getUrlBuilder'])->disableOriginalConstructor()->getMock(); + + $contextMock->expects($this->any()) + ->method('getEscaper') + ->will($this->returnValue($escaperMock)); + + $contextMock->expects($this->any()) + ->method('getUrlBuilder') + ->will($this->returnValue($urlBuilderMock)); + + /** @var \Magento\Framework\View\Element\Html\Link $linkWithAttributes */ + $linkWithAttributes = $objectManagerHelper->getObject( + 'Magento\Framework\View\Element\Html\Link', + ['context' => $contextMock] + ); + /** @var \Magento\Framework\View\Element\Html\Link $linkWithoutAttributes */ + $linkWithoutAttributes = $objectManagerHelper->getObject( + 'Magento\Framework\View\Element\Html\Link', + ['context' => $contextMock] + ); + + foreach ($this->allowedAttributes as $attribute) { + $linkWithAttributes->setDataUsingMethod($attribute, $attribute); + } + + return [ + 'full' => [ + 'link' => $linkWithAttributes, + 'expected' => 'shape="shape" tabindex="tabindex" onfocus="onfocus" onblur="onblur" id="id"' + ], + 'empty' => [ + 'link' => $linkWithoutAttributes, + 'expected' => '' + ], + ]; + } +} diff --git a/dev/tests/unit/testsuite/Magento/Framework/View/Element/Html/SelectTest.php b/dev/tests/unit/testsuite/Magento/Framework/View/Element/Html/SelectTest.php new file mode 100644 index 0000000000000000000000000000000000000000..f74f0e07254c8bffa14b416ac68a25b21f0e3177 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Framework/View/Element/Html/SelectTest.php @@ -0,0 +1,184 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Framework\View\Element\Html; + +class SelectTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var Select + */ + protected $select; + + protected function setUp() + { + $eventManager = $this->getMock('Magento\Framework\Event\ManagerInterface'); + + $scopeConfig = $this->getMock('Magento\Framework\App\Config\ScopeConfigInterface'); + + $escaper = $this->getMockBuilder('Magento\Framework\Escaper') + ->disableOriginalConstructor() + ->getMock(); + $escaper->expects($this->any()) + ->method('escapeHtml') + ->will($this->returnArgument(0)); + + $context = $this->getMockBuilder('Magento\Framework\View\Element\Context') + ->disableOriginalConstructor() + ->getMock(); + $context->expects($this->once()) + ->method('getEscaper') + ->will($this->returnValue($escaper)); + $context->expects($this->once()) + ->method('getEventManager') + ->will($this->returnValue($eventManager)); + $context->expects($this->once()) + ->method('getScopeConfig') + ->will($this->returnValue($scopeConfig)); + + $objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this); + $this->select = $objectManagerHelper->getObject('Magento\Framework\View\Element\Html\Select', [ + 'context' => $context + ]); + } + + public function testAddOptionAndSetOptionsAndGetOptions() + { + $value = 'testValue'; + $label = 'testLabel'; + $params = ['paramKey' => 'paramValue']; + + $options = [['value' => $value, 'label' => $label, 'params' => $params]]; + + $this->assertEquals([], $this->select->getOptions()); + + $this->select->addOption($value, $label, $params); + $this->assertEquals($options, $this->select->getOptions()); + + $options[0]['value'] = 'newValue'; + $this->select->setOptions($options); + $this->assertEquals($options, $this->select->getOptions()); + } + + public function testGetSetId() + { + $selectId = 'testId'; + + $this->assertNull($this->select->getId()); + $this->select->setId($selectId); + $this->assertEquals($selectId, $this->select->getId()); + } + + public function testGetSetClass() + { + $selectClass = 'testClass'; + + $this->assertNull($this->select->getClass()); + $this->select->setClass($selectClass); + $this->assertEquals($selectClass, $this->select->getClass()); + } + + public function testGetSetTitle() + { + $selectTitle = 'testTitle'; + + $this->assertNull($this->select->getTitle()); + $this->select->setTitle($selectTitle); + $this->assertEquals($selectTitle, $this->select->getTitle()); + } + + public function testGetHtml() + { + $selectId = 'testId'; + $selectClass = 'testClass'; + $selectTitle = 'testTitle'; + $selectName = 'testName'; + + $value = 'testValue'; + $label = 'testLabel'; + $params = ['paramKey' => 'paramValue']; + + $valueGroup = [ + 'groupElementValue' => 'GroupElementLabel', + 'selectedGroupElementValue' => 'SelectedGroupElementLabel' + ]; + $labelGroup = 'groupLabel'; + + $selectedValue = 'selectedValue'; + $selectedLabel = 'selectedLabel'; + $selectedParams = [['paramKey' => 'paramValue', 'paramKey2' => 'paramValue2']]; + + $selectedValues = [$selectedValue, 'selectedGroupElementValue']; + + $this->select->setId($selectId); + $this->select->setClass($selectClass); + $this->select->setTitle($selectTitle); + $this->select->setName($selectName); + $this->select->addOption($value, $label, $params); + $this->select->addOption($selectedValue, $selectedLabel, $selectedParams); + $this->select->addOption($valueGroup, $labelGroup); + $this->select->setValue($selectedValues); + + $result = '<select name="testName" id="testId" class="testClass" title="testTitle" >' + . '<option value="testValue" paramKey="paramValue" >testLabel</option>' + . '<option value="selectedValue" selected="selected" paramKey="paramValue" ' + . ' paramKey2="paramValue2" >selectedLabel</option>' + . '<optgroup label="groupLabel">' + . '<option value="groupElementValue" >GroupElementLabel</option>' + . '<option value="selectedGroupElementValue" selected="selected" >SelectedGroupElementLabel</option>' + . '</optgroup>' + . '</select>'; + + $this->assertEquals($result, $this->select->getHtml()); + } + + public function testGetHtmlJs() + { + $selectId = 'testId'; + $selectClass = 'testClass'; + $selectTitle = 'testTitle'; + $selectName = 'testName'; + + + $options = [ + 'testValue' => 'testLabel', + 'selectedValue' => 'selectedLabel', + ]; + $selectedValue = 'selectedValue'; + + $this->select->setId($selectId); + $this->select->setClass($selectClass); + $this->select->setTitle($selectTitle); + $this->select->setName($selectName); + $this->select->setOptions($options); + $this->select->setValue($selectedValue); + + $result = '<select name="testName" id="testId" class="testClass" title="testTitle" >' + . '<option value="testValue" #{option_extra_attr_4016862802} >testLabel</option>' + . '<option value="selectedValue" selected="selected" #{option_extra_attr_662265145} >selectedLabel</option>' + . '</select>'; + + $this->select->setIsRenderToJsTemplate(true); + $this->assertEquals($result, $this->select->getHtml()); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Framework/View/Element/MessagesTest.php b/dev/tests/unit/testsuite/Magento/Framework/View/Element/MessagesTest.php new file mode 100644 index 0000000000000000000000000000000000000000..b49955c17ff3ba6d7ecb881270eb583faf3daa62 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Framework/View/Element/MessagesTest.php @@ -0,0 +1,251 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +/** + * Test for view Messages model + */ +namespace Magento\Framework\View\Element; + +use Magento\Framework\Message\MessageInterface; +use Magento\Framework\Message\ManagerInterface; + +class MessagesTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var Messages + */ + protected $messages; + + /** + * @var \Magento\Framework\Message\Factory|\PHPUnit_Framework_MockObject_MockObject + */ + protected $messageFactory; + + /** + * @var \Magento\Framework\Message\CollectionFactory|\PHPUnit_Framework_MockObject_MockObject + */ + protected $collectionFactory; + + protected function setUp() + { + $this->collectionFactory = $this->getMockBuilder('Magento\Framework\Message\CollectionFactory') + ->disableOriginalConstructor() + ->getMock(); + + $this->messageFactory = $this->getMockBuilder('Magento\Framework\Message\Factory') + ->disableOriginalConstructor() + ->getMock(); + + $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this); + $this->messages = $objectManager->getObject('Magento\Framework\View\Element\Messages', [ + 'collectionFactory' => $this->collectionFactory, + 'messageFactory' => $this->messageFactory + ]); + } + + /** + * @return \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\Message\Collection + */ + protected function initMessageCollection() + { + $collection = $this->getMockBuilder('Magento\Framework\Message\Collection') + ->disableOriginalConstructor() + ->getMock(); + + $this->collectionFactory->expects($this->once()) + ->method('create') + ->will($this->returnValue($collection)); + return $collection; + } + + public function testSetMessages() + { + $collection = $this->getMockBuilder('Magento\Framework\Message\Collection') + ->disableOriginalConstructor() + ->getMock(); + + $this->collectionFactory->expects($this->never())->method('create'); + + $this->messages->setMessages($collection); + $this->assertSame($collection, $this->messages->getMessageCollection()); + } + + public function testGetMessageCollection() + { + $collection = $this->initMessageCollection(); + + $this->assertSame($collection, $this->messages->getMessageCollection()); + } + + public function testAddMessages() + { + $messageOne = $this->getMock('Magento\Framework\Message\MessageInterface'); + $messageTwo = $this->getMock('Magento\Framework\Message\MessageInterface'); + + $arrayMessages = [$messageOne, $messageTwo]; + + $collection = $this->initMessageCollection(); + + $collection->expects($this->at(0)) + ->method('addMessage') + ->with($messageOne); + $collection->expects($this->at(1)) + ->method('addMessage') + ->with($messageTwo); + + $collectionForAdd = $this->getMockBuilder('Magento\Framework\Message\Collection') + ->disableOriginalConstructor() + ->getMock(); + + $collectionForAdd->expects($this->atLeastOnce()) + ->method('getItems') + ->will($this->returnValue($arrayMessages)); + + $this->assertSame($this->messages, $this->messages->addMessages($collectionForAdd)); + } + + public function testAddMessage() + { + $message = $this->getMock('Magento\Framework\Message\MessageInterface'); + + $collection = $this->initMessageCollection(); + + $collection->expects($this->once()) + ->method('addMessage') + ->with($message); + + $this->assertSame($this->messages, $this->messages->addMessage($message)); + } + + public function testAddError() + { + $messageText = 'Some message error text'; + + $message = $this->getMock('Magento\Framework\Message\MessageInterface'); + + $this->messageFactory->expects($this->once()) + ->method('create') + ->with(MessageInterface::TYPE_ERROR, $messageText) + ->will($this->returnValue($message)); + + $collection = $this->initMessageCollection(); + $collection->expects($this->once()) + ->method('addMessage') + ->with($message); + + $this->assertSame($this->messages, $this->messages->addError($messageText)); + } + + public function testAddWarning() + { + $messageText = 'Some message warning text'; + + $message = $this->getMock('Magento\Framework\Message\MessageInterface'); + + $this->messageFactory->expects($this->once()) + ->method('create') + ->with(MessageInterface::TYPE_WARNING, $messageText) + ->will($this->returnValue($message)); + + $collection = $this->initMessageCollection(); + $collection->expects($this->once()) + ->method('addMessage') + ->with($message); + + $this->assertSame($this->messages, $this->messages->addWarning($messageText)); + } + + public function testAddNotice() + { + $messageText = 'Some message notice text'; + + $message = $this->getMock('Magento\Framework\Message\MessageInterface'); + + $this->messageFactory->expects($this->once()) + ->method('create') + ->with(MessageInterface::TYPE_NOTICE, $messageText) + ->will($this->returnValue($message)); + + $collection = $this->initMessageCollection(); + $collection->expects($this->once()) + ->method('addMessage') + ->with($message); + + $this->assertSame($this->messages, $this->messages->addNotice($messageText)); + } + + public function testAddSuccess() + { + $messageText = 'Some message success text'; + + $message = $this->getMock('Magento\Framework\Message\MessageInterface'); + + $this->messageFactory->expects($this->once()) + ->method('create') + ->with(MessageInterface::TYPE_SUCCESS, $messageText) + ->will($this->returnValue($message)); + + $collection = $this->initMessageCollection(); + $collection->expects($this->once()) + ->method('addMessage') + ->with($message); + + $this->assertSame($this->messages, $this->messages->addSuccess($messageText)); + } + + public function testGetMessagesByType() + { + $messageType = MessageInterface::TYPE_SUCCESS; + $resultMessages = [$this->getMock('Magento\Framework\Message\MessageInterface')]; + + $collection = $this->initMessageCollection(); + $collection->expects($this->once()) + ->method('getItemsByType') + ->with($messageType) + ->will($this->returnValue($resultMessages)); + + $this->assertSame($resultMessages, $this->messages->getMessagesByType($messageType)); + } + + public function testGetMessageTypes() + { + $types = array( + MessageInterface::TYPE_ERROR, + MessageInterface::TYPE_WARNING, + MessageInterface::TYPE_NOTICE, + MessageInterface::TYPE_SUCCESS + ); + $this->assertEquals($types, $this->messages->getMessageTypes()); + } + + public function testGetCacheKeyInfo() + { + $emptyMessagesCacheKey = ['storage_types' => 'a:0:{}']; + $this->assertEquals($emptyMessagesCacheKey, $this->messages->getCacheKeyInfo()); + + $messagesCacheKey = ['storage_types' => 'a:1:{i:0;s:7:"default";}']; + $this->messages->addStorageType(ManagerInterface::DEFAULT_GROUP); + $this->assertEquals($messagesCacheKey, $this->messages->getCacheKeyInfo()); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Framework/View/Element/RendererListTest.php b/dev/tests/unit/testsuite/Magento/Framework/View/Element/RendererListTest.php new file mode 100644 index 0000000000000000000000000000000000000000..de0a7e563c9867a6f143607467f6a24cce55ef37 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Framework/View/Element/RendererListTest.php @@ -0,0 +1,116 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Framework\View\Element; + +class RendererListTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Framework\View\Element\RendererList + */ + protected $renderList; + + /** + * @var \Magento\Framework\View\Element\Context|\PHPUnit_Framework_MockObject_MockObject + */ + protected $contextMock; + + /** + * @var \Magento\Framework\View\LayoutInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $layoutMock; + + /** + * @var \Magento\Framework\View\Element\AbstractBlock|\PHPUnit_Framework_MockObject_MockObject + */ + protected $blockMock; + + protected function setUp() + { + $objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this); + + $this->blockMock = $this->getMockBuilder('Magento\Framework\View\Element\AbstractBlock') + ->setMethods(['setRenderedBlock', 'getTemplate', 'setTemplate'])->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $this->layoutMock = $this->getMockBuilder('Magento\Framework\View\LayoutInterface') + ->setMethods(['getBlock', 'getChildName'])->disableOriginalConstructor()->getMockForAbstractClass(); + + $this->layoutMock->expects($this->any()) + ->method('getBlock') + ->will($this->returnValue($this->blockMock)); + + $this->contextMock = $this->getMockBuilder('Magento\Framework\View\Element\Context') + ->setMethods(['getLayout'])->disableOriginalConstructor()->getMock(); + + $this->contextMock->expects($this->any()) + ->method('getLayout') + ->will($this->returnValue($this->layoutMock)); + + $this->renderList = $objectManagerHelper->getObject( + 'Magento\Framework\View\Element\RendererList', + ['context' => $this->contextMock] + ); + } + + public function testGetRenderer() + { + $this->blockMock->expects($this->any()) + ->method('setRenderedBlock') + ->will($this->returnValue($this->blockMock)); + + $this->blockMock->expects($this->any()) + ->method('getTemplate') + ->will($this->returnValue('template')); + + $this->blockMock->expects($this->any()) + ->method('setTemplate') + ->will($this->returnValue($this->blockMock)); + + $this->layoutMock->expects($this->any()) + ->method('getChildName') + ->will($this->returnValue(true)); + + /** During the first call cache will be generated */ + $this->assertInstanceOf( + '\Magento\Framework\View\Element\BlockInterface', + $this->renderList->getRenderer('type', null, null) + ); + /** Cached value should be returned during second call */ + $this->assertInstanceOf( + '\Magento\Framework\View\Element\BlockInterface', + $this->renderList->getRenderer('type', null, 'renderer_template') + ); + } + + /** + * @expectedException \RuntimeException + */ + public function testGetRendererWithException() + { + $this->assertInstanceOf( + '\Magento\Framework\View\Element\BlockInterface', + $this->renderList->getRenderer(null) + ); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Framework/View/Element/Text/TextList/ItemTest.php b/dev/tests/unit/testsuite/Magento/Framework/View/Element/Text/TextList/ItemTest.php new file mode 100644 index 0000000000000000000000000000000000000000..478add800fd09307758add53927caf20cbcf6957 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Framework/View/Element/Text/TextList/ItemTest.php @@ -0,0 +1,86 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +/** + * Test for view BlockPool model + */ +namespace Magento\Framework\View\Element\Text\TextList; + +class ItemTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var Item + */ + protected $item; + + protected function setUp() + { + $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this); + $this->item = $objectManager->getObject('Magento\Framework\View\Element\Text\TextList\Item'); + } + + public function testSetLink() + { + $liParams = ['class' => 'some-css-class']; + $innerText = 'text'; + + $this->assertNull($this->item->getLiParams()); + $this->assertNull($this->item->getInnerText()); + + $this->item->setLink($liParams, $innerText); + + $this->assertEquals($liParams, $this->item->getLiParams()); + $this->assertEquals($innerText, $this->item->getInnerText()); + } + + /** + * @dataProvider toHtmlDataProvider + */ + public function testToHtml($liParams, $attrName, $attrValue, $innerText) + { + $this->item->setLink($liParams, $innerText); + $this->assertTag([ + 'tag' => 'li', + 'attributes' => [$attrName => $attrValue], + 'content' => $innerText + ], $this->item->toHtml()); + } + + public function toHtmlDataProvider() + { + return [ + [ + 'liParams' => ['class' => 'some-css-class'], + 'attrName' => 'class', + 'attrValue' => 'some-css-class', + 'innerText' => 'text', + ], [ + 'liParams' => 'class="some-css-class"', + 'attrName' => 'class', + 'attrValue' => 'some-css-class', + 'innerText' => 'text', + ] + ]; + } +} diff --git a/dev/tests/unit/testsuite/Magento/Framework/View/Element/Text/TextList/LinkTest.php b/dev/tests/unit/testsuite/Magento/Framework/View/Element/Text/TextList/LinkTest.php new file mode 100644 index 0000000000000000000000000000000000000000..d78182eb8926d23af2cb5c076821a53846576464 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Framework/View/Element/Text/TextList/LinkTest.php @@ -0,0 +1,102 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +/** + * Test for view BlockPool model + */ +namespace Magento\Framework\View\Element\Text\TextList; + +class LinkTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var Link + */ + protected $link; + + protected function setUp() + { + $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this); + $this->link = $objectManager->getObject('Magento\Framework\View\Element\Text\TextList\Link'); + } + + public function testSetLink() + { + $liParams = ['class' => 'some-css-class']; + $aParams = ['href' => 'url']; + $innerText = 'text'; + $afterText = 'afterText'; + + $this->assertNull($this->link->getLiParams()); + $this->assertNull($this->link->getAParams()); + $this->assertNull($this->link->getInnerText()); + $this->assertNull($this->link->getAfterText()); + + $this->link->setLink($liParams, $aParams, $innerText, $afterText); + + $this->assertEquals($liParams, $this->link->getLiParams()); + $this->assertEquals($aParams, $this->link->getAParams()); + $this->assertEquals($innerText, $this->link->getInnerText()); + $this->assertEquals($afterText, $this->link->getAfterText()); + } + + /** + * @dataProvider toHtmlDataProvider + */ + public function testToHtml($liParams, $liAttr, $aParams, $aAttr, $innerText, $afterText) + { + $this->link->setLink($liParams, $aParams, $innerText, $afterText); + $this->assertTag([ + 'tag' => 'li', + 'attributes' => [$liAttr['name'] => $liAttr['value']], + 'child' => [ + 'tag' => 'a', + 'attributes' => [$aAttr['name'] => $aAttr['value']], + 'content' => $innerText + ], + 'content' => $afterText + ], $this->link->toHtml()); + } + + public function toHtmlDataProvider() + { + return [ + [ + 'liParams' => ['class' => 'some-css-class'], + 'liAttr' => ['name' => 'class', 'value' => 'some-css-class'], + 'aParams' => ['href' => 'url'], + 'aAttr' => ['name' => 'href', 'value' => 'url'], + 'innerText' => 'text', + 'afterText' => 'afterText', + ], + [ + 'liParams' => 'class="some-css-class"', + 'liAttr' => ['name' => 'class', 'value' => 'some-css-class'], + 'aParams' => 'href="url"', + 'aAttr' => ['name' => 'href', 'value' => 'url'], + 'innerText' => 'text', + 'afterText' => 'afterText', + ] + ]; + } +} diff --git a/dev/tests/unit/testsuite/Magento/Framework/View/Element/TextTest.php b/dev/tests/unit/testsuite/Magento/Framework/View/Element/TextTest.php new file mode 100644 index 0000000000000000000000000000000000000000..c8fc6a1e448dc3d9ef6edf4e4a78af2a782539df --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Framework/View/Element/TextTest.php @@ -0,0 +1,83 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Framework\View\Element; + +class TextTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Framework\View\Element\Text + */ + protected $elementText; + + protected function setUp() + { + $objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this); + $this->elementText = $objectManagerHelper->getObject('Magento\Framework\View\Element\Text'); + + } + + public function testSetText() + { + $this->assertInstanceOf('Magento\Framework\View\Element\Text', $this->elementText->setText('example')); + } + + public function testGetText() + { + $this->elementText->setText('example'); + $this->assertEquals('example', $this->elementText->getText('example')); + } + + /** + * @param string $text + * @param bool $before + * @param string $expectedResult + * + * @dataProvider addTextDataProvider + */ + public function testAddText($text, $before, $expectedResult) + { + $this->elementText->setText('example'); + $this->elementText->addText($text, $before); + $this->assertEquals($expectedResult, $this->elementText->getText('example')); + } + + /** + * @return array + */ + public function addTextDataProvider() + { + return [ + 'before_false' => [ + 'text' => '_after', + 'before' => false, + 'expectedResult' => 'example_after' + ], + 'before_true' => [ + 'text' => 'before_', + 'before' => true, + 'expectedResult' => 'before_example' + ], + ]; + } +} diff --git a/dev/tests/unit/testsuite/Magento/Framework/View/LayoutFactoryTest.php b/dev/tests/unit/testsuite/Magento/Framework/View/LayoutFactoryTest.php new file mode 100644 index 0000000000000000000000000000000000000000..a1c699c350e0d0ce7853af7bbca06a7523f690b4 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Framework/View/LayoutFactoryTest.php @@ -0,0 +1,77 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Framework\View; + +use Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper; + +class LayoutFactoryTest extends \PHPUnit_Framework_TestCase +{ + /** @var \Magento\Framework\View\LayoutFactory */ + protected $layoutFactory; + + /** @var ObjectManagerHelper */ + protected $objectManagerHelper; + + /** @var \Magento\Framework\ObjectManager|\PHPUnit_Framework_MockObject_MockObject */ + protected $objectManagerMock; + + protected function setUp() + { + $this->objectManagerMock = $this->getMock('Magento\Framework\ObjectManager'); + + $this->objectManagerHelper = new ObjectManagerHelper($this); + $this->layoutFactory = $this->objectManagerHelper->getObject( + 'Magento\Framework\View\LayoutFactory', + [ + 'objectManager' => $this->objectManagerMock + ] + ); + } + + public function testCreate() + { + $instance = 'Magento\Framework\View\LayoutInterface'; + $layoutMock = $this->getMock($instance, [], [], '', false); + $data = ['some' => 'data']; + $this->objectManagerMock->expects($this->once()) + ->method('create') + ->with($this->equalTo($instance), $this->equalTo($data)) + ->will($this->returnValue($layoutMock)); + $this->assertInstanceOf($instance, $this->layoutFactory->create($data)); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage stdClass must be an instance of LayoutInterface. + */ + public function testCreateException() + { + $data = ['some' => 'other_data']; + $this->objectManagerMock->expects($this->once()) + ->method('create') + ->will($this->returnValue(new \stdClass())); + $this->layoutFactory->create($data); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Framework/View/LayoutTest.php b/dev/tests/unit/testsuite/Magento/Framework/View/LayoutTest.php index 67704dd9d191cd2a556f67d203871cbf940780c0..260008d98e0258c4728f8db00067ccb3ac1bbfc7 100644 --- a/dev/tests/unit/testsuite/Magento/Framework/View/LayoutTest.php +++ b/dev/tests/unit/testsuite/Magento/Framework/View/LayoutTest.php @@ -23,22 +23,25 @@ */ namespace Magento\Framework\View; +/** + * Class LayoutTest + */ class LayoutTest extends \PHPUnit_Framework_TestCase { /** * @var \Magento\Framework\View\Layout */ - protected $_model; + protected $model; /** * @var \PHPUnit_Framework_MockObject_MockObject */ - protected $_structureMock; + protected $structureMock; /** * @var \PHPUnit_Framework_MockObject_MockObject */ - protected $_blockFactoryMock; + protected $blockFactoryMock; /** * @var \Magento\Framework\View\Layout\ProcessorFactory|\PHPUnit_Framework_MockObject_MockObject @@ -60,18 +63,25 @@ class LayoutTest extends \PHPUnit_Framework_TestCase */ protected $processorMock; + /** + * @var \Magento\Framework\Event\ManagerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $eventManagerMock; + + /** + * @var \Magento\Framework\View\Layout\ScheduledStructure|\PHPUnit_Framework_MockObject_MockObject + */ + protected $schStructureMock; + protected function setUp() { - $this->_structureMock = $this->getMockBuilder( - 'Magento\Framework\Data\Structure' - )->setMethods( - array('createElement') - )->disableOriginalConstructor()->getMock(); - $this->_blockFactoryMock = $this->getMockBuilder( - 'Magento\Framework\View\Element\BlockFactory' - )->setMethods( - array('createBlock') - )->disableOriginalConstructor()->getMock(); + $this->structureMock = $this->getMockBuilder('Magento\Framework\Data\Structure') + ->disableOriginalConstructor() + ->getMock(); + $this->blockFactoryMock = $this->getMockBuilder('Magento\Framework\View\Element\BlockFactory') + ->setMethods(['createBlock']) + ->disableOriginalConstructor() + ->getMock(); $this->processorFactoryMock = $this->getMock( 'Magento\Framework\View\Layout\ProcessorFactory', ['create'], @@ -79,33 +89,25 @@ class LayoutTest extends \PHPUnit_Framework_TestCase '', false ); - $this->appStateMock = $this->getMock( - 'Magento\Framework\App\State', - [], - [], - '', - false - ); + $this->appStateMock = $this->getMock('Magento\Framework\App\State', [], [], '', false); $this->themeResolverMock = $this->getMockForAbstractClass( 'Magento\Framework\View\Design\Theme\ResolverInterface' ); - $this->processorMock = $this->getMock( - 'Magento\Core\Model\Layout\Merge', - ['__destruct'], - [], - '', - false - ); + $this->processorMock = $this->getMock('Magento\Core\Model\Layout\Merge', [], [], '', false); + $this->schStructureMock = $this->getMock('Magento\Framework\View\Layout\ScheduledStructure', [], [], '', false); + $this->eventManagerMock = $this->getMock('Magento\Framework\Event\ManagerInterface'); $objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this); - $this->_model = $objectManagerHelper->getObject( + $this->model = $objectManagerHelper->getObject( 'Magento\Framework\View\Layout', array( - 'structure' => $this->_structureMock, - 'blockFactory' => $this->_blockFactoryMock, + 'structure' => $this->structureMock, + 'blockFactory' => $this->blockFactoryMock, 'themeResolver' => $this->themeResolverMock, 'processorFactory' => $this->processorFactoryMock, 'appState' => $this->appStateMock, + 'eventManager' => $this->eventManagerMock, + 'scheduledStructure' => $this->schStructureMock ) ); } @@ -115,43 +117,600 @@ class LayoutTest extends \PHPUnit_Framework_TestCase */ public function testCreateBlockException() { - $this->_model->createBlock('type', 'blockname', array()); + $this->model->createBlock('type', 'blockname', array()); } public function testCreateBlockSuccess() { - $blockMock = $this->getMockBuilder( - 'Magento\Framework\View\Element\AbstractBlock' - )->disableOriginalConstructor()->getMockForAbstractClass(); - $this->_blockFactoryMock->expects($this->once())->method('createBlock')->will($this->returnValue($blockMock)); + $blockMock = $this->getMockBuilder('Magento\Framework\View\Element\AbstractBlock') + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + $this->blockFactoryMock->expects($this->once())->method('createBlock')->will($this->returnValue($blockMock)); - $this->_model->createBlock('type', 'blockname', array()); - $this->assertInstanceOf('Magento\Framework\View\Element\AbstractBlock', $this->_model->getBlock('blockname')); + $this->model->createBlock('type', 'blockname', array()); + $this->assertInstanceOf('Magento\Framework\View\Element\AbstractBlock', $this->model->getBlock('blockname')); + $this->assertFalse($this->model->getBlock('not_exist')); } public function testGetUpdate() { $themeMock = $this->getMockForAbstractClass('Magento\Framework\View\Design\ThemeInterface'); - $this->themeResolverMock->expects( - $this->once() - )->method( - 'get' - )->will( - $this->returnValue($themeMock) - ); + $this->themeResolverMock->expects($this->once()) + ->method('get') + ->will($this->returnValue($themeMock)); + + $this->processorFactoryMock->expects($this->once()) + ->method('create') + ->with(array('theme' => $themeMock)) + ->will($this->returnValue($this->processorMock)); + + $this->assertEquals($this->processorMock, $this->model->getUpdate()); + $this->assertEquals($this->processorMock, $this->model->getUpdate()); + } + + public function testGenerateXml() + { + $themeMock = $this->getMockForAbstractClass('Magento\Framework\View\Design\ThemeInterface'); + + $this->themeResolverMock->expects($this->once()) + ->method('get') + ->will($this->returnValue($themeMock)); + + $this->processorFactoryMock->expects($this->once()) + ->method('create') + ->with(array('theme' => $themeMock)) + ->will($this->returnValue($this->processorMock)); + + $xmlString = '<?xml version="1.0"?><layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' + . '<some_update>123</some_update></layout>'; + $xml = simplexml_load_string($xmlString, 'Magento\Framework\View\Layout\Element'); + $this->processorMock->expects($this->once()) + ->method('asSimplexml') + ->will($this->returnValue($xml)); + + $this->structureMock->expects($this->once()) + ->method('importElements') + ->with($this->equalTo([])) + ->will($this->returnSelf()); + $this->assertSame($this->model, $this->model->generateXml()); + $this->assertSame('<some_update>123</some_update>', $this->model->getNode('some_update')->asXml()); + } + + /** + * @param string $parentName + * @param string $alias + * @param string $name + * @param bool $isBlock + * @dataProvider getChildBlockDataProvider + */ + public function testGetChildBlock($parentName, $alias, $name, $isBlock) + { + $this->structureMock->expects($this->once()) + ->method('getChildId') + ->with($this->equalTo($parentName), $this->equalTo($alias)) + ->will($this->returnValue($name)); + $this->structureMock->expects($this->once()) + ->method('hasElement') + ->with($this->equalTo($name)) + ->will($this->returnValue($isBlock)); + if ($isBlock) { + $this->schStructureMock->expects($this->once()) + ->method('hasElement') + ->with($this->equalTo($name)) + ->will($this->returnValue($isBlock)); + $this->structureMock->expects($this->once()) + ->method('getAttribute') + ->with($this->equalTo($name), $this->equalTo('type')) + ->will($this->returnValue(\Magento\Framework\View\Layout\Element::TYPE_BLOCK)); + $this->prepareGenerateBlock($name); + $this->assertInstanceOf( + 'Magento\Framework\View\Element\AbstractBlock', + $this->model->getChildBlock($parentName, $alias) + ); + } else { + $this->assertFalse($this->model->getChildBlock($parentName, $alias)); + } + } + + /** + * @return array + */ + public function getChildBlockDataProvider() + { + return [ + ['parent_name', 'alias', 'block_name', true], + ['parent_name', 'alias', 'block_name', false] + ]; + } - $this->processorFactoryMock->expects( - $this->once() - )->method( - 'create' - )->with( - array('theme' => $themeMock) - )->will( - $this->returnValue($this->processorMock) + /** + * @param string $name + */ + protected function prepareGenerateBlock($name) + { + $blockClass = 'Magento\Framework\View\Element\Template'; + $template = 'file.phtml'; + $ttl = 100; + $xmlString = '<?xml version="1.0"?><block class="' . $blockClass . '" template="' . $template + . '" ttl="' . $ttl . '"></block>'; + $xml = simplexml_load_string($xmlString, 'Magento\Framework\View\Layout\Element'); + $elementData = [\Magento\Framework\View\Layout\Element::TYPE_BLOCK, $xml, [], []]; + $this->schStructureMock->expects($this->once()) + ->method('getElement') + ->with($this->equalTo($name)) + ->will($this->returnValue($elementData)); + $this->schStructureMock->expects($this->once()) + ->method('unsetElement') + ->with($this->equalTo($name)) + ->will($this->returnSelf()); + $blockMock = $this->getMockBuilder('Magento\Framework\View\Element\Template') + ->setMethods(['setType', 'setNameInLayout', 'addData', 'setLayout', 'setTemplate', 'setTtl']) + ->disableOriginalConstructor() + ->getMock(); + $blockMock->expects($this->once()) + ->method('setTemplate') + ->with($this->equalTo($template)) + ->will($this->returnSelf()); + $blockMock->expects($this->once()) + ->method('setTtl') + ->with($this->equalTo($ttl)) + ->will($this->returnSelf()); + $blockMock->expects($this->once()) + ->method('setType') + ->with($this->equalTo(get_class($blockMock))) + ->will($this->returnSelf()); + $blockMock->expects($this->once()) + ->method('setNameInLayout') + ->with($this->equalTo($name)) + ->will($this->returnSelf()); + $blockMock->expects($this->once()) + ->method('addData') + ->with($this->equalTo([])) + ->will($this->returnSelf()); + $blockMock->expects($this->once()) + ->method('setLayout') + ->with($this->equalTo($this->model)) + ->will($this->returnSelf()); + $this->blockFactoryMock->expects($this->once()) + ->method('createBlock') + ->with($this->equalTo('Magento\Framework\View\Element\Template'), $this->equalTo(['data' => []])) + ->will($this->returnValue($blockMock)); + $this->eventManagerMock->expects($this->once()) + ->method('dispatch') + ->with( + $this->equalTo('core_layout_block_create_after'), + $this->equalTo(['block' => $blockMock]) + ) + ->will($this->returnSelf()); + } + + public function testSetChild() + { + $elementName = 'child'; + $parentName = 'parent'; + $alias = 'some_alias'; + $this->structureMock->expects($this->once()) + ->method('setAsChild') + ->with($this->equalTo($elementName), $this->equalTo($parentName), $this->equalTo($alias)) + ->will($this->returnSelf()); + $this->assertSame($this->model, $this->model->setChild($parentName, $elementName, $alias)); + } + + public function testUnsetChild() + { + $parentName = 'parent'; + $alias = 'some_alias'; + $this->structureMock->expects($this->once()) + ->method('unsetChild') + ->with($this->equalTo($parentName), $this->equalTo($alias)) + ->will($this->returnSelf()); + $this->assertSame($this->model, $this->model->unsetChild($parentName, $alias)); + } + + public function testGetChildNames() + { + $parentName = 'parent'; + $childrenArray = ['key1' => 'value1', 'key2' => 'value2']; + $this->structureMock->expects($this->once()) + ->method('getChildren') + ->with($this->equalTo($parentName)) + ->will($this->returnValue($childrenArray)); + $this->assertSame(['key1', 'key2'], $this->model->getChildNames($parentName)); + } + + public function testGetChildBlocks() + { + $parentName = 'parent'; + $childrenArray = ['block_name' => 'value1']; + $this->structureMock->expects($this->once()) + ->method('getChildren') + ->with($this->equalTo($parentName)) + ->will($this->returnValue($childrenArray)); + + $blockMock = $this->getMockBuilder('Magento\Framework\View\Element\AbstractBlock') + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + $this->blockFactoryMock->expects($this->once())->method('createBlock')->will($this->returnValue($blockMock)); + $this->assertSame($blockMock, $this->model->createBlock('type', 'block_name', [])); + $this->assertSame(['value1' => $blockMock], $this->model->getChildBlocks($parentName)); + } + + public function testGetChildName() + { + $parentName = 'parent'; + $alias = 'some_alias'; + $this->structureMock->expects($this->once()) + ->method('getChildId') + ->with($this->equalTo($parentName), $this->equalTo($alias)) + ->will($this->returnValue('1')); + $this->assertSame('1', $this->model->getChildName($parentName, $alias)); + } + + public function testAddToParentGroup() + { + $blockName = 'block_name'; + $parentGroup = 'parent_group'; + $this->structureMock->expects($this->once()) + ->method('addToParentGroup') + ->with($this->equalTo($blockName), $this->equalTo($parentGroup)) + ->will($this->returnSelf()); + $this->assertSame($this->structureMock, $this->model->addToParentGroup($blockName, $parentGroup)); + } + + public function testGetGroupChildNames() + { + $blockName = 'block_name'; + $groupName = 'group_name'; + $this->structureMock->expects($this->once()) + ->method('getGroupChildNames') + ->with($this->equalTo($blockName), $this->equalTo($groupName)) + ->will($this->returnSelf()); + $this->assertSame($this->structureMock, $this->model->getGroupChildNames($blockName, $groupName)); + } + + public function testHasElement() + { + $elementName = 'name'; + $this->structureMock->expects($this->once()) + ->method('hasElement') + ->with($this->equalTo($elementName)) + ->will($this->returnValue(true)); + $this->assertTrue($this->model->hasElement($elementName)); + } + + public function testGetElementProperty() + { + $elementName = 'name'; + $elementAttr = 'attribute'; + $result = 'result'; + $this->structureMock->expects($this->once()) + ->method('getAttribute') + ->with($this->equalTo($elementName), $this->equalTo($elementAttr)) + ->will($this->returnValue($result)); + $this->assertSame($result, $this->model->getElementProperty($elementName, $elementAttr)); + } + + /** + * @param bool $hasElement + * @param string $attribute + * @param bool $result + * @dataProvider isContainerDataProvider + */ + public function testIsContainer($hasElement, $attribute, $result) + { + $elementName = 'element_name'; + $this->structureMock->expects($this->once()) + ->method('hasElement') + ->with($this->equalTo($elementName)) + ->will($this->returnValue($hasElement)); + if ($hasElement) { + $this->structureMock->expects($this->once()) + ->method('getAttribute') + ->with($this->equalTo($elementName), $this->equalTo('type')) + ->will($this->returnValue($attribute)); + } + $this->assertSame($result, $this->model->isContainer($elementName)); + } + + /** + * @return array + */ + public function isContainerDataProvider() + { + return [ + [false, '', false], + [true, 'container', true], + [true, 'block', false], + [true, 'something', false], + ]; + } + + /** + * @param bool $parentName + * @param array $containerConfig + * @param bool $result + * @dataProvider isManipulationAllowedDataProvider + */ + public function testIsManipulationAllowed($parentName, $containerConfig, $result) + { + $elementName = 'element_name'; + $this->structureMock->expects($this->once()) + ->method('getParentId') + ->with($this->equalTo($elementName)) + ->will($this->returnValue($parentName)); + if ($parentName) { + $this->structureMock->expects($this->once()) + ->method('hasElement') + ->with($this->equalTo($parentName)) + ->will($this->returnValue($containerConfig['has_element'])); + if ($containerConfig['has_element']) { + $this->structureMock->expects($this->once()) + ->method('getAttribute') + ->with($this->equalTo($parentName), $this->equalTo('type')) + ->will($this->returnValue($containerConfig['attribute'])); + } + } + + $this->assertSame($result, $this->model->isManipulationAllowed($elementName)); + } + + /** + * @return array + */ + public function isManipulationAllowedDataProvider() + { + return [ + ['parent', ['has_element' => true, 'attribute' => 'container'], true], + ['parent', ['has_element' => true, 'attribute' => 'block'], false], + [false, [], false], + ]; + } + + /** + * @covers \Magento\Framework\View\Layout::setBlock + * @covers \Magento\Framework\View\Layout::getAllBlocks + * @covers \Magento\Framework\View\Layout::unsetElement + */ + public function testSetGetBlock() + { + $blockName = 'some_name'; + $blockMock = $this->getMockBuilder('Magento\Framework\View\Element\AbstractBlock') + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + $this->assertSame($this->model, $this->model->setBlock($blockName, $blockMock)); + $this->assertSame([$blockName => $blockMock], $this->model->getAllBlocks()); + $this->structureMock->expects($this->once()) + ->method('unsetElement') + ->with($this->equalTo($blockName)) + ->will($this->returnSelf()); + $this->assertSame($this->model, $this->model->unsetElement($blockName)); + $this->assertSame([], $this->model->getAllBlocks()); + } + + public function testRenameElement() + { + $oldName = 'old_name'; + $newName = 'new_name'; + $blockMock = $this->getMockBuilder('Magento\Framework\View\Element\AbstractBlock') + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $this->structureMock->expects($this->once()) + ->method('renameElement') + ->with($this->equalTo($oldName), $this->equalTo($newName)) + ->will($this->returnSelf()); + $this->assertSame($this->model, $this->model->setBlock($oldName, $blockMock)); + $this->assertSame($this->model, $this->model->renameElement($oldName, $newName)); + $this->assertSame([$newName => $blockMock], $this->model->getAllBlocks()); + } + + public function testGetParentName() + { + $childName = 'child_name'; + $parentId = 'parent_id'; + $this->structureMock->expects($this->once()) + ->method('getParentId') + ->with($this->equalTo($childName)) + ->will($this->returnValue($parentId)); + $this->assertSame($parentId, $this->model->getParentName($childName)); + } + + public function testGetElementAlias() + { + $name = 'child_name'; + $parentId = 'parent_id'; + $alias = 'alias'; + $this->structureMock->expects($this->once()) + ->method('getParentId') + ->with($this->equalTo($name)) + ->will($this->returnValue($parentId)); + $this->structureMock->expects($this->once()) + ->method('getChildAlias') + ->with($this->equalTo($parentId), $this->equalTo($name)) + ->will($this->returnValue($alias)); + $this->assertSame($alias, $this->model->getElementAlias($name)); + } + + public function testAddRemoveOutputElement() + { + $this->assertSame($this->model, $this->model->addOutputElement('name')); + $this->assertSame($this->model, $this->model->removeOutputElement('name')); + } + + public function testGetBlockFactory() + { + $this->assertSame($this->blockFactoryMock, $this->model->getBlockFactory()); + } + + public function testIsPrivate() + { + $this->assertFalse($this->model->isPrivate()); + $this->assertSame($this->model, $this->model->setIsPrivate(true)); + $this->assertTrue($this->model->isPrivate()); + } + + /** + * @expectedException \Magento\Framework\Model\Exception + * @expectedExceptionMessage Invalid block type + */ + public function testGetBlockSingletonException() + { + $this->model->getBlockSingleton(false); + } + + /** + * @param array $type + * @param array $blockInstance + * @dataProvider getBlockSingletonDataProvider + */ + public function testGetBlockSingleton($type, $blockInstance, $isAbstract) + { + $blockMock = $this->getMock($blockInstance, [], [], '', false); + $this->blockFactoryMock->expects($this->once()) + ->method('createBlock') + ->with($this->equalTo($type)) + ->will($this->returnValue($blockMock)); + if ($isAbstract) { + $blockMock->expects($this->once()) + ->method('setLayout') + ->with($this->equalTo($this->model)) + ->will($this->returnSelf()); + } + $this->assertInstanceOf($blockInstance, $this->model->getBlockSingleton($type)); + // singleton test + $this->assertInstanceOf($blockInstance, $this->model->getBlockSingleton($type)); + } + + /** + * @return array + */ + public function getBlockSingletonDataProvider() + { + return [ + [ + 'some_type', + 'Magento\Framework\View\Element\Template', + true, + ], + [ + 'other_type', + 'stdClass', + false, + ], + ]; + } + + /** + * @param array $rendererData + * @param array $getData + * @param bool $result + * @dataProvider getRendererOptionsDataProvider + */ + public function testAddGetRendererOptions($rendererData, $getData, $result) + { + $this->assertSame( + $this->model, + $this->model->addAdjustableRenderer( + $rendererData['namespace'], + $rendererData['static_type'], + $rendererData['dynamic_type'], + $rendererData['type'], + $rendererData['template'], + $rendererData['data'] + ) + ); + $this->assertSame( + $result, + $this->model->getRendererOptions($getData['namespace'], $getData['static_type'], $getData['dynamic_type']) ); + } - $this->assertEquals($this->processorMock, $this->_model->getUpdate()); - $this->assertEquals($this->processorMock, $this->_model->getUpdate()); + /** + * @return array + */ + public function getRendererOptionsDataProvider() + { + $rendererData = [ + 'namespace' => 'namespace_value', + 'static_type' => 'static_type_value', + 'dynamic_type' => 'dynamic_type_value', + 'type' => 'type_value', + 'template' => 'template.phtml', + 'data' => ['some' => 'data'] + ]; + return [ + 'wrong namespace' => [ + $rendererData, + [ + 'namespace' => 'wrong namespace', + 'static_type' => 'static_type_value', + 'dynamic_type' => 'dynamic_type_value', + ], + null + ], + 'wrong static type' => [ + $rendererData, + [ + 'namespace' => 'namespace_value', + 'static_type' => 'wrong static type', + 'dynamic_type' => 'dynamic_type_value', + ], + null + ], + 'wrong dynamic type' => [ + $rendererData, + [ + 'namespace' => 'namespace_value', + 'static_type' => 'static_type_value', + 'dynamic_type' => 'wrong dynamic type', + ], + null + ], + 'set and get test' => [ + $rendererData, + [ + 'namespace' => 'namespace_value', + 'static_type' => 'static_type_value', + 'dynamic_type' => 'dynamic_type_value', + ], + [ + 'type' => 'type_value', + 'template' => 'template.phtml', + 'data' => ['some' => 'data'], + ] + ], + ]; + } + + /** + * @param string $xmlString + * @param bool $result + * @dataProvider isCacheableDataProvider + */ + public function testIsCacheable($xmlString, $result) + { + $xml = simplexml_load_string($xmlString, 'Magento\Framework\View\Layout\Element'); + $this->assertSame($this->model, $this->model->setXml($xml)); + $this->assertSame($result, $this->model->isCacheable()); + } + + /** + * @return array + */ + public function isCacheableDataProvider() + { + return [ + [ + '<?xml version="1.0"?><layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' + . '<block></block></layout>', + true + ], + [ + '<?xml version="1.0"?><layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' + . '<block cacheable="false"></block></layout>', + false + ], + ]; } } diff --git a/dev/tests/unit/testsuite/Magento/Framework/View/Render/RenderFactoryTest.php b/dev/tests/unit/testsuite/Magento/Framework/View/Render/RenderFactoryTest.php new file mode 100644 index 0000000000000000000000000000000000000000..06b567e5da48eeb5ba2157da0383abce2743b86b --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Framework/View/Render/RenderFactoryTest.php @@ -0,0 +1,77 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Framework\View\Render; + +use Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper; + +class RenderFactoryTest extends \PHPUnit_Framework_TestCase +{ + /** @var \Magento\Framework\View\Render\RenderFactory */ + protected $renderFactory; + + /** @var ObjectManagerHelper */ + protected $objectManagerHelper; + + /** @var \Magento\Framework\ObjectManager|\PHPUnit_Framework_MockObject_MockObject */ + protected $objectManagerMock; + + protected function setUp() + { + $this->objectManagerMock = $this->getMock('Magento\Framework\ObjectManager'); + + $this->objectManagerHelper = new ObjectManagerHelper($this); + $this->renderFactory = $this->objectManagerHelper->getObject( + 'Magento\Framework\View\Render\RenderFactory', + [ + 'objectManager' => $this->objectManagerMock + ] + ); + } + + public function testGet() + { + $instance = 'Magento\Framework\View\RenderInterface'; + $renderMock = $this->getMock($instance, [], [], '', false); + $data = 'RenderInterface'; + $this->objectManagerMock->expects($this->once()) + ->method('get') + ->with($this->equalTo('Magento\Framework\View\Render\RenderInterface')) + ->will($this->returnValue($renderMock)); + $this->assertInstanceOf($instance, $this->renderFactory->get($data)); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage Type "RenderInterface" is not instance on Magento\Framework\View\RenderInterface + */ + public function testGetException() + { + $this->objectManagerMock->expects($this->once()) + ->method('get') + ->with($this->equalTo('Magento\Framework\View\Render\RenderInterface')) + ->will($this->returnValue(new \stdClass())); + $this->renderFactory->get('RenderInterface'); + } +} diff --git a/dev/tests/unit/testsuite/Magento/GiftMessage/Helper/MessageTest.php b/dev/tests/unit/testsuite/Magento/GiftMessage/Helper/MessageTest.php index 98b778f4551f1cc6731c2eee239d8d23090b5b4f..0bf128cd1169a3d44c43ea06154ac6e82f202d7c 100644 --- a/dev/tests/unit/testsuite/Magento/GiftMessage/Helper/MessageTest.php +++ b/dev/tests/unit/testsuite/Magento/GiftMessage/Helper/MessageTest.php @@ -56,7 +56,7 @@ class MessageTest extends \PHPUnit_Framework_TestCase $entityMock = $this->getMock('\Magento\Framework\Object', array(), array(), '', false); $inlineMock = $this->getMock( 'Magento\GiftMessage\Block\Message\Inline', - array('setId', 'setDontDisplayContainer', 'setEntity', 'setType', 'toHtml'), + array('setId', 'setDontDisplayContainer', 'setEntity', 'setCheckoutType', 'toHtml'), array(), '', false @@ -68,7 +68,7 @@ class MessageTest extends \PHPUnit_Framework_TestCase $inlineMock->expects($this->once())->method('setId')->will($this->returnSelf()); $inlineMock->expects($this->once())->method('setDontDisplayContainer')->will($this->returnSelf()); $inlineMock->expects($this->once())->method('setEntity')->with($entityMock)->will($this->returnSelf()); - $inlineMock->expects($this->once())->method('setType')->will($this->returnSelf()); + $inlineMock->expects($this->once())->method('setCheckoutType')->will($this->returnSelf()); $inlineMock->expects($this->once())->method('toHtml')->will($this->returnValue($expectedHtml)); $this->assertEquals($expectedHtml, $this->helper->getInline('onepage_checkout', $entityMock)); diff --git a/dev/tests/unit/testsuite/Magento/GoogleShopping/Model/Attribute/ContentTest.php b/dev/tests/unit/testsuite/Magento/GoogleShopping/Model/Attribute/ContentTest.php index ff0cf157981757382116ac3413856972f7323a12..349e5339af78e90c42953af1876449fceeae6657 100644 --- a/dev/tests/unit/testsuite/Magento/GoogleShopping/Model/Attribute/ContentTest.php +++ b/dev/tests/unit/testsuite/Magento/GoogleShopping/Model/Attribute/ContentTest.php @@ -76,14 +76,14 @@ class ContentTest extends \PHPUnit_Framework_TestCase ->will($this->returnValue($attribute)); - $gsData = $this->getMock( + $googleShoppingHelper = $this->getMock( '\Magento\GoogleShopping\Helper\Data', array('cleanAtomAttribute'), array(), '', false ); - $gsData->expects($this->once()) + $googleShoppingHelper->expects($this->once()) ->method('cleanAtomAttribute') ->with($mapValue) ->will($this->returnValue($mapValue)); @@ -91,7 +91,7 @@ class ContentTest extends \PHPUnit_Framework_TestCase $model = (new \Magento\TestFramework\Helper\ObjectManager($this)) ->getObject( '\Magento\GoogleShopping\Model\Attribute\Content', - array('gsProduct' => $productHelper, 'gsData' => $gsData) + array('gsProduct' => $productHelper, 'googleShoppingHelper' => $googleShoppingHelper) ); $service = $this->getMock('Zend_Gdata_App', array('newContent', 'setText'), array(), '', false); diff --git a/dev/tests/unit/testsuite/Magento/GoogleShopping/Model/Attribute/TaxTest.php b/dev/tests/unit/testsuite/Magento/GoogleShopping/Model/Attribute/TaxTest.php new file mode 100644 index 0000000000000000000000000000000000000000..18854daef3e85bea5eb115b8aa416a115105fce1 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/GoogleShopping/Model/Attribute/TaxTest.php @@ -0,0 +1,337 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\GoogleShopping\Model\Attribute; + +/** + * Class TaxTest + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ +class TaxTest extends \PHPUnit_Framework_TestCase +{ + + /** + * @var \Magento\Tax\Helper\Data | \PHPUnit_Framework_MockObject_MockObject + */ + protected $mockTaxHelper; + + /** + * @var \Magento\Tax\Service\V1\TaxRuleService | \PHPUnit_Framework_MockObject_MockObject + */ + protected $mockTaxRuleService; + + /** + * @var \Magento\GoogleShopping\Model\Config | \PHPUnit_Framework_MockObject_MockObject + */ + protected $mockConfig; + + /** + * @var \Magento\GoogleShopping\Model\Resource\Attribute | \PHPUnit_Framework_MockObject_MockObject + */ + protected $mockResource; + + /** + * @var \Magento\Customer\Service\V1\CustomerGroupServiceInterface | \PHPUnit_Framework_MockObject_MockObject + */ + protected $mockGroupService; + + /** + * @var \Magento\Tax\Service\V1\Data\QuoteDetailsBuilder | \PHPUnit_Framework_MockObject_MockObject + */ + protected $mockQuoteDetailsBuilder; + + /** + * @var \Magento\Tax\Service\V1\TaxCalculationService | \PHPUnit_Framework_MockObject_MockObject + */ + protected $mockTaxCalculationService; + + /** + * @var \Magento\Directory\Model\RegionFactory | \PHPUnit_Framework_MockObject_MockObject + */ + protected $mockRegionFactory; + + /** + * @var \Magento\GoogleShopping\Model\Attribute\Tax + */ + protected $model; + + public function setUp() + { + $this->mockTaxHelper = $this->getMockBuilder('\Magento\Tax\Helper\Data') + ->disableOriginalConstructor() + ->getMock(); + $this->mockTaxRuleService = $this->getMockBuilder('Magento\Tax\Service\V1\TaxRuleService') + ->disableOriginalConstructor() + ->getMock(); + $this->mockConfig = $this->getMockBuilder('\Magento\GoogleShopping\Model\Config') + ->disableOriginalConstructor() + ->getMock(); + $this->mockGroupService = $this->getMockBuilder('\Magento\Customer\Service\V1\CustomerGroupServiceInterface') + ->disableOriginalConstructor() + ->getMock(); + $this->mockQuoteDetailsBuilder = $this->getMockBuilder('\Magento\Tax\Service\V1\Data\QuoteDetailsBuilder') + ->disableOriginalConstructor() + ->getMock(); + $this->mockTaxCalculationService = $this->getMockBuilder('\Magento\Tax\Service\V1\TaxCalculationService') + ->disableOriginalConstructor() + ->getMock(); + $this->mockRegionFactory = $this->getMockBuilder('\Magento\Directory\Model\RegionFactory') + ->disableOriginalConstructor() + ->getMock(); + + $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this); + $arguments = [ + 'taxData' => $this->mockTaxHelper, + 'taxRuleService' => $this->mockTaxRuleService, + 'groupServiceInterface' => $this->mockGroupService, + 'config' => $this->mockConfig, + 'quoteDetailsBuilder' => $this->mockQuoteDetailsBuilder, + 'taxCalculationService' => $this->mockTaxCalculationService, + 'regionFactory' => $this->mockRegionFactory + ]; + $this->model = $objectManager->getObject('Magento\GoogleShopping\Model\Attribute\Tax', $arguments); + } + + public function testGetDefaultCustomerTaxClass() + { + $taxClassId = 'tax_class_id'; + $store = 'store'; + $this->setUpGetDefaultCustomerTaxClass($taxClassId, $store); + + $reflectionObject = new \ReflectionObject($this->model); + $reflectionMethod = $reflectionObject->getMethod('_getDefaultCustomerTaxClassId'); + $reflectionMethod->setAccessible(true); + $this->assertSame($taxClassId, $reflectionMethod->invokeArgs($this->model, [$store])); + } + + public function testGetRegionsByRegionId() + { + $regionId = 1; + $postalCode = '*'; + $regionCode = '90210'; + $this->setUpGetRegionsByRegionId($regionId, $regionCode); + + $reflectionObject = new \ReflectionObject($this->model); + $reflectionMethod = $reflectionObject->getMethod('_getRegionsByRegionId'); + $reflectionMethod->setAccessible(true); + $this->assertSame([$regionCode], $reflectionMethod->invokeArgs($this->model, [$regionId, $postalCode])); + } + + public function testConvertAttribute() + { + $productStoreId = 'product_store_id'; + $sku = 'sku'; + $price = 'price'; + $name = 'name'; + $productTaxClassId = 'product_tax_class_id'; + $customerTaxClassId = 'tax_class_id'; + $postCode = '90210'; + $this->setUpGetDefaultCustomerTaxClass($customerTaxClassId, $productStoreId); + $this->setUpGetRegionsByRegionId($postCode, '*'); + $this->mockTaxHelper->expects($this->any())->method('getConfig')->will($this->returnSelf()); + $this->mockTaxHelper->expects($this->any())->method('priceIncludesTax')->will($this->returnValue(false)); + $mockTaxRate = $this->getMockBuilder('Magento\Tax\Service\V1\Data\TaxRate') + ->disableOriginalConstructor() + ->getMock(); + $rates = [$mockTaxRate]; + $this->mockTaxRuleService->expects($this->once())->method('getRatesByCustomerAndProductTaxClassId')->with( + $customerTaxClassId, + $productTaxClassId + )->will($this->returnValue($rates)); + $targetCountry = 'target_country'; + $this->mockConfig->expects($this->once())->method('getTargetCountry')->with($productStoreId)->will( + $this->returnValue($targetCountry) + ); + $mockTaxRate->expects($this->once())->method('getCountryId')->will($this->returnValue($targetCountry)); + $mockTaxRate->expects($this->once())->method('getPostcode')->will($this->returnValue($postCode)); + $mockTaxRate->expects($this->any())->method('getRegionId')->will($this->returnValue($postCode)); + + $this->mockQuoteDetailsBuilder->expects($this->once())->method('populateWithArray') + ->with( + [ + 'billing_address' => [ + 'country_id' => $targetCountry, + 'region' => ['region_id' => $postCode], + 'postcode' => $postCode + ], + 'shipping_address' => [ + 'country_id' => $targetCountry, + 'region' => ['region_id' => $postCode], + 'postcode' => $postCode + ], + 'customer_tax_class_key' => [ + 'type' => 'id', + 'value' => $customerTaxClassId, + ], + 'items' => [ + [ + 'code' => $sku, + 'type' => 'product', + 'tax_class_key' => [ + 'type' => 'id', + 'value' => $productTaxClassId, + ], + 'unit_price' => $price, + 'quantity' => 1, + 'tax_included' => 1, + 'short_description' => $name + ] + ] + ] + ) + ->will($this->returnSelf()); + /** @var \Magento\Tax\Service\V1\Data\QuoteDetails + * | \PHPUnit_Framework_MockObject_MockObject $quoteDetailsObject */ + $quoteDetailsObject = $this->getMockBuilder('Magento\Tax\Service\V1\Data\QuoteDetails') + ->disableOriginalConstructor()->getMock(); + $this->mockQuoteDetailsBuilder->expects($this->once())->method('create')->will( + $this->returnValue($quoteDetailsObject) + ); + $taxDetailsObject = $this->getMockBuilder('\Magento\Tax\Service\V1\Data\TaxDetails') + ->disableOriginalConstructor()->getMock(); + $this->mockTaxCalculationService->expects($this->once())->method('calculateTax')->with( + $quoteDetailsObject, + $productStoreId + )->will($this->returnValue($taxDetailsObject)); + $taxAmount = 777; + $subTotal = 555; + $taxDetailsObject->expects($this->once())->method('getTaxAmount')->will($this->returnValue($taxAmount)); + $taxDetailsObject->expects($this->once())->method('getSubtotal')->will($this->returnValue($subTotal)); + $taxRate = ($taxAmount / $subTotal) * 100; + // mock product + $mockProduct = $this->getMockProduct($productStoreId, $productTaxClassId, $sku, $price, $name); + $mockEntry = $this->getMockEntry(); + $mockEntry->expects($this->once()) + ->method('addTax') + ->with( + [ + 'tax_rate' => $taxRate, + 'tax_country' => $targetCountry, + 'tax_region' => $postCode, + ] + ); + $this->assertSame($mockEntry, $this->model->convertAttribute($mockProduct, $mockEntry)); + } + + private function setUpGetDefaultCustomerTaxClass($taxClassId, $store) + { + $mockGroup = $this->getMockBuilder('\Magento\Customer\Service\V1\Data\CustomerGroup') + ->disableOriginalConstructor() + ->getMock(); + + $this->mockGroupService->expects($this->once()) + ->method('getDefaultGroup') + ->with($store) + ->will($this->returnValue($mockGroup)); + + $mockGroup->expects($this->once()) + ->method('getTaxClassId') + ->will($this->returnValue($taxClassId)); + } + + private function setUpGetRegionsByRegionId($regionId, $code) + { + $mockRegion = $this->getMockBuilder('\Magento\Directory\Model\Region') + ->disableOriginalConstructor() + ->setMethods(['getCode', 'load', '__wakeup']) + ->getMock(); + + $mockRegion->expects($this->once()) + ->method('load') + ->with($regionId) + ->will($this->returnSelf()); + + $mockRegion->expects($this->once()) + ->method('getCode') + ->will($this->returnValue($code)); + + $this->mockRegionFactory->expects($this->once()) + ->method('create') + ->will($this->returnValue($mockRegion)); + } + + /** + * Get a mock product object. + * + * @param $productStoreId + * @param $productTaxClassId + * @param $sku + * @param $price + * @param $name + * @return \Magento\Catalog\Model\Product | \PHPUnit_Framework_MockObject_MockObject + */ + private function getMockProduct($productStoreId, $productTaxClassId, $sku, $price, $name) + { + $mockProduct = $this->getMockBuilder('\Magento\Catalog\Model\Product') + ->setMethods( + [ + 'getTaxClassId', + '__wakeup', + 'getStoreId', + 'getPriceInfo', + 'getAdjustments', + 'getSku', + 'getPrice', + 'getName' + ] + ) + ->disableOriginalConstructor() + ->getMock(); + $mockProduct->expects($this->once()) + ->method('getPriceInfo') + ->will($this->returnSelf()); + $mockProduct->expects($this->once()) + ->method('getAdjustments') + ->will($this->returnValue(['tax' => 'something'])); + $mockProduct->expects($this->any()) + ->method('getStoreId') + ->will($this->returnValue($productStoreId)); + $mockProduct->expects($this->any()) + ->method('getTaxClassId') + ->will($this->returnValue($productTaxClassId)); + $mockProduct->expects($this->once()) + ->method('getSku') + ->will($this->returnValue($sku)); + $mockProduct->expects($this->once()) + ->method('getPrice') + ->will($this->returnValue($price)); + $mockProduct->expects($this->once()) + ->method('getName') + ->will($this->returnValue($name)); + return $mockProduct; + } + + /** + * Get a mock entry object. + * + * @return \Magento\Framework\Gdata\Gshopping\Entry | \PHPUnit_Framework_MockObject_MockObject + */ + private function getMockEntry() + { + $mockEntry = $this->getMockBuilder('\Magento\Framework\Gdata\Gshopping\Entry') + ->disableOriginalConstructor() + ->getMock(); + return $mockEntry; + } +} diff --git a/dev/tests/unit/testsuite/Magento/Payment/Helper/DataTest.php b/dev/tests/unit/testsuite/Magento/Payment/Helper/DataTest.php index 666a2f5a89ec9529bf246ba68c5aeed032f7c5b8..c1ac9481ec47b8fb0c63d9ad2d51bc65359b65e6 100644 --- a/dev/tests/unit/testsuite/Magento/Payment/Helper/DataTest.php +++ b/dev/tests/unit/testsuite/Magento/Payment/Helper/DataTest.php @@ -32,6 +32,9 @@ class DataTest extends \PHPUnit_Framework_TestCase /** @var \PHPUnit_Framework_MockObject_MockObject */ protected $_scopeConfig; + /** @var \PHPUnit_Framework_MockObject_MockObject */ + protected $_initialConfig; + /** @var \PHPUnit_Framework_MockObject_MockObject */ protected $_methodFactory; @@ -43,7 +46,7 @@ class DataTest extends \PHPUnit_Framework_TestCase $this->_methodFactory = $this->getMock('Magento\Payment\Model\Method\Factory', [], [], '', false); $appEmulation = $this->getMock('Magento\Core\Model\App\Emulation', [], [], '', false); $paymentConfig = $this->getMock('Magento\Payment\Model\Config', [], [], '', false); - $initialConfig = $this->getMock('Magento\Framework\App\Config\Initial', [], [], '', false); + $this->_initialConfig = $this->getMock('Magento\Framework\App\Config\Initial', [], [], '', false); $this->_helper = new \Magento\Payment\Helper\Data( $context, @@ -52,7 +55,7 @@ class DataTest extends \PHPUnit_Framework_TestCase $this->_methodFactory, $appEmulation, $paymentConfig, - $initialConfig + $this->_initialConfig ); } @@ -88,6 +91,68 @@ class DataTest extends \PHPUnit_Framework_TestCase $this->assertEquals($methodInstance, $this->_helper->getMethodInstance($code)); } + /** + * @param $method1 array + * @param $method2 array + * + * @dataProvider getSortMethodsDataProvider + */ + public function testSortMethods($method1, $method2) + { + $this->_initialConfig->expects($this->once()) + ->method('getData') + ->will($this->returnValue( + array(\Magento\Payment\Helper\Data::XML_PATH_PAYMENT_METHODS => array( + 'method1' => $method1, + 'method2 '=> $method2 + )) + )); + + $this->_scopeConfig->expects($this->any()) + ->method('getValue') + ->will($this->returnValue('Magento\Payment\Model\Method\AbstractMethod')); + + $methodInstanceMock1 = $this->getMock( + 'Magento\Framework\Object', + array('isAvailable','getConfigData'), + array(), + '', + false + ); + $methodInstanceMock1->expects($this->any()) + ->method('isAvailable') + ->will($this->returnValue(true)); + $methodInstanceMock1->expects($this->any()) + ->method('getConfigData') + ->will($this->returnValue($method1['sort_order'])); + + $methodInstanceMock2 = $this->getMock( + 'Magento\Framework\Object', + array('isAvailable','getConfigData'), + array(), + '', + false + ); + $methodInstanceMock2->expects($this->any()) + ->method('isAvailable') + ->will($this->returnValue(true)); + $methodInstanceMock2->expects($this->any()) + ->method('getConfigData') + ->will($this->returnValue($method2['sort_order'])); + + $this->_methodFactory->expects($this->at(0)) + ->method('create') + ->will($this->returnValue($methodInstanceMock1)); + + $this->_methodFactory->expects($this->at(1)) + ->method('create') + ->will($this->returnValue($methodInstanceMock2)); + + $sortedMethods = $this->_helper->getStoreMethods(); + $this->assertTrue(array_shift($sortedMethods)->getSortOrder() < array_shift($sortedMethods)->getSortOrder()); + } + + public function getMethodInstanceDataProvider() { return array( @@ -95,4 +160,18 @@ class DataTest extends \PHPUnit_Framework_TestCase ['method_code', false, false] ); } + + public function getSortMethodsDataProvider() + { + return array( + array( + array('sort_order' => 0), + array('sort_order' => 1) + ), + array( + array('sort_order' => 2), + array('sort_order' => 1), + ) + ); + } } diff --git a/dev/tests/unit/testsuite/Magento/Payment/Model/CartTest.php b/dev/tests/unit/testsuite/Magento/Payment/Model/CartTest.php index 02d0d87fbbdfc5da3db80d3e595df82e974a4d5c..75b9ffc41abd813a7587709ba695214b3c9ed6c8 100644 --- a/dev/tests/unit/testsuite/Magento/Payment/Model/CartTest.php +++ b/dev/tests/unit/testsuite/Magento/Payment/Model/CartTest.php @@ -294,11 +294,22 @@ class CartTest extends \PHPUnit_Framework_TestCase */ protected function _getSalesModelItems() { + $product = new \Magento\Framework\Object(['id' => '1']); return array( - new \Magento\Framework\Object(array('name' => 'name 1', 'qty' => 1, 'price' => 0.1)), - new \Magento\Framework\Object(array('name' => 'name 2', 'qty' => 2, 'price' => 1.2)), new \Magento\Framework\Object( - array('parent_item' => 'parent item 3', 'name' => 'name 3', 'qty' => 3, 'price' => 2.3) + ['name' => 'name 1', 'qty' => 1, 'price' => 0.1, 'original_item' => $product] + ), + new \Magento\Framework\Object( + ['name' => 'name 2', 'qty' => 2, 'price' => 1.2, 'original_item' => $product] + ), + new \Magento\Framework\Object( + [ + 'parent_item' => 'parent item 3', + 'name' => 'name 3', + 'qty' => 3, + 'price' => 2.3, + 'original_item' => $product + ] ) ); } @@ -317,7 +328,12 @@ class CartTest extends \PHPUnit_Framework_TestCase continue; } $result[] = new \Magento\Framework\Object( - array('name' => $item->getName(), 'qty' => $item->getQty(), 'amount' => $item->getPrice()) + array( + 'name' => $item->getName(), + 'qty' => $item->getQty(), + 'amount' => $item->getPrice(), + 'id' => $item->getOriginalItem()->getId() + ) ); } return $result; diff --git a/dev/tests/unit/testsuite/Magento/Paypal/Controller/Ipn/IndexTest.php b/dev/tests/unit/testsuite/Magento/Paypal/Controller/Ipn/IndexTest.php new file mode 100644 index 0000000000000000000000000000000000000000..9e93e78829df963c995099518043fb3ec8c0712b --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Paypal/Controller/Ipn/IndexTest.php @@ -0,0 +1,67 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Paypal\Controller\Ipn; + +class IndexTest extends \PHPUnit_Framework_TestCase +{ + /** @var Index */ + protected $model; + + /** @var \Magento\Framework\Logger|\PHPUnit_Framework_MockObject_MockObject */ + protected $logger; + + /** @var \Magento\Framework\App\RequestInterface|\PHPUnit_Framework_MockObject_MockObject */ + protected $request; + + /** @var \Magento\Framework\App\ResponseInterface|\PHPUnit_Framework_MockObject_MockObject */ + protected $response; + + protected function setUp() + { + $this->logger = $this->getMock('Magento\Framework\Logger', [], [], '', false); + $this->request = $this->getMock('Magento\Framework\App\Request\Http', [], [], '', false); + $this->response = $this->getMock('Magento\Framework\App\Response\Http', [], [], '', false); + + $objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this); + $this->model = $objectManagerHelper->getObject( + 'Magento\Paypal\Controller\Ipn\Index', + [ + 'logger' => $this->logger, + 'request' => $this->request, + 'response' => $this->response, + ] + ); + } + + public function testIndexActionException() + { + $this->request->expects($this->once())->method('isPost')->will($this->returnValue(true)); + $exception = new \Exception(); + $this->request->expects($this->once())->method('getPost')->will($this->throwException($exception)); + $this->logger->expects($this->once())->method('logException')->with($this->identicalTo($exception)); + $this->response->expects($this->once())->method('setHttpResponseCode')->with(500); + $this->model->execute(); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Paypal/Helper/Shortcut/ValidatorTest.php b/dev/tests/unit/testsuite/Magento/Paypal/Helper/Shortcut/ValidatorTest.php index 867c79fe172b2aa2d174b9082086320320964148..251ee0a8c2a650cb2ecf403bf1bc085bbbbf989d 100644 --- a/dev/tests/unit/testsuite/Magento/Paypal/Helper/Shortcut/ValidatorTest.php +++ b/dev/tests/unit/testsuite/Magento/Paypal/Helper/Shortcut/ValidatorTest.php @@ -106,7 +106,17 @@ class ValidatorTest extends \PHPUnit_Framework_TestCase */ public function testIsPriceOrSetAvailable($isInCatalog, $productPrice, $isProductSet, $expected) { - $currentProduct = new \Magento\Framework\Object(['final_price' => $productPrice, 'type_id' => 'simple']); + $currentProduct = $this->getMockBuilder('Magento\Catalog\Model\Product')->disableOriginalConstructor() + ->setMethods(['__wakeup', 'getFinalPrice', 'getTypeId', 'getTypeInstance']) + ->getMock(); + $typeInstance = $this->getMockBuilder('Magento\Catalog\Model\Product\Type\AbstractType') + ->disableOriginalConstructor() + ->setMethods([]) + ->getMock(); + $currentProduct->expects($this->any())->method('getFinalPrice')->will($this->returnValue($productPrice)); + $currentProduct->expects($this->any())->method('getTypeId')->will($this->returnValue('simple')); + $currentProduct->expects($this->any())->method('getTypeInstance')->will($this->returnValue($typeInstance)); + $this->_registry->expects($this->any()) ->method('registry') ->with($this->equalTo('current_product')) @@ -116,6 +126,11 @@ class ValidatorTest extends \PHPUnit_Framework_TestCase ->method('isProductSet') ->will($this->returnValue($isProductSet)); + $typeInstance->expects($this->any()) + ->method('canConfigure') + ->with($currentProduct) + ->will($this->returnValue(false)); + $this->assertEquals($expected, $this->helper->isPriceOrSetAvailable($isInCatalog)); } diff --git a/dev/tests/unit/testsuite/Magento/Paypal/Model/Api/NvpTest.php b/dev/tests/unit/testsuite/Magento/Paypal/Model/Api/NvpTest.php index 4bcee55b0f43706757e4876d584551f78fca9be9..0d195b7957ca26364fd289ee27c4058eaef1dab0 100644 --- a/dev/tests/unit/testsuite/Magento/Paypal/Model/Api/NvpTest.php +++ b/dev/tests/unit/testsuite/Magento/Paypal/Model/Api/NvpTest.php @@ -155,6 +155,21 @@ class NvpTest extends \PHPUnit_Framework_TestCase 'PayPal gateway has rejected request. Long Message (#10417: Message).', 10417 ], + [ + "\r\n" . 'ACK[7]=Failure&L_ERRORCODE0[5]=10417' + . '&L_SHORTMESSAGE0[8]=Message.&L_LONGMESSAGE0[15]=Long%20Message.', + [10417, 10422], + 'Magento\Paypal\Model\Api\ProcessableException', + 'PayPal gateway has rejected request. Long Message (#10417: Message).', + 10417 + ], + [ + "\r\n" . 'ACK[7]=Failure&L_ERRORCODE0[5]=10417&L_SHORTMESSAGE0[8]=Message.', + [10417, 10422], + 'Magento\Paypal\Model\Api\ProcessableException', + 'PayPal gateway has rejected request. #10417: Message.', + 10417 + ], ]; } diff --git a/dev/tests/unit/testsuite/Magento/Paypal/Model/CartTest.php b/dev/tests/unit/testsuite/Magento/Paypal/Model/CartTest.php index 3d812332426c72199a09718b96fadc6efcb783a3..81aea8dee63376cb7451124504387df24bc57116 100644 --- a/dev/tests/unit/testsuite/Magento/Paypal/Model/CartTest.php +++ b/dev/tests/unit/testsuite/Magento/Paypal/Model/CartTest.php @@ -379,4 +379,12 @@ class CartTest extends \PHPUnit_Framework_TestCase ); return $totals; } + + public function testHasNegativeItemAmount() + { + $this->_model->addCustomItem('item1', 1, 2.1); + $this->assertFalse($this->_model->hasNegativeItemAmount()); + $this->_model->addCustomItem('item1', 1, -1.3); + $this->assertTrue($this->_model->hasNegativeItemAmount()); + } } diff --git a/dev/tests/unit/testsuite/Magento/Paypal/Model/Hostedpro/RequestTest.php b/dev/tests/unit/testsuite/Magento/Paypal/Model/Hostedpro/RequestTest.php new file mode 100644 index 0000000000000000000000000000000000000000..3e962f68a511d44c187dd619f639db203451aad9 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Paypal/Model/Hostedpro/RequestTest.php @@ -0,0 +1,113 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Paypal\Model\Hostedpro; + +class RequestTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Paypal\Model\Hostedpro\Request + */ + protected $_model; + + protected function setUp() + { + $helper = new \Magento\TestFramework\Helper\ObjectManager($this); + $this->_model = $helper->getObject( + 'Magento\Paypal\Model\Hostedpro\Request' + ); + } + + /** + * @dataProvider addressesDataProvider + */ + public function testSetOrderAddresses($billing, $shipping, $billingState, $state) + { + $payment = $this->getMock('Magento\Sales\Model\Order\Payment', ['__wakeup'], [], '', false); + $order = $this->getMock( + 'Magento\Sales\Model\Order', + ['getPayment', '__wakeup', 'getBillingAddress', 'getShippingAddress'], + [], + '', + false + ); + $order->expects($this->any()) + ->method('getPayment') + ->will($this->returnValue($payment)); + $order->expects($this->any()) + ->method('getBillingAddress') + ->will($this->returnValue($billing)); + $order->expects($this->any()) + ->method('getShippingAddress') + ->will($this->returnValue($shipping)); + $this->_model->setOrder($order); + $this->assertEquals($billingState, $this->_model->getData('billing_state')); + $this->assertEquals($state, $this->_model->getData('state')); + } + + /** + * @return array + */ + public function addressesDataProvider() + { + $billing = new \Magento\Framework\Object([ + 'firstname' => 'Firstname', + 'lastname' => 'Lastname', + 'city' => 'City', + 'region_code' => 'CA', + 'postcode' => '12346', + 'country' => 'United States', + 'Street' => '1 Ln Ave' + ]); + $shipping = new \Magento\Framework\Object([ + 'firstname' => 'ShipFirstname', + 'lastname' => 'ShipLastname', + 'city' => 'ShipCity', + 'region' => 'olala', + 'postcode' => '12346', + 'country' => 'United States', + 'Street' => '1 Ln Ave' + ]); + $billing2 = new \Magento\Framework\Object([ + 'firstname' => 'Firstname', + 'lastname' => 'Lastname', + 'city' => 'City', + 'region_code' => 'muuuu', + 'postcode' => '12346', + 'country' => 'United States', + 'Street' => '1 Ln Ave' + ]); + $shipping2 = new \Magento\Framework\Object([ + 'firstname' => 'ShipFirstname', + 'lastname' => 'ShipLastname', + 'city' => 'ShipCity', + 'postcode' => '12346', + 'country' => 'United States', + 'Street' => '1 Ln Ave' + ]); + return [ + [$billing, $shipping, 'CA', 'olala'], + [$billing2, $shipping2, 'muuuu', 'ShipCity'] + ]; + } +} diff --git a/dev/tests/unit/testsuite/Magento/Paypal/Model/IpnTest.php b/dev/tests/unit/testsuite/Magento/Paypal/Model/IpnTest.php index 3945c6e4e91f5391d0adfc76b8ddf6de1385e8d5..7ad537f55d52709ba2ffd28c85f16fad78bf016e 100644 --- a/dev/tests/unit/testsuite/Magento/Paypal/Model/IpnTest.php +++ b/dev/tests/unit/testsuite/Magento/Paypal/Model/IpnTest.php @@ -27,6 +27,8 @@ */ namespace Magento\Paypal\Model; +use \Magento\Sales\Model\Order; + class IpnTest extends \PHPUnit_Framework_TestCase { /** @@ -44,6 +46,16 @@ class IpnTest extends \PHPUnit_Framework_TestCase */ protected $_paypalInfo; + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $configFactory; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $curlFactory; + protected function setUp() { $methods = [ @@ -57,7 +69,8 @@ class IpnTest extends \PHPUnit_Framework_TestCase 'registerPaymentReviewAction', 'getAdditionalInformation', 'getEmailSent', - 'save' + 'save', + 'getState' ]; $this->_orderMock = $this->getMock('Magento\Sales\Model\OrderFactory', $methods, [], '', false); $this->_orderMock->expects($this->any())->method('create')->will($this->returnSelf()); @@ -67,30 +80,31 @@ class IpnTest extends \PHPUnit_Framework_TestCase $this->_orderMock->expects($this->any())->method('getStoreId')->will($this->returnSelf()); $this->_orderMock->expects($this->any())->method('getEmailSent')->will($this->returnValue(true)); - $configFactory = $this->getMock( + $this->configFactory = $this->getMock( 'Magento\Paypal\Model\ConfigFactory', ['create', 'isMethodActive', 'isMethodAvailable', 'getConfigValue', 'getPaypalUrl'], [], '', false ); - $configFactory->expects($this->any())->method('create')->will($this->returnSelf()); - $configFactory->expects($this->any())->method('isMethodActive')->will($this->returnValue(true)); - $configFactory->expects($this->any())->method('isMethodAvailable')->will($this->returnValue(true)); - $configFactory->expects($this->any())->method('getConfigValue')->will($this->returnValue(null)); - $configFactory->expects($this->any())->method('getPaypalUrl')->will($this->returnValue('http://paypal_url')); + $this->configFactory->expects($this->any())->method('create')->will($this->returnSelf()); + $this->configFactory->expects($this->any())->method('isMethodActive')->will($this->returnValue(true)); + $this->configFactory->expects($this->any())->method('isMethodAvailable')->will($this->returnValue(true)); + $this->configFactory->expects($this->any())->method('getConfigValue')->will($this->returnValue(null)); + $this->configFactory->expects($this->any())->method('getPaypalUrl') + ->will($this->returnValue('http://paypal_url')); - $curlFactory = $this->getMock( + $this->curlFactory = $this->getMock( 'Magento\Framework\HTTP\Adapter\CurlFactory', ['create', 'setConfig', 'write', 'read'], [], '', false ); - $curlFactory->expects($this->any())->method('create')->will($this->returnSelf()); - $curlFactory->expects($this->any())->method('setConfig')->will($this->returnSelf()); - $curlFactory->expects($this->any())->method('write')->will($this->returnSelf()); - $curlFactory->expects($this->any())->method('read')->will($this->returnValue( + $this->curlFactory->expects($this->any())->method('create')->will($this->returnSelf()); + $this->curlFactory->expects($this->any())->method('setConfig')->will($this->returnSelf()); + $this->curlFactory->expects($this->any())->method('write')->will($this->returnSelf()); + $this->curlFactory->expects($this->any())->method('read')->will($this->returnValue( ' VERIFIED' )); @@ -105,9 +119,9 @@ class IpnTest extends \PHPUnit_Framework_TestCase $objectHelper = new \Magento\TestFramework\Helper\ObjectManager($this); $this->_ipn = $objectHelper->getObject('Magento\Paypal\Model\Ipn', [ - 'configFactory' => $configFactory, + 'configFactory' => $this->configFactory, 'logAdapterFactory' => $this->getMock('Magento\Framework\Logger\AdapterFactory', [], [], '', false), - 'curlFactory' => $curlFactory, + 'curlFactory' => $this->curlFactory, 'orderFactory' => $this->_orderMock, 'paypalInfo' => $this->_paypalInfo, 'data' => ['payment_status' => 'Pending', 'pending_reason' => 'authorization'] @@ -150,4 +164,53 @@ class IpnTest extends \PHPUnit_Framework_TestCase )->will($this->returnSelf()); $this->_ipn->processIpnRequest(); } + + public function testPaymentReviewRegisterPaymentFraud() + { + $paymentMock = $this->getMock( + '\Magento\Sales\Model\Order\Payment', + ['getAdditionalInformation', '__wakeup', 'registerCaptureNotification'], + [], + '', + false + ); + $paymentMock->expects($this->any()) + ->method('getAdditionalInformation') + ->will($this->returnValue([])); + $paymentMock->expects($this->any()) + ->method('registerCaptureNotification') + ->will($this->returnValue(true)); + $this->_orderMock->expects($this->any())->method('getPayment')->will($this->returnValue($paymentMock)); + $this->_orderMock->expects($this->any())->method('canFetchPaymentReviewUpdate')->will($this->returnValue(true)); + $this->_orderMock->expects($this->once())->method('getState')->will( + $this->returnValue(Order::STATE_PENDING_PAYMENT) + ); + $this->_paypalInfo->expects($this->once()) + ->method('importToPayment') + ->with( + [ + 'payment_status' => 'pending', + 'pending_reason' => 'fraud', + 'collected_fraud_filters' => ['Maximum Transaction Amount'] + ], + $paymentMock + ); + $objectHelper = new \Magento\TestFramework\Helper\ObjectManager($this); + $this->_ipn = $objectHelper->getObject('Magento\Paypal\Model\Ipn', + [ + 'configFactory' => $this->configFactory, + 'logAdapterFactory' => $this->getMock('Magento\Framework\Logger\AdapterFactory', [], [], '', false), + 'curlFactory' => $this->curlFactory, + 'orderFactory' => $this->_orderMock, + 'paypalInfo' => $this->_paypalInfo, + 'data' => [ + 'payment_status' => 'Pending', + 'pending_reason' => 'fraud', + 'fraud_management_pending_filters_1' => 'Maximum Transaction Amount' + ] + ] + ); + $this->_ipn->processIpnRequest(); + $this->assertEquals('IPN "Pending"', $paymentMock->getPreparedMessage()); + } } diff --git a/dev/tests/unit/testsuite/Magento/Paypal/Model/Method/Checks/SpecificationPluginTest.php b/dev/tests/unit/testsuite/Magento/Paypal/Model/Method/Checks/SpecificationPluginTest.php new file mode 100644 index 0000000000000000000000000000000000000000..b62c97db433301d8af37db353fb2e0071c179462 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Paypal/Model/Method/Checks/SpecificationPluginTest.php @@ -0,0 +1,172 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Paypal\Model\Method\Checks; + +use Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Payment\Model\Checks\PaymentMethodChecksInterface; +use Magento\Sales\Model\Quote; +use Magento\Paypal\Model\Billing\AgreementFactory; + +class SpecificationPluginTest extends \PHPUnit_Framework_TestCase +{ + /** @var SpecificationPlugin */ + protected $model; + + /** @var AgreementFactory|\PHPUnit_Framework_MockObject_MockObject */ + protected $agreementFactory; + + protected function setUp() + { + $this->agreementFactory = $this->getMock('Magento\Paypal\Model\Billing\AgreementFactory', ['create']); + + $objectManagerHelper = new ObjectManagerHelper($this); + $this->model = $objectManagerHelper->getObject( + 'Magento\Paypal\Model\Method\Checks\SpecificationPlugin', + [ + 'agreementFactory' => $this->agreementFactory + ] + ); + } + + public function testAroundIsApplicableNotOriginallyApplicable() + { + $paymentMethod = $this->getPaymentMethod('any'); + $quote = $this->getQuote('any'); + $proceed = $this->getProceedClosure(false, $paymentMethod, $quote); + $this->assertFalse($this->callAroundIsApplicable($proceed, $paymentMethod, $quote)); + } + + public function testAroundIsApplicableNotAgreement() + { + $paymentMethod = $this->getPaymentMethod('not_agreement'); + $quote = $this->getQuote('any'); + $proceed = $this->getProceedClosure(true, $paymentMethod, $quote); + $this->assertTrue($this->callAroundIsApplicable($proceed, $paymentMethod, $quote)); + } + + public function testAroundIsApplicableNoCustomerId() + { + $paymentMethod = $this->getPaymentMethod('paypal_billing_agreement'); + $quote = $this->getQuote(null); + $proceed = $this->getProceedClosure(true, $paymentMethod, $quote); + $this->assertTrue($this->callAroundIsApplicable($proceed, $paymentMethod, $quote)); + } + + /** + * @param int $count + * @dataProvider aroundIsApplicableDataProvider + */ + public function testAroundIsApplicable($count) + { + $paymentMethod = $this->getPaymentMethod('paypal_billing_agreement'); + $quote = $this->getQuote(1); + $proceed = $this->getProceedClosure(true, $paymentMethod, $quote); + $agreementCollection = $this->getMock( + 'Magento\Paypal\Model\Resource\Billing\Agreement\Collection', + [], + [], + '', + false + ); + $agreementCollection->expects($this->once()) + ->method('count') + ->will($this->returnValue($count)); + $agreement = $this->getMock('Magento\Paypal\Model\Billing\Agreement', [], [], '', false); + $agreement->expects($this->once()) + ->method('getAvailableCustomerBillingAgreements') + ->with(1) + ->will($this->returnValue($agreementCollection)); + $this->agreementFactory->expects($this->once()) + ->method('create') + ->will($this->returnValue($agreement)); + $this->assertEquals($count > 0, $this->callAroundIsApplicable($proceed, $paymentMethod, $quote)); + } + + public function aroundIsApplicableDataProvider() + { + return [[0], [1], [2]]; + } + + /** + * @param bool $result + * @param PaymentMethodChecksInterface $paymentMethod + * @param Quote $quote + * @return \Closure + */ + private function getProceedClosure($result, PaymentMethodChecksInterface $paymentMethod, Quote $quote) + { + $self = $this; + return function ($parameter1, $parameter2) use ($result, $paymentMethod, $quote, $self) { + $self->assertSame($paymentMethod, $parameter1); + $self->assertSame($quote, $parameter2); + return $result; + }; + } + + /** + * Get payment method parameter + * + * @param string $code + * @return PaymentMethodChecksInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private function getPaymentMethod($code) + { + $paymentMethod = $this->getMockForAbstractClass('Magento\Payment\Model\Checks\PaymentMethodChecksInterface'); + $paymentMethod->expects($this->any()) + ->method('getCode') + ->will($this->returnValue($code)); + return $paymentMethod; + } + + /** + * Get quote parameter + * + * @param mixed $customerId + * @return Quote|\PHPUnit_Framework_MockObject_MockObject + */ + private function getQuote($customerId) + { + $quote = $this->getMock('Magento\Sales\Model\Quote', ['__wakeup'], [], '', false); + $quote->setCustomerId($customerId); + return $quote; + } + + /** + * Call aroundIsApplicable method + * + * @param \Closure $proceed + * @param PaymentMethodChecksInterface $paymentMethod + * @param Quote $quote + * @return bool + */ + private function callAroundIsApplicable( + \Closure $proceed, + PaymentMethodChecksInterface $paymentMethod, + Quote $quote + ) { + $specification = $this->getMockForAbstractClass('Magento\Payment\Model\Checks\SpecificationInterface'); + return $this->model->aroundIsApplicable($specification, $proceed, $paymentMethod, $quote); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Paypal/Model/PayflowlinkTest.php b/dev/tests/unit/testsuite/Magento/Paypal/Model/PayflowlinkTest.php index 2d6e8d5c1f1b8d35b1e70cf91517004ff572de26..b2eb2eba5e84d6f5f8ec14c401c31ea2ee3bd58e 100644 --- a/dev/tests/unit/testsuite/Magento/Paypal/Model/PayflowlinkTest.php +++ b/dev/tests/unit/testsuite/Magento/Paypal/Model/PayflowlinkTest.php @@ -47,14 +47,10 @@ class PayflowlinkTest extends \PHPUnit_Framework_TestCase { $this->store = $this->getMock('Magento\Store\Model\Store', [], [], '', false); $storeManager = $this->getMock('Magento\Store\Model\StoreManagerInterface'); - $storeManager->expects($this->any()) - ->method('getStore') - ->will($this->returnValue($this->store)); + $storeManager->expects($this->any())->method('getStore')->will($this->returnValue($this->store)); $this->paypalConfig = $this->getMock('Magento\Paypal\Model\Config', [], [], '', false); $configFactory = $this->getMock('Magento\Paypal\Model\ConfigFactory', ['create']); - $configFactory->expects($this->any()) - ->method('create') - ->will($this->returnValue($this->paypalConfig)); + $configFactory->expects($this->any())->method('create')->will($this->returnValue($this->paypalConfig)); $this->payflowRequest = $this->getMock('Magento\Paypal\Model\Payflow\Request', [], [], '', false); $this->payflowRequest->expects($this->any()) ->method('__call') @@ -65,11 +61,37 @@ class PayflowlinkTest extends \PHPUnit_Framework_TestCase return null; })); $requestFactory = $this->getMock('Magento\Paypal\Model\Payflow\RequestFactory', ['create']); - $requestFactory->expects($this->any()) - ->method('create') - ->will($this->returnValue($this->payflowRequest)); + $requestFactory->expects($this->any())->method('create')->will($this->returnValue($this->payflowRequest)); $this->infoInstance = $this->getMock('Magento\Sales\Model\Order\Payment', [], [], '', false); + $client = $this->getMock( + 'Magento\Framework\HTTP\ZendClient', + [ + 'setUri', + 'setConfig', + 'setMethod', + 'setParameterPost', + 'setHeaders', + 'setUrlEncodeBody', + 'request', + 'getBody' + ], + [], + '', + false + ); + $client->expects($this->any())->method('create')->will($this->returnSelf()); + $client->expects($this->any())->method('setUri')->will($this->returnSelf()); + $client->expects($this->any())->method('setConfig')->will($this->returnSelf()); + $client->expects($this->any())->method('setMethod')->will($this->returnSelf()); + $client->expects($this->any())->method('setParameterPost')->will($this->returnSelf()); + $client->expects($this->any())->method('setHeaders')->will($this->returnSelf()); + $client->expects($this->any())->method('setUrlEncodeBody')->will($this->returnSelf()); + $client->expects($this->any())->method('request')->will($this->returnSelf()); + $client->expects($this->any())->method('getBody')->will($this->returnValue('RESULT name=value&name2=value2')); + $clientFactory = $this->getMock('Magento\Framework\HTTP\ZendClientFactory', ['create'], [], '', false); + $clientFactory->expects($this->any())->method('create')->will($this->returnValue($client)); + $helper = new ObjectManagerHelper($this); $this->model = $helper->getObject( 'Magento\Paypal\Model\Payflowlink', @@ -77,30 +99,22 @@ class PayflowlinkTest extends \PHPUnit_Framework_TestCase 'storeManager' => $storeManager, 'configFactory' => $configFactory, 'requestFactory' => $requestFactory, + 'httpClientFactory' => $clientFactory ] ); $this->model->setInfoInstance($this->infoInstance); } - /** - * @expectedException \Magento\Framework\Model\Exception - */ public function testInitialize() { $order = $this->getMock('Magento\Sales\Model\Order', [], [], '', false); - $this->infoInstance->expects($this->any()) - ->method('getOrder') - ->will($this->returnValue($order)); - $this->paypalConfig->expects($this->once()) - ->method('getBuildNotationCode') + $this->infoInstance->expects($this->any())->method('getOrder')->will($this->returnValue($order)); + $this->infoInstance->expects($this->any())->method('setAdditionalInformation')->will($this->returnSelf()); + $this->paypalConfig->expects($this->once())->method('getBuildNotationCode') ->will($this->returnValue('build notation code')); - $this->payflowRequest->expects($this->once()) - ->method('setData') - ->with('BNCODE', 'build notation code') + $this->payflowRequest->expects($this->once())->method('setData')->with('BNCODE', 'build notation code') ->will($this->returnSelf()); - $this->model->initialize( - \Magento\Paypal\Model\Config::PAYMENT_ACTION_AUTH, - new \Magento\Framework\Object() - ); + $stateObject = new \Magento\Framework\Object(); + $this->model->initialize(\Magento\Paypal\Model\Config::PAYMENT_ACTION_AUTH, $stateObject); } } diff --git a/dev/tests/unit/testsuite/Magento/Paypal/Model/PayflowproTest.php b/dev/tests/unit/testsuite/Magento/Paypal/Model/PayflowproTest.php index 50467279928cc6381697363c8c199b85a34b9378..df13e41db1fc45385d967f4f785b1b8cb7ab0d8b 100644 --- a/dev/tests/unit/testsuite/Magento/Paypal/Model/PayflowproTest.php +++ b/dev/tests/unit/testsuite/Magento/Paypal/Model/PayflowproTest.php @@ -53,10 +53,41 @@ class PayflowproTest extends \PHPUnit_Framework_TestCase '', false ); + $client = $this->getMock( + 'Magento\Framework\HTTP\ZendClient', + [ + 'setUri', + 'setConfig', + 'setMethod', + 'setParameterPost', + 'setHeaders', + 'setUrlEncodeBody', + 'request', + 'getBody' + ], + [], + '', + false + ); + $client->expects($this->any())->method('create')->will($this->returnSelf()); + $client->expects($this->any())->method('setUri')->will($this->returnSelf()); + $client->expects($this->any())->method('setConfig')->will($this->returnSelf()); + $client->expects($this->any())->method('setMethod')->will($this->returnSelf()); + $client->expects($this->any())->method('setParameterPost')->will($this->returnSelf()); + $client->expects($this->any())->method('setHeaders')->will($this->returnSelf()); + $client->expects($this->any())->method('setUrlEncodeBody')->will($this->returnSelf()); + $client->expects($this->any())->method('request')->will($this->returnSelf()); + $client->expects($this->any())->method('getBody')->will($this->returnValue('RESULT name=value&name2=value2')); + $clientFactory = $this->getMock('Magento\Framework\HTTP\ZendClientFactory', ['create'], [], '', false); + $clientFactory->expects($this->any())->method('create')->will($this->returnValue($client)); + $this->_helper = new \Magento\TestFramework\Helper\ObjectManager($this); $this->_model = $this->_helper->getObject( 'Magento\Paypal\Model\Payflowpro', - ['configFactory' => $this->_configFactory] + [ + 'configFactory' => $this->_configFactory, + 'httpClientFactory' => $clientFactory + ] ); } @@ -98,17 +129,15 @@ class PayflowproTest extends \PHPUnit_Framework_TestCase } /** - * test for _buildBasicRequest (BDCODE) and catch exception of response + * test for _buildBasicRequest (BDCODE) */ - public function testFetchTransactionInfoForBNException() + public function testFetchTransactionInfoForBN() { $this->_configFactory->expects($this->once())->method('create')->will($this->returnSelf()); $this->_configFactory->expects($this->once())->method('getBuildNotationCode') ->will($this->returnValue('BNCODE')); - $payment = $this->getMock('Magento\Payment\Model\Info', [], [], '', false); - $this->setExpectedException( - 'Magento\Framework\Model\Exception', 'User authentication failed' - ); + $payment = $this->getMock('Magento\Payment\Model\Info', ['setTransactionId', '__wakeup'], [], '', false); + $payment->expects($this->once())->method('setTransactionId')->will($this->returnSelf()); $this->_model->fetchTransactionInfo($payment, 'AD49G8N825'); } } diff --git a/dev/tests/unit/testsuite/Magento/SalesRule/Model/RulesApplierTest.php b/dev/tests/unit/testsuite/Magento/SalesRule/Model/RulesApplierTest.php new file mode 100644 index 0000000000000000000000000000000000000000..449dbb6acd72f2fc64ef8640b53149495fe00bf8 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/SalesRule/Model/RulesApplierTest.php @@ -0,0 +1,215 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\SalesRule\Model; + +class RulesApplierTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\SalesRule\Model\RulesApplier + */ + protected $rulesApplier; + + /** + * @var \Magento\SalesRule\Model\Rule\Action\Discount\CalculatorFactory|\PHPUnit_Framework_MockObject_MockObject + */ + protected $calculatorFactory; + + /** + * @var \Magento\Framework\Event\Manager|\PHPUnit_Framework_MockObject_MockObject + */ + protected $eventManager; + + /** + * @var \Magento\SalesRule\Model\Utility|\PHPUnit_Framework_MockObject_MockObject + */ + protected $validatorUtility; + + public function setUp() + { + $this->calculatorFactory = $this->getMock( + 'Magento\SalesRule\Model\Rule\Action\Discount\CalculatorFactory', + [], + [], + '', + false + ); + $this->eventManager = $this->getMock( + 'Magento\Framework\Event\Manager', + ['dispatch'], + [], + '', + false + ); + $this->validatorUtility = $this->getMock( + 'Magento\SalesRule\Model\Utility', + ['canProcessRule', 'minFix', 'deltaRoundingFix', 'getItemQty'], + [], + '', + false + ); + + + $this->rulesApplier = new \Magento\SalesRule\Model\RulesApplier( + $this->calculatorFactory, + $this->eventManager, + $this->validatorUtility + ); + } + + public function testApplyRulesWhenRuleWithStopRulesProcessingIsUsed() + { + $positivePrice = 1; + $skipValidation = true; + $item = $this->getPreparedItem(); + $couponCode = 111; + + $ruleId = 1; + $appliedRuleIds = [$ruleId => $ruleId]; + + /** + * @var \Magento\SalesRule\Model\Rule|\PHPUnit_Framework_MockObject_MockObject $ruleWithStopFurtherProcessing + */ + $ruleWithStopFurtherProcessing = $this->getMock( + 'Magento\SalesRule\Model\Rule', + ['getStoreLabel', 'getCouponType', 'getRuleId', '__wakeup'], + [], + '', + false + ); + /** @var \Magento\SalesRule\Model\Rule|\PHPUnit_Framework_MockObject_MockObject $ruleThatShouldNotBeRun */ + $ruleThatShouldNotBeRun = $this->getMock( + 'Magento\SalesRule\Model\Rule', + ['getStopRulesProcessing', '__wakeup'], + [], + '', + false + ); + + $ruleWithStopFurtherProcessing->setName('ruleWithStopFurtherProcessing'); + $ruleThatShouldNotBeRun->setName('ruleThatShouldNotBeRun'); + $rules = [$ruleWithStopFurtherProcessing, $ruleThatShouldNotBeRun]; + + $item->setDiscountCalculationPrice($positivePrice); + $item->setData('calculation_price', $positivePrice); + + $this->validatorUtility->expects($this->atLeastOnce()) + ->method('canProcessRule') + ->will( + $this->returnValue(true) + ); + $ruleWithStopFurtherProcessing->expects($this->any()) + ->method('getRuleId') + ->will($this->returnValue($ruleId)); + $this->applyRule($item, $ruleWithStopFurtherProcessing); + $ruleWithStopFurtherProcessing->setStopRulesProcessing(true); + $ruleThatShouldNotBeRun->expects($this->never()) + ->method('getStopRulesProcessing'); + $result = $this->rulesApplier->applyRules($item, $rules, $skipValidation, $couponCode); + $this->assertEquals($appliedRuleIds, $result); + } + + /** + * @return \Magento\Sales\Model\Quote\Item\AbstractItem|\PHPUnit_Framework_MockObject_MockObject + */ + protected function getPreparedItem() + { + /** @var \Magento\Sales\Model\Quote\Address|\PHPUnit_Framework_MockObject_MockObject $address */ + $address = $this->getMock( + 'Magento\Sales\Model\Quote\Address', + [ + 'getQuote', + 'setCouponCode', + 'setAppliedRuleIds', + '__wakeup' + ], + [], + '', + false + ); + /** @var \Magento\Sales\Model\Quote\Item\AbstractItem|\PHPUnit_Framework_MockObject_MockObject $item */ + $item = $this->getMock( + 'Magento\Sales\Model\Quote\Item', + [ + 'setDiscountAmount', + 'setBaseDiscountAmount', + 'setDiscountPercent', + 'getAddress', + 'setAppliedRuleIds', + '__wakeup' + ], + [], + '', + false + ); + $quote = $this->getMock('Magento\Sales\Model\Quote', ['getStore', '__wakeUp'], [], '', false); + $item->expects($this->any())->method('getAddress')->will($this->returnValue($address)); + $address->expects($this->any()) + ->method('getQuote') + ->will($this->returnValue($quote)); + + return $item; + } + + protected function applyRule($item, $rule) + { + $qty = 2; + $discountCalc = $this->getMock( + 'Magento\SalesRule\Model\Rule\Action\Discount', + ['fixQuantity', 'calculate'], + [], + '', + false + ); + $discountData = $this->getMock( + 'Magento\SalesRule\Model\Rule\Action\Discount\Data', + [], + [ + 'amount' => 30, + 'baseAmount' => 30, + 'originalAmount' => 30, + 'baseOriginalAmount' => 30 + ], + '', + false + ); + $this->validatorUtility->expects($this->any()) + ->method('getItemQty') + ->with($this->anything(), $this->anything()) + ->will($this->returnValue($qty)); + $discountCalc->expects($this->any()) + ->method('fixQuantity') + ->with($this->equalTo($qty), $this->equalTo($rule)) + ->will($this->returnValue($qty)); + + $discountCalc->expects($this->any()) + ->method('calculate') + ->with($this->equalTo($rule), $this->equalTo($item), $this->equalTo($qty)) + ->will($this->returnValue($discountData)); + $this->calculatorFactory->expects($this->any()) + ->method('create') + ->with($this->anything()) + ->will($this->returnValue($discountCalc)); + } +} diff --git a/dev/tests/unit/testsuite/Magento/SalesRule/Model/ValidatorTest.php b/dev/tests/unit/testsuite/Magento/SalesRule/Model/ValidatorTest.php index 3d8e21bf9d0b5d02ec85e3e9e4522c182fffe976..a2c29e03ce83d9ba41162ae13eb947f9a0912b1f 100644 --- a/dev/tests/unit/testsuite/Magento/SalesRule/Model/ValidatorTest.php +++ b/dev/tests/unit/testsuite/Magento/SalesRule/Model/ValidatorTest.php @@ -30,6 +30,7 @@ class ValidatorTest extends \PHPUnit_Framework_TestCase */ protected $model; + protected function setUp() { // @TODO Re-write test according to standards of writing test (e.g do not mock tested class) @@ -108,11 +109,18 @@ class ValidatorTest extends \PHPUnit_Framework_TestCase /** @var \Magento\SalesRule\Model\Validator|\PHPUnit_Framework_MockObject_MockObject $validator */ $validator = $this->getMock( 'Magento\SalesRule\Model\Validator', - array('applyRules', '__wakeup'), + array('__wakeup'), array(), '', false ); + $rulesApplier = $this->getMock( + 'Magento\SalesRule\Model\Validator\RulesApplier', + ['applyRules', '__wakeup'], + [], + '', + false + ); /** @var \Magento\Sales\Model\Quote\Item\AbstractItem|\PHPUnit_Framework_MockObject_MockObject $item */ $item = $this->getMock('Magento\Sales\Model\Quote\Item', array('__wakeup'), array(), '', false); @@ -122,7 +130,7 @@ class ValidatorTest extends \PHPUnit_Framework_TestCase $item->setData('calculation_price', $negativePrice); // 3. Set expectations - $validator->expects($this->never())->method('applyRules'); + $rulesApplier->expects($this->never())->method('applyRules'); // 4. Run tested method $validator->process($item); @@ -137,7 +145,7 @@ class ValidatorTest extends \PHPUnit_Framework_TestCase /** @var \Magento\SalesRule\Model\Validator|\PHPUnit_Framework_MockObject_MockObject $validator */ $validator = $this->getMock( 'Magento\SalesRule\Model\Validator', - array('applyRules', '__wakeup'), + array('__wakeup'), array(), '', false @@ -164,101 +172,49 @@ class ValidatorTest extends \PHPUnit_Framework_TestCase $this->assertEquals(0, $item->getDiscountPercent()); } - public function testApplyRulesWhenRuleWithStopRulesProcessingIsUsed() + public function testApplyRulesThatAppliedRuleIdsAreCollected() { $positivePrice = 1; + $ruleId1 = 123; + $ruleId2 = 234; + $expectedRuleIds = array($ruleId1 => $ruleId1, $ruleId2 => $ruleId2); // 1. Get mocks - /** @var \Magento\SalesRule\Model\Validator|\PHPUnit_Framework_MockObject_MockObject $validator */ - $validator = $this->getMock( - 'Magento\SalesRule\Model\Validator', - array('applyRule', 'setAppliedRuleIds', '_canProcessRule', '_getRules', '__wakeup'), - array(), - '', - false - ); - /** @var \Magento\Sales\Model\Quote\Address|\PHPUnit_Framework_MockObject_MockObject $address */ - $address = $this->getMock('Magento\Sales\Model\Quote\Address', array('__wakeup'), array(), '', false); - /** @var \Magento\Sales\Model\Quote\Item\AbstractItem|\PHPUnit_Framework_MockObject_MockObject $item */ - $item = $this->getMock('Magento\Sales\Model\Quote\Item', array('getAddress', '__wakeup'), array(), '', false); - /** - * @var \Magento\SalesRule\Model\Rule|\PHPUnit_Framework_MockObject_MockObject $ruleWithStopFurtherProcessing - */ - $ruleWithStopFurtherProcessing = $this->getMock( - 'Magento\SalesRule\Model\Rule', - array('__wakeup'), - array(), + $rulesApplier = $this->getMock( + 'Magento\SalesRule\Model\RulesApplier', + ['applyRules', 'setAppliedRuleIds'], + [], '', false ); - /** @var \Magento\SalesRule\Model\Rule|\PHPUnit_Framework_MockObject_MockObject $ruleThatShouldNotBeRun */ - $ruleThatShouldNotBeRun = $this->getMock( - 'Magento\SalesRule\Model\Rule', - array('__wakeup'), - array(), + $context = $this->getMock('Magento\Framework\Model\Context', [], [], '', false); + $registry = $this->getMock('Magento\Framework\Registry', [], [], '', false); + $collectionFactory = $this->getMock( + 'Magento\SalesRule\Model\Resource\Rule\CollectionFactory', + [], + [], '', false ); + $taxData = $this->getMock('Magento\Tax\Helper\Data', [], [], '', false); + $utility = $this->getMock('Magento\SalesRule\Model\Utility', [], [], '', false); - $item->expects($this->any())->method('getAddress')->will($this->returnValue($address)); - $ruleWithStopFurtherProcessing->setName('ruleWithStopFurtherProcessing'); - $ruleThatShouldNotBeRun->setName('ruleThatShouldNotBeRun'); - $rules = array($ruleWithStopFurtherProcessing, $ruleThatShouldNotBeRun); - $validator->expects($this->any())->method('_getRules')->will($this->returnValue($rules)); - - // 2. Set fixtures, provide tested code isolation - $item->setDiscountCalculationPrice($positivePrice); - $item->setData('calculation_price', $positivePrice); - $validator->setSkipActionsValidation(true); - $validator->expects($this->any())->method('_canProcessRule')->will($this->returnValue(true)); - $ruleWithStopFurtherProcessing->setStopRulesProcessing(true); - - // 3. Set expectations - $callback = function ($rule) use ($ruleThatShouldNotBeRun) { - /** @var $rule \Magento\SalesRule\Model\Rule|\PHPUnit_Framework_MockObject_MockObject */ - if ($rule->getName() == $ruleThatShouldNotBeRun->getName()) { - $this->fail('Rule should not be run after applying rule that stops further rules processing'); - } - - return true; - }; - $validator->expects( - $this->any() - )->method( - 'applyRule' - )->with( - $this->anything(), - $this->callback($callback), - $this->anything() - ); - - // 4. Run tested method - $validator->process($item); - - // 5. Set new expectations - $validator->expects($this->never())->method('applyRule'); - //No rules should be applied further - - // 6. Run tested method again - $validator->process($item); - } - - public function testApplyRulesThatAppliedRuleIdsAreCollected() - { - $positivePrice = 1; - $ruleId1 = 123; - $ruleId2 = 234; - $expectedRuleIds = array($ruleId1 => $ruleId1, $ruleId2 => $ruleId2); - - // 1. Get mocks /** @var \Magento\SalesRule\Model\Validator|\PHPUnit_Framework_MockObject_MockObject $validator */ $validator = $this->getMock( 'Magento\SalesRule\Model\Validator', - array('applyRule', '_getRules', '_canProcessRule', 'setAppliedRuleIds', '__wakeup'), - array(), + ['_getRules', '_canProcessRule', '__wakeup'], + [ + 'context' => $context, + 'registry' => $registry, + 'collectionFactory' => $collectionFactory, + 'taxData' => $taxData, + 'utility' => $utility, + 'rulesApplier' => $rulesApplier + ], '', - false + true ); + /** @var \Magento\Sales\Model\Quote\Item\AbstractItem|\PHPUnit_Framework_MockObject_MockObject $item */ $item = $this->getMock('Magento\Sales\Model\Quote\Item', array('getAddress', '__wakeup'), array(), '', false); /** @var \Magento\SalesRule\Model\Rule|\PHPUnit_Framework_MockObject_MockObject $rule */ @@ -274,108 +230,23 @@ class ValidatorTest extends \PHPUnit_Framework_TestCase $item->setDiscountCalculationPrice($positivePrice); $item->setData('calculation_price', $positivePrice); $validator->setSkipActionsValidation(true); - $validator->expects($this->any())->method('_canProcessRule')->will($this->returnValue(true)); // 3. Set expectations - $validator->expects($this->once())->method('setAppliedRuleIds')->with($this->anything(), $expectedRuleIds); - - // 4. Run tested method again - $validator->process($item); - } - - public function testApplyRule() - { - $positivePrice = 1; - - // 1. Get mocks - /** @var \Magento\SalesRule\Model\Validator|\PHPUnit_Framework_MockObject_MockObject $validator */ - $validator = $this->getMockBuilder( - 'Magento\SalesRule\Model\Validator' - )->setMethods( - array( - 'getDiscountData', - 'setDiscountData', - '_addDiscountDescription', - '_maintainAddressCouponCode', - '_canProcessRule', - 'setAppliedRuleIds', - '_getRules', - '__wakeup' + $rulesApplier->expects($this->once()) + ->method('applyRules') + ->with( + $this->equalTo($item), + $this->equalTo($rules), + $this->anything(), + $this->anything() ) - )->disableOriginalConstructor()->getMock(); - $rule = $this->getMockBuilder( - 'Magento\SalesRule\Model\Rule' - )->disableOriginalConstructor()->setMethods( - array() - )->getMock(); - /** @var \Magento\Sales\Model\Quote\Item\AbstractItem|\PHPUnit_Framework_MockObject_MockObject $item */ - $item = $this->getMock('Magento\Sales\Model\Quote\Item', array('getAddress', '__wakeup'), array(), '', false); - $discountData = $this->getMockBuilder('Magento\SalesRule\Model\Rule\Action\Discount\Data')->getMock(); - - // 2.Provide tested code isolation - $item->setDiscountCalculationPrice($positivePrice); - $item->setData('calculation_price', $positivePrice); - $validator->setSkipActionsValidation(true); - $validator->expects($this->any())->method('_canProcessRule')->will($this->returnValue(true)); - $validator->expects($this->any())->method('_getRules')->will($this->returnValue(array($rule))); - $validator->expects($this->any())->method('getDiscountData')->will($this->returnValue($discountData)); - - // 3. Set expectations - $validator->expects($this->any())->method('setDiscountData')->with($discountData); + ->will($this->returnValue($expectedRuleIds)); + $rulesApplier->expects($this->once())->method('setAppliedRuleIds')->with($this->anything(), $expectedRuleIds); // 4. Run tested method again $validator->process($item); } - public function testSetAppliedRuleIds() - { - $positivePrice = 1; - $previouslySetRuleIds = array(1, 2, 4); - $exampleRuleIds = array(1, 2, 3, 5); - $expectedRuleIds = '1,2,3,5'; - $expectedMergedRuleIds = '1,2,3,4,5'; - - // 1. Get mocks - /** @var \Magento\SalesRule\Model\Validator|\PHPUnit_Framework_MockObject_MockObject $validator */ - $validator = $this->getMock( - 'Magento\SalesRule\Model\Validator', - array('applyRules', '__wakeup'), - array(), - '', - false - ); - /** @var \Magento\Sales\Model\Quote\Item\AbstractItem|\PHPUnit_Framework_MockObject_MockObject $item */ - $item = $this->getMock( - 'Magento\Sales\Model\Quote\Item', - array('getAddress', 'getQuote', '__wakeup'), - array(), - '', - false - ); - /** @var \Magento\Sales\Model\Quote\Address|\PHPUnit_Framework_MockObject_MockObject $address */ - $address = $this->getMock('Magento\Sales\Model\Quote\Address', array('__wakeup'), array(), '', false); - /** @var \Magento\Sales\Model\Quote|\PHPUnit_Framework_MockObject_MockObject $quote */ - $quote = $this->getMock('Magento\Sales\Model\Quote', array('__wakeup'), array(), '', false); - $item->expects($this->any())->method('getAddress')->will($this->returnValue($address)); - $item->expects($this->any())->method('getQuote')->will($this->returnValue($quote)); - - // 2. Set fixtures - $item->setDiscountCalculationPrice($positivePrice); - $item->setData('calculation_price', $positivePrice); - $validator->expects($this->any())->method('applyRules')->will($this->returnValue($exampleRuleIds)); - $address->setAppliedRuleIds($previouslySetRuleIds); - $quote->setAppliedRuleIds($previouslySetRuleIds); - - // 3. Run tested method - $validator->process($item); - - // 4. Check expected result - $this->assertEquals($expectedRuleIds, $item->getAppliedRuleIds()); - - $this->assertObjectHasRuleIdsSet($expectedMergedRuleIds, $item->getAddress()); - $this->assertObjectHasRuleIdsSet($expectedMergedRuleIds, $item->getQuote()); - } - /** * @param $expectedMergedRuleIds * @param \Magento\Sales\Model\Quote\Address|\Magento\Sales\Model\Quote $object diff --git a/dev/tests/unit/testsuite/Magento/Tax/Model/Calculation/CalculatorFactoryTest.php b/dev/tests/unit/testsuite/Magento/Tax/Model/Calculation/CalculatorFactoryTest.php new file mode 100644 index 0000000000000000000000000000000000000000..2318f8ffa6553e543a2689cd04a600733efadd12 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Tax/Model/Calculation/CalculatorFactoryTest.php @@ -0,0 +1,214 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Tax\Model\Calculation; + +use Magento\Customer\Service\V1\Data\Address; +use Magento\TestFramework\Helper\ObjectManager; + +/** + * Test class for \Magento\Tax\Model\CalculatorFactory + */ +class CalculatorFactoryTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\TestFramework\Helper\ObjectManager + */ + public $objectManager; + + public function setUp() + { + $this->objectManager = new ObjectManager($this); + } + + /** + * @param string $type Type of calculator + * @param int $storeId + * @param Address $billingAddress + * @param Address $shippingAddress + * @param null|int $customerTaxClassId + * @param null|int $customerId + * @param \Magento\Tax\Model\Calculation\AbstractCalculator $expectedInstanceType + * expected type of calculator instance + * + * @dataProvider createDataProvider + */ + public function testCreate( + $type, + $storeId, + $billingAddress, + $shippingAddress, + $customerTaxClassId, + $customerId, + $expectedInstanceType + ) { + $instanceMock = $this->getMockBuilder($expectedInstanceType)->disableOriginalConstructor()->getMock(); + $objectManagerMock = $this->getMockBuilder('Magento\Framework\ObjectManager')->getMock(); + + // Verify create() is called with correct concrete type + $objectManagerMock->expects($this->once()) + ->method('create') + ->with($expectedInstanceType, ['storeId' => $storeId]) + ->will($this->returnValue($instanceMock)); + + /** @var CalculatorFactory $calculatorFactory */ + $calculatorFactory = $this->objectManager->getObject( + 'Magento\Tax\Model\Calculation\CalculatorFactory', + ['objectManager' => $objectManagerMock] + ); + + // Verify billing is set correctly if passed in + if ($billingAddress != null) { + $instanceMock->expects($this->once()) + ->method('setBillingAddress') + ->with($billingAddress); + } else { + $instanceMock->expects($this->never()) + ->method('setBillingAddress'); + } + + // Verify shipping is set correctly if passed in + if ($shippingAddress != null) { + $instanceMock->expects($this->once()) + ->method('setShippingAddress') + ->with($shippingAddress); + } else { + $instanceMock->expects($this->never()) + ->method('setShippingAddress'); + } + + // Verify customerTaxClassId is set correctly if passed in + if ($customerTaxClassId != null) { + $instanceMock->expects($this->once()) + ->method('setCustomerTaxClassId') + ->with($customerTaxClassId); + } else { + $instanceMock->expects($this->never()) + ->method('setCustomerTaxClassId'); + } + + // Verify customerId is set correctly if passed in + if ($customerId != null) { + $instanceMock->expects($this->once()) + ->method('setCustomerId') + ->with($customerId); + } else { + $instanceMock->expects($this->never()) + ->method('setCustomerId'); + } + + // Call create() + $calculator = $calculatorFactory + ->create($type, $storeId, $billingAddress, $shippingAddress, $customerTaxClassId, $customerId); + + // Verify correct type is returned + $this->assertInstanceOf($expectedInstanceType, $calculator); + } + + /** + * Returns a set of 'true' and 'false' parameters for each of the setter/getter method pairs + * + * @return array + */ + public function createDataProvider() + { + $billingAddressMock = $this->getMockBuilder('\Magento\Customer\Service\V1\Data\Address') + ->disableOriginalConstructor() + ->getMock(); + $shippingAddressMock = $this->getMockBuilder('\Magento\Customer\Service\V1\Data\Address') + ->disableOriginalConstructor() + ->getMock(); + + return [ + 'Unit' => [ + CalculatorFactory::CALC_UNIT_BASE, + 1, + null, + null, + null, + null, + 'Magento\Tax\Model\Calculation\UnitBaseCalculator' + ], + 'Row HasBilling' => [ + CalculatorFactory::CALC_ROW_BASE, + 2, + $billingAddressMock, + null, + null, + null, + 'Magento\Tax\Model\Calculation\RowBaseCalculator' + ], + 'Row HasCustomerTaxClassId' => [ + CalculatorFactory::CALC_ROW_BASE, + 3, + null, + null, + 123, + null, + 'Magento\Tax\Model\Calculation\RowBaseCalculator' + ], + 'Total HasShipping' => [ + CalculatorFactory::CALC_TOTAL_BASE, + 1, + null, + $shippingAddressMock, + null, + null, + 'Magento\Tax\Model\Calculation\TotalBaseCalculator' + ], + 'Total HasShipping HasBilling HasCustomerTaxClassId' => [ + CalculatorFactory::CALC_TOTAL_BASE, + 1, + $billingAddressMock, + $shippingAddressMock, + 1, + null, + 'Magento\Tax\Model\Calculation\TotalBaseCalculator' + ], + 'Total HasShipping HasBilling HasCustomerTaxClassId, HasCustomer' => [ + CalculatorFactory::CALC_TOTAL_BASE, + 1, + $billingAddressMock, + $shippingAddressMock, + 1, + 1, + 'Magento\Tax\Model\Calculation\TotalBaseCalculator' + ], + ]; + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage Unknown calculation type: NOT_A_TYPE + */ + public function testCreateInvalid() + { + /** @var CalculatorFactory $calculatorFactory */ + $calculatorFactory = $this->objectManager->getObject( + 'Magento\Tax\Model\Calculation\CalculatorFactory' + ); + + // Call create() with a bad type to generate exception + $calculatorFactory->create('NOT_A_TYPE', 1); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Tax/Model/Calculation/RowBaseAndTotalBaseCalculatorTestCase.php b/dev/tests/unit/testsuite/Magento/Tax/Model/Calculation/RowBaseAndTotalBaseCalculatorTestCase.php new file mode 100644 index 0000000000000000000000000000000000000000..ede59e89b3b90c11ded32cb804ff9a0822213e1a --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Tax/Model/Calculation/RowBaseAndTotalBaseCalculatorTestCase.php @@ -0,0 +1,334 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Tax\Model\Calculation; + +use Magento\TestFramework\Helper\ObjectManager; +use Magento\Tax\Service\V1\Data\TaxDetails\AppliedTaxBuilder; + +class RowBaseAndTotalBaseCalculatorTestCase extends \PHPUnit_Framework_TestCase +{ + const STORE_ID = 2300; + const QUANTITY = 1; + const UNIT_PRICE = 500; + const RATE = 10; + const STORE_RATE = 11; + + const CODE = 'CODE'; + const TYPE = 'TYPE'; + + const ONCE = 'once'; + const MOCK_METHOD_NAME = 'mock_method_name'; + const MOCK_VALUE = 'mock_value'; + const WITH_ARGUMENT = 'with_argument'; + const EXPECTED_VALUE = "some_return_object"; + + /** @var ObjectManager */ + protected $objectManager; + + /** @var \Magento\Tax\Service\V1\Data\TaxDetails\ItemBuilder | \PHPUnit_Framework_MockObject_MockObject */ + protected $mockTaxItemDetailsBuilder; + + /** @var \Magento\Tax\Model\Calculation | \PHPUnit_Framework_MockObject_MockObject */ + protected $mockCalculationTool; + + /** @var \Magento\Tax\Model\Config | \PHPUnit_Framework_MockObject_MockObject */ + protected $mockConfig; + + /** @var $mockItem \Magento\Tax\Service\V1\Data\QuoteDetails\Item | \PHPUnit_Framework_MockObject_MockObject */ + protected $mockItem; + + /** @var $mockAppliedTaxBuilder AppliedTaxBuilder | \PHPUnit_Framework_MockObject_MockObject */ + protected $mockAppliedTaxBuilder; + + /** @var $mockAppliedTaxRateBuilder AppliedTaxBuilder | \PHPUnit_Framework_MockObject_MockObject */ + protected $mockAppliedTaxRateBuilder; + + /** @var \Magento\Tax\Service\V1\Data\TaxDetails\AppliedTax | \PHPUnit_Framework_MockObject_MockObject */ + protected $mockAppliedTax; + + protected $addressRateRequest; + + /** + * initialize all mocks + * + * @param bool $taxIncluded + */ + public function initMocks($taxIncluded) + { + $this->initMockItem($taxIncluded); + $this->initMockConfig(); + $this->initMockCalculationTool(); + $this->initMockItemBuilder(); + $this->initMockAppliedTaxBuilder(); + } + + public function setUp() + { + $this->objectManager = new ObjectManager($this); + $this->mockTaxItemDetailsBuilder = $this->getMockBuilder('\Magento\Tax\Service\V1\Data\TaxDetails\ItemBuilder') + ->disableOriginalConstructor() + ->getMock(); + $this->mockCalculationTool = $this->getMockBuilder('\Magento\Tax\Model\Calculation') + ->disableOriginalConstructor() + ->setMethods( + ['__wakeup', 'round', 'getRate', 'getStoreRate', 'getRateRequest', 'getAppliedRates', 'calcTaxAmount'] + ) + ->getMock(); + $this->mockConfig = $this->getMockBuilder('\Magento\Tax\Model\Config') + ->disableOriginalConstructor() + ->getMock(); + + $this->mockItem = $this->getMockBuilder('Magento\Tax\Service\V1\Data\QuoteDetails\Item') + ->disableOriginalConstructor() + ->getMock(); + + $this->mockAppliedTaxRateBuilder = $this->getMockBuilder( + 'Magento\Tax\Service\V1\Data\TaxDetails\AppliedTaxRateBuilder' + ) + ->disableOriginalConstructor() + ->getMock(); + $this->mockAppliedTaxBuilder = $this->getMockBuilder( + 'Magento\Tax\Service\V1\Data\TaxDetails\AppliedTaxBuilder' + ) + ->disableOriginalConstructor() + ->getMock(); + $this->mockAppliedTax = $this->getMockBuilder( + 'Magento\Tax\Service\V1\Data\TaxDetails\AppliedTax' + )->disableOriginalConstructor() + ->getMock(); + + $this->mockAppliedTax->expects($this->any())->method('getTaxRateKey')->will($this->returnValue('taxKey')); + //Magento\Tax\Service\V1\Data\TaxDetails + $this->addressRateRequest = new \Magento\Framework\Object(); + + } + + /** + * @param $calculator RowBaseCalculator|TotalBaseCalculator + * @return \Magento\Tax\Service\V1\Data\QuoteDetails\Item + */ + public function calculate($calculator) + { + return $calculator->calculate($this->mockItem, 1); + } + + /** + * init mock Items + * + * @param bool $taxIncluded + */ + protected function initMockItem($taxIncluded) + { + $this->mockReturnValues( + $this->mockItem, + [ + [ + self::ONCE => true, + self::MOCK_METHOD_NAME => 'getDiscountAmount', + self::MOCK_VALUE => 1 + ], + [ + self::ONCE => true, + self::MOCK_METHOD_NAME => 'getCode', + self::MOCK_VALUE => self::CODE + ], + [ + self::ONCE => true, + self::MOCK_METHOD_NAME => 'getType', + self::MOCK_VALUE => self::TYPE + ], + [ + self::ONCE => true, + self::MOCK_METHOD_NAME => 'getUnitPrice', + self::MOCK_VALUE => self::UNIT_PRICE + ], + [ + self::ONCE => true, + self::MOCK_METHOD_NAME => 'getTaxIncluded', + self::MOCK_VALUE => $taxIncluded + ] + ] + ); + } + + /** + * init mock config + * + */ + protected function initMockConfig() + { + $this->mockReturnValues( + $this->mockConfig, + [ + [ + self::ONCE => true, + self::MOCK_METHOD_NAME => 'applyTaxAfterDiscount', + self::MOCK_VALUE => true + ] + ] + ); + } + + /** + * init mock calculation model + * + */ + + protected function initMockCalculationTool() + { + $this->mockReturnValues( + $this->mockCalculationTool, + [ + [ + self::ONCE => false, + self::MOCK_METHOD_NAME => 'calcTaxAmount', + self::MOCK_VALUE => 1.5 + ], + [ + self::ONCE => true, + self::MOCK_METHOD_NAME => 'getRate', + self::MOCK_VALUE => self::RATE + ], + [ + self::ONCE => true, + self::MOCK_METHOD_NAME => 'getAppliedRates', + self::MOCK_VALUE => [ + [ + 'id' => 0, + 'percent' => 1.4, + 'rates' => [ + [ + 'code' => 'sku_1', + 'title' => 'title1', + 'percent' => 1.1 + ] + ] + ] + ] + ], + [ + self::ONCE => false, + self::MOCK_METHOD_NAME => 'round', + self::MOCK_VALUE => 1.3 + ] + ] + ); + } + + /** + * init mock applied itemBuilder + * + */ + + protected function initMockItemBuilder() + { + $this->mockReturnValues( + $this->mockTaxItemDetailsBuilder, + [ + [ + self::ONCE => true, + self::MOCK_METHOD_NAME => 'setType', + self::MOCK_VALUE => self::TYPE + ], + [ + self::ONCE => true, + self::MOCK_METHOD_NAME => 'setCode', + self::MOCK_VALUE => self::CODE + ], + [ + self::ONCE => true, + self::MOCK_METHOD_NAME => 'setRowTax', + self::MOCK_VALUE => 1.3 + ], + [ + self::ONCE => true, + self::MOCK_METHOD_NAME => 'setTaxPercent', + self::MOCK_VALUE => self::RATE + ], + [ + self::ONCE => true, + self::MOCK_METHOD_NAME => 'create', + self::MOCK_VALUE => self::EXPECTED_VALUE + ], + [ + self::ONCE => true, + self::MOCK_METHOD_NAME => 'getAppliedTaxBuilder', + self::MOCK_VALUE => $this->mockAppliedTaxBuilder + ] + ] + + ); + } + + /** + * init mock appliedTaxBuilder + * + */ + protected function initMockAppliedTaxBuilder() + { + + $this->mockReturnValues( + $this->mockAppliedTaxBuilder, + [ + [ + self::ONCE => true, + self::MOCK_METHOD_NAME => 'getAppliedTaxRateBuilder', + self::MOCK_VALUE => $this->mockAppliedTaxRateBuilder + ], + [ + self::ONCE => true, + self::MOCK_METHOD_NAME => 'create', + self::MOCK_VALUE => $this->mockAppliedTax + ] + ] + ); + } + + /** + * @param \PHPUnit_Framework_MockObject_MockObject $mockObject + * @param array $mockMap + */ + private function mockReturnValues($mockObject, $mockMap) + { + foreach ($mockMap as $valueMap) { + + if (isset($valueMap[self::WITH_ARGUMENT])) { + $mockObject->expects( + $valueMap[self::ONCE] == true ? $this->once() : $this->atLeastOnce() + )->method($valueMap[self::MOCK_METHOD_NAME])->with($valueMap[self::WITH_ARGUMENT]) + ->will( + $this->returnValue($valueMap[self::MOCK_VALUE]) + ); + } else { + $mockObject->expects( + $valueMap[self::ONCE] == true ? $this->once() : $this->atLeastOnce() + )->method($valueMap[self::MOCK_METHOD_NAME])->withAnyParameters() + ->will( + $this->returnValue($valueMap[self::MOCK_VALUE]) + ); + } + } + } +} diff --git a/dev/tests/unit/testsuite/Magento/Tax/Model/Calculation/RowBaseCalculatorTest.php b/dev/tests/unit/testsuite/Magento/Tax/Model/Calculation/RowBaseCalculatorTest.php new file mode 100644 index 0000000000000000000000000000000000000000..3ad65feca0906f03fdbd947afcfa36e500f07e0f --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Tax/Model/Calculation/RowBaseCalculatorTest.php @@ -0,0 +1,78 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Tax\Model\Calculation; + +/** + * Class RowBaseCalculatorTest + * + */ +class RowBaseCalculatorTest extends RowBaseAndTotalBaseCalculatorTestCase +{ + + /** @var RowBaseCalculator | \PHPUnit_Framework_MockObject_MockObject */ + protected $rowBaseCalculator; + + public function testCalculateWithTaxInPrice() + { + $this->initMocks(true); + $this->initRowBaseCalculator(); + $this->rowBaseCalculator->expects($this->once()) + ->method('deltaRound')->will($this->returnValue(0)); + + $this->assertSame( + self::EXPECTED_VALUE, + $this->calculate($this->rowBaseCalculator) + ); + } + + public function testCalculateWithTaxNotInPrice() + { + $this->initMocks(false); + $this->initRowBaseCalculator(); + $this->rowBaseCalculator->expects($this->never()) + ->method('deltaRound'); + + $this->assertSame( + self::EXPECTED_VALUE, + $this->calculate($this->rowBaseCalculator) + ); + } + + private function initRowBaseCalculator() + { + $taxClassService = $this->objectManager->getObject('Magento\Tax\Service\V1\TaxClassService'); + $this->rowBaseCalculator = $this->getMockBuilder('Magento\Tax\Model\Calculation\RowBaseCalculator') + ->setConstructorArgs( + [ + 'taxClassService' => $taxClassService, + 'taxDetailsItemBuilder' => $this->mockTaxItemDetailsBuilder, + 'calculationTool' => $this->mockCalculationTool, + 'config' => $this->mockConfig, + 'storeId' => self::STORE_ID, + 'addressRateRequest' => $this->addressRateRequest + ] + )->setMethods(['deltaRound'])->getMock(); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Tax/Model/Calculation/TotalBaseCalculatorTest.php b/dev/tests/unit/testsuite/Magento/Tax/Model/Calculation/TotalBaseCalculatorTest.php new file mode 100644 index 0000000000000000000000000000000000000000..89efb6547f1b20f3d878f1b53b391716efa3beda --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Tax/Model/Calculation/TotalBaseCalculatorTest.php @@ -0,0 +1,82 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Tax\Model\Calculation; + + +use Magento\Tax\Model\Calculation; +use Magento\TestFramework\Helper\ObjectManager; +use Magento\Tax\Service\V1\Data\QuoteDetails; + +/** + * Class TotalBaseCalculatorTest + * + */ +class TotalBaseCalculatorTest extends RowBaseAndTotalBaseCalculatorTestCase +{ + /** @var TotalBaseCalculator | \PHPUnit_Framework_MockObject_MockObject */ + protected $totalBaseCalculator; + + public function testCalculateWithTaxInPrice() + { + $this->initTotalBaseCalculator(); + $this->totalBaseCalculator->expects($this->exactly(3)) + ->method('deltaRound')->will($this->returnValue(0)); + $this->initMocks(true); + + $this->assertSame( + self::EXPECTED_VALUE, + $this->calculate($this->totalBaseCalculator) + ); + } + + public function testCalculateWithTaxNotInPrice() + { + $this->initTotalBaseCalculator(); + $this->totalBaseCalculator->expects($this->exactly(2)) + ->method('deltaRound')->will($this->returnValue(0)); + $this->initMocks(false); + + $this->assertSame( + self::EXPECTED_VALUE, + $this->calculate($this->totalBaseCalculator) + ); + } + + private function initTotalBaseCalculator() + { + $taxClassService = $this->objectManager->getObject('Magento\Tax\Service\V1\TaxClassService'); + $this->totalBaseCalculator = $this->getMockBuilder('Magento\Tax\Model\Calculation\TotalBaseCalculator') + ->setConstructorArgs( + [ + 'taxClassService' => $taxClassService, + 'taxDetailsItemBuilder' => $this->mockTaxItemDetailsBuilder, + 'calculationTool' => $this->mockCalculationTool, + 'config' => $this->mockConfig, + 'storeId' => self::STORE_ID, + 'addressRateRequest' => $this->addressRateRequest + ] + )->setMethods(['deltaRound'])->getMock(); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Tax/Model/Calculation/UnitBaseCalculatorTest.php b/dev/tests/unit/testsuite/Magento/Tax/Model/Calculation/UnitBaseCalculatorTest.php new file mode 100644 index 0000000000000000000000000000000000000000..91f33d7bcdff6a1de8926eafc9171a3dd94904f9 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Tax/Model/Calculation/UnitBaseCalculatorTest.php @@ -0,0 +1,199 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Tax\Model\Calculation; + +class UnitBaseCalculatorTest extends \PHPUnit_Framework_TestCase +{ + const STORE_ID = 2300; + const QUANTITY = 1; + const UNIT_PRICE = 500; + const RATE = 10; + const STORE_RATE = 11; + + const CODE = 'CODE'; + const TYPE = 'TYPE'; + const ROW_TAX = 44.954135954136; + + /** @var \Magento\Tax\Service\V1\Data\TaxDetails\ItemBuilder | \PHPUnit_Framework_MockObject_MockObject */ + protected $mockTaxItemDetailsBuilder; + + /** @var \Magento\Tax\Model\Calculation | \PHPUnit_Framework_MockObject_MockObject */ + protected $mockCalculationTool; + + /** @var \Magento\Tax\Model\Config | \PHPUnit_Framework_MockObject_MockObject */ + protected $mockConfig; + + /** @var UnitBaseCalculator */ + protected $model; + + protected $addressRateRequest; + + public function setUp() + { + $this->mockTaxItemDetailsBuilder = $this->getMockBuilder('\Magento\Tax\Service\V1\Data\TaxDetails\ItemBuilder') + ->disableOriginalConstructor() + ->getMock(); + $this->mockCalculationTool = $this->getMockBuilder('\Magento\Tax\Model\Calculation') + ->disableOriginalConstructor() + ->setMethods(['__wakeup', 'round', 'getRate', 'getStoreRate', 'getRateRequest', 'getAppliedRates']) + ->getMock(); + $this->mockCalculationTool->expects($this->any()) + ->method('round') + ->withAnyParameters() + ->will($this->returnArgument(0)); + $this->mockConfig = $this->getMockBuilder('\Magento\Tax\Model\Config') + ->disableOriginalConstructor() + ->getMock(); + $this->addressRateRequest = new \Magento\Framework\Object(); + + $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this); + $arguments = [ + 'taxDetailsItemBuilder' => $this->mockTaxItemDetailsBuilder, + 'calculationTool' => $this->mockCalculationTool, + 'config' => $this->mockConfig, + 'storeId' => self::STORE_ID, + 'addressRateRequest' => $this->addressRateRequest + ]; + $this->model = $objectManager->getObject('Magento\Tax\Model\Calculation\UnitBaseCalculator', $arguments); + } + + public function testCalculateWithTaxInPrice() + { + $mockItem = $this->getMockItem(); + $mockItem->expects($this->once()) + ->method('getTaxIncluded') + ->will($this->returnValue(true)); + + $this->mockConfig->expects($this->once()) + ->method('crossBorderTradeEnabled') + ->will($this->returnValue(false)); + $this->mockConfig->expects($this->once()) + ->method('applyTaxAfterDiscount') + ->will($this->returnValue(true)); + + $this->mockCalculationTool->expects($this->once()) + ->method('getRate') + ->with($this->addressRateRequest) + ->will($this->returnValue(self::RATE)); + $this->mockCalculationTool->expects($this->once()) + ->method('getStoreRate') + ->with($this->addressRateRequest, self::STORE_ID) + ->will($this->returnValue(self::STORE_RATE)); + $this->mockCalculationTool->expects($this->once()) + ->method('getAppliedRates') + ->withAnyParameters() + ->will($this->returnValue([])); + + $mockAppliedTaxRateBuilder = $this->getMockBuilder('Magento\Tax\Service\V1\Data\TaxDetails\AppliedTaxBuilder') + ->disableOriginalConstructor() + ->getMock(); + $this->mockTaxItemDetailsBuilder->expects($this->once()) + ->method('getAppliedTaxBuilder') + ->will($this->returnValue($mockAppliedTaxRateBuilder)); + $this->mockTaxItemDetailsBuilder->expects($this->once()) + ->method('setCode') + ->with(self::CODE); + $this->mockTaxItemDetailsBuilder->expects($this->once()) + ->method('setType') + ->with(self::TYPE); + $this->mockTaxItemDetailsBuilder->expects($this->once()) + ->method('setRowTax') + ->with(self::ROW_TAX); + $expectedReturnValue = 'SOME RETURN OBJECT'; + $this->mockTaxItemDetailsBuilder->expects($this->once()) + ->method('create') + ->will($this->returnValue($expectedReturnValue)); + + $this->assertSame($expectedReturnValue, $this->model->calculate($mockItem, self::QUANTITY)); + } + + public function testCalculateWithTaxNotInPrice() + { + $mockItem = $this->getMockItem(); + $mockItem->expects($this->once()) + ->method('getTaxIncluded') + ->will($this->returnValue(false)); + + $this->mockConfig->expects($this->once()) + ->method('applyTaxAfterDiscount') + ->will($this->returnValue(true)); + + $this->mockCalculationTool->expects($this->once()) + ->method('getRate') + ->with($this->addressRateRequest) + ->will($this->returnValue(self::RATE)); + $this->mockCalculationTool->expects($this->once()) + ->method('getAppliedRates') + ->withAnyParameters() + ->will($this->returnValue([['id' => 0, 'percent' => 0, 'rates' => []]])); + + $mockAppliedTaxRateBuilder = $this->getMockBuilder('Magento\Tax\Service\V1\Data\TaxDetails\AppliedTaxBuilder') + ->disableOriginalConstructor() + ->getMock(); + $this->mockTaxItemDetailsBuilder->expects($this->once()) + ->method('getAppliedTaxBuilder') + ->will($this->returnValue($mockAppliedTaxRateBuilder)); + $this->mockTaxItemDetailsBuilder->expects($this->once()) + ->method('setCode') + ->with(self::CODE); + $this->mockTaxItemDetailsBuilder->expects($this->once()) + ->method('setType') + ->with(self::TYPE); + $this->mockTaxItemDetailsBuilder->expects($this->once()) + ->method('setRowTax') + ->with(0.0); + $expectedReturnValue = 'SOME RETURN OBJECT'; + $this->mockTaxItemDetailsBuilder->expects($this->once()) + ->method('create') + ->will($this->returnValue($expectedReturnValue)); + + $this->assertSame($expectedReturnValue, $this->model->calculate($mockItem, self::QUANTITY)); + } + + /** + * @return \Magento\Tax\Service\V1\Data\QuoteDetails\Item|\PHPUnit_Framework_MockObject_MockObject + */ + protected function getMockItem() + { + /** @var $mockItem \Magento\Tax\Service\V1\Data\QuoteDetails\Item | \PHPUnit_Framework_MockObject_MockObject */ + $mockItem = $this->getMockBuilder('Magento\Tax\Service\V1\Data\QuoteDetails\Item') + ->disableOriginalConstructor() + ->getMock(); + $mockItem->expects($this->once()) + ->method('getDiscountAmount') + ->will($this->returnValue(1)); + $mockItem->expects($this->once()) + ->method('getCode') + ->will($this->returnValue(self::CODE)); + $mockItem->expects($this->once()) + ->method('getType') + ->will($this->returnValue(self::TYPE)); + $mockItem->expects($this->once()) + ->method('getUnitPrice') + ->will($this->returnValue(self::UNIT_PRICE)); + + return $mockItem; + } +} diff --git a/dev/tests/unit/testsuite/Magento/Tax/Model/ConfigTest.php b/dev/tests/unit/testsuite/Magento/Tax/Model/ConfigTest.php index 3502632adeb076bb3cb6a07574ff8523f59561dc..f61c6738555cbf803a3360bc0ee862a764c3f2b1 100644 --- a/dev/tests/unit/testsuite/Magento/Tax/Model/ConfigTest.php +++ b/dev/tests/unit/testsuite/Magento/Tax/Model/ConfigTest.php @@ -27,8 +27,6 @@ */ namespace Magento\Tax\Model; -use Magento\Tax\Model\Config; - class ConfigTest extends \PHPUnit_Framework_TestCase { /** @@ -52,56 +50,21 @@ class ConfigTest extends \PHPUnit_Framework_TestCase } /** - * Returns a set of 'true' and 'false' parameters for each of the setter/getter method pairs - * * @return array */ public function dataProviderDirectSettersGettersMethods() { - return $this->_buildTrueFalsePairs( - [ - [ - 'setShippingPriceIncludeTax', - 'shippingPriceIncludesTax' - ], - [ - 'setNeedUseShippingExcludeTax', - 'getNeedUseShippingExcludeTax' - ], - [ - 'setPriceIncludesTax', - 'priceIncludesTax' - ] - ] - ); + return [ + ['setShippingPriceIncludeTax', 'shippingPriceIncludesTax', true], + ['setShippingPriceIncludeTax', 'shippingPriceIncludesTax', false], + ['setNeedUseShippingExcludeTax', 'getNeedUseShippingExcludeTax', true], + ['setNeedUseShippingExcludeTax', 'getNeedUseShippingExcludeTax', false], + ['setPriceIncludesTax', 'priceIncludesTax', true], + ['setPriceIncludesTax', 'priceIncludesTax', false], + ['setPriceIncludesTax', 'priceIncludesTax', null] + ]; } - /** - * Returns an output array that is twice the size of the input array by adding 'true' and then 'false' to the - * set of parameters given - * - * @param array $arrayIn - * @return array - */ - protected function _buildTrueFalsePairs($arrayIn) - { - $arrayOut = []; - - foreach ($arrayIn as $paramArray) { - // replicate the paramArray, append 'true', and add the new array to the output array - $arrayT = $paramArray; - $arrayT[] = true; - $arrayOut[] = $arrayT; - // replicate the paramArray, append 'false', and add the new array to the output array - $arrayF = $paramArray; - $arrayF[] = false; - $arrayOut[] = $arrayF; - } - - return $arrayOut; - } - - /** * Tests the getCalculationSequence method * @@ -399,6 +362,24 @@ class ConfigTest extends \PHPUnit_Framework_TestCase Config::CONFIG_XML_PATH_CROSS_BORDER_TRADE_ENABLED, true, true + ], + [ + 'isWrongDisplaySettingsIgnored', + Config::XML_PATH_TAX_NOTIFICATION_IGNORE_PRICE_DISPLAY, + true, + true + ], + [ + 'isWrongDiscountSettingsIgnored', + Config::XML_PATH_TAX_NOTIFICATION_IGNORE_DISCOUNT, + true, + true + ], + [ + 'getInfoUrl', + Config::XML_PATH_TAX_NOTIFICATION_INFO_URL, + true, + true ] ]; } diff --git a/dev/tests/unit/testsuite/Magento/Tax/Model/Sales/Total/Quote/TaxTest.php b/dev/tests/unit/testsuite/Magento/Tax/Model/Sales/Total/Quote/TaxTest.php new file mode 100644 index 0000000000000000000000000000000000000000..1b13b62cf29575e886aab8d3111b3f16329ef431 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Tax/Model/Sales/Total/Quote/TaxTest.php @@ -0,0 +1,72 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Tax\Model\Sales\Total\Quote; + +/** + * Test class for \Magento\Tax\Model\Sales\Total\Quote\Tax + */ +use Magento\Tax\Model\Calculation; + +class TaxTest extends \PHPUnit_Framework_TestCase +{ + /** + * Tests the specific method + * + * @param string $calculationSequence + * @param string $keyExpected + * @param string $keyAbsent + * @dataProvider dataProviderProcessConfigArray + */ + public function testProcessConfigArray($calculationSequence, $keyExpected, $keyAbsent) + { + $taxData = $this->getMock('Magento\Tax\Helper\Data', [], [], '', false); + $taxData + ->expects($this->any()) + ->method('getCalculationSequence') + ->will($this->returnValue($calculationSequence)); + + $config = $this->getMock('\Magento\Tax\Model\Config', [], [], '', false); + $taxCalculationService = $this->getMock('\Magento\Tax\Service\V1\TaxCalculationService', [], [], '', false); + $quoteDetailsBuilder = $this->getMock('\Magento\Tax\Service\V1\Data\QuoteDetailsBuilder', [], [], '', false); + + /** @var \Magento\Tax\Model\Sales\Total\Quote\Tax */ + $taxTotalsCalcModel = new Tax($taxData, $config, $taxCalculationService, $quoteDetailsBuilder); + $array = $taxTotalsCalcModel->processConfigArray([], null); + $this->assertArrayHasKey($keyExpected, $array, 'Did not find the expected array key: ' . $keyExpected); + $this->assertArrayNotHasKey($keyAbsent, $array, 'Should not have found the array key; ' . $keyAbsent); + } + + /** + * @return array + */ + public function dataProviderProcessConfigArray() + { + return [ + [Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_INCL, 'before', 'after'], + [Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_EXCL, 'after', 'before'], + [Calculation::CALC_TAX_AFTER_DISCOUNT_ON_EXCL, 'after', 'before'], + [Calculation::CALC_TAX_AFTER_DISCOUNT_ON_INCL, 'after', 'before'] + ]; + } +} diff --git a/dev/tests/unit/testsuite/Magento/Tax/Model/TaxClass/Source/ProductTest.php b/dev/tests/unit/testsuite/Magento/Tax/Model/TaxClass/Source/ProductTest.php index fd5ea72fb4738e9a278457926bc943ae96d7e6b4..0e03cc3c019a9d7dff5080747d499150ea3da6db 100644 --- a/dev/tests/unit/testsuite/Magento/Tax/Model/TaxClass/Source/ProductTest.php +++ b/dev/tests/unit/testsuite/Magento/Tax/Model/TaxClass/Source/ProductTest.php @@ -38,7 +38,7 @@ class ProductTest extends \PHPUnit_Framework_TestCase $this->_model = $objectManager->getObject('Magento\Tax\Model\TaxClass\Source\Product'); } - public function testGetFlatColums() + public function testGetFlatColumns() { $abstractAttributeMock = $this->getMock( '\Magento\Eav\Model\Entity\Attribute\AbstractAttribute', @@ -52,17 +52,17 @@ class ProductTest extends \PHPUnit_Framework_TestCase $this->_model->setAttribute($abstractAttributeMock); - $flatColums = $this->_model->getFlatColums(); + $flatColumns = $this->_model->getFlatColumns(); - $this->assertTrue(is_array($flatColums), 'FlatColums must be an array value'); - $this->assertTrue(!empty($flatColums), 'FlatColums must be not empty'); - foreach ($flatColums as $result) { - $this->assertArrayHasKey('unsigned', $result, 'FlatColums must have "unsigned" column'); - $this->assertArrayHasKey('default', $result, 'FlatColums must have "default" column'); - $this->assertArrayHasKey('extra', $result, 'FlatColums must have "extra" column'); - $this->assertArrayHasKey('type', $result, 'FlatColums must have "type" column'); - $this->assertArrayHasKey('nullable', $result, 'FlatColums must have "nullable" column'); - $this->assertArrayHasKey('comment', $result, 'FlatColums must have "comment" column'); + $this->assertTrue(is_array($flatColumns), 'FlatColumns must be an array value'); + $this->assertTrue(!empty($flatColumns), 'FlatColumns must be not empty'); + foreach ($flatColumns as $result) { + $this->assertArrayHasKey('unsigned', $result, 'FlatColumns must have "unsigned" column'); + $this->assertArrayHasKey('default', $result, 'FlatColumns must have "default" column'); + $this->assertArrayHasKey('extra', $result, 'FlatColumns must have "extra" column'); + $this->assertArrayHasKey('type', $result, 'FlatColumns must have "type" column'); + $this->assertArrayHasKey('nullable', $result, 'FlatColumns must have "nullable" column'); + $this->assertArrayHasKey('comment', $result, 'FlatColumns must have "comment" column'); } } } diff --git a/dev/tests/unit/testsuite/Magento/Tax/Pricing/Price/Plugin/AttributePriceTest.php b/dev/tests/unit/testsuite/Magento/Tax/Pricing/Price/Plugin/AttributePriceTest.php index 9e9e3bd4c9aa5c05c912d7816a95bd77daf1ff7c..a19f769154c3fc600c506fb4f41a547d12dcb175 100644 --- a/dev/tests/unit/testsuite/Magento/Tax/Pricing/Price/Plugin/AttributePriceTest.php +++ b/dev/tests/unit/testsuite/Magento/Tax/Pricing/Price/Plugin/AttributePriceTest.php @@ -33,8 +33,8 @@ class AttributePriceTest extends \PHPUnit_Framework_TestCase /** @var \Magento\Tax\Helper\Data|\PHPUnit_Framework_MockObject_MockObject */ protected $taxHelperMock; - /** @var \Magento\Tax\Model\Calculation|\PHPUnit_Framework_MockObject_MockObject */ - protected $calculationMock; + /** @var \Magento\Tax\Service\V1\TaxCalculationServiceInterface|\PHPUnit_Framework_MockObject_MockObject */ + protected $calculationServiceMock; /** @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject */ protected $productMock; @@ -67,9 +67,9 @@ class AttributePriceTest extends \PHPUnit_Framework_TestCase false, false ); - $this->calculationMock = $this->getMock( - 'Magento\Tax\Model\Calculation', - ['getRate', 'getRateRequest', '__wakeup'], + $this->calculationServiceMock = $this->getMock( + 'Magento\Tax\Service\V1\TaxCalculationService', + ['getDefaultCalculatedRate', 'getCalculatedRate'], [], '', false, @@ -118,7 +118,7 @@ class AttributePriceTest extends \PHPUnit_Framework_TestCase $this->plugin = new \Magento\Tax\Pricing\Price\Plugin\AttributePrice( $this->taxHelperMock, - $this->calculationMock + $this->calculationServiceMock ); @@ -132,12 +132,13 @@ class AttributePriceTest extends \PHPUnit_Framework_TestCase $this->productMock->expects($this->once()) ->method('getTaxClassId') ->will($this->returnValue('tax-class-id')); - $this->calculationMock->expects($this->exactly(2)) - ->method('getRateRequest') - ->will($this->returnValue($this->rateRequestMock)); - $this->calculationMock->expects($this->exactly(2)) - ->method('getRate') - ->with($this->equalTo($this->rateRequestMock)) + $this->calculationServiceMock->expects($this->once()) + ->method('getDefaultCalculatedRate') + ->with('tax-class-id', 1) + ->will($this->returnValue(99.10)); + $this->calculationServiceMock->expects($this->once()) + ->method('getCalculatedRate') + ->with('tax-class-id', 1) ->will($this->returnValue(99.10)); $this->productMock->expects($this->once()) ->method('getPriceInfo') diff --git a/dev/tests/unit/testsuite/Magento/Tax/Service/V1/TaxCalculationServiceTest.php b/dev/tests/unit/testsuite/Magento/Tax/Service/V1/TaxCalculationServiceTest.php new file mode 100644 index 0000000000000000000000000000000000000000..b13cd650e6f034cc0f52c1b1fd14e196e429bf69 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Tax/Service/V1/TaxCalculationServiceTest.php @@ -0,0 +1,419 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Tax\Service\V1; + +use Magento\Tax\Service\V1\Data\QuoteDetails\Item as QuoteDetailsItem; +use Magento\TestFramework\Helper\ObjectManager; + +/** + * Test TaxCalculationService + */ +class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase +{ + const TAX = 0.1; + + /** @var \Magento\Tax\Service\V1\TaxCalculationService */ + private $taxCalculationService; + + /** @var \Magento\Tax\Service\V1\Data\QuoteDetailsBuilder */ + private $quoteDetailsBuilder; + + /** @var \Magento\Tax\Service\V1\Data\TaxDetails\ItemBuilder*/ + private $taxDetailsItemBuilder; + + /** @var \Magento\Tax\Service\V1\Data\TaxDetailsBuilder */ + private $taxDetailsBuilder; + + /** @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Store\Model\StoreManagerInterface */ + private $storeManager; + + /** @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Tax\Model\Calculation\CalculatorFactory */ + private $calculatorFactory; + + public function setUp() + { + $objectManager = new ObjectManager($this); + $this->quoteDetailsBuilder = $objectManager->getObject('Magento\Tax\Service\V1\Data\QuoteDetailsBuilder'); + $this->storeManager = $this->getMockBuilder('Magento\Store\Model\StoreManagerInterface') + ->disableOriginalConstructor()->getMock(); + $this->calculatorFactory = $this->getMockBuilder('Magento\Tax\Model\Calculation\CalculatorFactory') + ->disableOriginalConstructor()->getMock(); + $calculationTool = $this->getMockBuilder('Magento\Tax\Model\Calculation') + ->disableOriginalConstructor()->getMock(); + $calculationTool->expects($this->any()) + ->method('round') + ->will($this->returnArgument(0)); + $this->taxDetailsBuilder = $objectManager->getObject('Magento\Tax\Service\V1\Data\TaxDetailsBuilder'); + $this->taxDetailsItemBuilder = $objectManager->getObject('Magento\Tax\Service\V1\Data\TaxDetails\ItemBuilder'); + $this->taxCalculationService = $objectManager->getObject( + 'Magento\Tax\Service\V1\TaxCalculationService', + [ + 'calculation' => $calculationTool, + 'calculatorFactory' => $this->calculatorFactory, + 'taxDetailsBuilder' => $this->taxDetailsBuilder, + 'taxDetailsItemBuilder' => $this->taxDetailsItemBuilder, + 'storeManager' => $this->storeManager, + ] + ); + } + + /** + * @param array $quoteDetailsData + * @param array $taxDetailsData + * @param string $calculateCallback Name of a function within this test class which will be executed to create + * a tax details item. + * @return void + * @dataProvider calculateTaxProvider + */ + public function testCalculateTax($quoteDetailsData, $taxDetailsData, $calculateCallback = 'createTaxDetailsItem') + { + $storeMock = $this->getMockBuilder('Magento\Store\Model\Store')->disableOriginalConstructor()->getMock(); + $this->storeManager->expects($this->any()) + ->method('getStore') + ->will($this->returnValue($storeMock)); + $calculatorMock = $this->getMockBuilder('\Magento\Tax\Model\Calculation\AbstractCalculator') + ->disableOriginalConstructor()->setMethods(['calculate'])->getMockForAbstractClass(); + $this->calculatorFactory->expects($this->any()) + ->method('create') + ->will($this->returnValue($calculatorMock)); + $calculatorMock->expects($this->any()) + ->method('calculate') + ->will($this->returnCallback([$this, $calculateCallback])); + + $quoteDetails = $this->quoteDetailsBuilder->populateWithArray($quoteDetailsData)->create(); + + $taxDetails = $this->taxCalculationService->calculateTax($quoteDetails); + + $this->assertEquals($taxDetailsData, $taxDetails->__toArray()); + } + + /** + * @return array + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ + public function calculateTaxProvider() + { + return [ + 'empty' => [ + 'quoteDetails' => [], + 'taxDetails' => [ + 'subtotal' => 0, + 'tax_amount' => 0, + 'discount_tax_compensation_amount' => 0, + 'applied_taxes' => [], + 'items' => [], + ], + ], + 'one_item' => [ + 'quoteDetails' => [ + 'billing_address' => [ + 'postcode' => '55555', + 'country_id' => 'US', + 'region' => ['region_id' => 42], + ], + 'shipping_address' => [ + 'postcode' => '55555', + 'country_id' => 'US', + 'region' => ['region_id' => 42], + ], + 'customer_tax_class_id' => 'DefaultCustomerClass', + 'items' => [ + [ + 'code' => 'sku_1', + 'type' => 'product', + 'quantity' => 10, + 'unit_price' => 1, + 'tax_class_id' => 'DefaultProductClass', + ] + ], + ], + 'taxDetails' => [ + 'subtotal' => 10, + 'tax_amount' => 1, + 'discount_tax_compensation_amount' => 0, + 'applied_taxes' => [], + 'items' => [ + 'sku_1' => [ + 'code' => 'sku_1', + 'type' => 'product', + 'price' => 1, + 'row_total' => 10, + 'tax_percent' => self::TAX, + 'row_tax' => 1, + 'row_total_incl_tax' => 11, + 'price_incl_tax' => 1.1, + ] + ], + ], + ], // End one_item + 'empty_applied' => [ + 'quoteDetails' => [], + 'taxDetails' => [ + 'subtotal' => 0, + 'tax_amount' => 0, + 'discount_tax_compensation_amount' => 0, + 'applied_taxes' => [], + 'items' => [], + ], + 'calculateCallbacks' => 'createTaxDetailsItemWithAppliedTaxes', + ], // End empty_applied + 'one_item_applied' => [ + 'quoteDetails' => [ + 'billing_address' => [ + 'postcode' => '55555', + 'country_id' => 'US', + 'region' => ['region_id' => 42], + ], + 'shipping_address' => [ + 'postcode' => '55555', + 'country_id' => 'US', + 'region' => ['region_id' => 42], + ], + 'customer_tax_class_id' => 'DefaultCustomerClass', + 'items' => [ + [ + 'code' => 'sku_1', + 'type' => 'product', + 'quantity' => 10, + 'unit_price' => 1, + 'tax_class_id' => 'DefaultProductClass', + ] + ], + ], + 'taxDetails' => [ + 'subtotal' => 10, + 'tax_amount' => 1, + 'discount_tax_compensation_amount' => 0, + 'applied_taxes' => [ + [ + 'amount' => 0.1, + 'percent' => self::TAX, + 'rates' => [ + [ + 'code' => 'TAX', + 'title' => 'Tax', + 'percent' => self::TAX, + ] + ], + 'tax_rate_key' => 'TAX_RATE', + ] + ], + 'items' => [ + 'sku_1' => [ + 'code' => 'sku_1', + 'type' => 'product', + 'price' => 1, + 'row_total' => 10, + 'tax_percent' => self::TAX, + 'row_tax' => 1, + 'row_total_incl_tax' => 11, + 'price_incl_tax' => 1.1, + 'applied_taxes' => [ + [ + 'amount' => 0.1, + 'percent' => self::TAX, + 'rates' => [ + [ + 'code' => 'TAX', + 'title' => 'Tax', + 'percent' => self::TAX, + ] + ], + 'tax_rate_key' => 'TAX_RATE', + ] + ], + ] + ], + ], + 'calculateCallbacks' => 'createTaxDetailsItemWithAppliedTaxes', + ], // End one_item_applied + 'bundled_items_applied' => [ + 'quoteDetails' => [ + 'billing_address' => [ + 'postcode' => '55555', + 'country_id' => 'US', + 'region' => ['region_id' => 42], + ], + 'shipping_address' => [ + 'postcode' => '55555', + 'country_id' => 'US', + 'region' => ['region_id' => 42], + ], + 'customer_tax_class_id' => 'DefaultCustomerClass', + 'items' => [ + [ + 'code' => 'sku_1', + 'type' => 'product', + 'quantity' => 10, + 'unit_price' => 1, + 'tax_class_id' => 'DefaultProductClass', + 'parent_code' => 'bundle', + ], + [ + 'code' => 'sku_2', + 'type' => 'product', + 'quantity' => 1, + 'unit_price' => 10, + 'tax_class_id' => 'DefaultProductClass', + 'parent_code' => 'bundle', + ], + [ + 'code' => 'bundle', + 'type' => 'product', + 'quantity' => 2, + 'unit_price' => 0, + 'tax_class_id' => 'DefaultProductClass', + ], + ], + ], + 'taxDetails' => [ + 'subtotal' => 20, + 'tax_amount' => 2, + 'discount_tax_compensation_amount' => 0, + 'applied_taxes' => [ + [ + 'amount' => 1.1, + 'percent' => self::TAX, + 'rates' => [ + [ + 'code' => 'TAX', + 'title' => 'Tax', + 'percent' => self::TAX, + ] + ], + 'tax_rate_key' => 'TAX_RATE', + ] + ], + 'items' => [ + 'sku_1' => [ + 'code' => 'sku_1', + 'type' => 'product', + 'price' => 1, + 'row_total' => 10, + 'tax_percent' => self::TAX, + 'row_tax' => 1, + 'row_total_incl_tax' => 11, + 'price_incl_tax' => 1.1, + 'applied_taxes' => [ + [ + 'amount' => 0.1, + 'percent' => self::TAX, + 'rates' => [ + [ + 'code' => 'TAX', + 'title' => 'Tax', + 'percent' => self::TAX, + ] + ], + 'tax_rate_key' => 'TAX_RATE', + ] + ], + ], + 'sku_2' => [ + 'code' => 'sku_2', + 'type' => 'product', + 'price' => 10, + 'row_total' => 10, + 'tax_percent' => self::TAX, + 'row_tax' => 1, + 'row_total_incl_tax' => 11, + 'price_incl_tax' => 11, + 'applied_taxes' => [ + [ + 'amount' => 1, + 'percent' => self::TAX, + 'rates' => [ + [ + 'code' => 'TAX', + 'title' => 'Tax', + 'percent' => self::TAX, + ] + ], + 'tax_rate_key' => 'TAX_RATE', + ] + ], + ], + 'bundle' => [ + 'price' => 10, + 'price_incl_tax' => 11, + 'row_total' => 20, + 'row_total_incl_tax' => 22, + 'row_tax' => 2, + 'code' => 'bundle', + 'type' => 'product', + ], + ], + ], + 'calculateCallbacks' => 'createTaxDetailsItemWithAppliedTaxes', + ], // End bundled_items_applied + ]; + } + + /** + * Callback function that creates a tax details item from a quote details item for testing. + * + * @param QuoteDetailsItem $item + * @return Data\TaxDetails\Item + */ + public function createTaxDetailsItem(QuoteDetailsItem $item) + { + $rowTotal = $item->getUnitPrice() * $item->getQuantity(); + $rowTax = $rowTotal * self::TAX; + return $this->taxDetailsItemBuilder->populateWithArray($item->__toArray()) + ->setPrice($item->getUnitPrice()) + ->setRowTotal($rowTotal) + ->setTaxPercent(self::TAX) + ->setRowTax($rowTax) + ->setRowTotalInclTax($rowTotal + $rowTax) + ->setPriceInclTax($item->getUnitPrice() + ($item->getUnitPrice() * self::TAX)) + ->create(); + } + + /** + * Callback function that creates a tax details item with applied taxes from a quote details item for testing. + * + * @param QuoteDetailsItem $item + * @return Data\TaxDetails\Item + */ + public function createTaxDetailsItemWithAppliedTaxes(QuoteDetailsItem $item) + { + $appliedTaxRateBuilder = $this->taxDetailsBuilder->getAppliedTaxBuilder(); + $taxRateBuilder = $appliedTaxRateBuilder->getAppliedTaxRateBuilder(); + $rate = $taxRateBuilder + ->setPercent(self::TAX) + ->setCode('TAX') + ->setTitle('Tax') + ->create(); + $appliedTaxes = $appliedTaxRateBuilder + ->setAmount($item->getUnitPrice() * self::TAX) + ->setTaxRateKey('TAX_RATE') + ->setPercent(self::TAX) + ->setRates([$rate]) + ->create(); + return $this->taxDetailsItemBuilder->populate($this->createTaxDetailsItem($item)) + ->setAppliedTaxes([$appliedTaxes]) + ->create(); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Tax/Service/V1/TaxClassServiceTest.php b/dev/tests/unit/testsuite/Magento/Tax/Service/V1/TaxClassServiceTest.php index 654619dbf083b25af70704eabcbff26e90973dc3..b988bdefdfa56e6c8645f65729fea1b2ccde1c53 100644 --- a/dev/tests/unit/testsuite/Magento/Tax/Service/V1/TaxClassServiceTest.php +++ b/dev/tests/unit/testsuite/Magento/Tax/Service/V1/TaxClassServiceTest.php @@ -27,6 +27,7 @@ namespace Magento\Tax\Service\V1; use Magento\Framework\Exception\InputException; use Magento\Tax\Service\V1\Data\TaxClass; use Magento\Tax\Service\V1\Data\TaxClassBuilder; +use Magento\Tax\Service\V1\Data\TaxClassKey; /** * Test for \Magento\Tax\Service\V1\TaxClassService @@ -35,6 +36,8 @@ use Magento\Tax\Service\V1\Data\TaxClassBuilder; */ class TaxClassServiceTest extends \PHPUnit_Framework_TestCase { + const TAX_CLASS_ID = 'tax_class_id'; + const TAX_CLASS_NAME = 'tax_class_name'; /** * @var \Magento\Tax\Model\Resource\TaxClass\CollectionFactory|\PHPUnit_Framework_MockObject_MockObject */ @@ -45,6 +48,11 @@ class TaxClassServiceTest extends \PHPUnit_Framework_TestCase */ private $searchResultBuilder; + /** + * @var \Magento\Framework\Service\V1\Data\SearchCriteriaBuilder|\PHPUnit_Framework_MockObject_MockObject + */ + private $searchCriteriaBuilderMock; + /** * @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Tax\Model\ClassModelFactory */ @@ -376,31 +384,19 @@ class TaxClassServiceTest extends \PHPUnit_Framework_TestCase public function testSearch() { - $collectionSize = 3; - $currentPage = 1; - $pageSize = 10; $searchCriteria = $this->createSearchCriteria(); $this->searchResultBuilder->expects($this->once())->method('setSearchCriteria')->with($searchCriteria); - /** @var \PHPUnit_Framework_MockObject_MockObject $collectionMock */ - $collectionMock = $this->getMockBuilder('Magento\Tax\Model\Resource\TaxClass\Collection') + + /** @var \PHPUnit_Framework_MockObject_MockObject $taxClassModelMock */ + $taxClassModelMock = $this->getMockBuilder('Magento\Tax\Model\ClassModel') ->disableOriginalConstructor() - ->setMethods(['addFieldToFilter', 'getSize', 'setCurPage', 'setPageSize', 'getItems', 'addOrder']) ->getMock(); + $collectionMock = $this->mockTaxClassCollection($taxClassModelMock); + $this->taxClassCollectionFactory ->expects($this->once()) ->method('create') ->will($this->returnValue($collectionMock)); - $collectionMock->expects($this->exactly(2))->method('addFieldToFilter'); - $collectionMock->expects($this->any())->method('getSize')->will($this->returnValue($collectionSize)); - $collectionMock->expects($this->once())->method('setCurPage')->with($currentPage); - $collectionMock->expects($this->once())->method('setPageSize')->with($pageSize); - $collectionMock->expects($this->once())->method('addOrder')->with('class_name', 'ASC'); - - /** @var \PHPUnit_Framework_MockObject_MockObject $taxClassModelMock */ - $taxClassModelMock = $this->getMockBuilder('Magento\Tax\Model\ClassModel') - ->disableOriginalConstructor() - ->getMock(); - $collectionMock->expects($this->once())->method('getItems')->will($this->returnValue([$taxClassModelMock])); /** @var \PHPUnit_Framework_MockObject_MockObject $taxMock */ $taxClassMock = $this->getMockBuilder('Magento\Tax\Service\V1\Data\TaxClass') ->disableOriginalConstructor() @@ -418,6 +414,106 @@ class TaxClassServiceTest extends \PHPUnit_Framework_TestCase $this->taxClassService->searchTaxClass($searchCriteria); } + /** + * @param string $expected + * @param string[] $taxClassKeyMockValeMap + * @param bool $found + * @dataProvider getTaxClassIdDataProvider + */ + public function testGetTaxClassId($expected, $taxClassKeyMockValeMap, $found = false) + { + /** @var \Magento\Tax\Service\V1\Data\TaxClassKey|\PHPUnit_Framework_MockObject_MockObject $taxClassKeyMock */ + $taxClassKeyMock = $this->getMockBuilder('Magento\Tax\Service\V1\Data\TaxClassKey') + ->disableOriginalConstructor() + ->getMock(); + $this->mockReturnValue($taxClassKeyMock, $taxClassKeyMockValeMap); + + if ($taxClassKeyMockValeMap['getType'] == TaxClassKey::TYPE_NAME) { + $this->searchCriteriaBuilderMock->expects($this->exactly(2)) + ->method('addFilter') + ->will($this->returnValue($this->searchCriteriaBuilderMock)); + /** @var \Magento\Framework\Service\V1\Data\SearchCriteria $searchCriteria*/ + $searchCriteria = $this->createSearchCriteria(); + $this->searchCriteriaBuilderMock->expects($this->once()) + ->method('create') + ->will($this->returnValue($searchCriteria)); + $this->searchResultBuilder->expects($this->once())->method('setSearchCriteria')->with($searchCriteria); + + /** @var \PHPUnit_Framework_MockObject_MockObject $taxClassModelMock */ + $taxClassModelMock = $this->getMockBuilder('Magento\Tax\Model\ClassModel') + ->disableOriginalConstructor() + ->getMock(); + $collectionMock = $this->mockTaxClassCollection($taxClassModelMock); + + $this->taxClassCollectionFactory + ->expects($this->once()) + ->method('create') + ->will($this->returnValue($collectionMock)); + /** @var \PHPUnit_Framework_MockObject_MockObject $taxMock */ + $taxClassMock = $this->getMockBuilder('Magento\Tax\Service\V1\Data\TaxClass') + ->disableOriginalConstructor() + ->getMock(); + $this->converterMock + ->expects($this->once()) + ->method('createTaxClassData') + ->with($taxClassModelMock) + ->will($this->returnValue($taxClassMock)); + $this->searchResultBuilder + ->expects($this->once()) + ->method('setItems') + ->will($this->returnValue([$taxClassMock])); + $searchResultsMock = $this->getMockBuilder('Magento\Tax\Service\V1\Data\TaxClassSearchResults') + ->disableOriginalConstructor() + ->getMock(); + $searchResultsMock->expects($this->once()) + ->method('getItems') + ->will($this->returnValue($found ? [$taxClassMock] : [])); + $taxClassMock->expects($this->any()) + ->method('getClassId') + ->will($this->returnValue(self::TAX_CLASS_ID)); + $this->searchResultBuilder + ->expects($this->once()) + ->method('create') + ->will($this->returnValue($searchResultsMock)); + + } + $this->assertEquals($expected, $this->taxClassService->getTaxClassId($taxClassKeyMock)); + } + + public function testGetTaxClassIdEmptyTaxClassKey() + { + $this->assertNull($this->taxClassService->getTaxClassId(null)); + } + + public function getTaxClassIdDataProvider() + { + return [ + + 'type_id' => [ + self::TAX_CLASS_ID, + [ + 'getType' => TaxClassKey::TYPE_ID, + 'getValue' => self::TAX_CLASS_ID, + ], + ], + 'type_name_not_found' => [ + null, + [ + 'getType' => TaxClassKey::TYPE_NAME, + 'getValue' => self::TAX_CLASS_NAME, + ], + ], + 'type_name_found' => [ + self::TAX_CLASS_ID, + [ + 'getType' => TaxClassKey::TYPE_NAME, + 'getValue' => self::TAX_CLASS_NAME, + ], + true, + ], + ]; + } + /** * @return TaxClassService */ @@ -439,9 +535,15 @@ class TaxClassServiceTest extends \PHPUnit_Framework_TestCase ->disableOriginalConstructor() ->getMock(); + $this->searchCriteriaBuilderMock = $this->getMockBuilder( + 'Magento\Framework\Service\V1\Data\SearchCriteriaBuilder' + )->disableOriginalConstructor() + ->getMock(); + $taxClassService = $this->objectManager->getObject( 'Magento\Tax\Service\V1\TaxClassService', [ + 'searchCriteriaBuilder' => $this->searchCriteriaBuilderMock, 'taxClassCollectionFactory' => $this->taxClassCollectionFactory, 'classModelRegistry' => $this->classModelRegistryMock, 'searchResultsBuilder' => $this->searchResultBuilder, @@ -497,4 +599,38 @@ class TaxClassServiceTest extends \PHPUnit_Framework_TestCase ->create(); return $searchCriteria; } + + /** + * @param $taxClassModelMock + * @return \PHPUnit_Framework_MockObject_MockObject + */ + private function mockTaxClassCollection($taxClassModelMock) + { + $collectionSize = 3; + $currentPage = 1; + $pageSize = 10; + /** @var \PHPUnit_Framework_MockObject_MockObject $collectionMock */ + $collectionMock = $this->getMockBuilder('Magento\Tax\Model\Resource\TaxClass\Collection') + ->disableOriginalConstructor() + ->setMethods(['addFieldToFilter', 'getSize', 'setCurPage', 'setPageSize', 'getItems', 'addOrder']) + ->getMock(); + $collectionMock->expects($this->exactly(2))->method('addFieldToFilter'); + $collectionMock->expects($this->any())->method('getSize')->will($this->returnValue($collectionSize)); + $collectionMock->expects($this->once())->method('setCurPage')->with($currentPage); + $collectionMock->expects($this->once())->method('setPageSize')->with($pageSize); + $collectionMock->expects($this->once())->method('addOrder')->with('class_name', 'ASC'); + $collectionMock->expects($this->once())->method('getItems')->will($this->returnValue([$taxClassModelMock])); + return $collectionMock; + } + + /** + * @param \PHPUnit_Framework_MockObject_MockObject $mock + * @param array $valueMap + */ + private function mockReturnValue($mock, $valueMap) + { + foreach ($valueMap as $method => $value) { + $mock->expects($this->any())->method($method)->will($this->returnValue($value)); + } + } } diff --git a/dev/tests/unit/testsuite/Magento/Tax/Service/V1/TaxRateServiceTest.php b/dev/tests/unit/testsuite/Magento/Tax/Service/V1/TaxRateServiceTest.php index 66e4acd2ff73cd28af59c3e4df4a76c4520b4ae6..3f78f7a08df8a4d2abfa059889c987feb6ece04e 100644 --- a/dev/tests/unit/testsuite/Magento/Tax/Service/V1/TaxRateServiceTest.php +++ b/dev/tests/unit/testsuite/Magento/Tax/Service/V1/TaxRateServiceTest.php @@ -268,6 +268,7 @@ class TaxRateServiceTest extends \PHPUnit_Framework_TestCase $taxRate = $this->taxRateBuilder ->setId(2) ->setCode('Rate-Code') + ->setCountryId('US') ->setPercentageRate(0.1) ->setRegionId('TX') ->create(); diff --git a/dev/tests/unit/testsuite/Magento/Tax/Service/V1/TaxRuleServiceTest.php b/dev/tests/unit/testsuite/Magento/Tax/Service/V1/TaxRuleServiceTest.php index 8e782df621e273e74f0a27e3e57ff74b52ba78fd..a72665c8cf884b51d7f33b0390a8cfaa93c1f407 100644 --- a/dev/tests/unit/testsuite/Magento/Tax/Service/V1/TaxRuleServiceTest.php +++ b/dev/tests/unit/testsuite/Magento/Tax/Service/V1/TaxRuleServiceTest.php @@ -26,9 +26,14 @@ namespace Magento\Tax\Service\V1; use Magento\Framework\Exception\ErrorMessage; use Magento\Framework\Exception\InputException; use Magento\Framework\Exception\NoSuchEntityException; -use Magento\Framework\Model\Resource\Iterator; +use Magento\Tax\Service\V1\Data\TaxRule; use Magento\TestFramework\Helper\ObjectManager; +/** + * Class TaxRuleServiceTest + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ class TaxRuleServiceTest extends \PHPUnit_Framework_TestCase { /** @@ -56,6 +61,22 @@ class TaxRuleServiceTest extends \PHPUnit_Framework_TestCase */ private $taxRuleModelFactoryMock; + /** + * @var \Magento\Framework\Service\V1\Data\FilterBuilder | \PHPUnit_Framework_MockObject_MockObject + */ + protected $filterBuilderMock; + + /** + * @var \Magento\Framework\Service\V1\Data\SearchCriteriaBuilder | \PHPUnit_Framework_MockObject_MockObject + */ + protected $searchCriteriaBuilderMock; + + + /** + * @var \Magento\Tax\Service\V1\TaxRateServiceInterface | \PHPUnit_Framework_MockObject_MockObject + */ + protected $taxRateServiceMock; + /** * @var ObjectManager */ @@ -84,15 +105,19 @@ class TaxRuleServiceTest extends \PHPUnit_Framework_TestCase $taxRuleResultsBuilder = $this->objectManager->getObject( 'Magento\Tax\Service\V1\Data\TaxRuleSearchResultsBuilder' ); - $this->taxRuleService = $this->objectManager->getObject( - 'Magento\Tax\Service\V1\TaxRuleService', - [ - 'taxRuleRegistry' => $this->ruleRegistryMock, - 'converter' => $this->converterMock, - 'taxRuleModelFactory' => $this->taxRuleModelFactoryMock, - 'taxRuleSearchResultsBuilder' => $taxRuleResultsBuilder - ] - ); + $this->filterBuilderMock = $this->getMockBuilder('\Magento\Framework\Service\V1\Data\FilterBuilder') + ->disableOriginalConstructor() + ->getMock(); + $this->searchCriteriaBuilderMock = $this->getMockBuilder( + '\Magento\Framework\Service\V1\Data\SearchCriteriaBuilder' + ) + ->disableOriginalConstructor() + ->getMock(); + $this->taxRateServiceMock = $this->getMockBuilder('\Magento\Tax\Service\V1\TaxRateServiceInterface') + ->disableOriginalConstructor() + ->getMock(); + + $this->taxRuleService = $this->getTaxRuleService($taxRuleResultsBuilder); } public function testDeleteTaxRule() @@ -290,6 +315,8 @@ class TaxRuleServiceTest extends \PHPUnit_Framework_TestCase 'empty fields' => [ [], [ + 'sort_order is a required field.', + 'priority is a required field.', 'code is a required field.', 'customer_tax_class_ids is a required field.', 'product_tax_class_ids is a required field.', @@ -388,7 +415,7 @@ class TaxRuleServiceTest extends \PHPUnit_Framework_TestCase ->getMock(); /** @var \Magento\Tax\Service\V1\Data\TaxRuleBuilder $taxRuleBuilder */ $taxRuleBuilder = $this->objectManager->getObject('Magento\Tax\Service\V1\Data\TaxRuleBuilder'); - /** @var \Magento\Tax\Service\V1\Data\TaxRule $taxRule */ + /** @var TaxRule $taxRule */ $taxRule = $taxRuleBuilder->create(); $taxRuleModel = $this->getMockBuilder('Magento\Tax\Model\Calculation\Rule') @@ -441,4 +468,150 @@ class TaxRuleServiceTest extends \PHPUnit_Framework_TestCase $this->assertEquals($expectedResults->getItems(), $actualResults->getItems()); $this->assertSame($taxRule, $actualResults->getItems()[0]); } + + /** + * + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ + public function testGetRatesByCustomerAndProductTaxClassId() + { + $customerTaxClass = 0; + $productTaxClass = 0; + + $filterOne = 'filter_one'; + $filterTwo = 'filter_two'; + + /** @var \PHPUnit_Framework_MockObject_MockObject | + * \Magento\Tax\Model\Resource\Calculation\Rule\Collection $mockCollection */ + $mockCollection = $this->getMockBuilder('\Magento\Tax\Model\Resource\Calculation\Rule\Collection') + ->disableOriginalConstructor() + ->setMethods(['__wakeup', 'getItems', 'getSize', 'addFieldToFilter', '_beforeLoad', 'getIterator']) + ->getMock(); + + $taxRuleModel = $this->getMockBuilder('Magento\Tax\Model\Calculation\Rule') + ->disableOriginalConstructor()->getMock(); + $mockCollection->expects($this->once()) + ->method('getIterator') + ->will($this->returnValue(new \ArrayIterator([$taxRuleModel]))); + $mockCollection->expects($this->once()) + ->method('getSize') + ->will($this->returnValue(1)); + + $this->ruleModelMock->expects($this->once()) + ->method('getCollection') + ->will($this->returnValue($mockCollection)); + + $this->filterBuilderMock->expects($this->exactly(2)) + ->method('setField') + ->with( + $this->logicalOr( + $this->equalTo(TaxRule::CUSTOMER_TAX_CLASS_IDS), + $this->equalTo(TaxRule::PRODUCT_TAX_CLASS_IDS) + ) + ) + ->will($this->returnSelf()); + + $this->filterBuilderMock->expects($this->exactly(2)) + ->method('setValue') + ->with( + $this->logicalOr( + $this->equalTo([$customerTaxClass]), + $this->equalTo([$productTaxClass]) + ) + ) + ->will($this->returnSelf()); + + $this->filterBuilderMock->expects($this->at(2)) + ->method('create') + ->will($this->returnValue($filterOne)); + $this->filterBuilderMock->expects($this->at(5)) + ->method('create') + ->will($this->returnValue($filterTwo)); + + $this->searchCriteriaBuilderMock->expects($this->exactly(2)) + ->method('addFilter') + ->with($this->logicalOr([$filterOne], [$filterTwo])) + ->will($this->returnSelf()); + + $searchCriteria = $this->getMockBuilder('\Magento\Framework\Service\V1\Data\SearchCriteria') + ->disableOriginalConstructor() + ->getMock(); + + $mockFilters = $this->getMockBuilder('\Magento\Framework\Service\V1\Data\Filter') + ->disableOriginalConstructor() + ->getMock(); + + $mockFilterGroups = $this->getMockBuilder('\Magento\Framework\Service\V1\Data\Search\FilterGroup') + ->disableOriginalConstructor() + ->getMock(); + + $mockFilterGroups->expects($this->any()) + ->method('getFilters') + ->will($this->returnValue([$mockFilters])); + + $searchCriteria->expects($this->once()) + ->method('getFilterGroups') + ->will($this->returnValue([$mockFilterGroups])); + + $this->searchCriteriaBuilderMock->expects($this->once()) + ->method('create') + ->will($this->returnValue($searchCriteria)); + + $searchResults = $this->getMockBuilder('\Magento\Tax\Service\V1\Data\TaxRuleSearchResults') + ->disableOriginalConstructor() + ->getMock(); + + $taxRuleResultsBuilderMock= $this->getMockBuilder('Magento\Tax\Service\V1\Data\TaxRuleSearchResultsBuilder') + ->disableOriginalConstructor() + ->getMock(); + $mockTaxRule = $this->getMockBuilder('\Magento\Tax\Service\V1\Data\TaxRule') + ->disableOriginalConstructor() + ->getMock(); + $taxRules = [$mockTaxRule]; + + $searchResults->expects($this->once()) + ->method('getItems') + ->will($this->returnValue($taxRules)); + + $mockTaxRule->expects($this->once()) + ->method('getTaxRateIds') + ->will($this->returnValue([777])); + + $this->taxRateServiceMock->expects($this->once()) + ->method('getTaxRate') + ->with(777) + ->will($this->returnValue(888)); + + $taxRuleResultsBuilderMock->expects($this->once()) + ->method('create') + ->will($this->returnValue($searchResults)); + + $taxRuleService = $this->getTaxRuleService($taxRuleResultsBuilderMock); + $this->assertSame( + [888], + $taxRuleService->getRatesByCustomerAndProductTaxClassId($customerTaxClass, $productTaxClass) + ); + } + + /** + * Get tax rule service + * + * @param $taxRuleResultsBuilder + * @return \Magento\Tax\Service\V1\TaxRuleService + */ + private function getTaxRuleService($taxRuleResultsBuilder) + { + return $this->objectManager->getObject( + 'Magento\Tax\Service\V1\TaxRuleService', + [ + 'taxRuleRegistry' => $this->ruleRegistryMock, + 'converter' => $this->converterMock, + 'taxRuleModelFactory' => $this->taxRuleModelFactoryMock, + 'taxRuleSearchResultsBuilder' => $taxRuleResultsBuilder, + 'filterBuilder' => $this->filterBuilderMock, + 'taxRateService' => $this->taxRateServiceMock, + 'searchCriteriaBuilder' => $this->searchCriteriaBuilderMock + ] + ); + } } diff --git a/dev/tests/unit/testsuite/Magento/Theme/Controller/Adminhtml/System/Design/Theme/SaveTest.php b/dev/tests/unit/testsuite/Magento/Theme/Controller/Adminhtml/System/Design/Theme/SaveTest.php index 0c65499b8c3c760995baa3ae8215ca3b7a1801c3..56d3e8970cb82a445bfbfe806fb01d75ee04bab9 100644 --- a/dev/tests/unit/testsuite/Magento/Theme/Controller/Adminhtml/System/Design/Theme/SaveTest.php +++ b/dev/tests/unit/testsuite/Magento/Theme/Controller/Adminhtml/System/Design/Theme/SaveTest.php @@ -32,7 +32,6 @@ class SaveTest extends \Magento\Theme\Controller\Adminhtml\System\Design\ThemeTe protected $name = 'Save'; /** - * @covers \Magento\Theme\Controller\Adminhtml\System\Design\Theme::saveAction * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ public function testSaveAction() @@ -42,53 +41,31 @@ class SaveTest extends \Magento\Theme\Controller\Adminhtml\System\Design\ThemeTe $jsRemovedFiles = array(3, 4); $jsOrder = array(1 => '1', 2 => 'test'); - $this->_request->expects( - $this->at(0) - )->method( - 'getParam' - )->with( - 'back', - false - )->will( - $this->returnValue(true) - ); + $this->_request->expects($this->at(0)) + ->method('getParam') + ->with('back', false) + ->will($this->returnValue(true)); + + $this->_request->expects($this->at(1)) + ->method('getParam') + ->with('theme') + ->will($this->returnValue($themeData)); + + $this->_request->expects($this->at(2)) + ->method('getParam') + ->with('custom_css_content') + ->will($this->returnValue($customCssContent)); + + $this->_request->expects($this->at(3)) + ->method('getParam') + ->with('js_removed_files') + ->will($this->returnValue($jsRemovedFiles)); + + $this->_request->expects($this->at(4)) + ->method('getParam') + ->with('js_order') + ->will($this->returnValue($jsOrder)); - $this->_request->expects( - $this->at(1) - )->method( - 'getParam' - )->with( - 'theme' - )->will( - $this->returnValue($themeData) - ); - $this->_request->expects( - $this->at(2) - )->method( - 'getParam' - )->with( - 'custom_css_content' - )->will( - $this->returnValue($customCssContent) - ); - $this->_request->expects( - $this->at(3) - )->method( - 'getParam' - )->with( - 'js_removed_files' - )->will( - $this->returnValue($jsRemovedFiles) - ); - $this->_request->expects( - $this->at(4) - )->method( - 'getParam' - )->with( - 'js_order' - )->will( - $this->returnValue($jsOrder) - ); $this->_request->expects($this->once(5))->method('getPost')->will($this->returnValue(true)); $themeMock = $this->getMock( @@ -111,35 +88,20 @@ class SaveTest extends \Magento\Theme\Controller\Adminhtml\System\Design\ThemeTe ); $themeFactory->expects($this->once())->method('create')->will($this->returnValue($themeMock)); - $this->_objectManagerMock->expects( - $this->at(0) - )->method( - 'get' - )->with( - 'Magento\Framework\View\Design\Theme\FlyweightFactory' - )->will( - $this->returnValue($themeFactory) - ); + $this->_objectManagerMock->expects($this->at(0)) + ->method('get') + ->with('Magento\Framework\View\Design\Theme\FlyweightFactory') + ->will($this->returnValue($themeFactory)); - $this->_objectManagerMock->expects( - $this->at(1) - )->method( - 'get' - )->with( - 'Magento\Theme\Model\Theme\Customization\File\CustomCss' - )->will( - $this->returnValue(null) - ); + $this->_objectManagerMock->expects($this->at(1)) + ->method('get') + ->with('Magento\Theme\Model\Theme\Customization\File\CustomCss') + ->will($this->returnValue(null)); - $this->_objectManagerMock->expects( - $this->at(2) - )->method( - 'create' - )->with( - 'Magento\Theme\Model\Theme\SingleFile' - )->will( - $this->returnValue(null) - ); + $this->_objectManagerMock->expects($this->at(2)) + ->method('create') + ->with('Magento\Theme\Model\Theme\SingleFile') + ->will($this->returnValue(null)); $this->_model->execute(); } diff --git a/dev/tests/unit/testsuite/Magento/UrlRedirect/Model/OptionProviderTest.php b/dev/tests/unit/testsuite/Magento/UrlRedirect/Model/OptionProviderTest.php new file mode 100644 index 0000000000000000000000000000000000000000..f58a6afd6a4fe97fcc4b6458c681b796137008de --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/UrlRedirect/Model/OptionProviderTest.php @@ -0,0 +1,37 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\UrlRedirect\Model; + +class OptionProviderTest extends \PHPUnit_Framework_TestCase +{ + public function testGetAllOptions() + { + $model = new OptionProvider(); + $options = $model->getAllOptions(); + $this->assertInternalType('array', $options); + $expectedOptions = array('' => 'No', 'R' => 'Temporary (302)', 'RP' => 'Permanent (301)'); + $this->assertEquals($expectedOptions, $options); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Webapi/Model/Soap/Wsdl/GeneratorTest.php b/dev/tests/unit/testsuite/Magento/Webapi/Model/Soap/Wsdl/GeneratorTest.php index e52b1aa2b5f4b25382d9fa1f4ca4ac98841cd3b7..51316482330a193eb4a642bd68b9981f3aae84f0 100644 --- a/dev/tests/unit/testsuite/Magento/Webapi/Model/Soap/Wsdl/GeneratorTest.php +++ b/dev/tests/unit/testsuite/Magento/Webapi/Model/Soap/Wsdl/GeneratorTest.php @@ -42,6 +42,9 @@ class GeneratorTest extends \PHPUnit_Framework_TestCase /** @var \Magento\Webapi\Model\Config\ClassReflector\TypeProcessor|\PHPUnit_Framework_MockObject_MockObject */ protected $_typeProcessor; + /** @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject */ + protected $storeManagerMock; + protected function setUp() { $this->_soapConfigMock = $this->getMockBuilder( @@ -87,11 +90,32 @@ class GeneratorTest extends \PHPUnit_Framework_TestCase false ); - $this->_wsdlGenerator = new \Magento\Webapi\Model\Soap\Wsdl\Generator( - $this->_soapConfigMock, - $this->_wsdlFactoryMock, - $this->_cacheMock, - $this->_typeProcessor + $this->storeManagerMock = $this->getMockBuilder( + 'Magento\Store\Model\StoreManagerInterface' + )->setMethods(['getStore'])->disableOriginalConstructor()->getMockForAbstractClass(); + + $storeMock = $this->getMockBuilder( + 'Magento\Store\Model\Store' + )->setMethods(['getCode', '__wakeup'])->disableOriginalConstructor()->getMock(); + + $this->storeManagerMock->expects($this->any()) + ->method('getStore') + ->will($this->returnValue($storeMock)); + + $storeMock->expects($this->any()) + ->method('getCode') + ->will($this->returnValue('store_code')); + + $helper = new \Magento\TestFramework\Helper\ObjectManager($this); + $this->_wsdlGenerator = $helper->getObject( + 'Magento\Webapi\Model\Soap\Wsdl\Generator', + [ + 'apiConfig' => $this->_soapConfigMock, + 'wsdlFactory' => $this->_wsdlFactoryMock, + 'cache' => $this->_cacheMock, + 'typeProcessor' => $this->_typeProcessor, + 'storeManagerMock' => $this->storeManagerMock + ] ); parent::setUp(); @@ -178,7 +202,13 @@ class GeneratorTest extends \PHPUnit_Framework_TestCase )->setMethods( array('_collectCallInfo') )->setConstructorArgs( - array($this->_soapConfigMock, $this->_wsdlFactoryMock, $this->_cacheMock, $this->_typeProcessor) + [ + $this->_soapConfigMock, + $this->_wsdlFactoryMock, + $this->_cacheMock, + $this->_typeProcessor, + $this->storeManagerMock + ] )->getMock(); $wsdlGeneratorMock->expects( diff --git a/dev/tests/unit/testsuite/Magento/Weee/Model/ConfigTest.php b/dev/tests/unit/testsuite/Magento/Weee/Model/ConfigTest.php new file mode 100644 index 0000000000000000000000000000000000000000..03952de7d815bc90607d33634ef5ee3ba17b4176 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Weee/Model/ConfigTest.php @@ -0,0 +1,117 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +/** + * Test class for \Magento\Weee\Model\Config + */ +namespace Magento\Weee\Model; + +class ConfigTest extends \PHPUnit_Framework_TestCase +{ + /** + * Tests the methods that rely on the ScopeConfigInterface object to provide their return values + * + * @param string $method + * @param string $path + * @param bool $configValue + * @param bool $expectedValue + * @dataProvider dataProviderScopeConfigMethods + */ + public function testScopeConfigMethods($method, $path, $configValue, $expectedValue) + { + $scopeConfigMock = $this->getMockForAbstractClass('Magento\Framework\App\Config\ScopeConfigInterface'); + $scopeConfigMock->expects($this->any()) + ->method('getValue') + ->with($path, \Magento\Store\Model\ScopeInterface::SCOPE_STORE, null) + ->will($this->returnValue($configValue)); + $scopeConfigMock->expects($this->any()) + ->method('isSetFlag') + ->with($path, \Magento\Store\Model\ScopeInterface::SCOPE_STORE, null) + ->will($this->returnValue($configValue)); + + $taxData = $this->getMock('Magento\Tax\Helper\Data', [], [], '', false); + + /** @var \Magento\Weee\Model\Config */ + $model = new Config($scopeConfigMock, $taxData); + $this->assertEquals($expectedValue, $model->{$method}()); + } + + /** + * @return array + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ + public function dataProviderScopeConfigMethods() + { + return [ + [ + 'getPriceDisplayType', + Config::XML_PATH_FPT_DISPLAY_PRODUCT_VIEW, + true, + true + ], + [ + 'getListPriceDisplayType', + Config::XML_PATH_FPT_DISPLAY_PRODUCT_LIST, + true, + true + ], + [ + 'getSalesPriceDisplayType', + Config::XML_PATH_FPT_DISPLAY_SALES, + true, + true + ], + [ + 'getEmailPriceDisplayType', + Config::XML_PATH_FPT_DISPLAY_EMAIL, + true, + true + ], + [ + 'includeInSubtotal', + Config::XML_PATH_FPT_INCLUDE_IN_SUBTOTAL, + true, + true + ], + [ + 'isDiscounted', + Config::XML_PATH_FPT_DISCOUNTED, + true, + true + ], + [ + 'isTaxable', + Config::XML_PATH_FPT_TAXABLE, + true, + true + ], + [ + 'isEnabled', + Config::XML_PATH_FPT_ENABLED, + true, + true + ] + ]; + } +} diff --git a/dev/tests/unit/testsuite/Magento/Weee/Model/Total/Quote/WeeeTaxTest.php b/dev/tests/unit/testsuite/Magento/Weee/Model/Total/Quote/WeeeTaxTest.php new file mode 100644 index 0000000000000000000000000000000000000000..b848ef344a900fc493f5eb69f6cf9298aaf4a40b --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Weee/Model/Total/Quote/WeeeTaxTest.php @@ -0,0 +1,598 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Weee\Model\Total\Quote; + +use Magento\Tax\Model\Calculation; +use Magento\Tax\Model\Sales\Total\Quote\CommonTaxCollector as CTC; + +class WeeeTaxTest extends \PHPUnit_Framework_TestCase +{ + /** + * Setup tax helper with an array of methodName, returnValue + * + * @param array $taxConfig + * @return \PHPUnit_Framework_MockObject_MockObject|\Magento\Tax\Helper\Data + */ + protected function setupTaxHelper($taxConfig) + { + $taxHelper = $this->getMock('Magento\Tax\Helper\Data', [], [], '', false); + + foreach ($taxConfig as $method => $value) { + $taxHelper->expects($this->any())->method($method)->will($this->returnValue($value)); + } + + return $taxHelper; + } + + /** + * Setup calculator to return tax rates + * + * @param array $taxRates + * @return \PHPUnit_Framework_MockObject_MockObject|\Magento\Tax\Model\Calculation + */ + protected function setupTaxCalculation($taxRates) + { + $storeTaxRate = $taxRates['store_tax_rate']; + $customerTaxRate = $taxRates['customer_tax_rate']; + + $taxCalculation = $this->getMock('Magento\Tax\Model\Calculation', [], [], '', false); + + $rateRequest = new \Magento\Framework\Object(); + $defaultRateRequest = new \Magento\Framework\Object(); + + $taxCalculation->expects($this->any())->method('getRateRequest')->will($this->returnValue($rateRequest)); + $taxCalculation + ->expects($this->any()) + ->method('getRateOriginRequest') + ->will($this->returnValue($defaultRateRequest)); + + $taxCalculation + ->expects($this->any()) + ->method('getRate') + ->will($this->onConsecutiveCalls($storeTaxRate, $customerTaxRate)); + + return $taxCalculation; + } + + /** + * Setup weee helper with an array of methodName, returnValue + * + * @param array $weeeConfig + * @return \PHPUnit_Framework_MockObject_MockObject|\Magento\Weee\Helper\Data + */ + protected function setupWeeeHelper($weeeConfig) + { + $weeeHelper = $this->getMock('Magento\Weee\Helper\Data', [], [], '', false); + + foreach ($weeeConfig as $method => $value) { + $weeeHelper->expects($this->any())->method($method)->will($this->returnValue($value)); + } + + return $weeeHelper; + } + + /** + * Setup an item mock + * + * @param float $itemQty + * @return \PHPUnit_Framework_MockObject_MockObject|\Magento\Sales\Model\Quote\Item + */ + protected function setupItemMock($itemQty) + { + $itemMock = $this->getMock( + 'Magento\Sales\Model\Quote\Item', + [ + 'getProduct', + 'getQuote', + 'getAddress', + 'getTotalQty', + '__wakeup', + ], + [], + '', + false + ); + + $productMock = $this->getMock('Magento\Catalog\Model\Product', [], [], '', false); + $itemMock->expects($this->any())->method('getProduct')->will($this->returnValue($productMock)); + $itemMock->expects($this->any())->method('getTotalQty')->will($this->returnValue($itemQty)); + + return $itemMock; + } + + /** + * Setup address mock + * + * @param \PHPUnit_Framework_MockObject_MockObject|\Magento\Sales\Model\Quote\Item $itemMock + * @param boolean $isWeeeTaxable + * @param array $itemData + * @return \PHPUnit_Framework_MockObject_MockObject + */ + protected function setupAddressMock($itemMock, $isWeeeTaxable, $itemData) + { + $addressMock = $this->getMock( + 'Magento\Sales\Model\Quote\Address', + [ + '__wakeup', + 'getAllNonNominalItems', + 'getQuote', + 'getWeeeCodeToItemMap', + 'getExtraTaxableDetails', + ], + [], + '', + false + ); + + $map = []; + $extraDetails = []; + if ($isWeeeTaxable) { + $code = 'weee1-myWeeeCode'; + $map = [$code => $itemMock]; + $extraDetails = [ + 'weee' => [ + 'sequence-1' => [ + [ + CTC::KEY_TAX_DETAILS_TYPE => 'weee', + CTC::KEY_TAX_DETAILS_CODE => $code, + CTC::KEY_TAX_DETAILS_PRICE_EXCL_TAX => $itemData['weee_tax_applied_amount'], + CTC::KEY_TAX_DETAILS_BASE_PRICE_EXCL_TAX => $itemData['base_weee_tax_applied_amount'], + CTC::KEY_TAX_DETAILS_PRICE_INCL_TAX => $itemData['weee_tax_applied_amount_incl_tax'], + CTC::KEY_TAX_DETAILS_BASE_PRICE_INCL_TAX => + $itemData['base_weee_tax_applied_amount_incl_tax'], + CTC::KEY_TAX_DETAILS_ROW_TOTAL => $itemData['weee_tax_applied_row_amount'], + CTC::KEY_TAX_DETAILS_BASE_ROW_TOTAL => $itemData['base_weee_tax_applied_row_amnt'], + CTC::KEY_TAX_DETAILS_ROW_TOTAL_INCL_TAX => + $itemData['weee_tax_applied_row_amount_incl_tax'], + CTC::KEY_TAX_DETAILS_BASE_ROW_TOTAL_INCL_TAX => + $itemData['base_weee_tax_applied_row_amnt_incl_tax'], + ] + ] + ] + ]; + } + + $quoteMock = $this->getMock('Magento\Sales\Model\Quote', [], [], '', false); + $storeMock = $this->getMock('Magento\Store\Model\Store', ['__wakeup', 'convertPrice'], [], '', false); + $storeMock->expects($this->any())->method('convertPrice')->will($this->returnArgument(0)); + $quoteMock->expects($this->any())->method('getStore')->will($this->returnValue($storeMock)); + + $addressMock->expects($this->any())->method('getAllNonNominalItems')->will($this->returnValue([$itemMock])); + $addressMock->expects($this->any())->method('getQuote')->will($this->returnValue($quoteMock)); + $addressMock->expects($this->any())->method('getWeeeCodeToItemMap')->will($this->returnValue($map)); + $addressMock->expects($this->any())->method('getExtraTaxableDetails')->will($this->returnValue($extraDetails)); + + return $addressMock; + } + + /** + * Verify that correct fields of item has been set + * + * @param \PHPUnit_Framework_MockObject_MockObject|\Magento\Sales\Model\Quote\Item $item + * @param array $itemData + */ + public function verifyItem(\Magento\Sales\Model\Quote\Item $item, $itemData) + { + foreach ($itemData as $key => $value) { + $this->assertEquals($value, $item->getData($key), 'item ' . $key . ' is incorrect'); + } + } + + /** + * Verify that correct fields of address has been set + * + * @param \PHPUnit_Framework_MockObject_MockObject|\Magento\Sales\Model\Quote\Address $address + * @param array $addressData + */ + public function verifyAddress(\Magento\Sales\Model\Quote\Address $address, $addressData) + { + foreach ($addressData as $key => $value) { + $this->assertEquals($value, $address->getData($key), 'address ' . $key . ' is incorrect'); + } + } + + /** + * Test the collect function of the weee collector + * + * @param array $taxConfig + * @param array $weeeConfig + * @param array $taxRates + * @param array $itemData + * @param float $itemQty + * @param array $addressData + * @dataProvider collectDataProvider + */ + public function testCollect($taxConfig, $weeeConfig, $taxRates, $itemData, $itemQty, $addressData = []) + { + $itemMock = $this->setupItemMock($itemQty); + $addressMock = $this->setupAddressMock($itemMock, $weeeConfig['isTaxable'], $itemData); + + $taxHelper = $this->setupTaxHelper($taxConfig); + $weeeHelper = $this->setupWeeeHelper($weeeConfig); + $calculator = $this->setupTaxCalculation($taxRates); + + $arguments = [ + 'taxData' => $taxHelper, + 'calculation' => $calculator, + 'weeeData' => $weeeHelper, + ]; + + $helper = new \Magento\TestFramework\Helper\ObjectManager($this); + $this->weeeCollector = $helper->getObject('Magento\Weee\Model\Total\Quote\WeeeTax', $arguments); + + $this->weeeCollector->collect($addressMock); + + $this->verifyItem($itemMock, $itemData); + $this->verifyAddress($addressMock, $addressData); + } + + /** + * Data provider for testCollect + * + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + * Multiple datasets + * + * @return array + */ + public function collectDataProvider() + { + // 1. When the Weee is not taxable, this collector does not change the item or the address data + // 2. If the Weee amount is included in the subtotal, then it is not included in the 'weee_amount' field + + $data = []; + + $data['price_incl_tax_weee_taxable_unit_included_in_subtotal'] = [ + 'tax_config' => [ + 'priceIncludesTax' => true, + 'getCalculationAgorithm' => Calculation::CALC_UNIT_BASE, + ], + 'weee_config' => [ + 'isEnabled' => true, + 'includeInSubtotal' => true, + 'isTaxable' => true, + 'getApplied' => [], + 'getProductWeeeAttributes' => [ + new \Magento\Framework\Object( + [ + 'name' => 'Recycling Fee', + 'amount' => 10, + ] + ), + ], + ], + 'tax_rates' => [ + 'store_tax_rate' => 8.25, + 'customer_tax_rate' => 8.25, + ], + 'item' => [ + 'weee_tax_applied_amount' => 9.24, + 'base_weee_tax_applied_amount' => 9.24, + 'weee_tax_applied_row_amount' => 18.48, + 'base_weee_tax_applied_row_amnt' => 18.48, + 'weee_tax_applied_amount_incl_tax' => 10, + 'base_weee_tax_applied_amount_incl_tax' => 10, + 'weee_tax_applied_row_amount_incl_tax' => 20, + 'base_weee_tax_applied_row_amnt_incl_tax' => 20, + ], + 'item_qty' => 2, + 'address_data' => [ + 'subtotal' => 18.48, + 'base_subtotal' => 18.48, + 'subtotal_incl_tax' => 20, + 'base_subtotal_incl_tax' => 20, + 'weee_amount' => 0, + 'base_weee_amount' => 0, + ] + ]; + + $data['price_incl_tax_weee_taxable_unit_not_included_in_subtotal'] = [ + 'tax_config' => [ + 'priceIncludesTax' => true, + 'getCalculationAgorithm' => Calculation::CALC_UNIT_BASE, + ], + 'weee_config' => [ + 'isEnabled' => true, + 'includeInSubtotal' => false, + 'isTaxable' => true, + 'getApplied' => [], + 'getProductWeeeAttributes' => [ + new \Magento\Framework\Object( + [ + 'name' => 'Recycling Fee', + 'amount' => 10, + ] + ), + ], + ], + 'tax_rates' => [ + 'store_tax_rate' => 8.25, + 'customer_tax_rate' => 8.25, + ], + 'item' => [ + 'weee_tax_applied_amount' => 9.24, + 'base_weee_tax_applied_amount' => 9.24, + 'weee_tax_applied_row_amount' => 18.48, + 'base_weee_tax_applied_row_amnt' => 18.48, + 'weee_tax_applied_amount_incl_tax' => 10, + 'base_weee_tax_applied_amount_incl_tax' => 10, + 'weee_tax_applied_row_amount_incl_tax' => 20, + 'base_weee_tax_applied_row_amnt_incl_tax' => 20, + ], + 'item_qty' => 2, + 'address_data' => [ + 'subtotal' => 0, + 'base_subtotal' => 0, + 'subtotal_incl_tax' => 20, + 'base_subtotal_incl_tax' => 20, + 'weee_amount' => 18.48, + 'base_weee_amount' => 18.48, + ] + ]; + + $data['price_excl_tax_weee_taxable_unit_included_in_subtotal'] = [ + 'tax_config' => [ + 'priceIncludesTax' => false, + 'getCalculationAgorithm' => Calculation::CALC_UNIT_BASE, + ], + 'weee_config' => [ + 'isEnabled' => true, + 'includeInSubtotal' => true, + 'isTaxable' => true, + 'getApplied' => [], + 'getProductWeeeAttributes' => [ + new \Magento\Framework\Object( + [ + 'name' => 'Recycling Fee', + 'amount' => 10, + ] + ), + ], + ], + 'tax_rates' => [ + 'store_tax_rate' => 8.25, + 'customer_tax_rate' => 8.25, + ], + 'item' => [ + 'weee_tax_applied_amount' => 10, + 'base_weee_tax_applied_amount' => 10, + 'weee_tax_applied_row_amount' => 20, + 'base_weee_tax_applied_row_amnt' => 20, + 'weee_tax_applied_amount_incl_tax' => 10.83, + 'base_weee_tax_applied_amount_incl_tax' => 10.83, + 'weee_tax_applied_row_amount_incl_tax' => 21.66, + 'base_weee_tax_applied_row_amnt_incl_tax' => 21.66, + ], + 'item_qty' => 2, + 'address_data' => [ + 'subtotal' => 20, + 'base_subtotal' => 20, + 'subtotal_incl_tax' => 21.66, + 'base_subtotal_incl_tax' => 21.66, + 'weee_amount' => 0, + 'base_weee_amount' => 0, + ] + ]; + + $data['price_incl_tax_weee_non_taxable_unit_included_in_subtotal'] = [ + 'tax_config' => [ + 'priceIncludesTax' => true, + 'getCalculationAgorithm' => Calculation::CALC_UNIT_BASE, + ], + 'weee_config' => [ + 'isEnabled' => true, + 'includeInSubtotal' => true, + 'isTaxable' => false, + 'getApplied' => [], + 'getProductWeeeAttributes' => [ + new \Magento\Framework\Object( + [ + 'name' => 'Recycling Fee', + 'amount' => 10, + ] + ), + ], + ], + 'tax_rates' => [ + 'store_tax_rate' => 8.25, + 'customer_tax_rate' => 8.25, + ], + 'item' => [ + ], + 'item_qty' => 2, + ]; + + $data['price_excl_tax_weee_non_taxable_unit_include_in_subtotal'] = [ + 'tax_config' => [ + 'priceIncludesTax' => false, + 'getCalculationAgorithm' => Calculation::CALC_UNIT_BASE, + ], + 'weee_config' => [ + 'isEnabled' => true, + 'includeInSubtotal' => true, + 'isTaxable' => false, + 'getApplied' => [], + 'getProductWeeeAttributes' => [ + new \Magento\Framework\Object( + [ + 'name' => 'Recycling Fee', + 'amount' => 10, + ] + ), + ], + ], + 'tax_rates' => [ + 'store_tax_rate' => 8.25, + 'customer_tax_rate' => 8.25, + ], + 'item' => [ + ], + 'item_qty' => 2, + ]; + $data['price_incl_tax_weee_taxable_row_include_in_subtotal'] = [ + 'tax_config' => [ + 'priceIncludesTax' => true, + 'getCalculationAgorithm' => Calculation::CALC_ROW_BASE, + ], + 'weee_config' => [ + 'isEnabled' => true, + 'includeInSubtotal' => true, + 'isTaxable' => true, + 'getApplied' => [], + 'getProductWeeeAttributes' => [ + new \Magento\Framework\Object( + [ + 'name' => 'Recycling Fee', + 'amount' => 10, + ] + ), + ], + ], + 'tax_rates' => [ + 'store_tax_rate' => 8.25, + 'customer_tax_rate' => 8.25, + ], + 'item' => [ + 'weee_tax_applied_amount' => 9.24, + 'base_weee_tax_applied_amount' => 9.24, + 'weee_tax_applied_row_amount' => 18.48, + 'base_weee_tax_applied_row_amnt' => 18.48, + 'weee_tax_applied_amount_incl_tax' => 10, + 'base_weee_tax_applied_amount_incl_tax' => 10, + 'weee_tax_applied_row_amount_incl_tax' => 20, + 'base_weee_tax_applied_row_amnt_incl_tax' => 20, + ], + 'item_qty' => 2, + 'address_data' => [ + 'subtotal' => 18.48, + 'base_subtotal' => 18.48, + 'subtotal_incl_tax' => 20, + 'base_subtotal_incl_tax' => 20, + 'weee_amount' => 0, + 'base_weee_amount' => 0, + ] + ]; + + $data['price_excl_tax_weee_taxable_row_include_in_subtotal'] = [ + 'tax_config' => [ + 'priceIncludesTax' => false, + 'getCalculationAgorithm' => Calculation::CALC_ROW_BASE, + ], + 'weee_config' => [ + 'isEnabled' => true, + 'includeInSubtotal' => true, + 'isTaxable' => true, + 'getApplied' => [], + 'getProductWeeeAttributes' => [ + new \Magento\Framework\Object( + [ + 'name' => 'Recycling Fee', + 'amount' => 10, + ] + ), + ], + ], + 'tax_rates' => [ + 'store_tax_rate' => 8.25, + 'customer_tax_rate' => 8.25, + ], + 'item' => [ + 'weee_tax_applied_amount' => 10, + 'base_weee_tax_applied_amount' => 10, + 'weee_tax_applied_row_amount' => 20, + 'base_weee_tax_applied_row_amnt' => 20, + 'weee_tax_applied_amount_incl_tax' => 10.83, + 'base_weee_tax_applied_amount_incl_tax' => 10.83, + 'weee_tax_applied_row_amount_incl_tax' => 21.65, + 'base_weee_tax_applied_row_amnt_incl_tax' => 21.65, + ], + 'item_qty' => 2, + 'address_data' => [ + 'subtotal' => 20, + 'base_subtotal' => 20, + 'subtotal_incl_tax' => 21.65, + 'base_subtotal_incl_tax' => 21.65, + 'weee_amount' => 0, + 'base_weee_amount' => 0, + ] + ]; + + $data['price_incl_tax_weee_non_taxable_row_include_in_subtotal'] = [ + 'tax_config' => [ + 'priceIncludesTax' => true, + 'getCalculationAgorithm' => Calculation::CALC_ROW_BASE, + ], + 'weee_config' => [ + 'isEnabled' => true, + 'includeInSubtotal' => true, + 'isTaxable' => false, + 'getApplied' => [], + 'getProductWeeeAttributes' => [ + new \Magento\Framework\Object( + [ + 'name' => 'Recycling Fee', + 'amount' => 10, + ] + ), + ], + ], + 'tax_rates' => [ + 'store_tax_rate' => 8.25, + 'customer_tax_rate' => 8.25, + ], + 'item' => [ + ], + 'item_qty' => 2, + ]; + + $data['price_excl_tax_weee_non_taxable_row_not_included_in_subtotal'] = [ + 'tax_config' => [ + 'priceIncludesTax' => false, + 'getCalculationAgorithm' => Calculation::CALC_ROW_BASE, + ], + 'weee_config' => [ + 'isEnabled' => true, + 'includeInSubtotal' => false, + 'isTaxable' => false, + 'getApplied' => [], + 'getProductWeeeAttributes' => [ + new \Magento\Framework\Object( + [ + 'name' => 'Recycling Fee', + 'amount' => 10, + ] + ), + ], + ], + 'tax_rates' => [ + 'store_tax_rate' => 8.25, + 'customer_tax_rate' => 8.25, + ], + 'item' => [ + ], + 'item_qty' => 2, + ]; + + return $data; + } +} diff --git a/dev/tests/unit/testsuite/Magento/Weee/Model/Total/Quote/WeeeTest.php b/dev/tests/unit/testsuite/Magento/Weee/Model/Total/Quote/WeeeTest.php index 54ea80cd854745bae0c529aad993ce3be93cc37f..07684fb048fb3772701539257e4fa9cab7d48b1e 100644 --- a/dev/tests/unit/testsuite/Magento/Weee/Model/Total/Quote/WeeeTest.php +++ b/dev/tests/unit/testsuite/Magento/Weee/Model/Total/Quote/WeeeTest.php @@ -168,7 +168,7 @@ class WeeeTest extends \PHPUnit_Framework_TestCase * Verify that correct fields of address has been set * * @param \PHPUnit_Framework_MockObject_MockObject|\Magento\Sales\Model\Quote\Address $address - * @param $itemData + * @param $addressData */ public function verifyAddress(\Magento\Sales\Model\Quote\Address $address, $addressData) { @@ -223,7 +223,13 @@ class WeeeTest extends \PHPUnit_Framework_TestCase public function collectDataProvider() { $data = []; - $data['price_incl_tax_weee_taxable_unit'] = [ + + // 1. This collector does not compute tax. Instead it sets up various fields for the tax calculation + // 2. When the Weee is not taxable, this collector will change the address data as follows: + // 2a. If Weee is included in the subtotal, the 'subtotal' fields are populated + // 2b. Otherwise the 'weee_amount' fields are populated + + $data['price_incl_tax_weee_taxable_unit_included_in_subtotal'] = [ 'tax_config' => [ 'priceIncludesTax' => true, 'getCalculationAgorithm' => Calculation::CALC_UNIT_BASE, @@ -247,27 +253,19 @@ class WeeeTest extends \PHPUnit_Framework_TestCase 'customer_tax_rate' => 8.25, ], 'item' => [ - 'weee_tax_applied_amount' => 9.24, - 'base_weee_tax_applied_amount' => 9.24, - 'weee_tax_applied_row_amount' => 18.48, - 'base_weee_tax_applied_row_amnt' => 18.48, + 'weee_tax_applied_amount' => 10, + 'base_weee_tax_applied_amount' => 10, + 'weee_tax_applied_row_amount' => 20, + 'base_weee_tax_applied_row_amnt' => 20, 'weee_tax_applied_amount_incl_tax' => 10, 'base_weee_tax_applied_amount_incl_tax' => 10, 'weee_tax_applied_row_amount_incl_tax' => 20, 'base_weee_tax_applied_row_amnt_incl_tax' => 20, - 'extra_taxable_amount' => 10, - 'base_extra_taxable_amount' => 10, - 'extra_row_taxable_amount' => 20, - 'base_extra_row_taxable_amount' => 20, ], 'item_qty' => 2, 'address_data' => [ 'subtotal_incl_tax' => 20, 'base_subtotal_incl_tax' => 20, - 'weee' => 18.48, - 'base_weee' => 18.48, - 'extra_tax_amount' => 0, - 'base_extra_tax_amount' => 0, ] ]; @@ -295,31 +293,23 @@ class WeeeTest extends \PHPUnit_Framework_TestCase 'customer_tax_rate' => 8.25, ], 'item' => [ - 'weee_tax_applied_amount' => 9.24, - 'base_weee_tax_applied_amount' => 9.24, - 'weee_tax_applied_row_amount' => 18.48, - 'base_weee_tax_applied_row_amnt' => 18.48, + 'weee_tax_applied_amount' => 10, + 'base_weee_tax_applied_amount' => 10, + 'weee_tax_applied_row_amount' => 20, + 'base_weee_tax_applied_row_amnt' => 20, 'weee_tax_applied_amount_incl_tax' => 10, 'base_weee_tax_applied_amount_incl_tax' => 10, 'weee_tax_applied_row_amount_incl_tax' => 20, 'base_weee_tax_applied_row_amnt_incl_tax' => 20, - 'extra_taxable_amount' => 10, - 'base_extra_taxable_amount' => 10, - 'extra_row_taxable_amount' => 20, - 'base_extra_row_taxable_amount' => 20, ], 'item_qty' => 2, 'address_data' => [ 'subtotal_incl_tax' => 20, 'base_subtotal_incl_tax' => 20, - 'subtotal' => 0, - 'base_subtotal' => 0, - 'weee_amount' => 18.48, - 'base_weee_amount' => 18.48, ] ]; - $data['price_excl_tax_weee_taxable_unit'] = [ + $data['price_excl_tax_weee_taxable_unit_included_in_subtotal'] = [ 'tax_config' => [ 'priceIncludesTax' => false, 'getCalculationAgorithm' => Calculation::CALC_UNIT_BASE, @@ -347,19 +337,19 @@ class WeeeTest extends \PHPUnit_Framework_TestCase 'base_weee_tax_applied_amount' => 10, 'weee_tax_applied_row_amount' => 20, 'base_weee_tax_applied_row_amnt' => 20, - 'weee_tax_applied_amount_incl_tax' => 10.83, - 'base_weee_tax_applied_amount_incl_tax' => 10.83, - 'weee_tax_applied_row_amount_incl_tax' => 21.66, - 'base_weee_tax_applied_row_amnt_incl_tax' => 21.66, - 'extra_taxable_amount' => 10, - 'base_extra_taxable_amount' => 10, - 'extra_row_taxable_amount' => 20, - 'base_extra_row_taxable_amount' => 20, + 'weee_tax_applied_amount_incl_tax' => 10, + 'base_weee_tax_applied_amount_incl_tax' => 10, + 'weee_tax_applied_row_amount_incl_tax' => 20, + 'base_weee_tax_applied_row_amnt_incl_tax' => 20, ], 'item_qty' => 2, + 'address_data' => [ + 'subtotal_incl_tax' => 20, + 'base_subtotal_incl_tax' => 20, + ] ]; - $data['price_incl_tax_weee_taxable_unit'] = [ + $data['price_incl_tax_weee_non_taxable_unit_included_in_subtotal'] = [ 'tax_config' => [ 'priceIncludesTax' => true, 'getCalculationAgorithm' => Calculation::CALC_UNIT_BASE, @@ -367,7 +357,7 @@ class WeeeTest extends \PHPUnit_Framework_TestCase 'weee_config' => [ 'isEnabled' => true, 'includeInSubtotal' => true, - 'isTaxable' => true, + 'isTaxable' => false, 'getApplied' => [], 'getProductWeeeAttributes' => [ new \Magento\Framework\Object( @@ -383,33 +373,29 @@ class WeeeTest extends \PHPUnit_Framework_TestCase 'customer_tax_rate' => 8.25, ], 'item' => [ - 'weee_tax_applied_amount' => 9.24, - 'base_weee_tax_applied_amount' => 9.24, - 'weee_tax_applied_row_amount' => 18.48, - 'base_weee_tax_applied_row_amnt' => 18.48, + 'weee_tax_applied_amount' => 10, + 'base_weee_tax_applied_amount' => 10, + 'weee_tax_applied_row_amount' => 20, + 'base_weee_tax_applied_row_amnt' => 20, 'weee_tax_applied_amount_incl_tax' => 10, 'base_weee_tax_applied_amount_incl_tax' => 10, 'weee_tax_applied_row_amount_incl_tax' => 20, 'base_weee_tax_applied_row_amnt_incl_tax' => 20, - 'extra_taxable_amount' => 10, - 'base_extra_taxable_amount' => 10, - 'extra_row_taxable_amount' => 20, - 'base_extra_row_taxable_amount' => 20, ], 'item_qty' => 2, 'address_data' => [ 'subtotal_incl_tax' => 20, 'base_subtotal_incl_tax' => 20, - 'extra_subtotal_amount' => 18.48, - 'base_extra_subtotal_amount' => 18.48, - 'extra_tax_amount' => 1.52, - 'base_extra_tax_amount' => 1.52, + 'subtotal' => 20, + 'base_subtotal' => 20, + 'weee_amount' => 0, + 'base_weee_amount' => 0, ] ]; - $data['price_incl_tax_weee_non_taxable_unit'] = [ + $data['price_excl_tax_weee_non_taxable_unit_included_in_subtotal'] = [ 'tax_config' => [ - 'priceIncludesTax' => true, + 'priceIncludesTax' => false, 'getCalculationAgorithm' => Calculation::CALC_UNIT_BASE, ], 'weee_config' => [ @@ -439,23 +425,27 @@ class WeeeTest extends \PHPUnit_Framework_TestCase 'base_weee_tax_applied_amount_incl_tax' => 10, 'weee_tax_applied_row_amount_incl_tax' => 20, 'base_weee_tax_applied_row_amnt_incl_tax' => 20, - 'extra_taxable_amount' => 0, - 'base_extra_taxable_amount' => 0, - 'extra_row_taxable_amount' => 0, - 'base_extra_row_taxable_amount' => 0, ], 'item_qty' => 2, + 'address_data' => [ + 'subtotal_incl_tax' => 20, + 'base_subtotal_incl_tax' => 20, + 'subtotal' => 20, + 'base_subtotal' => 20, + 'weee_amount' => 0, + 'base_weee_amount' => 0, + ] ]; - $data['price_excl_tax_weee_non_taxable_unit'] = [ + $data['price_incl_tax_weee_taxable_row_included_in_subtotal'] = [ 'tax_config' => [ - 'priceIncludesTax' => false, - 'getCalculationAgorithm' => Calculation::CALC_UNIT_BASE, + 'priceIncludesTax' => true, + 'getCalculationAgorithm' => Calculation::CALC_ROW_BASE, ], 'weee_config' => [ 'isEnabled' => true, 'includeInSubtotal' => true, - 'isTaxable' => false, + 'isTaxable' => true, 'getApplied' => [], 'getProductWeeeAttributes' => [ new \Magento\Framework\Object( @@ -479,16 +469,17 @@ class WeeeTest extends \PHPUnit_Framework_TestCase 'base_weee_tax_applied_amount_incl_tax' => 10, 'weee_tax_applied_row_amount_incl_tax' => 20, 'base_weee_tax_applied_row_amnt_incl_tax' => 20, - 'extra_taxable_amount' => 0, - 'base_extra_taxable_amount' => 0, - 'extra_row_taxable_amount' => 0, - 'base_extra_row_taxable_amount' => 0, ], 'item_qty' => 2, + 'address_data' => [ + 'subtotal_incl_tax' => 20, + 'base_subtotal_incl_tax' => 20, + ] ]; - $data['price_incl_tax_weee_taxable_row'] = [ + + $data['price_excl_tax_weee_taxable_row_included_in_subtotal'] = [ 'tax_config' => [ - 'priceIncludesTax' => true, + 'priceIncludesTax' => false, 'getCalculationAgorithm' => Calculation::CALC_ROW_BASE, ], 'weee_config' => [ @@ -510,31 +501,31 @@ class WeeeTest extends \PHPUnit_Framework_TestCase 'customer_tax_rate' => 8.25, ], 'item' => [ - 'weee_tax_applied_amount' => 9.24, - 'base_weee_tax_applied_amount' => 9.24, - 'weee_tax_applied_row_amount' => 18.48, - 'base_weee_tax_applied_row_amnt' => 18.48, + 'weee_tax_applied_amount' => 10, + 'base_weee_tax_applied_amount' => 10, + 'weee_tax_applied_row_amount' => 20, + 'base_weee_tax_applied_row_amnt' => 20, 'weee_tax_applied_amount_incl_tax' => 10, 'base_weee_tax_applied_amount_incl_tax' => 10, 'weee_tax_applied_row_amount_incl_tax' => 20, 'base_weee_tax_applied_row_amnt_incl_tax' => 20, - 'extra_taxable_amount' => 10, - 'base_extra_taxable_amount' => 10, - 'extra_row_taxable_amount' => 20, - 'base_extra_row_taxable_amount' => 20, ], 'item_qty' => 2, + 'address_data' => [ + 'subtotal_incl_tax' => 20, + 'base_subtotal_incl_tax' => 20, + ] ]; - $data['price_excl_tax_weee_taxable_row'] = [ + $data['price_incl_tax_weee_non_taxable_row_included_in_subtotal'] = [ 'tax_config' => [ - 'priceIncludesTax' => false, + 'priceIncludesTax' => true, 'getCalculationAgorithm' => Calculation::CALC_ROW_BASE, ], 'weee_config' => [ 'isEnabled' => true, 'includeInSubtotal' => true, - 'isTaxable' => true, + 'isTaxable' => false, 'getApplied' => [], 'getProductWeeeAttributes' => [ new \Magento\Framework\Object( @@ -554,21 +545,25 @@ class WeeeTest extends \PHPUnit_Framework_TestCase 'base_weee_tax_applied_amount' => 10, 'weee_tax_applied_row_amount' => 20, 'base_weee_tax_applied_row_amnt' => 20, - 'weee_tax_applied_amount_incl_tax' => 10.83, - 'base_weee_tax_applied_amount_incl_tax' => 10.83, - 'weee_tax_applied_row_amount_incl_tax' => 21.65, - 'base_weee_tax_applied_row_amnt_incl_tax' => 21.65, - 'extra_taxable_amount' => 10, - 'base_extra_taxable_amount' => 10, - 'extra_row_taxable_amount' => 20, - 'base_extra_row_taxable_amount' => 20, + 'weee_tax_applied_amount_incl_tax' => 10, + 'base_weee_tax_applied_amount_incl_tax' => 10, + 'weee_tax_applied_row_amount_incl_tax' => 20, + 'base_weee_tax_applied_row_amnt_incl_tax' => 20, ], 'item_qty' => 2, + 'address_data' => [ + 'subtotal_incl_tax' => 20, + 'base_subtotal_incl_tax' => 20, + 'subtotal' => 20, + 'base_subtotal' => 20, + 'weee_amount' => 0, + 'base_weee_amount' => 0, + ] ]; - $data['price_incl_tax_weee_non_taxable_row'] = [ + $data['price_excl_tax_weee_non_taxable_row_included_in_subtotal'] = [ 'tax_config' => [ - 'priceIncludesTax' => true, + 'priceIncludesTax' => false, 'getCalculationAgorithm' => Calculation::CALC_ROW_BASE, ], 'weee_config' => [ @@ -598,22 +593,26 @@ class WeeeTest extends \PHPUnit_Framework_TestCase 'base_weee_tax_applied_amount_incl_tax' => 10, 'weee_tax_applied_row_amount_incl_tax' => 20, 'base_weee_tax_applied_row_amnt_incl_tax' => 20, - 'extra_taxable_amount' => 0, - 'base_extra_taxable_amount' => 0, - 'extra_row_taxable_amount' => 0, - 'base_extra_row_taxable_amount' => 0, ], 'item_qty' => 2, + 'address_data' => [ + 'subtotal_incl_tax' => 20, + 'base_subtotal_incl_tax' => 20, + 'subtotal' => 20, + 'base_subtotal' => 20, + 'weee_amount' => 0, + 'base_weee_amount' => 0, + ] ]; - $data['price_excl_tax_weee_non_taxable_row'] = [ + $data['price_excl_tax_weee_non_taxable_row_not_included_in_subtotal'] = [ 'tax_config' => [ 'priceIncludesTax' => false, 'getCalculationAgorithm' => Calculation::CALC_ROW_BASE, ], 'weee_config' => [ 'isEnabled' => true, - 'includeInSubtotal' => true, + 'includeInSubtotal' => false, 'isTaxable' => false, 'getApplied' => [], 'getProductWeeeAttributes' => [ @@ -638,13 +637,18 @@ class WeeeTest extends \PHPUnit_Framework_TestCase 'base_weee_tax_applied_amount_incl_tax' => 10, 'weee_tax_applied_row_amount_incl_tax' => 20, 'base_weee_tax_applied_row_amnt_incl_tax' => 20, - 'extra_taxable_amount' => 0, - 'base_extra_taxable_amount' => 0, - 'extra_row_taxable_amount' => 0, - 'base_extra_row_taxable_amount' => 0, ], 'item_qty' => 2, + 'address_data' => [ + 'subtotal_incl_tax' => 20, + 'base_subtotal_incl_tax' => 20, + 'subtotal' => 0, + 'base_subtotal' => 0, + 'weee_amount' => 20, + 'base_weee_amount' => 20, + ] ]; + return $data; } -} \ No newline at end of file +} diff --git a/lib/internal/Magento/Framework/App/Language/Config.php b/lib/internal/Magento/Framework/App/Language/Config.php new file mode 100644 index 0000000000000000000000000000000000000000..1b569b62e47b6517f7ecf6104fd7ea8ac80fa09f --- /dev/null +++ b/lib/internal/Magento/Framework/App/Language/Config.php @@ -0,0 +1,152 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Framework\App\Language; + +use Magento\Framework\Config\Dom; + +/** + * Language pack configuration file + */ +class Config +{ + /** + * Data extracted from the configuration file + * + * @var array + */ + protected $_data; + + /** + * Constructor + * + * @param string $source + * @throws \Magento\Framework\Exception + */ + public function __construct($source) + { + $config = new \DOMDocument(); + $config->loadXML($source); + $errors = Dom::validateDomDocument($config, $this->getSchemaFile()); + if (!empty($errors)) { + throw new \Magento\Framework\Exception("Invalid Document: \n" . implode("\n", $errors)); + } + $this->_data = $this->_extractData($config); + } + + /** + * Get absolute path to validation scheme for language.xml + * + * @return string + */ + protected function getSchemaFile() + { + return __DIR__ . '/package.xsd'; + } + + /** + * Extract configuration data from the DOM structure + * + * @param \DOMDocument $dom + * @return array + */ + protected function _extractData(\DOMDocument $dom) + { + /** @var $languageNode \DOMElement */ + $languageNode = $dom->getElementsByTagName('language')->item(0); + /** @var $codeNode \DOMElement */ + $codeNode = $languageNode->getElementsByTagName('code')->item(0); + /** @var $vendorNode \DOMElement */ + $vendorNode = $languageNode->getElementsByTagName('vendor')->item(0); + /** @var $packageNode \DOMElement */ + $packageNode = $languageNode->getElementsByTagName('package')->item(0); + /** @var $sortOrderNode \DOMElement */ + $sortOrderNode = $languageNode->getElementsByTagName('sort_order')->item(0); + $use = []; + /** @var $useNode \DOMElement */ + foreach ($languageNode->getElementsByTagName('use') as $useNode) { + $use[] = [ + 'vendor' => $useNode->getAttribute('vendor'), + 'package' => $useNode->getAttribute('package') + ]; + } + return [ + 'code' => $codeNode->nodeValue, + 'vendor' => $vendorNode->nodeValue, + 'package' => $packageNode->nodeValue, + 'sort_order' => $sortOrderNode ? $sortOrderNode->nodeValue : 0, + 'use' => $use + ]; + } + + /** + * Language code + * + * @return string + */ + public function getCode() + { + return $this->_data['code']; + } + + /** + * Language vendor + * + * @return string + */ + public function getVendor() + { + return $this->_data['vendor']; + } + + /** + * Language package + * + * @return string + */ + public function getPackage() + { + return $this->_data['package']; + } + + /** + * Sort order + * + * @return null|int + */ + public function getSortOrder() + { + return $this->_data['sort_order']; + } + + /** + * Declaration of Inheritances + * + * @return string[][] + */ + public function getUses() + { + return $this->_data['use']; + } +} diff --git a/lib/internal/Magento/Framework/App/Language/ConfigFactory.php b/lib/internal/Magento/Framework/App/Language/ConfigFactory.php new file mode 100644 index 0000000000000000000000000000000000000000..ae60f01cd770539b5e895a225c9a05a915ffb5db --- /dev/null +++ b/lib/internal/Magento/Framework/App/Language/ConfigFactory.php @@ -0,0 +1,56 @@ +<?php +/** + * Application language config factory + * + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Framework\App\Language; + +/** + * @codeCoverageIgnore + */ +class ConfigFactory +{ + /** + * @var \Magento\Framework\ObjectManager + */ + protected $_objectManager; + + /** + * @param \Magento\Framework\ObjectManager $objectManager + */ + public function __construct(\Magento\Framework\ObjectManager $objectManager) + { + $this->_objectManager = $objectManager; + } + + /** + * Create config + * + * @param array $arguments + * @return Config + */ + public function create(array $arguments = array()) + { + return $this->_objectManager->create('Magento\Framework\App\Language\Config', $arguments); + } +} diff --git a/lib/internal/Magento/Framework/App/Language/Dictionary.php b/lib/internal/Magento/Framework/App/Language/Dictionary.php index 02357f2c0b5adb7d26086d84413b36da60fada8f..622a01adc6718e71e6f411f9784acc0ca46ae936 100644 --- a/lib/internal/Magento/Framework/App/Language/Dictionary.php +++ b/lib/internal/Magento/Framework/App/Language/Dictionary.php @@ -24,6 +24,8 @@ namespace Magento\Framework\App\Language; +use \Magento\Framework\App\Filesystem; + /** * A service for reading language package dictionaries */ @@ -34,17 +36,26 @@ class Dictionary */ private $dir; + /** + * @var ConfigFactory + */ + private $configFactory; + /** * @var array */ - private $packs = array(); + private $packList = array(); /** - * @param \Magento\Framework\App\Filesystem $filesystem + * @param Filesystem $filesystem + * @param ConfigFactory $configFactory */ - public function __construct(\Magento\Framework\App\Filesystem $filesystem) - { - $this->dir = $filesystem->getDirectoryRead(\Magento\Framework\App\Filesystem::LOCALE_DIR); + public function __construct( + Filesystem $filesystem, + ConfigFactory $configFactory + ) { + $this->dir = $filesystem->getDirectoryRead(Filesystem::LOCALE_DIR); + $this->configFactory = $configFactory; } /** @@ -58,125 +69,31 @@ class Dictionary */ public function getDictionary($languageCode) { + $languages = []; $declarations = $this->dir->search('*/*/language.xml'); foreach ($declarations as $file) { - list($vendor, $code) = explode('/', $file); - if ($languageCode == $code) { - $this->readPackDeclaration($vendor, $code); - } - } - $packs = []; - $this->collectInheritedPacks($languageCode, $packs); - uasort($packs, [$this, 'sortInherited']); - $result = []; - foreach ($packs as $info) { - $dictionary = $this->readPackCsv($info['vendor'], $info['code']); - $result = array_merge($result, $dictionary); - } - return $result; - } - - /** - * Read declaration of the specified language pack - * - * Will recursively load any parent packs - * - * @param string $vendor - * @param string $code - * @return void - */ - private function readPackDeclaration($vendor, $code) - { - if (isset($this->packs[$code][$vendor])) { - return; - } - $file = "{$vendor}/{$code}/language.xml"; - $dom = new \DOMDocument(); - $xml = $this->dir->readFile($file); - $dom->loadXML($xml); - $root = $dom->documentElement; - $this->assertVendor($vendor, $root); - $this->assertCode($code, $root); - $this->packs[$code][$vendor] = [ - 'vendor' => $vendor, - 'code' => $code, - 'sort_order' => $this->getSortOrder($root), - ]; - $use = $this->getUse($root); - if ($use) { - foreach ($use as $info) { - $this->packs[$code][$vendor]['use'][] = $info; - $this->readPackDeclaration($info['vendor'], $info['code']); - } - } - } - - /** - * Assert that vendor code in the declaration matches the one discovered in file system - * - * @param string $expected - * @param \DOMElement $root - * @return void - * @throws \LogicException - */ - public static function assertVendor($expected, \DOMElement $root) - { - foreach ($root->getElementsByTagName('vendor') as $node) { - if ($expected != $node->nodeValue) { - throw new \LogicException('Vendor name mismatch'); - } - break; - } - } - - /** - * Assert that language code in the declaration matches the one discovered in file system - * - * @param string $expected - * @param \DOMElement $root - * @return void - * @throws \LogicException - */ - public static function assertCode($expected, \DOMElement $root) - { - foreach ($root->getElementsByTagName('code') as $node) { - if ($expected != $node->nodeValue) { - throw new \LogicException('Language code name mismatch'); + $xmlSource = $this->dir->readFile($file); + $languageConfig = $this->configFactory->create(['source' => $xmlSource]); + $this->packList[$languageConfig->getVendor()][$languageConfig->getPackage()] = $languageConfig; + if ($languageConfig->getCode() === $languageCode) { + $languages[] = $languageConfig; } - break; } - } - /** - * Read sort order from the declaration - * - * By default will be 0 - * - * @param \DOMElement $root - * @return int - */ - private function getSortOrder(\DOMElement $root) - { - foreach ($root->getElementsByTagName('sort_order') as $node) { - return (int)$node->nodeValue; + // Collect the inherited packages with meta-information of sorting + $packs = []; + foreach ($languages as $languageConfig) { + $this->collectInheritedPacks($languageConfig, $packs); } - return 0; - } + uasort($packs, [$this, 'sortInherited']); - /** - * Read information about reusing other packs from the declaration - * - * @param \DOMElement $root - * @return array - */ - private function getUse(\DOMElement $root) - { + // Merge all packages of translation to one dictionary $result = []; - foreach ($root->getElementsByTagName('use') as $parent) { - $result[] = [ - 'vendor' => $parent->getAttribute('vendor'), - 'code' => $parent->getAttribute('code'), - ]; + foreach ($packs as $packInfo) { + /** @var Config $languageConfig */ + $languageConfig = $packInfo['language']; + $dictionary = $this->readPackCsv($languageConfig->getVendor(), $languageConfig->getPackage()); + $result = array_merge($result, $dictionary); } return $result; } @@ -186,21 +103,24 @@ class Dictionary * * Record level of recursion (level of inheritance) for further use in sorting * - * @param string $code + * @param Config $languageConfig * @param array $result * @param int $level * @return void */ - private function collectInheritedPacks($code, array &$result, $level = 0) + private function collectInheritedPacks($languageConfig, &$result, $level = 0) { - if (isset($this->packs[$code])) { - foreach ($this->packs[$code] as $vendor => $info) { - $info['inheritance_level'] = $level; - $result["{$code}|{$vendor}"] = $info; - if (isset($info['use'])) { - foreach ($info['use'] as $reuse) { - $this->collectInheritedPacks($reuse['code'], $result, $level + 1); - } + $packKey = implode('|', [$languageConfig->getVendor(), $languageConfig->getPackage()]); + if (!isset($result[$packKey])) { + $result[$packKey] = [ + 'inheritance_level' => $level, + 'sort_order' => $languageConfig->getSortOrder(), + 'language' => $languageConfig + ]; + foreach ($languageConfig->getUses() as $reuse) { + if (isset($this->packList[$reuse['vendor']][$reuse['package']])) { + $parentLanguageConfig = $this->packList[$reuse['vendor']][$reuse['package']]; + $this->collectInheritedPacks($parentLanguageConfig, $result, $level + 1); } } } @@ -211,23 +131,21 @@ class Dictionary * * First sort by inheritance level descending, then by sort order ascending * - * @param array $a - * @param array $b + * @param array $current + * @param array $next * @return int * @SuppressWarnings(PHPMD.UnusedPrivateMethod) */ - private function sortInherited($a, $b) + private function sortInherited($current, $next) { - if ($a['inheritance_level'] > $b['inheritance_level']) { + if ($current['inheritance_level'] > $next['inheritance_level']) { return -1; - } - if ($a['inheritance_level'] < $b['inheritance_level']) { + } elseif ($current['inheritance_level'] < $next['inheritance_level']) { return 1; } - if ($a['sort_order'] > $b['sort_order']) { + if ($current['sort_order'] > $next['sort_order']) { return 1; - } - if ($a['sort_order'] < $b['sort_order']) { + } elseif ($current['sort_order'] < $next['sort_order']) { return -1; } return 0; @@ -239,12 +157,12 @@ class Dictionary * The files are sorted alphabetically, then each of them is read, and results are recorded into key => value array * * @param string $vendor - * @param string $code + * @param string $package * @return array */ - private function readPackCsv($vendor, $code) + private function readPackCsv($vendor, $package) { - $files = $this->dir->search("{$vendor}/{$code}/*.csv"); + $files = $this->dir->search("{$vendor}/{$package}/*.csv"); sort($files); $result = []; foreach ($files as $path) { diff --git a/lib/internal/Magento/Framework/App/Language/package.xsd b/lib/internal/Magento/Framework/App/Language/package.xsd index 8eb7aa87c5e5de0391906614a17bc63e99407d5e..3f3e33a182be072b7c33d7ee26bf11d8708b1679 100644 --- a/lib/internal/Magento/Framework/App/Language/package.xsd +++ b/lib/internal/Magento/Framework/App/Language/package.xsd @@ -24,7 +24,13 @@ */ --> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> - <xs:element name="language" type="languageDeclarationType"/> + <xs:element name="language" type="languageDeclarationType"> + <xs:unique name="vendorCode"> + <xs:selector xpath="use"/> + <xs:field xpath="@vendor"/> + <xs:field xpath="@package"/> + </xs:unique> + </xs:element> <xs:complexType name="languageDeclarationType"> <xs:annotation> @@ -33,8 +39,9 @@ <xs:sequence> <xs:element minOccurs="1" maxOccurs="1" name="code" type="codeType"/> <xs:element minOccurs="1" maxOccurs="1" name="vendor" type="vendorType"/> + <xs:element minOccurs="1" maxOccurs="1" name="package" type="packageType"/> <xs:element minOccurs="0" maxOccurs="1" name="sort_order" type="xs:integer"/> - <xs:element minOccurs="0" maxOccurs="1" name="use" type="useType"/> + <xs:element minOccurs="0" maxOccurs="unbounded" name="use" type="useType"/> </xs:sequence> </xs:complexType> @@ -46,12 +53,18 @@ <xs:simpleType name="vendorType"> <xs:restriction base="xs:string"> - <xs:pattern value="[A-Z][A-Za-z]+"/> + <xs:pattern value="[a-z\-_]+"/> + </xs:restriction> + </xs:simpleType> + + <xs:simpleType name="packageType"> + <xs:restriction base="xs:string"> + <xs:pattern value="[a-z\-_]+"/> </xs:restriction> </xs:simpleType> <xs:complexType name="useType"> <xs:attribute use="required" name="vendor" type="vendorType"/> - <xs:attribute use="required" name="code" type="codeType"/> + <xs:attribute use="required" name="package" type="packageType"/> </xs:complexType> </xs:schema> diff --git a/lib/internal/Magento/Framework/App/Resource.php b/lib/internal/Magento/Framework/App/Resource.php index 9cc0704240ae3badc9d2c8c1145bd59d47aee9aa..bdb1f8ffbfe439f5a305d88ec091818161643519 100644 --- a/lib/internal/Magento/Framework/App/Resource.php +++ b/lib/internal/Magento/Framework/App/Resource.php @@ -40,6 +40,8 @@ class Resource const DEFAULT_READ_RESOURCE = 'core_read'; + const DEFAULT_WRITE_RESOURCE = 'core_write'; + /** * Instances of actual connections * diff --git a/lib/internal/Magento/Framework/AppInterface.php b/lib/internal/Magento/Framework/AppInterface.php index a51c3246ce9ea94ad37dee28bf1893c2f28e2975..14cdde47f814fc543dbf6cddf0664e75957d52d3 100644 --- a/lib/internal/Magento/Framework/AppInterface.php +++ b/lib/internal/Magento/Framework/AppInterface.php @@ -35,7 +35,7 @@ interface AppInterface /** * Magento version */ - const VERSION = '2.0.0.0-dev87'; + const VERSION = '2.0.0.0-dev88'; /** * Launch application diff --git a/lib/internal/Magento/Framework/Data/Tree/Node.php b/lib/internal/Magento/Framework/Data/Tree/Node.php index 0e3db60102a8f44fbc18dc54748856f7a3d3cb4f..ec8591aa17437946da25c1f930af1dee46b07fda 100644 --- a/lib/internal/Magento/Framework/Data/Tree/Node.php +++ b/lib/internal/Magento/Framework/Data/Tree/Node.php @@ -65,15 +65,15 @@ class Node extends \Magento\Framework\Object * Data tree node constructor * * @param array $data - * @param string $idFeild + * @param string $idField * @param Tree $tree * @param Node $parent */ - public function __construct($data, $idFeild, $tree, $parent = null) + public function __construct($data, $idField, $tree, $parent = null) { $this->setTree($tree); $this->setParent($parent); - $this->setIdField($idFeild); + $this->setIdField($idField); $this->setData($data); $this->_childNodes = new Collection($this); } diff --git a/lib/internal/Magento/Framework/Data/Tree/Node/Collection.php b/lib/internal/Magento/Framework/Data/Tree/Node/Collection.php index 6242a0963b4b4bdf4062d6ba7f3f2eccf401d82e..68ff413299dc0c9e4c7638560fde8a5f15574698 100644 --- a/lib/internal/Magento/Framework/Data/Tree/Node/Collection.php +++ b/lib/internal/Magento/Framework/Data/Tree/Node/Collection.php @@ -165,7 +165,14 @@ class Collection implements \ArrayAccess, \IteratorAggregate */ public function lastNode() { - return !empty($this->_nodes) ? $this->_nodes[count($this->_nodes) - 1] : null; + if (!empty($this->_nodes)) { + $result = end($this->_nodes); + reset($this->_nodes); + } else { + $result = null; + } + + return $result; } /** diff --git a/lib/internal/Magento/Framework/Filesystem/Driver/File.php b/lib/internal/Magento/Framework/Filesystem/Driver/File.php index b86ae711736677db017f73a90bdb6b85f2315c95..8fb3a6505dcbfe6afbf3b099898fe585a2ad9b4c 100644 --- a/lib/internal/Magento/Framework/Filesystem/Driver/File.php +++ b/lib/internal/Magento/Framework/Filesystem/Driver/File.php @@ -239,17 +239,7 @@ class File implements DriverInterface clearstatcache(); $globPattern = rtrim($path, '/') . '/' . ltrim($pattern, '/'); $result = @glob($globPattern, GLOB_BRACE); - if ($result === false) { - throw new FilesystemException( - sprintf( - 'The "%s" pattern cannot be processed in "%s" path %s', - $pattern, - $path, - $this->getWarningMessage() - ) - ); - } - return $result; + return is_array($result) ? $result : []; } /** diff --git a/lib/internal/Magento/Framework/HTTP/Adapter/Curl.php b/lib/internal/Magento/Framework/HTTP/Adapter/Curl.php index 7230f00131f1d7d14761a2a3d2dae5d357dec06b..ea9837ef99d2848af53d34feee6508e6af8ba957 100644 --- a/lib/internal/Magento/Framework/HTTP/Adapter/Curl.php +++ b/lib/internal/Magento/Framework/HTTP/Adapter/Curl.php @@ -197,7 +197,9 @@ class Curl implements \Zend_Http_Client_Adapter_Interface $response = curl_exec($this->_getResource()); // Remove 100 and 101 responses headers - if (\Zend_Http_Response::extractCode($response) == 100 || \Zend_Http_Response::extractCode($response) == 101) { + while (\Zend_Http_Response::extractCode($response) == 100 + || \Zend_Http_Response::extractCode($response) == 101 + ) { $response = preg_split('/^\r?$/m', $response, 2); $response = trim($response[1]); } diff --git a/lib/internal/Magento/Framework/Module/Declaration/FileResolver.php b/lib/internal/Magento/Framework/Module/Declaration/FileResolver.php index ecc6214f0e7815997fb2555e98013d1afe6d55a6..07fba50d6407dd275116dfd6f19bac86cb70ca4c 100644 --- a/lib/internal/Magento/Framework/Module/Declaration/FileResolver.php +++ b/lib/internal/Magento/Framework/Module/Declaration/FileResolver.php @@ -82,13 +82,17 @@ class FileResolver implements \Magento\Framework\Config\FileResolverInterface $mageScopePath = $moduleDir . '/Magento'; $output = array('base' => array(), 'mage' => array(), 'custom' => array()); $files = glob($moduleDir . '*/*/etc/module.xml'); - foreach ($files as $file) { - $scope = strpos($file, $mageScopePath) === 0 ? 'mage' : 'custom'; - $output[$scope][] = $this->rootDirectory->getRelativePath($file); + if (!empty($files)) { + foreach ($files as $file) { + $scope = strpos($file, $mageScopePath) === 0 ? 'mage' : 'custom'; + $output[$scope][] = $this->rootDirectory->getRelativePath($file); + } } $files = glob($configDir . '*/module.xml'); - foreach ($files as $file) { - $output['base'][] = $this->rootDirectory->getRelativePath($file); + if (!empty($files)) { + foreach ($files as $file) { + $output['base'][] = $this->rootDirectory->getRelativePath($file); + } } return $this->iteratorFactory->create( $this->rootDirectory, diff --git a/lib/internal/Magento/Framework/Module/ResourceResolver.php b/lib/internal/Magento/Framework/Module/ResourceResolver.php index fec05e749f8734d1fd8bd5cb4ba0d9aeb0f0592c..857810be2f3ebd797088bfb8a877ba164793b39f 100644 --- a/lib/internal/Magento/Framework/Module/ResourceResolver.php +++ b/lib/internal/Magento/Framework/Module/ResourceResolver.php @@ -61,14 +61,20 @@ class ResourceResolver implements \Magento\Framework\Module\ResourceResolverInte // Process sub-directories within modules sql directory $moduleSqlDir = $this->_moduleReader->getModuleDir('sql', $moduleName); $sqlResources = array(); - foreach (glob($moduleSqlDir . '/*', GLOB_ONLYDIR) as $resourceDir) { - $sqlResources[] = basename($resourceDir); + $resourceDirs = glob($moduleSqlDir . '/*', GLOB_ONLYDIR); + if (!empty($resourceDirs)) { + foreach ($resourceDirs as $resourceDir) { + $sqlResources[] = basename($resourceDir); + } } $moduleDataDir = $this->_moduleReader->getModuleDir('data', $moduleName); // Process sub-directories within modules data directory $dataResources = array(); - foreach (glob($moduleDataDir . '/*', GLOB_ONLYDIR) as $resourceDir) { - $dataResources[] = basename($resourceDir); + $resourceDirs = glob($moduleDataDir . '/*', GLOB_ONLYDIR); + if (!empty($resourceDirs)) { + foreach ($resourceDirs as $resourceDir) { + $dataResources[] = basename($resourceDir); + } } $this->_moduleResources[$moduleName] = array_unique(array_merge($sqlResources, $dataResources)); } diff --git a/lib/internal/Magento/Framework/Parse/Zip.php b/lib/internal/Magento/Framework/Parse/Zip.php new file mode 100644 index 0000000000000000000000000000000000000000..e8c2c9884e0ae92966c36484f8c73dbc7b296c1c --- /dev/null +++ b/lib/internal/Magento/Framework/Parse/Zip.php @@ -0,0 +1,167 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +/** + * Various methods for parsing Zip codes + * + */ +namespace Magento\Framework\Parse; + +class Zip +{ + /** + * Retrieve array of regions characterized by provided params + * + * @param string $state + * @param string $zip + * @return string[] + */ + public static function parseRegions($state, $zip) + { + return !empty($zip) && $zip != '*' ? self::parseZip($zip) : ($state ? array($state) : array('*')); + } + + /** + * Retrieve array of regions characterized by provided zip code + * + * @param string $zip + * @return string[] + */ + public static function parseZip($zip) + { + if (strpos($zip, '-') == -1) { + return array($zip); + } else { + return self::zipRangeToZipPattern($zip); + } + } + + /** + * Convert a Magento zip range to an array of zip patterns + * (e.g., 12000-13999 -> [12*, 13*]) + * + * @param string $zipRange + * @return array + */ + public static function zipRangeToZipPattern($zipRange) + { + $zipLength = 5; + $zipPattern = array(); + + if (!preg_match("/^(.+)-(.+)$/", $zipRange, $zipParts)) { + return array($zipRange); + } + + if ($zipParts[1] == $zipParts[2]) { + return array($zipParts[1]); + } + + if ($zipParts[1] > $zipParts[2]) { + list($zipParts[2], $zipParts[1]) = array($zipParts[1], $zipParts[2]); + } + + $from = str_split($zipParts[1]); + $to = str_split($zipParts[2]); + + $startZip = ''; + $diffPosition = null; + for ($pos = 0; $pos < $zipLength; $pos++) { + if ($from[$pos] == $to[$pos]) { + $startZip .= $from[$pos]; + } else { + $diffPosition = $pos; + break; + } + } + + /* + * calculate zip-patterns + */ + if (min(array_slice($to, $diffPosition)) == 9 && max(array_slice($from, $diffPosition)) == 0) { + // particular case like 11000-11999 -> 11* + return array($startZip . '*'); + } else { + // calculate approximate zip-patterns + $start = $from[$diffPosition]; + $finish = $to[$diffPosition]; + if ($diffPosition < $zipLength - 1) { + $start++; + $finish--; + } + $end = $diffPosition < $zipLength - 1 ? '*' : ''; + for ($digit = $start; $digit <= $finish; $digit++) { + $zipPattern[] = $startZip . $digit . $end; + } + } + + if ($diffPosition == $zipLength - 1) { + return $zipPattern; + } + + $nextAsteriskFrom = true; + $nextAsteriskTo = true; + for ($pos = $zipLength - 1; $pos > $diffPosition; $pos--) { + // calculate zip-patterns based on $from value + if ($from[$pos] == 0 && $nextAsteriskFrom) { + $nextAsteriskFrom = true; + } else { + $subZip = ''; + for ($k = $diffPosition; $k < $pos; $k++) { + $subZip .= $from[$k]; + } + $delta = $nextAsteriskFrom ? 0 : 1; + $end = $pos < $zipLength - 1 ? '*' : ''; + for ($i = $from[$pos] + $delta; $i <= 9; $i++) { + $zipPattern[] = $startZip . $subZip . $i . $end; + } + $nextAsteriskFrom = false; + } + + // calculate zip-patterns based on $to value + if ($to[$pos] == 9 && $nextAsteriskTo) { + $nextAsteriskTo = true; + } else { + $subZip = ''; + for ($k = $diffPosition; $k < $pos; $k++) { + $subZip .= $to[$k]; + } + $delta = $nextAsteriskTo ? 0 : 1; + $end = $pos < $zipLength - 1 ? '*' : ''; + for ($i = 0; $i <= $to[$pos] - $delta; $i++) { + $zipPattern[] = $startZip . $subZip . $i . $end; + } + $nextAsteriskTo = false; + } + } + + if ($nextAsteriskFrom) { + $zipPattern[] = $startZip . $from[$diffPosition] . '*'; + } + if ($nextAsteriskTo) { + $zipPattern[] = $startZip . $to[$diffPosition] . '*'; + } + + return $zipPattern; + } +} diff --git a/lib/internal/Magento/Framework/Phrase/Renderer/Translate.php b/lib/internal/Magento/Framework/Phrase/Renderer/Translate.php index 58be776147f542259a5ed04679dd88d97d510b97..9eae2cc21a3ff0054c5015380727e7fae16e79d8 100644 --- a/lib/internal/Magento/Framework/Phrase/Renderer/Translate.php +++ b/lib/internal/Magento/Framework/Phrase/Renderer/Translate.php @@ -53,17 +53,8 @@ class Translate implements \Magento\Framework\Phrase\RendererInterface { $text = end($source); - $code = $this->translator->getTheme() . '::' . $text; - $data = $this->translator->getData(); - if (array_key_exists($code, $data)) { - return $data[$code]; - } - if (array_key_exists($text, $data)) { - return $data[$text]; - } - - return $text; + return array_key_exists($text, $data) ? $data[$text] : $text; } } diff --git a/lib/internal/Magento/Framework/Simplexml/Config.php b/lib/internal/Magento/Framework/Simplexml/Config.php index 3e56edf2f43c01a9d713b629542c87174b79244a..64f071b6dddd9d0a63dd70e521d1f89d0a153d29 100644 --- a/lib/internal/Magento/Framework/Simplexml/Config.php +++ b/lib/internal/Magento/Framework/Simplexml/Config.php @@ -31,7 +31,7 @@ class Config /** * Configuration xml * - * @var \Magento\Framework\Simplexml\Element + * @var Element */ protected $_xml = null; @@ -73,7 +73,7 @@ class Config /** * Cache resource object * - * @var \Magento\Framework\Simplexml\Config\Cache\AbstractCache + * @var Config\Cache\AbstractCache */ protected $_cache = null; @@ -96,15 +96,15 @@ class Config * * Initializes XML for this configuration * - * @see self::setXml - * @param string|\Magento\Framework\Simplexml\Element $sourceData + * @see \Magento\Framework\Simplexml\Config::setXml + * @param string|Element $sourceData */ public function __construct($sourceData = null) { - if (is_null($sourceData)) { + if ($sourceData === null) { return; } - if ($sourceData instanceof \Magento\Framework\Simplexml\Element) { + if ($sourceData instanceof Element) { $this->setXml($sourceData); } elseif (is_string($sourceData) && !empty($sourceData)) { if (strlen($sourceData) < 1000 && is_readable($sourceData)) { @@ -118,10 +118,10 @@ class Config /** * Sets xml for this configuration * - * @param \Magento\Framework\Simplexml\Element $node + * @param Element $node * @return $this */ - public function setXml(\Magento\Framework\Simplexml\Element $node) + public function setXml(Element $node) { $this->_xml = $node; return $this; @@ -130,13 +130,13 @@ class Config /** * Returns node found by the $path * - * @see \Magento\Framework\Simplexml\Element::descend - * @param string $path - * @return \Magento\Framework\Simplexml\Element|bool + * @see \Magento\Framework\Simplexml\Element::descend + * @param string $path + * @return Element|bool */ public function getNode($path = null) { - if (!$this->_xml instanceof \Magento\Framework\Simplexml\Element) { + if (!$this->_xml instanceof Element) { return false; } elseif ($path === null) { return $this->_xml; @@ -149,7 +149,7 @@ class Config * Returns nodes found by xpath expression * * @param string $xpath - * @return \SimpleXMLElement[]|bool + * @return Element[]|bool */ public function getXpath($xpath) { @@ -167,7 +167,7 @@ class Config /** * Enter description here... * - * @param \Magento\Framework\Simplexml\Config\Cache\AbstractCache $cache + * @param Config\Cache\AbstractCache $cache * @return $this */ public function setCache($cache) @@ -179,7 +179,7 @@ class Config /** * Enter description here... * - * @return \Magento\Framework\Simplexml\Config\Cache\AbstractCache + * @return Config\Cache\AbstractCache */ public function getCache() { @@ -282,7 +282,7 @@ class Config */ public function setCacheChecksum($data) { - if (is_null($data)) { + if ($data === null) { $this->_cacheChecksum = null; } elseif (false === $data || 0 === $data) { $this->_cacheChecksum = false; @@ -352,7 +352,7 @@ class Config if (false === $newChecksum) { return false; } - if (is_null($newChecksum)) { + if ($newChecksum === null) { return true; } $cachedChecksum = $this->getCache()->load($this->getCacheChecksumId()); @@ -371,9 +371,7 @@ class Config } $xmlString = $this->_loadCache($this->getCacheId()); - $xml = simplexml_load_string($xmlString, $this->_elementClass); - if ($xml) { - $this->_xml = $xml; + if ($this->loadString($xmlString)) { $this->setCacheSaved(true); return true; } @@ -389,29 +387,19 @@ class Config */ public function saveCache($tags = null) { - if ($this->getCacheSaved()) { - return $this; - } - if (false === $this->getCacheChecksum()) { + if ($this->getCacheSaved() || $this->getCacheChecksum() === false) { return $this; } - if (is_null($tags)) { - $tags = $this->_cacheTags; + if ($tags === null) { + $tags = $this->getCacheTags(); } - if (!is_null($this->getCacheChecksum())) { - $this->_saveCache( - $this->getCacheChecksum(), - $this->getCacheChecksumId(), - $tags, - $this->getCacheLifetime() - ); + if ($this->getCacheChecksum() === null) { + $this->_saveCache($this->getCacheChecksum(), $this->getCacheChecksumId(), $tags, $this->getCacheLifetime()); } - $xmlString = $this->getXmlString(); - $this->_saveCache($xmlString, $this->getCacheId(), $tags, $this->getCacheLifetime()); - + $this->_saveCache($this->getXmlString(), $this->getCacheId(), $tags, $this->getCacheLifetime()); $this->setCacheSaved(true); return $this; @@ -491,7 +479,7 @@ class Config $fileData = file_get_contents($filePath); $fileData = $this->processFileData($fileData); - return $this->loadString($fileData, $this->_elementClass); + return $this->loadString($fileData); } /** @@ -504,7 +492,7 @@ class Config { if (!empty($string)) { $xml = simplexml_load_string($string, $this->_elementClass); - if ($xml instanceof \Magento\Framework\Simplexml\Element) { + if ($xml) { $this->_xml = $xml; return true; } @@ -540,7 +528,7 @@ class Config */ public function setNode($path, $value, $overwrite = true) { - $xml = $this->_xml->setNode($path, $value, $overwrite); + $this->_xml->setNode($path, $value, $overwrite); return $this; } @@ -555,7 +543,6 @@ class Config if (!$targets) { return $this; } - foreach ($targets as $target) { $sources = $this->getXpath((string)$target['extends']); if ($sources) { @@ -584,11 +571,11 @@ class Config /** * Enter description here... * - * @param \Magento\Framework\Simplexml\Config $config + * @param Config $config * @param boolean $overwrite * @return $this */ - public function extend(\Magento\Framework\Simplexml\Config $config, $overwrite = true) + public function extend(Config $config, $overwrite = true) { $this->getNode()->extend($config->getNode(), $overwrite); return $this; diff --git a/lib/internal/Magento/Framework/Simplexml/Config/Cache/AbstractCache.php b/lib/internal/Magento/Framework/Simplexml/Config/Cache/AbstractCache.php index a423f4a68c5ca567ac9c4b28bca7345626bee643..7ec8e191b0609adefee753e28ad4bd1b20cfa796 100644 --- a/lib/internal/Magento/Framework/Simplexml/Config/Cache/AbstractCache.php +++ b/lib/internal/Magento/Framework/Simplexml/Config/Cache/AbstractCache.php @@ -26,12 +26,15 @@ namespace Magento\Framework\Simplexml\Config\Cache; /** * Abstract class for configuration cache + * @method void setComponents(array $components) + * @method void setIsAllowedToSave(bool $isAllowedToSave) + * @method array getComponents() */ abstract class AbstractCache extends \Magento\Framework\Object { /** * Constructor - * + * * Initializes components and allows to save the cache * * @param array $data @@ -72,7 +75,7 @@ abstract class AbstractCache extends \Magento\Framework\Object if (empty($data) || !is_array($data)) { return false; } - // check that no source files were changed or check file exsists + // check that no source files were changed or check file exists foreach ($data as $sourceFile => $stat) { if (empty($stat['mtime']) || !is_file($sourceFile) || filemtime($sourceFile) !== $stat['mtime']) { return false; @@ -93,4 +96,14 @@ abstract class AbstractCache extends \Magento\Framework\Object $hash = md5($sum); return $hash; } + + /** + * @return bool + */ + abstract public function load(); + + /** + * @return bool + */ + abstract public function save(); } diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/DateTime.php b/lib/internal/Magento/Framework/Stdlib/DateTime/DateTime.php index 938a79672962bdad837547bf70fdbaa55c8271cd..92b1f1e35ffb176b556f709017abaae644706cdb 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/DateTime.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/DateTime.php @@ -21,13 +21,14 @@ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ + +namespace Magento\Framework\Stdlib\DateTime; + /** * Date conversion model * - * @author Magento Core Team <core@magentocommerce.com> + * @author Magento Core Team <core@magentocommerce.com> */ -namespace Magento\Framework\Stdlib\DateTime; - class DateTime { /** @@ -38,14 +39,14 @@ class DateTime private $_offset = 0; /** - * @var \Magento\Framework\Stdlib\DateTime\TimezoneInterface + * @var TimezoneInterface */ protected $_localeDate; /** - * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate + * @param TimezoneInterface $localeDate */ - public function __construct(\Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate) + public function __construct(TimezoneInterface $localeDate) { $this->_localeDate = $localeDate; $this->_offset = $this->calculateOffset($this->_localeDate->getConfigTimezone()); @@ -61,15 +62,15 @@ class DateTime { $result = true; $offset = 0; - if (!is_null($timezone)) { - $oldzone = @date_default_timezone_get(); + if ($timezone !== null) { + $oldZone = @date_default_timezone_get(); $result = date_default_timezone_set($timezone); } if ($result === true) { $offset = gmmktime(0, 0, 0, 1, 2, 1970) - mktime(0, 0, 0, 1, 2, 1970); } - if (!is_null($timezone)) { - date_default_timezone_set($oldzone); + if ($timezone !== null) { + date_default_timezone_set($oldZone); } return $offset; } @@ -83,7 +84,7 @@ class DateTime */ public function gmtDate($format = null, $input = null) { - if (is_null($format)) { + if ($format === null) { $format = 'Y-m-d H:i:s'; } $date = $this->gmtTimestamp($input); @@ -104,7 +105,7 @@ class DateTime */ public function date($format = null, $input = null) { - if (is_null($format)) { + if ($format === null) { $format = 'Y-m-d H:i:s'; } $result = date($format, $this->timestamp($input)); @@ -119,14 +120,12 @@ class DateTime */ public function gmtTimestamp($input = null) { - if (is_null($input)) { + if ($input === null) { return gmdate('U'); + } elseif (is_numeric($input)) { + $result = $input; } else { - if (is_numeric($input)) { - $result = $input; - } else { - $result = strtotime($input); - } + $result = strtotime($input); } if ($result === false) { // strtotime() unable to parse string (it's not a date or has incorrect format) @@ -147,14 +146,12 @@ class DateTime */ public function timestamp($input = null) { - if (is_null($input)) { + if ($input === null) { $result = $this->gmtTimestamp(); + } elseif (is_numeric($input)) { + $result = $input; } else { - if (is_numeric($input)) { - $result = $input; - } else { - $result = strtotime($input); - } + $result = strtotime($input); } $date = $this->_localeDate->date($result); $timestamp = $date->get(\Zend_Date::TIMESTAMP) + $date->get(\Zend_Date::TIMEZONE_SECS); diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php index eb8a3a4ed755fbfe8f6cd05f1b5cdde9dc091c8e..5e611157f0311c9a5d89640949232e0751b3f853 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php @@ -54,7 +54,7 @@ class Timezone implements TimezoneInterface protected $_dateTime; /** - * @var \Magento\Framework\Stdlib\DateTime\DateFactory + * @var DateFactory */ protected $_dateFactory; @@ -72,7 +72,7 @@ class Timezone implements TimezoneInterface * @param \Magento\Framework\App\ScopeResolverInterface $scopeResolver * @param \Magento\Framework\Locale\ResolverInterface $localeResolver * @param \Magento\Framework\Stdlib\DateTime $dateTime - * @param \Magento\Framework\Stdlib\DateTime\DateFactory $dateFactory + * @param DateFactory $dateFactory * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param string $scopeType * @param string $defaultTimezonePath @@ -198,20 +198,17 @@ class Timezone implements TimezoneInterface /** * {@inheritdoc} */ - public function formatDate( - $date = null, - $format = \Magento\Framework\Stdlib\DateTime\TimezoneInterface::FORMAT_TYPE_SHORT, - $showTime = false - ) { + public function formatDate($date = null, $format = TimezoneInterface::FORMAT_TYPE_SHORT, $showTime = false) + { if (!in_array($format, $this->_allowedFormats, true)) { return $date; } - if (!$date instanceof \Magento\Framework\Stdlib\DateTime\DateInterface && $date && !strtotime($date)) { + if (!$date instanceof DateInterface && $date && !strtotime($date)) { return ''; } if (is_null($date)) { $date = $this->date(gmdate('U'), null, null); - } elseif (!$date instanceof \Magento\Framework\Stdlib\DateTime\DateInterface) { + } elseif (!$date instanceof DateInterface) { $date = $this->date(strtotime($date), null, null); } @@ -227,11 +224,8 @@ class Timezone implements TimezoneInterface /** * {@inheritdoc} */ - public function formatTime( - $time = null, - $format = \Magento\Framework\Stdlib\DateTime\TimezoneInterface::FORMAT_TYPE_SHORT, - $showDate = false - ) { + public function formatTime($time = null, $format = TimezoneInterface::FORMAT_TYPE_SHORT, $showDate = false) + { if (!in_array($format, $this->_allowedFormats, true)) { return $time; } @@ -304,11 +298,11 @@ class Timezone implements TimezoneInterface } /** - * Returns a localized information string, supported are several types of informations. + * Returns a localized information string, supported are several types of information. * For detailed information about the types look into the documentation * - * @param string $value Name to get detailed information about - * @param string $path (Optional) Type of information to return + * @param string $value Name to get detailed information about + * @param string $path (Optional) Type of information to return * @return string|false The wished information in the given language */ protected function _getTranslation($value = null, $path = null) diff --git a/lib/internal/Magento/Framework/Stdlib/String.php b/lib/internal/Magento/Framework/Stdlib/String.php index 3b3a0840242b05f59479519ae4e2e2be09bde9c1..852bf99d3b1f5e56906b4d13bc65afd019c434c1 100644 --- a/lib/internal/Magento/Framework/Stdlib/String.php +++ b/lib/internal/Magento/Framework/Stdlib/String.php @@ -62,14 +62,8 @@ class String foreach ($str as $part) { if ($this->strlen($part) >= $length) { $lastDelimiter = $this->strpos($this->strrev($part), $needle); - $tmpNewStr = $this->substr( - $this->strrev($part), - 0, - $lastDelimiter - ) . $insert . $this->substr( - $this->strrev($part), - $lastDelimiter - ); + $tmpNewStr = $this->substr($this->strrev($part), 0, $lastDelimiter) . $insert + . $this->substr($this->strrev($part), $lastDelimiter); $newStr .= $this->strrev($tmpNewStr); } else { $newStr .= $part; diff --git a/lib/internal/Magento/Framework/Translate.php b/lib/internal/Magento/Framework/Translate.php index 6dd0d97c7a04e1470579e0f868ac2d51e0103ed2..1bc59d063528e29c5f0f852478e604718733155d 100644 --- a/lib/internal/Magento/Framework/Translate.php +++ b/lib/internal/Magento/Framework/Translate.php @@ -59,13 +59,6 @@ class Translate implements \Magento\Framework\TranslateInterface */ protected $_data = []; - /** - * Translation data for data scope (per module) - * - * @var array - */ - protected $_dataScope; - /** * @var \Magento\Framework\View\DesignInterface */ @@ -199,10 +192,10 @@ class Translate implements \Magento\Framework\TranslateInterface } $this->_data = []; - $this->_loadModuleTranslation($forceReload); - $this->_loadThemeTranslation($forceReload); - $this->_loadPackTranslation($forceReload); - $this->_loadDbTranslation($forceReload); + $this->_loadModuleTranslation(); + $this->_loadThemeTranslation(); + $this->_loadPackTranslation(); + $this->_loadDbTranslation(); if (!$forceReload) { $this->_saveCache(); @@ -260,14 +253,13 @@ class Translate implements \Magento\Framework\TranslateInterface /** * Load data from module translation files * - * @param bool $forceReload * @return $this */ - protected function _loadModuleTranslation($forceReload = false) + protected function _loadModuleTranslation() { foreach ($this->_moduleList->getModules() as $module) { $moduleFilePath = $this->_getModuleTranslationFile($module['name'], $this->getLocale()); - $this->_addData($this->_getFileData($moduleFilePath), false, $forceReload); + $this->_addData($this->_getFileData($moduleFilePath)); } return $this; } @@ -276,11 +268,9 @@ class Translate implements \Magento\Framework\TranslateInterface * Adding translation data * * @param array $data - * @param string|bool $scope - * @param boolean $forceReload * @return $this */ - protected function _addData($data, $scope = false, $forceReload = false) + protected function _addData($data) { foreach ($data as $key => $value) { if ($key === $value) { @@ -290,23 +280,7 @@ class Translate implements \Magento\Framework\TranslateInterface $key = str_replace('""', '"', $key); $value = str_replace('""', '"', $value); - if ($scope && isset($this->_dataScope[$key]) && !$forceReload) { - /** - * Checking previous value - */ - $scopeKey = $this->_dataScope[$key] . '::' . $key; - if (!isset($this->_data[$scopeKey])) { - if (isset($this->_data[$key])) { - $this->_data[$scopeKey] = $this->_data[$key]; - unset($this->_data[$key]); - } - } - $scopeKey = $scope . '::' . $key; - $this->_data[$scopeKey] = $value; - } else { - $this->_data[$key] = $value; - $this->_dataScope[$key] = $scope; - } + $this->_data[$key] = $value; } return $this; } @@ -314,10 +288,9 @@ class Translate implements \Magento\Framework\TranslateInterface /** * Load current theme translation * - * @param bool $forceReload * @return $this */ - protected function _loadThemeTranslation($forceReload = false) + protected function _loadThemeTranslation() { if (!$this->_config['theme']) { return $this; @@ -325,7 +298,7 @@ class Translate implements \Magento\Framework\TranslateInterface $file = $this->_getThemeTranslationFile($this->getLocale()); if ($file) { - $this->_addData($this->_getFileData($file), 'theme' . $this->_config['theme'], $forceReload); + $this->_addData($this->_getFileData($file)); } return $this; } @@ -333,25 +306,23 @@ class Translate implements \Magento\Framework\TranslateInterface /** * Load translation dictionary from language packages * - * @param bool $forceReload * @return void */ - protected function _loadPackTranslation($forceReload = false) + protected function _loadPackTranslation() { $data = $this->packDictionary->getDictionary($this->getLocale()); - $this->_addData($data, 'language_pack', $forceReload); + $this->_addData($data); } /** * Loading current translation from DB * - * @param bool $forceReload * @return $this */ - protected function _loadDbTranslation($forceReload = false) + protected function _loadDbTranslation() { - $arr = $this->_translateResource->getTranslationArray(null, $this->getLocale()); - $this->_addData($arr, $this->getConfig('scope'), $forceReload); + $data = $this->_translateResource->getTranslationArray(null, $this->getLocale()); + $this->_addData($data); return $this; } diff --git a/lib/internal/Magento/Framework/View/BlockPool.php b/lib/internal/Magento/Framework/View/BlockPool.php index 4304fc712e1f815f08819e823f26fb2864749609..836d6a6cd7bb249c46011176ff9fb56921300e4a 100644 --- a/lib/internal/Magento/Framework/View/BlockPool.php +++ b/lib/internal/Magento/Framework/View/BlockPool.php @@ -49,12 +49,10 @@ class BlockPool /** * Constructor * - * @param ObjectManager $objectManager * @param BlockFactory $blockFactory */ - public function __construct(ObjectManager $objectManager, BlockFactory $blockFactory) + public function __construct(BlockFactory $blockFactory) { - $this->objectManager = $objectManager; $this->blockFactory = $blockFactory; } diff --git a/lib/internal/Magento/Framework/View/Config.php b/lib/internal/Magento/Framework/View/Config.php index 3a89069eb38f4ce0e65b33f53272ed0aedcce6b0..4550ec84ed4ec43215b668bed544e8e6191308c8 100644 --- a/lib/internal/Magento/Framework/View/Config.php +++ b/lib/internal/Magento/Framework/View/Config.php @@ -123,17 +123,15 @@ class Config implements \Magento\Framework\View\ConfigInterface $configFiles = $this->moduleReader->getConfigurationFiles(basename($this->filename))->toArray(); $themeConfigFile = $currentTheme->getCustomization()->getCustomViewConfigPath(); - if (empty($themeConfigFile) || !$this->rootDirectory->isExist( - $this->rootDirectory->getRelativePath($themeConfigFile) - ) + if (empty($themeConfigFile) + || !$this->rootDirectory->isExist($this->rootDirectory->getRelativePath($themeConfigFile)) ) { $themeConfigFile = $this->viewFileSystem->getFilename($this->filename, $params); } - if ($themeConfigFile && $this->rootDirectory->isExist($this->rootDirectory->getRelativePath($themeConfigFile)) + if ($themeConfigFile + && $this->rootDirectory->isExist($this->rootDirectory->getRelativePath($themeConfigFile)) ) { - $configFiles[$this->rootDirectory->getRelativePath( - $themeConfigFile - )] = $this->rootDirectory->readFile( + $configFiles[$this->rootDirectory->getRelativePath($themeConfigFile)] = $this->rootDirectory->readFile( $this->rootDirectory->getRelativePath($themeConfigFile) ); } diff --git a/lib/internal/Magento/Framework/View/DataSourcePool.php b/lib/internal/Magento/Framework/View/DataSourcePool.php index c7816c71eace7c66f5bcf83b1ffe82649bf66613..853bc8ccc7ac3c7640835b3bfda701a58a340ddc 100644 --- a/lib/internal/Magento/Framework/View/DataSourcePool.php +++ b/lib/internal/Magento/Framework/View/DataSourcePool.php @@ -74,7 +74,7 @@ class DataSourcePool if (!isset($this->dataSources[$name])) { if (!class_exists($class)) { - throw new \Exception(__('Invalid Data Source class name: ' . $class)); + throw new \InvalidArgumentException(__('Invalid Data Source class name: ' . $class)); } $data = $this->blockFactory->createBlock($class); diff --git a/lib/internal/Magento/Framework/View/Element/Html/Link.php b/lib/internal/Magento/Framework/View/Element/Html/Link.php index a43e5a7310ed1fe7772c6c26318484f21bab4241..4d20cd83789ef705f0c309fa25de1a0a6925a851 100644 --- a/lib/internal/Magento/Framework/View/Element/Html/Link.php +++ b/lib/internal/Magento/Framework/View/Element/Html/Link.php @@ -32,6 +32,40 @@ namespace Magento\Framework\View\Element\Html; */ class Link extends \Magento\Framework\View\Element\Template { + /** + * @var array + */ + protected $allowedAttributes = [ + 'href', + 'title', + 'charset', + 'name', + 'hreflang', + 'rel', + 'rev', + 'accesskey', + 'shape', + 'coords', + 'tabindex', + 'onfocus', + 'onblur', // %attrs + 'id', + 'class', + 'style', // %coreattrs + 'lang', + 'dir', // %i18n + 'onclick', + 'ondblclick', + 'onmousedown', + 'onmouseup', + 'onmouseover', + 'onmousemove', + 'onmouseout', + 'onkeypress', + 'onkeydown', + 'onkeyup' // %events + ]; + /** * Prepare link attributes as serialized and formatted string * @@ -39,39 +73,8 @@ class Link extends \Magento\Framework\View\Element\Template */ public function getLinkAttributes() { - $allow = array( - 'href', - 'title', - 'charset', - 'name', - 'hreflang', - 'rel', - 'rev', - 'accesskey', - 'shape', - 'coords', - 'tabindex', - 'onfocus', - 'onblur', // %attrs - 'id', - 'class', - 'style', // %coreattrs - 'lang', - 'dir', // %i18n - 'onclick', - 'ondblclick', - 'onmousedown', - 'onmouseup', - 'onmouseover', - 'onmousemove', - 'onmouseout', - 'onkeypress', - 'onkeydown', - 'onkeyup' // %events - ); - $attributes = array(); - foreach ($allow as $attribute) { + foreach ($this->allowedAttributes as $attribute) { $value = $this->getDataUsingMethod($attribute); if (!is_null($value)) { $attributes[$attribute] = $this->escapeHtml($value); diff --git a/lib/internal/Magento/Framework/View/Element/Messages.php b/lib/internal/Magento/Framework/View/Element/Messages.php index ff69cc22da9064931d0395774cb084870a01f542..a97804ec2de2d5c9d796d2aab120a469c022a495 100644 --- a/lib/internal/Magento/Framework/View/Element/Messages.php +++ b/lib/internal/Magento/Framework/View/Element/Messages.php @@ -179,7 +179,7 @@ class Messages extends Template * @param MessageInterface $message * @return $this */ - public function addMessage(\Magento\Framework\Message\AbstractMessage $message) + public function addMessage(MessageInterface $message) { $this->getMessageCollection()->addMessage($message); return $this; diff --git a/lib/internal/Magento/Framework/View/Layout.php b/lib/internal/Magento/Framework/View/Layout.php index bc1f5cb3e11b66376c5565a9fb2fe4af1e52dcbf..bb55c22db1266e320f6ae8140debae8dc564756c 100644 --- a/lib/internal/Magento/Framework/View/Layout.php +++ b/lib/internal/Magento/Framework/View/Layout.php @@ -110,7 +110,7 @@ class Layout extends \Magento\Framework\Simplexml\Config implements \Magento\Fra * * @var \Magento\Framework\Object */ - protected $_renderingOutput = null; + protected $_renderingOutput; /** * Cache of generated elements' HTML @@ -1490,14 +1490,14 @@ class Layout extends \Magento\Framework\Simplexml\Config implements \Magento\Fra * Get block singleton * * @param string $type - * @throws \Magento\Framework\Model\Exception * @return \Magento\Framework\App\Helper\AbstractHelper + * @throws \Magento\Framework\Model\Exception */ public function getBlockSingleton($type) { if (!isset($this->_helpers[$type])) { if (!$type) { - throw new \Magento\Framework\Model\Exception(__('Invalid block type: %1', $type)); + throw new \Magento\Framework\Model\Exception('Invalid block type'); } $helper = $this->_blockFactory->createBlock($type); @@ -1532,12 +1532,6 @@ class Layout extends \Magento\Framework\Simplexml\Config implements \Magento\Fra */ public function addAdjustableRenderer($namespace, $staticType, $dynamicType, $type, $template, $data = array()) { - if (!isset($namespace)) { - $this->_renderers[$namespace] = array(); - } - if (!isset($namespace)) { - $this->_renderers[$namespace][$staticType] = array(); - } $this->_renderers[$namespace][$staticType][$dynamicType] = array( 'type' => $type, 'template' => $template, @@ -1578,18 +1572,11 @@ class Layout extends \Magento\Framework\Simplexml\Config implements \Magento\Fra if ($options = $this->getRendererOptions($namespace, $staticType, $dynamicType)) { $dictionary = array(); /** @var $block \Magento\Framework\View\Element\Template */ - $block = $this->createBlock( - $options['type'], - '' - )->setData( - $data - )->assign( - $dictionary - )->setTemplate( - $options['template'] - )->assign( - $data - ); + $block = $this->createBlock($options['type'], '') + ->setData($data) + ->assign($dictionary) + ->setTemplate($options['template']) + ->assign($data); echo $this->_renderBlock($block->getNameInLayout()); } diff --git a/lib/internal/Magento/Framework/View/LayoutFactory.php b/lib/internal/Magento/Framework/View/LayoutFactory.php index 13dc969b7cf854961f3e5a675fe547d8fee844f4..d06d3fe114ccf241ec7c8cc64690073168cdeef5 100644 --- a/lib/internal/Magento/Framework/View/LayoutFactory.php +++ b/lib/internal/Magento/Framework/View/LayoutFactory.php @@ -61,9 +61,14 @@ class LayoutFactory * * @param array $data * @return LayoutInterface + * @throws \InvalidArgumentException */ public function create(array $data = array()) { - return $this->_objectManager->create($this->_instanceName, $data); + $layout = $this->_objectManager->create($this->_instanceName, $data); + if (!$layout instanceof LayoutInterface) { + throw new \InvalidArgumentException(get_class($layout) . ' must be an instance of LayoutInterface.'); + } + return $layout; } } diff --git a/lib/internal/Magento/Framework/View/Render/RenderFactory.php b/lib/internal/Magento/Framework/View/Render/RenderFactory.php index 9d32bd67aadf20ba7b273bb269c514fb7567c672..67dcb382fc069ee784a21c58ee498ce9e11864e1 100644 --- a/lib/internal/Magento/Framework/View/Render/RenderFactory.php +++ b/lib/internal/Magento/Framework/View/Render/RenderFactory.php @@ -59,13 +59,11 @@ class RenderFactory { $className = 'Magento\\Framework\\View\\Render\\' . ucfirst($type); $model = $this->objectManager->get($className); - - if ($model instanceof RenderInterface === false) { + if (!$model instanceof RenderInterface) { throw new \InvalidArgumentException( - sprintf('Type "%s" is not instance on Magento\Framework\View\RenderInterface', $type) + 'Type "' . $type . '" is not instance on Magento\Framework\View\RenderInterface' ); } - return $model; } } diff --git a/lib/web/css/docs/source/rating.less b/lib/web/css/docs/source/rating.less index 83f8acd1755ba9ae0cba89336e784f9b0bede582..42bcc57ea92d1dcde592b4dcf4826c2e65483887 100644 --- a/lib/web/css/docs/source/rating.less +++ b/lib/web/css/docs/source/rating.less @@ -24,7 +24,7 @@ // # Ratings // -// Ratings styling mixins are based on using font icons as rate symbols. There are two types of ratings: rating which allows user to vote and rating which displays voting results summary. Depending on the rating type mixin <code>.rating-vote()</code> or <code>.rating-summary()</code> is used. +// Ratings styling mixins are based on using font icons as rate symbols. There are two types of ratings: rating which allows user to vote and rating which displays voting results summary. Depending on the rating type mixin <code>.mixin-rating-vote()</code> or <code>.mixin-rating-summary()</code> is used. // // # Global rating variables // @@ -91,7 +91,7 @@ // # Rating with vote // -// To implement rating with vote, use the <code>.rating-vote()</code> mixin. +// To implement rating with vote, use the <code>.mixin-rating-vote()</code> mixin. // ``` html // <div class="rating vote example-ratings-1"> // <input type="radio" name="rating-price" id="rating-price-1" value="1" /> @@ -118,7 +118,7 @@ // ``` .example-ratings-1 { - .rating-vote(); + .mixin-rating-vote(); } // # Rating with vote icons number customization @@ -163,7 +163,7 @@ // ``` .example-ratings-2 { - .rating-vote( + .mixin-rating-vote( @_icon-count: 8 ); } @@ -202,7 +202,7 @@ // ``` .example-ratings-3 { - .rating-vote( + .mixin-rating-vote( @_icon-color: #aff5e3, @_icon-color-active: #0a6767 ); @@ -238,7 +238,7 @@ // ``` .example-ratings-4 { - .rating-vote( + .mixin-rating-vote( @_icon-content: @icon-wishlist-full ); } @@ -279,7 +279,7 @@ .exapmle-ratings-5 { .control.rating.vote { - .rating-vote(); + .mixin-rating-vote(); } } @@ -289,14 +289,14 @@ // ``` html // <div class="example-rating-summary-1"> // <span class="label"><span>Rating</span></span> -// <div class="rating result" title="60%"> +// <div class="rating-result" title="60%"> // <span style="width:60%"><span>60</span></span> // </div> // </div> // ``` .example-rating-summary-1 { - .rating-summary(); + .mixin-rating-summary(); } // # Rating summary icons number customization @@ -309,14 +309,14 @@ // ``` html // <div class="example-rating-summary-2"> // <span class="label"><span>Rating</span></span> -// <div class="rating result" title="40%"> +// <div class="rating-result" title="40%"> // <span style="width:40%"><span>40</span></span> // </div> // </div> // ``` .example-rating-summary-2 { - .rating-summary( + .mixin-rating-summary( @_icon-count: 8 ); } @@ -332,14 +332,14 @@ // ``` html // <div class="example-rating-summary-3"> // <span class="label"><span>Rating</span></span> -// <div class="rating result" title="40%"> +// <div class="rating-result" title="40%"> // <span style="width:40%"><span>40</span></span> // </div> // </div> // ``` .example-rating-summary-3 { - .rating-summary( + .mixin-rating-summary( @_icon-color: #aff5e3, @_icon-color-active: #0a6767 ); @@ -355,14 +355,14 @@ // ``` html // <div class="example-rating-summary-4"> // <span class="label"><span>Rating</span></span> -// <div class="rating result" title="40%"> +// <div class="rating-result" title="40%"> // <span style="width:40%"><span>40</span></span> // </div> // </div> // ``` .example-rating-summary-4 { - .rating-summary( + .mixin-rating-summary( @_icon-content: @icon-wishlist-full ); } @@ -377,14 +377,14 @@ // ``` html // <div class="example-rating-summary-5"> // <span class="label"><span>Rating</span></span> -// <div class="rating result" title="40%"> +// <div class="rating-result" title="40%"> // <span style="width:40%"><span>40</span></span> // </div> // </div> // ``` .example-rating-summary-5 { - .rating-summary( + .mixin-rating-summary( @_label-hide: true ); } @@ -394,27 +394,27 @@ // ``` html // <div class="example-rating-summary-6" tabindex="1"> // <strong>Your Rating:</strong> -// <div class="rating summary item"> +// <div class="rating-summary item"> // <span class="label"><span>Value</span></span> -// <div class="rating result" title="100%" > +// <div class="rating-result" title="100%" > // <span style="width:100%"><span>100%</span></span> // </div> // </div> -// <div class="rating summary item"> +// <div class="rating-summary item"> // <span class="label"><span>Quality</span></span> -// <div class="rating result" title="100%"> +// <div class="rating-result" title="100%"> // <span style="width:100%"><span>100%</span></span> // </div> // </div> -// <div class="rating summary item"> +// <div class="rating-summary item"> // <span class="label"><span>rating +</span></span> -// <div class="rating result" title="20%"> +// <div class="rating-result" title="20%"> // <span style="width:20%"><span>20%</span></span> // </div> // </div> -// <div class="rating summary item"> +// <div class="rating-summary item"> // <span class="label"><span>Price</span></span> -// <div class="rating result" title="40%"> +// <div class="rating-result" title="40%"> // <span style="width:40%"><span>40%</span></span> // </div> // </div> @@ -422,25 +422,25 @@ // ``` .example-rating-summary-6 { - .rating.summary { - .rating-summary(); + .rating-summary { + .mixin-rating-summary(); } } // # Rating hide label mixin // -// The <code>.rating-summary-label-hide()</code> mixin is used to hide rating label in summary rating. +// The <code>.mixin-rating-summary-label-hide()</code> mixin is used to hide rating label in summary rating. // // ``` html // <div class="example-rating-summary-7"> // <span class="label"><span>Rating</span></span> -// <div class="rating result" title="40%"> +// <div class="rating-result" title="40%"> // <span style="width:40%"><span>40</span></span> // </div> // </div> // ``` .example-rating-summary-7 { - .rating-summary(); - .rating-summary-label-hide(); + .mixin-rating-summary(); + .mixin-rating-summary-label-hide(); } diff --git a/lib/web/css/docs/source/variables.less b/lib/web/css/docs/source/variables.less index 3b353807a9d2341b16e875a6fddd30d2717d5bb1..9bb7bf08304def493d7fac3518ec787a7016562a 100644 --- a/lib/web/css/docs/source/variables.less +++ b/lib/web/css/docs/source/variables.less @@ -4975,7 +4975,7 @@ // </pre> // // ## Rating variables -// #### The <code>.rating-vote()</code> and <code>.rating-summary()</code> mixin variables +// #### The <code>.mixin-rating-vote()</code> and <code>.mixin-rating-summary()</code> mixin variables // // <pre> // <table> diff --git a/lib/web/css/source/lib/rating.less b/lib/web/css/source/lib/rating.less index cf088fea4a2388a3254aaebd74877e8727a608c3..896bc218770f6c19b4dc901c31ed7cf2f2838747 100644 --- a/lib/web/css/source/lib/rating.less +++ b/lib/web/css/source/lib/rating.less @@ -23,7 +23,7 @@ // */ // rating-vote mixin -.rating-vote( +.mixin-rating-vote( @_icon-count: @rating-icon-count, @_icon-content: @rating-icon-content, @_icon-font: @rating-icon-font, @@ -40,7 +40,7 @@ @_icon-letter-spacing, @_icon-color ); - ._rating-icons-content( + .mixin-rating-icons-content( @_icon-count, @_icon-content ); @@ -93,7 +93,7 @@ } // rating-summary mixin -.rating-summary( +.mixin-rating-summary( @_icon-count: @rating-icon-count, @_icon-content: @rating-icon-content, @_icon-font: @rating-icon-font, @@ -105,8 +105,8 @@ ) { overflow: hidden; ._rating-label-hide(@_label-hide); - .rating.result { - width: (@_icon-font-size * @_icon-count) - (abs(@_icon-letter-spacing) * (@_icon-count - 1)); + .rating-result { + width: (@_icon-font-size * @_icon-count) + ceil(@_icon-letter-spacing * (@_icon-count - 1)); &:before { position: absolute; z-index: 1; @@ -150,7 +150,7 @@ } } -.rating-summary-label-hide() { +.mixin-rating-summary-label-hide() { .label { .visually-hidden(); } @@ -158,7 +158,7 @@ // Internal use mixins ._rating-label-hide(@_label-hide) when (@_label-hide = true) { - .rating-summary-label-hide(); + .mixin-rating-summary-label-hide(); } ._rating-iteration( @@ -169,7 +169,7 @@ .rating-@{_index} { z-index: @_icon-count - (@_index - 2); &:before { - ._rating-icons-content(@_index, @_icon-content); + .mixin-rating-icons-content(@_index, @_icon-content); } } // next iteration @@ -195,6 +195,7 @@ font-weight: normal; -webkit-font-smoothing: antialiased; color: @_icon-color; + vertical-align: top; } ._rating-summary-icon-default( @@ -207,7 +208,7 @@ ) { display: block; font-family: @_icon-font; - ._rating-icons-content(@_icon-count, @_icon-content); + .mixin-rating-icons-content(@_icon-count, @_icon-content); font-style: normal; font-size: @_icon-font-size; line-height: @_icon-font-size; @@ -219,70 +220,70 @@ color: @_icon-color; } -._rating-icons-content( +.mixin-rating-icons-content( @_icon-count: @rating-icon-count, @_icon-content: @rating-icon-content ) when (@_icon-count = 10) { content: @_icon-content @_icon-content @_icon-content @_icon-content @_icon-content @_icon-content @_icon-content @_icon-content @_icon-content @_icon-content; } -._rating-icons-content( +.mixin-rating-icons-content( @_icon-count: @rating-icon-count, @_icon-content: @rating-icon-content ) when (@_icon-count = 9) { content: @_icon-content @_icon-content @_icon-content @_icon-content @_icon-content @_icon-content @_icon-content @_icon-content @_icon-content; } -._rating-icons-content( +.mixin-rating-icons-content( @_icon-count: @rating-icon-count, @_icon-content: @rating-icon-content ) when (@_icon-count = 8) { content: @_icon-content @_icon-content @_icon-content @_icon-content @_icon-content @_icon-content @_icon-content @_icon-content; } -._rating-icons-content( +.mixin-rating-icons-content( @_icon-count: @rating-icon-count, @_icon-content: @rating-icon-content ) when (@_icon-count = 7) { content: @_icon-content @_icon-content @_icon-content @_icon-content @_icon-content @_icon-content @_icon-content; } -._rating-icons-content( +.mixin-rating-icons-content( @_icon-count: @rating-icon-count, @_icon-content: @rating-icon-content ) when (@_icon-count = 6) { content: @_icon-content @_icon-content @_icon-content @_icon-content @_icon-content @_icon-content; } -._rating-icons-content( +.mixin-rating-icons-content( @_icon-count: @rating-icon-count, @_icon-content: @rating-icon-content ) when (@_icon-count = 5) { content: @_icon-content @_icon-content @_icon-content @_icon-content @_icon-content; } -._rating-icons-content( +.mixin-rating-icons-content( @_icon-count: @rating-icon-count, @_icon-content: @rating-icon-content ) when (@_icon-count = 4) { content: @_icon-content @_icon-content @_icon-content @_icon-content; } -._rating-icons-content( +.mixin-rating-icons-content( @_icon-count: @rating-icon-count, @_icon-content: @rating-icon-content ) when (@_icon-count = 3) { content: @_icon-content @_icon-content @_icon-content; } -._rating-icons-content( +.mixin-rating-icons-content( @_icon-count: @rating-icon-count, @_icon-content: @rating-icon-content ) when (@_icon-count = 2) { content: @_icon-content @_icon-content; } -._rating-icons-content( +.mixin-rating-icons-content( @_icon-count: @rating-icon-count, @_icon-content: @rating-icon-content ) when (@_icon-count = 1) { diff --git a/lib/web/css/source/lib/responsive.less b/lib/web/css/source/lib/responsive.less index 7282ffdf5981dd50df663b2f32af76a6561ef5dd..ac1a4d76ec00628263ca32aa2f809ce4919fcebb 100644 --- a/lib/web/css/source/lib/responsive.less +++ b/lib/web/css/source/lib/responsive.less @@ -23,12 +23,16 @@ // */ // Small screens only -.responsive-smaller(@break-point-0) {}; +.responsive-smaller(@break-point-0) {} @media all and (max-width: @break-point-0) { .responsive-smaller(@break-point-0); } +@media all and (max-width: @break-point-1) { + .responsive-smaller(@break-point-1); +} + @media all and (min-width: @break-point-0) { .responsive(@break-point-0); } diff --git a/lib/web/css/source/lib/tables.less b/lib/web/css/source/lib/tables.less index a1e228d46f2d548dfbeb4c222061886359bc9109..cfa03de00b2f9482a6a687c5fc2fc291cca61c5a 100644 --- a/lib/web/css/source/lib/tables.less +++ b/lib/web/css/source/lib/tables.less @@ -30,7 +30,7 @@ ) { border-collapse: collapse; border-spacing: 0; - .css(margin-bottom, @table-margin-bottom); + .css(margin-bottom, @_table-margin-bottom); max-width: 100%; .css(width, @_table-width); th { @@ -57,7 +57,7 @@ > tr { > th, > td { - padding: @_cell-padding-vertical @_cell-padding-horizontal; + .css(padding, @_cell-padding-vertical @_cell-padding-horizontal); } } } @@ -112,18 +112,18 @@ @_table-td-bg: @table-td-bg, @_table-body-th-bg: @table-body-th-bg ) { - .add-background(@_table-bg); + .css(background, @_table-bg); > thead { - .add-background(@_table-head-bg); + .css(background, @_table-head-bg); } > tfoot { - .add-background(@_table-foot-bg); + .css(background, @_table-foot-bg); } > tbody > tr > td { - .add-background(@_table-td-bg); + .css(background, @_table-td-bg); } > tbody > tr >th { - .add-background(@_table-body-th-bg); + .css(background, @_table-body-th-bg); } } @@ -142,10 +142,10 @@ > tfoot { > tr { > td { - padding: @_td-padding-top @_td-padding-right @_td-padding-bottom @_td-padding-left; + .css(padding, @_td-padding-top @_td-padding-right @_td-padding-bottom @_td-padding-left); } > th { - padding: @_th-padding-top @_th-padding-right @_th-padding-bottom @_th-padding-left; + .css(padding, @_th-padding-top @_th-padding-right @_th-padding-bottom @_th-padding-left); } } } @@ -157,14 +157,14 @@ @_border-style: @table-border-style, @_border-color: @table-border-color ) when (@_type = normal){ - border: @_border-width @_border-style @_border-color; + .css(border, @_border-width @_border-style @_border-color); > thead, > tbody, > tfoot { > tr { > th, > td { - border: @_border-width @_border-style @_border-color; + .css(border, @_border-width @_border-style @_border-color); } } } @@ -182,7 +182,7 @@ > tr { > th, > td { - border-top: @table-border-width @table-border-style @table-border-color; + .css(border-top, @_border-width @_border-style @_border-color); } } } @@ -197,7 +197,7 @@ } } > tbody + tbody { - border-top: @table-border-width @table-border-style darken(@table-border-color, 25% ); + .css(border-top, @_border-width @_border-style @_border-color); } } @@ -213,7 +213,7 @@ > tr { > th, > td { - border-left: @table-border-width @table-border-style @table-border-color; + .css(border-left, @_border-width @_border-style @_border-color); &:first-child { border-left: none; } @@ -243,7 +243,7 @@ > tr { > th, > td { - border-bottom: @_border-width @_border-style @_border-color; + .css(border-bottom, @_border-width @_border-style @_border-color); } } } @@ -277,8 +277,8 @@ > tbody > tr:nth-child(odd) { > td, > th { - .add-background(@_stripped-bg); - color: @_stripped-color; + .css(background, @_stripped-bg); + .css(color, @_stripped-color); } } } @@ -292,8 +292,8 @@ > tbody > tr:nth-child(even) { > td, > th { - .add-background(@_stripped-bg); - color: @_stripped-color; + .css(background, @_stripped-bg); + .css(color, @_stripped-color); } } } @@ -310,8 +310,8 @@ > tr { > th:nth-child(odd), > td:nth-child(odd) { - .add-background(@_stripped-bg); - color: @_stripped-color; + .css(background, @_stripped-bg); + .css(color, @_stripped-color); } } } @@ -329,8 +329,8 @@ > tr { > th:nth-child(even), > td:nth-child(even) { - .add-background(@_stripped-bg); - .add-color(@_stripped-color) + .css(background, @_stripped-bg); + .css(color, @_stripped-color); } } } @@ -343,13 +343,13 @@ > tbody > tr:nth-child(even):hover { > td, > th { - .add-background(@_cell-bg-hover); + .css(background, @_cell-bg-hover); } } > tbody > tr:nth-child(odd):hover { > td, > th { - .add-background(@_cell-odd-bg-hover) + .css(background, @_cell-odd-bg-hover); } } } @@ -368,7 +368,7 @@ > tr { > th, > td { - white-space: nowrap; + //white-space: nowrap; } } } @@ -383,7 +383,7 @@ ) when (@_reset-table-striped = false) and (@_reset-table-hover = false){ ._responsive-table(@_table-bg-responsive: @_table-bg-responsive); > tbody > tr > th { - background-color: @_table-th-bg-responsive; + .css(background-color, @_table-th-bg-responsive); } } @@ -412,7 +412,7 @@ ) when (@_reset-table-striped = true) and (@_reset-table-hover = false){ .table-striped(@_stripped-bg: @_table-bg-responsive); ._responsive-table(@_table-bg-responsive: @_table-bg-responsive); - background-color: @_table-th-bg-responsive; + .css(background-color, @_table-th-bg-responsive); } .table-responsive( @@ -452,9 +452,9 @@ @_table-caption-line-height, @_table-caption-font-style ); - text-align: @_table-caption-alignment; - margin-top: @_table-caption-margin-top; - margin-bottom: @_table-caption-margin-bottom; + .css(text-align, @_table-caption-alignment); + .css(margin-top, @_table-caption-margin-top); + .css(margin-bottom, @_table-caption-margin-bottom); } } @@ -477,7 +477,7 @@ ._responsive-table(@_table-bg-responsive: @_table-bg-responsive) { border: none; - .add-background(@_table-bg-responsive); + .css(background, @_table-bg-responsive); > thead > tr > th { display: none; } @@ -488,9 +488,9 @@ padding: (@table-cell-padding-vertical / 2) @table-cell-padding-horizontal; border-bottom: none; &:before { - content: attr(data-th)": "; + content: attr(data-th)""; display: inline-block; - padding-right: @table-cell-padding-horizontal; + .css(padding-right, @table-cell-padding-horizontal); .typography ( @_font-size: @table-th-font-size, @_color: @table-th-color, @@ -503,7 +503,7 @@ } } > tbody > tr > td { - .add-background(@_table-bg-responsive); + .css(background, @_table-bg-responsive); } > tfoot > tr > { td, diff --git a/lib/web/css/source/lib/variables.less b/lib/web/css/source/lib/variables.less index 52ae6ed1e44bd80f5cd8750997940c7b0b5b5dda..1242f524db35f91e4a985880623d1784e48c3882 100644 --- a/lib/web/css/source/lib/variables.less +++ b/lib/web/css/source/lib/variables.less @@ -233,7 +233,7 @@ //-------------------------------------- @table-width: 100%; @table-margin-bottom: false; -@table-bg: transparent; +@table-bg: false; @table-head-bg: @table-bg; @table-foot-bg: @table-bg; @table-td-bg: @table-bg; @@ -249,34 +249,34 @@ @table-caption-hide: false; //Default value false, set true to hide caption @table-caption-font-size: @font-size-l; @table-caption-color: @text-color-intense; -@table-caption-font-family: @font-family-base; -@table-caption-font-weight: @font-weight-base; -@table-caption-font-style: @font-style-base; -@table-caption-line-height: @line-height-base; +@table-caption-font-family: false; +@table-caption-font-weight: false; +@table-caption-font-style: false; +@table-caption-line-height: false; @table-caption-alignment: left; @table-caption-margin-top: @indent-base; @table-caption-margin-bottom: @indent-s-base; -@table-td-font-size: @font-size-base; -@table-td-color: @text-color; -@table-td-font-family: @font-family-base; -@table-td-font-weight: @font-weight-base; -@table-td-line-height: @line-height-base; -@table-td-font-style: @font-style-base; +@table-td-font-size: false; +@table-td-color: false; +@table-td-font-family: false; +@table-td-font-weight: false; +@table-td-line-height: false; +@table-td-font-style: false; -@table-th-font-size: @font-size-base; +@table-th-font-size: false; @table-th-color: @text-color-intense; -@table-th-font-family: @font-family-base; +@table-th-font-family: false; @table-th-font-weight: @font-weight-bold; -@table-th-line-height: @line-height-base; -@table-th-font-style: @font-style-base; +@table-th-line-height: false; +@table-th-font-style: false; @table-cell-bg-stripped: lighten(@table-cell-bg-hover, 15%); @table-cell-bg-hover: @panel-bg; @table-cell-color-stripped: @table-td-color; @table-bg-responsive: @table-bg; -@table-th-bg-responsive: @table-cell-bg-stripped; +@table-th-bg-responsive: false; // // Page layout variables diff --git a/lib/web/jquery/jquery.mobile.custom.js b/lib/web/jquery/jquery.mobile.custom.js new file mode 100644 index 0000000000000000000000000000000000000000..f289b97b91d832621770f1cc56a54c04e1dd567d --- /dev/null +++ b/lib/web/jquery/jquery.mobile.custom.js @@ -0,0 +1,864 @@ +/* +* jQuery Mobile v1.4.3 +* http://jquerymobile.com +* +* Copyright 2010, 2014 jQuery Foundation, Inc. and other contributors +* Released under the MIT license. +* http://jquery.org/license +* +*/ + +(function ( root, doc, factory ) { + if ( typeof define === "function" && define.amd ) { + // AMD. Register as an anonymous module. + define( [ "jquery" ], function ( $ ) { + factory( $, root, doc ); + return $.mobile; + }); + } else { + // Browser globals + factory( root.jQuery, root, doc ); + } +}( this, document, function ( jQuery, window, document, undefined ) {// This plugin is an experiment for abstracting away the touch and mouse +// events so that developers don't have to worry about which method of input +// the device their document is loaded on supports. +// +// The idea here is to allow the developer to register listeners for the +// basic mouse events, such as mousedown, mousemove, mouseup, and click, +// and the plugin will take care of registering the correct listeners +// behind the scenes to invoke the listener at the fastest possible time +// for that device, while still retaining the order of event firing in +// the traditional mouse environment, should multiple handlers be registered +// on the same element for different events. +// +// The current version exposes the following virtual events to jQuery bind methods: +// "vmouseover vmousedown vmousemove vmouseup vclick vmouseout vmousecancel" + +(function( $, window, document, undefined ) { + +var dataPropertyName = "virtualMouseBindings", + touchTargetPropertyName = "virtualTouchID", + virtualEventNames = "vmouseover vmousedown vmousemove vmouseup vclick vmouseout vmousecancel".split( " " ), + touchEventProps = "clientX clientY pageX pageY screenX screenY".split( " " ), + mouseHookProps = $.event.mouseHooks ? $.event.mouseHooks.props : [], + mouseEventProps = $.event.props.concat( mouseHookProps ), + activeDocHandlers = {}, + resetTimerID = 0, + startX = 0, + startY = 0, + didScroll = false, + clickBlockList = [], + blockMouseTriggers = false, + blockTouchTriggers = false, + eventCaptureSupported = "addEventListener" in document, + $document = $( document ), + nextTouchID = 1, + lastTouchID = 0, threshold, + i; + +$.vmouse = { + moveDistanceThreshold: 10, + clickDistanceThreshold: 10, + resetTimerDuration: 1500 +}; + +function getNativeEvent( event ) { + + while ( event && typeof event.originalEvent !== "undefined" ) { + event = event.originalEvent; + } + return event; +} + +function createVirtualEvent( event, eventType ) { + + var t = event.type, + oe, props, ne, prop, ct, touch, i, j, len; + + event = $.Event( event ); + event.type = eventType; + + oe = event.originalEvent; + props = $.event.props; + + // addresses separation of $.event.props in to $.event.mouseHook.props and Issue 3280 + // https://github.com/jquery/jquery-mobile/issues/3280 + if ( t.search( /^(mouse|click)/ ) > -1 ) { + props = mouseEventProps; + } + + // copy original event properties over to the new event + // this would happen if we could call $.event.fix instead of $.Event + // but we don't have a way to force an event to be fixed multiple times + if ( oe ) { + for ( i = props.length, prop; i; ) { + prop = props[ --i ]; + event[ prop ] = oe[ prop ]; + } + } + + // make sure that if the mouse and click virtual events are generated + // without a .which one is defined + if ( t.search(/mouse(down|up)|click/) > -1 && !event.which ) { + event.which = 1; + } + + if ( t.search(/^touch/) !== -1 ) { + ne = getNativeEvent( oe ); + t = ne.touches; + ct = ne.changedTouches; + touch = ( t && t.length ) ? t[0] : ( ( ct && ct.length ) ? ct[ 0 ] : undefined ); + + if ( touch ) { + for ( j = 0, len = touchEventProps.length; j < len; j++) { + prop = touchEventProps[ j ]; + event[ prop ] = touch[ prop ]; + } + } + } + + return event; +} + +function getVirtualBindingFlags( element ) { + + var flags = {}, + b, k; + + while ( element ) { + + b = $.data( element, dataPropertyName ); + + for ( k in b ) { + if ( b[ k ] ) { + flags[ k ] = flags.hasVirtualBinding = true; + } + } + element = element.parentNode; + } + return flags; +} + +function getClosestElementWithVirtualBinding( element, eventType ) { + var b; + while ( element ) { + + b = $.data( element, dataPropertyName ); + + if ( b && ( !eventType || b[ eventType ] ) ) { + return element; + } + element = element.parentNode; + } + return null; +} + +function enableTouchBindings() { + blockTouchTriggers = false; +} + +function disableTouchBindings() { + blockTouchTriggers = true; +} + +function enableMouseBindings() { + lastTouchID = 0; + clickBlockList.length = 0; + blockMouseTriggers = false; + + // When mouse bindings are enabled, our + // touch bindings are disabled. + disableTouchBindings(); +} + +function disableMouseBindings() { + // When mouse bindings are disabled, our + // touch bindings are enabled. + enableTouchBindings(); +} + +function startResetTimer() { + clearResetTimer(); + resetTimerID = setTimeout( function() { + resetTimerID = 0; + enableMouseBindings(); + }, $.vmouse.resetTimerDuration ); +} + +function clearResetTimer() { + if ( resetTimerID ) { + clearTimeout( resetTimerID ); + resetTimerID = 0; + } +} + +function triggerVirtualEvent( eventType, event, flags ) { + var ve; + + if ( ( flags && flags[ eventType ] ) || + ( !flags && getClosestElementWithVirtualBinding( event.target, eventType ) ) ) { + + ve = createVirtualEvent( event, eventType ); + + $( event.target).trigger( ve ); + } + + return ve; +} + +function mouseEventCallback( event ) { + var touchID = $.data( event.target, touchTargetPropertyName ), + ve; + + if ( !blockMouseTriggers && ( !lastTouchID || lastTouchID !== touchID ) ) { + ve = triggerVirtualEvent( "v" + event.type, event ); + if ( ve ) { + if ( ve.isDefaultPrevented() ) { + event.preventDefault(); + } + if ( ve.isPropagationStopped() ) { + event.stopPropagation(); + } + if ( ve.isImmediatePropagationStopped() ) { + event.stopImmediatePropagation(); + } + } + } +} + +function handleTouchStart( event ) { + + var touches = getNativeEvent( event ).touches, + target, flags, t; + + if ( touches && touches.length === 1 ) { + + target = event.target; + flags = getVirtualBindingFlags( target ); + + if ( flags.hasVirtualBinding ) { + + lastTouchID = nextTouchID++; + $.data( target, touchTargetPropertyName, lastTouchID ); + + clearResetTimer(); + + disableMouseBindings(); + didScroll = false; + + t = getNativeEvent( event ).touches[ 0 ]; + startX = t.pageX; + startY = t.pageY; + + triggerVirtualEvent( "vmouseover", event, flags ); + triggerVirtualEvent( "vmousedown", event, flags ); + } + } +} + +function handleScroll( event ) { + if ( blockTouchTriggers ) { + return; + } + + if ( !didScroll ) { + triggerVirtualEvent( "vmousecancel", event, getVirtualBindingFlags( event.target ) ); + } + + didScroll = true; + startResetTimer(); +} + +function handleTouchMove( event ) { + if ( blockTouchTriggers ) { + return; + } + + var t = getNativeEvent( event ).touches[ 0 ], + didCancel = didScroll, + moveThreshold = $.vmouse.moveDistanceThreshold, + flags = getVirtualBindingFlags( event.target ); + + didScroll = didScroll || + ( Math.abs( t.pageX - startX ) > moveThreshold || + Math.abs( t.pageY - startY ) > moveThreshold ); + + if ( didScroll && !didCancel ) { + triggerVirtualEvent( "vmousecancel", event, flags ); + } + + triggerVirtualEvent( "vmousemove", event, flags ); + startResetTimer(); +} + +function handleTouchEnd( event ) { + if ( blockTouchTriggers ) { + return; + } + + disableTouchBindings(); + + var flags = getVirtualBindingFlags( event.target ), + ve, t; + triggerVirtualEvent( "vmouseup", event, flags ); + + if ( !didScroll ) { + ve = triggerVirtualEvent( "vclick", event, flags ); + if ( ve && ve.isDefaultPrevented() ) { + // The target of the mouse events that follow the touchend + // event don't necessarily match the target used during the + // touch. This means we need to rely on coordinates for blocking + // any click that is generated. + t = getNativeEvent( event ).changedTouches[ 0 ]; + clickBlockList.push({ + touchID: lastTouchID, + x: t.clientX, + y: t.clientY + }); + + // Prevent any mouse events that follow from triggering + // virtual event notifications. + blockMouseTriggers = true; + } + } + triggerVirtualEvent( "vmouseout", event, flags); + didScroll = false; + + startResetTimer(); +} + +function hasVirtualBindings( ele ) { + var bindings = $.data( ele, dataPropertyName ), + k; + + if ( bindings ) { + for ( k in bindings ) { + if ( bindings[ k ] ) { + return true; + } + } + } + return false; +} + +function dummyMouseHandler() {} + +function getSpecialEventObject( eventType ) { + var realType = eventType.substr( 1 ); + + return { + setup: function(/* data, namespace */) { + // If this is the first virtual mouse binding for this element, + // add a bindings object to its data. + + if ( !hasVirtualBindings( this ) ) { + $.data( this, dataPropertyName, {} ); + } + + // If setup is called, we know it is the first binding for this + // eventType, so initialize the count for the eventType to zero. + var bindings = $.data( this, dataPropertyName ); + bindings[ eventType ] = true; + + // If this is the first virtual mouse event for this type, + // register a global handler on the document. + + activeDocHandlers[ eventType ] = ( activeDocHandlers[ eventType ] || 0 ) + 1; + + if ( activeDocHandlers[ eventType ] === 1 ) { + $document.bind( realType, mouseEventCallback ); + } + + // Some browsers, like Opera Mini, won't dispatch mouse/click events + // for elements unless they actually have handlers registered on them. + // To get around this, we register dummy handlers on the elements. + + $( this ).bind( realType, dummyMouseHandler ); + + // For now, if event capture is not supported, we rely on mouse handlers. + if ( eventCaptureSupported ) { + // If this is the first virtual mouse binding for the document, + // register our touchstart handler on the document. + + activeDocHandlers[ "touchstart" ] = ( activeDocHandlers[ "touchstart" ] || 0) + 1; + + if ( activeDocHandlers[ "touchstart" ] === 1 ) { + $document.bind( "touchstart", handleTouchStart ) + .bind( "touchend", handleTouchEnd ) + + // On touch platforms, touching the screen and then dragging your finger + // causes the window content to scroll after some distance threshold is + // exceeded. On these platforms, a scroll prevents a click event from being + // dispatched, and on some platforms, even the touchend is suppressed. To + // mimic the suppression of the click event, we need to watch for a scroll + // event. Unfortunately, some platforms like iOS don't dispatch scroll + // events until *AFTER* the user lifts their finger (touchend). This means + // we need to watch both scroll and touchmove events to figure out whether + // or not a scroll happenens before the touchend event is fired. + + .bind( "touchmove", handleTouchMove ) + .bind( "scroll", handleScroll ); + } + } + }, + + teardown: function(/* data, namespace */) { + // If this is the last virtual binding for this eventType, + // remove its global handler from the document. + + --activeDocHandlers[ eventType ]; + + if ( !activeDocHandlers[ eventType ] ) { + $document.unbind( realType, mouseEventCallback ); + } + + if ( eventCaptureSupported ) { + // If this is the last virtual mouse binding in existence, + // remove our document touchstart listener. + + --activeDocHandlers[ "touchstart" ]; + + if ( !activeDocHandlers[ "touchstart" ] ) { + $document.unbind( "touchstart", handleTouchStart ) + .unbind( "touchmove", handleTouchMove ) + .unbind( "touchend", handleTouchEnd ) + .unbind( "scroll", handleScroll ); + } + } + + var $this = $( this ), + bindings = $.data( this, dataPropertyName ); + + // teardown may be called when an element was + // removed from the DOM. If this is the case, + // jQuery core may have already stripped the element + // of any data bindings so we need to check it before + // using it. + if ( bindings ) { + bindings[ eventType ] = false; + } + + // Unregister the dummy event handler. + + $this.unbind( realType, dummyMouseHandler ); + + // If this is the last virtual mouse binding on the + // element, remove the binding data from the element. + + if ( !hasVirtualBindings( this ) ) { + $this.removeData( dataPropertyName ); + } + } + }; +} + +// Expose our custom events to the jQuery bind/unbind mechanism. + +for ( i = 0; i < virtualEventNames.length; i++ ) { + $.event.special[ virtualEventNames[ i ] ] = getSpecialEventObject( virtualEventNames[ i ] ); +} + +// Add a capture click handler to block clicks. +// Note that we require event capture support for this so if the device +// doesn't support it, we punt for now and rely solely on mouse events. +if ( eventCaptureSupported ) { + document.addEventListener( "click", function( e ) { + var cnt = clickBlockList.length, + target = e.target, + x, y, ele, i, o, touchID; + + if ( cnt ) { + x = e.clientX; + y = e.clientY; + threshold = $.vmouse.clickDistanceThreshold; + + // The idea here is to run through the clickBlockList to see if + // the current click event is in the proximity of one of our + // vclick events that had preventDefault() called on it. If we find + // one, then we block the click. + // + // Why do we have to rely on proximity? + // + // Because the target of the touch event that triggered the vclick + // can be different from the target of the click event synthesized + // by the browser. The target of a mouse/click event that is synthesized + // from a touch event seems to be implementation specific. For example, + // some browsers will fire mouse/click events for a link that is near + // a touch event, even though the target of the touchstart/touchend event + // says the user touched outside the link. Also, it seems that with most + // browsers, the target of the mouse/click event is not calculated until the + // time it is dispatched, so if you replace an element that you touched + // with another element, the target of the mouse/click will be the new + // element underneath that point. + // + // Aside from proximity, we also check to see if the target and any + // of its ancestors were the ones that blocked a click. This is necessary + // because of the strange mouse/click target calculation done in the + // Android 2.1 browser, where if you click on an element, and there is a + // mouse/click handler on one of its ancestors, the target will be the + // innermost child of the touched element, even if that child is no where + // near the point of touch. + + ele = target; + + while ( ele ) { + for ( i = 0; i < cnt; i++ ) { + o = clickBlockList[ i ]; + touchID = 0; + + if ( ( ele === target && Math.abs( o.x - x ) < threshold && Math.abs( o.y - y ) < threshold ) || + $.data( ele, touchTargetPropertyName ) === o.touchID ) { + // XXX: We may want to consider removing matches from the block list + // instead of waiting for the reset timer to fire. + e.preventDefault(); + e.stopPropagation(); + return; + } + } + ele = ele.parentNode; + } + } + }, true); +} +})( jQuery, window, document ); + +(function( $ ) { + $.mobile = {}; +}( jQuery )); + + (function( $, undefined ) { + var support = { + touch: "ontouchend" in document + }; + + $.mobile.support = $.mobile.support || {}; + $.extend( $.support, support ); + $.extend( $.mobile.support, support ); + }( jQuery )); + + +(function( $, window, undefined ) { + var $document = $( document ), + supportTouch = $.mobile.support.touch, + scrollEvent = "touchmove scroll", + touchStartEvent = supportTouch ? "touchstart" : "mousedown", + touchStopEvent = supportTouch ? "touchend" : "mouseup", + touchMoveEvent = supportTouch ? "touchmove" : "mousemove"; + + // setup new event shortcuts + $.each( ( "touchstart touchmove touchend " + + "tap taphold " + + "swipe swipeleft swiperight " + + "scrollstart scrollstop" ).split( " " ), function( i, name ) { + + $.fn[ name ] = function( fn ) { + return fn ? this.bind( name, fn ) : this.trigger( name ); + }; + + // jQuery < 1.8 + if ( $.attrFn ) { + $.attrFn[ name ] = true; + } + }); + + function triggerCustomEvent( obj, eventType, event, bubble ) { + var originalType = event.type; + event.type = eventType; + if ( bubble ) { + $.event.trigger( event, undefined, obj ); + } else { + $.event.dispatch.call( obj, event ); + } + event.type = originalType; + } + + // also handles scrollstop + $.event.special.scrollstart = { + + enabled: true, + setup: function() { + + var thisObject = this, + $this = $( thisObject ), + scrolling, + timer; + + function trigger( event, state ) { + scrolling = state; + triggerCustomEvent( thisObject, scrolling ? "scrollstart" : "scrollstop", event ); + } + + // iPhone triggers scroll after a small delay; use touchmove instead + $this.bind( scrollEvent, function( event ) { + + if ( !$.event.special.scrollstart.enabled ) { + return; + } + + if ( !scrolling ) { + trigger( event, true ); + } + + clearTimeout( timer ); + timer = setTimeout( function() { + trigger( event, false ); + }, 50 ); + }); + }, + teardown: function() { + $( this ).unbind( scrollEvent ); + } + }; + + // also handles taphold + $.event.special.tap = { + tapholdThreshold: 750, + emitTapOnTaphold: true, + setup: function() { + var thisObject = this, + $this = $( thisObject ), + isTaphold = false; + + $this.bind( "vmousedown", function( event ) { + isTaphold = false; + if ( event.which && event.which !== 1 ) { + return false; + } + + var origTarget = event.target, + timer; + + function clearTapTimer() { + clearTimeout( timer ); + } + + function clearTapHandlers() { + clearTapTimer(); + + $this.unbind( "vclick", clickHandler ) + .unbind( "vmouseup", clearTapTimer ); + $document.unbind( "vmousecancel", clearTapHandlers ); + } + + function clickHandler( event ) { + clearTapHandlers(); + + // ONLY trigger a 'tap' event if the start target is + // the same as the stop target. + if ( !isTaphold && origTarget === event.target ) { + triggerCustomEvent( thisObject, "tap", event ); + } else if ( isTaphold ) { + event.preventDefault(); + } + } + + $this.bind( "vmouseup", clearTapTimer ) + .bind( "vclick", clickHandler ); + $document.bind( "vmousecancel", clearTapHandlers ); + + timer = setTimeout( function() { + if ( !$.event.special.tap.emitTapOnTaphold ) { + isTaphold = true; + } + triggerCustomEvent( thisObject, "taphold", $.Event( "taphold", { target: origTarget } ) ); + }, $.event.special.tap.tapholdThreshold ); + }); + }, + teardown: function() { + $( this ).unbind( "vmousedown" ).unbind( "vclick" ).unbind( "vmouseup" ); + $document.unbind( "vmousecancel" ); + } + }; + + // Also handles swipeleft, swiperight + $.event.special.swipe = { + + // More than this horizontal displacement, and we will suppress scrolling. + scrollSupressionThreshold: 30, + + // More time than this, and it isn't a swipe. + durationThreshold: 1000, + + // Swipe horizontal displacement must be more than this. + horizontalDistanceThreshold: 30, + + // Swipe vertical displacement must be less than this. + verticalDistanceThreshold: 30, + + getLocation: function ( event ) { + var winPageX = window.pageXOffset, + winPageY = window.pageYOffset, + x = event.clientX, + y = event.clientY; + + if ( event.pageY === 0 && Math.floor( y ) > Math.floor( event.pageY ) || + event.pageX === 0 && Math.floor( x ) > Math.floor( event.pageX ) ) { + + // iOS4 clientX/clientY have the value that should have been + // in pageX/pageY. While pageX/page/ have the value 0 + x = x - winPageX; + y = y - winPageY; + } else if ( y < ( event.pageY - winPageY) || x < ( event.pageX - winPageX ) ) { + + // Some Android browsers have totally bogus values for clientX/Y + // when scrolling/zooming a page. Detectable since clientX/clientY + // should never be smaller than pageX/pageY minus page scroll + x = event.pageX - winPageX; + y = event.pageY - winPageY; + } + + return { + x: x, + y: y + }; + }, + + start: function( event ) { + var data = event.originalEvent.touches ? + event.originalEvent.touches[ 0 ] : event, + location = $.event.special.swipe.getLocation( data ); + return { + time: ( new Date() ).getTime(), + coords: [ location.x, location.y ], + origin: $( event.target ) + }; + }, + + stop: function( event ) { + var data = event.originalEvent.touches ? + event.originalEvent.touches[ 0 ] : event, + location = $.event.special.swipe.getLocation( data ); + return { + time: ( new Date() ).getTime(), + coords: [ location.x, location.y ] + }; + }, + + handleSwipe: function( start, stop, thisObject, origTarget ) { + if ( stop.time - start.time < $.event.special.swipe.durationThreshold && + Math.abs( start.coords[ 0 ] - stop.coords[ 0 ] ) > $.event.special.swipe.horizontalDistanceThreshold && + Math.abs( start.coords[ 1 ] - stop.coords[ 1 ] ) < $.event.special.swipe.verticalDistanceThreshold ) { + var direction = start.coords[0] > stop.coords[ 0 ] ? "swipeleft" : "swiperight"; + + triggerCustomEvent( thisObject, "swipe", $.Event( "swipe", { target: origTarget, swipestart: start, swipestop: stop }), true ); + triggerCustomEvent( thisObject, direction,$.Event( direction, { target: origTarget, swipestart: start, swipestop: stop } ), true ); + return true; + } + return false; + + }, + + // This serves as a flag to ensure that at most one swipe event event is + // in work at any given time + eventInProgress: false, + + setup: function() { + var events, + thisObject = this, + $this = $( thisObject ), + context = {}; + + // Retrieve the events data for this element and add the swipe context + events = $.data( this, "mobile-events" ); + if ( !events ) { + events = { length: 0 }; + $.data( this, "mobile-events", events ); + } + events.length++; + events.swipe = context; + + context.start = function( event ) { + + // Bail if we're already working on a swipe event + if ( $.event.special.swipe.eventInProgress ) { + return; + } + $.event.special.swipe.eventInProgress = true; + + var stop, + start = $.event.special.swipe.start( event ), + origTarget = event.target, + emitted = false; + + context.move = function( event ) { + if ( !start ) { + return; + } + + stop = $.event.special.swipe.stop( event ); + if ( !emitted ) { + emitted = $.event.special.swipe.handleSwipe( start, stop, thisObject, origTarget ); + if ( emitted ) { + + // Reset the context to make way for the next swipe event + $.event.special.swipe.eventInProgress = false; + } + } + // prevent scrolling + if ( Math.abs( start.coords[ 0 ] - stop.coords[ 0 ] ) > $.event.special.swipe.scrollSupressionThreshold ) { + event.preventDefault(); + } + }; + + context.stop = function() { + emitted = true; + + // Reset the context to make way for the next swipe event + $.event.special.swipe.eventInProgress = false; + $document.off( touchMoveEvent, context.move ); + context.move = null; + }; + + $document.on( touchMoveEvent, context.move ) + .one( touchStopEvent, context.stop ); + }; + $this.on( touchStartEvent, context.start ); + }, + + teardown: function() { + var events, context; + + events = $.data( this, "mobile-events" ); + if ( events ) { + context = events.swipe; + delete events.swipe; + events.length--; + if ( events.length === 0 ) { + $.removeData( this, "mobile-events" ); + } + } + + if ( context ) { + if ( context.start ) { + $( this ).off( touchStartEvent, context.start ); + } + if ( context.move ) { + $document.off( touchMoveEvent, context.move ); + } + if ( context.stop ) { + $document.off( touchStopEvent, context.stop ); + } + } + } + }; + $.each({ + scrollstop: "scrollstart", + taphold: "tap", + swipeleft: "swipe.left", + swiperight: "swipe.right" + }, function( event, sourceEvent ) { + + $.event.special[ event ] = { + setup: function() { + $( this ).bind( sourceEvent, $.noop ); + }, + teardown: function() { + $( this ).unbind( sourceEvent ); + } + }; + }); + +})( jQuery, this ); + + +})); diff --git a/lib/web/mage/backend/form.js b/lib/web/mage/backend/form.js index 11691e056b3949d01c01294917ba8d744604074a..38f638e272bc5a7636c42147a60d770623724581 100644 --- a/lib/web/mage/backend/form.js +++ b/lib/web/mage/backend/form.js @@ -109,7 +109,7 @@ _storeAttribute: function(attrName) { this.oldAttributes = this.oldAttributes || {}; if (!this.oldAttributes[attrName]) { - var prop = this.element.prop(attrName); + var prop = this.element.attr(attrName); this.oldAttributes[attrName] = prop ? prop : ''; } }, diff --git a/lib/web/mage/loader.js b/lib/web/mage/loader.js index 07d9694c2b90a5ec4b17f27c6f3efbdbca665f34..9c7e78ee8e98f6f2a6fe530404adc99436403d29 100644 --- a/lib/web/mage/loader.js +++ b/lib/web/mage/loader.js @@ -27,7 +27,7 @@ loaderStarted: 0, spinnerTemplate: $(undefined), options: { - icon: 'icon.gif', + icon: '', texts: { loaderText: $.mage.__('Please wait...'), imgAlt: $.mage.__('Loading...') @@ -142,7 +142,8 @@ */ $.widget("mage.loaderAjax", { options: { - defaultContainer: '[data-container=body]' + defaultContainer: '[data-container=body]', + loadingClass: 'ajax-loading' }, _create: function() { this._bind(); @@ -173,6 +174,8 @@ return ctx; }, _onAjaxSend: function(e, jqxhr, settings) { + $(this.options.defaultContainer).addClass(this.options.loadingClass); + if (settings && settings.showLoader) { var ctx = this._getJqueryObj(settings.loaderContext); ctx.trigger('processStart'); @@ -186,6 +189,7 @@ } }, _onAjaxComplete: function(e, jqxhr, settings) { + $(this.options.defaultContainer).removeClass(this.options.loadingClass); if (settings && settings.showLoader) { this._getJqueryObj(settings.loaderContext).trigger('processStop'); } diff --git a/lib/web/mage/menu.js b/lib/web/mage/menu.js index f03f72041b5f594d28b2f9c6ffb92e1ae81ccd61..b43685a1eb0bbfdca519360424b7af1fb4e0902c 100644 --- a/lib/web/mage/menu.js +++ b/lib/web/mage/menu.js @@ -53,12 +53,29 @@ }); } - $('.action.toggle.nav').on('click', function() { - $('.page-wrapper').toggleClass('open'); - $('body').toggleClass('open'); - $('html').toggleClass('open'); - }); + this._assignControls()._listen(); + }, + + _assignControls: function() { + this.controls = { + toggleBtn: $('[data-action="toggle-nav"]'), + swipeArea: $('.panel.wrapper'), + wrapper: $('.page-wrapper') + }; + + return this; + }, + + _listen: function() { + var controls = this.controls; + var toggle = this.toggle; + + this._on(controls.toggleBtn, { 'click' : toggle }); + this._on(controls.swipeArea, { 'swipeleft': toggle }); + }, + toggle: function() { + this.controls.wrapper.toggleClass('open'); }, //Add class for expanded option diff --git a/lib/web/mage/validation.js b/lib/web/mage/validation.js index 9e7d5d8044f52164fe9123e2a48bf89ee566d30a..01d1f30e25b1ea149bbff8881685bcc6f7c299d3 100644 --- a/lib/web/mage/validation.js +++ b/lib/web/mage/validation.js @@ -545,7 +545,7 @@ }, 'Please enter a valid social security number. For example 123-45-6789.' ], - "validate-zip": [ + "validate-zip-us": [ function(v) { return $.mage.isEmptyNoTrim(v) || /(^\d{5}$)|(^\d{5}-\d{4}$)/.test(v); @@ -611,11 +611,10 @@ ], "validate-css-length": [ function(v) { - if ($.mage.isEmptyNoTrim(v)) { - return true; + if (v !== '') { + return (/^[0-9]*\.*[0-9]+(px|pc|pt|ex|em|mm|cm|in|%)?$/).test(v); } - v = $.mage.parseNumber(v); - return !isNaN(v) && v > 0; + return true; }, 'Please input a valid CSS-length. For example 100px or 77pt or 20em or .5ex or 50%.' ], diff --git a/lib/web/prototype/validation.js b/lib/web/prototype/validation.js index 798194949ad5a55b62ba77435c130f755363792d..ecee5cc3a24672025ac8f798e57a3db30ab35a59 100644 --- a/lib/web/prototype/validation.js +++ b/lib/web/prototype/validation.js @@ -621,7 +621,7 @@ Validation.addAllThese([ ['validate-ssn', 'Please enter a valid social security number. For example 123-45-6789.', function(v) { return Validation.get('IsEmpty').test(v) || /^\d{3}-?\d{2}-?\d{4}$/.test(v); }], - ['validate-zip', 'Please enter a valid zip code. For example 90602 or 90602-1234.', function(v) { + ['validate-zip-us', 'Please enter a valid zip code. For example 90602 or 90602-1234.', function(v) { return Validation.get('IsEmpty').test(v) || /(^\d{5}$)|(^\d{5}-\d{4}$)/.test(v); }], ['validate-zip-international', 'Please enter a valid zip code.', function(v) {