diff --git a/CHANGELOG.md b/CHANGELOG.md index 55f2cc4ad577c..f08223e7f01d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,67 @@ +2.0.0.0-dev79 +============= +* Tax calculation updates: + * Fixed issues in tax calculation rounding with discount applied + * Fixed an issue with extra penny when exact tax amount ended with 0.5 cent + * Fixed an issue where there were tax calculation errors when customer tax rate was different from store tax rate + * Added support to round tax at individual tax rate + * Fixed price inconsistencies between catalog and shopping cart + * Added support for maintaining consistent price including tax for customers with different tax rates + * Added support for applying tax rules with different priorities to subtotal only +* Fixed bugs: + * Removed the extra '%' sign in the error\notice message on Gift Card Accounts page on the backend + * Fixed an issue with image uploading functionality in the Catalog configuration + * Fixed an issue where a customer could not navigate the store when downloading the downloadable product + * Fixed an issue where adding CMS block Catalog Events Lister caused an error + * Fixed an issue where the price was displayed twice on the Product page on the frontend + * Fixed an issue where an admin could not open search results on the backend + * Fixed an issue where the Rule Based Product Relations functionality was generating incorrect SQL when product category attribute was set through "is one of" or "contains" operator by constant value + * Fixed an issue where it was impossible to add a product to the Compare list for categories with three-column page layout + * Fixed an issue where a blank page opened when changing store view on a product page on the frontend + * Fixed an issue where the "Please specify at least one search term." error message was not displayed if search is performed without search data specified on the frontend + * Fixed a Google Chrome specific issue where page layout was broken when updating status for reviews on the backend + * Fixed admin look and feel issues + * Fixed an issue where the order notices and error messages were not red + * Fixed a UI issue which appeared during custom attribute creation + * Fixed an issue where the popup did not open after clicking What's this? next to the Remember Me check box when persistent shopping cart was enabled + * Fixed an issue where the options of the Add Product split dropdown did not fit the page + * Fixed an issue where the default theme preview image sample link was missing + * Fixed a Safari and Internet Explorer 9 specific issue where the backend menu is not displayed for users with custom admin roles + * Fixed an issue where the price of bundle products was not displayed correctly on the product page on the frontend + * Fixed a UI issue in the debug mode configuration + * Fixed minor issues with page layout + * Fixed an issue where the mini shopping cart loaded data from cache + * Fixed an issue where there was an incorrect value in the Grand Total (Base) column in the Orders grid if Catalog Price Scope was set to Website + * Fixed an issue where the Entity Generator tool did not accept the "class" parameter + * Fixed an issue where the default email template was not applied when the custom template in use was deleted + * Fixed an issue where shipping price for flat rate was set to 0 in the side block during checkout of a product with a configured recurring profile + * Fixed an issue where it was possible to create more Shipping Labels than there were products in the shipment + * Fixed an issue where data about "SHA-IN Pass Phrase" was missing after changing "Payment Action" in the Ogone payment method configuration + * Fixed performance issues with reindexing of the Price indexer + * Fixed an issue where importing tax rates with postal code = * led to incorrect data entered into database + * Fixed an issue where incorrect link to reset password was sent if secure URL was used on the frontend + * Fixed an issue where the Links section was absent while editing downloadable products from the Wishlist + * Fixed an issue where specified details for composite products were lost after adding to Gift Card and Downloadable products to the Wishlist + * Fixed and issue where the Date widget was set to incorrect date when creating a new customer + * Fixed an issue where a customer was redirected to Dashboard if the Redirect user to dashboard after login option was set to ‘No’ + * Fixed an issue where a customer was not able to register during checkout if Guest Checkout was not allowed + * Fixed an issue where System logs were not generated properly in integration tests + * Fixed benchmarking script + * Fixed an issue where it was impossible to put store to the maintenance mode during backup + * Fixed insecure use of mt_rand() + * Fixed an issue where Quoted price was displayed incorrectly from the shopping cart in the backend +* Functional tests: + * Tax Rule Creation + * Admin User Roe Creation + * Simple Product Creation + * Customer Group Creation + * Update Backend Customer + * Newsletter Creation +* Updated composer.json.dist to download and install MTF from Public GitHub repository +* GitHub requests: + * [#542] (https://github.com/magento/magento2/pull/542) Fix ImportExport bug which occurs while importing multiple rows per entity + * [#507] (https://github.com/magento/magento2/issues/507) "Insert Image" window is overlapped on menu + 2.0.0.0-dev78 ============= * Fixed bugs: @@ -158,7 +222,7 @@ * `lib/Magento/Framework/Data/Form/Element/Submit.php` * `lib/Magento/Framework/Data/Form/Element/Text.php` * `lib/Magento/Framework/Data/Form/Element/Textarea.php` - + 2.0.0.0-dev75 ============= * Modularity improvements: @@ -2678,4 +2742,3 @@ Deprecated code & minor fixes update: 2.0.0.0-dev01 ============= * Added initial version of Magento 2.x CE to public repository - diff --git a/app/bootstrap.php b/app/bootstrap.php index ecc668e5d2d19..202866a451bed 100644 --- a/app/bootstrap.php +++ b/app/bootstrap.php @@ -72,9 +72,10 @@ } if (!defined('BARE_BOOTSTRAP')) { - if (file_exists(BP . '/maintenance.flag')) { - - if (!in_array($_SERVER['REMOTE_ADDR'], explode(",", file_get_contents(BP . '/maintenance.flag')))) { + $maintenanceFlag = BP . '/' . \Magento\Framework\App\State\MaintenanceMode::FLAG_DIR . '/' + . \Magento\Framework\App\State\MaintenanceMode::FLAG_FILENAME; + if (file_exists($maintenanceFlag)) { + if (!in_array($_SERVER['REMOTE_ADDR'], explode(",", file_get_contents($maintenanceFlag)))) { if (PHP_SAPI == 'cli') { echo 'Service temporarily unavailable due to maintenance downtime.'; } else { diff --git a/app/code/Magento/Backend/Block/System/Config/Form/Field/Image.php b/app/code/Magento/Backend/Block/System/Config/Form/Field/Image.php index 2d49f5d0a043f..bfac382917cba 100644 --- a/app/code/Magento/Backend/Block/System/Config/Form/Field/Image.php +++ b/app/code/Magento/Backend/Block/System/Config/Form/Field/Image.php @@ -27,6 +27,11 @@ */ namespace Magento\Backend\Block\System\Config\Form\Field; +/** + * Class Image Field + * @method getFieldConfig() + * @method setFieldConfig() + */ class Image extends \Magento\Framework\Data\Form\Element\Image { /** @@ -39,10 +44,10 @@ protected function _getUrl() $url = parent::_getUrl(); $config = $this->getFieldConfig(); /* @var $config array */ - if (array_key_exists('base_url', $config)) { + if (isset($config['base_url'])) { $element = $config['base_url']; $urlType = empty($element['type']) ? 'link' : (string)$element['type']; - $url = $this->_urlBuilder->getBaseUrl($urlType) . $element['value'] . '/' . $url; + $url = $this->_urlBuilder->getBaseUrl(['_type' => $urlType]) . $element['value'] . '/' . $url; } return $url; } diff --git a/app/code/Magento/Backend/Block/Widget/Grid/Column/Renderer/Currency.php b/app/code/Magento/Backend/Block/Widget/Grid/Column/Renderer/Currency.php index 94981c4764024..d2bf0763a0833 100644 --- a/app/code/Magento/Backend/Block/Widget/Grid/Column/Renderer/Currency.php +++ b/app/code/Magento/Backend/Block/Widget/Grid/Column/Renderer/Currency.php @@ -57,7 +57,7 @@ class Currency extends \Magento\Backend\Block\Widget\Grid\Column\Renderer\Abstra /** * @var \Magento\Directory\Model\Currency */ - protected $_baseCurrency; + protected $_defaultBaseCurrency; /** * @var \Magento\Framework\Locale\CurrencyInterface @@ -84,11 +84,11 @@ public function __construct( $this->_storeManager = $storeManager; $this->_currencyLocator = $currencyLocator; $this->_localeCurrency = $localeCurrency; - $baseCurrencyCode = $this->_scopeConfig->getValue( + $defaultBaseCurrencyCode = $this->_scopeConfig->getValue( \Magento\Directory\Model\Currency::XML_PATH_CURRENCY_BASE, 'default' ); - $this->_baseCurrency = $currencyFactory->create()->load($baseCurrencyCode); + $this->_defaultBaseCurrency = $currencyFactory->create()->load($defaultBaseCurrencyCode); } /** @@ -142,7 +142,7 @@ protected function _getRate($row) if ($rate = $row->getData($this->getColumn()->getRateField())) { return floatval($rate); } - return $this->_baseCurrency->getRate($this->_getCurrencyCode($row)); + return $this->_defaultBaseCurrency->getRate($this->_getCurrencyCode($row)); } /** diff --git a/app/code/Magento/Backend/etc/adminhtml/di.xml b/app/code/Magento/Backend/etc/adminhtml/di.xml index 056b8a58b9c1a..55d4bff058eb3 100644 --- a/app/code/Magento/Backend/etc/adminhtml/di.xml +++ b/app/code/Magento/Backend/etc/adminhtml/di.xml @@ -51,40 +51,8 @@ adminhtml - - - backend_system_configuration_structure - - - - - - Magento\Backend\Model\Config\Structure\Element\Group\Proxy - - - - - Magento\Backend\Model\Config\Structure\Search\Proxy - - - - - Magento\Backend\Model\Config\Structure\Element\Iterator\Section - - - - - Magento\Backend\Model\Config\Structure\Element\Iterator\Group - - - - - Magento\Backend\Model\Config\Structure\Element\Iterator\Field - - - adminhtml diff --git a/app/code/Magento/Backend/etc/di.xml b/app/code/Magento/Backend/etc/di.xml index 85f461366af5f..cd6813917a314 100644 --- a/app/code/Magento/Backend/etc/di.xml +++ b/app/code/Magento/Backend/etc/di.xml @@ -183,4 +183,38 @@ Magento\Backend\Model\Session\Quote\Storage + + + + + + + Magento\Backend\Model\Config\Structure\Search\Proxy + + + + + backend_system_configuration_structure + + + + + Magento\Backend\Model\Config\Structure\Element\Iterator\Section + + + + + Magento\Backend\Model\Config\Structure\Element\Iterator\Group + + + + + Magento\Backend\Model\Config\Structure\Element\Group\Proxy + + + + + Magento\Backend\Model\Config\Structure\Element\Iterator\Field + + diff --git a/app/code/Magento/Backend/view/adminhtml/page/js/calendar.phtml b/app/code/Magento/Backend/view/adminhtml/page/js/calendar.phtml index 91f134d95ff6e..0b0c8c0b660f2 100644 --- a/app/code/Magento/Backend/view/adminhtml/page/js/calendar.phtml +++ b/app/code/Magento/Backend/view/adminhtml/page/js/calendar.phtml @@ -64,7 +64,8 @@ showHour: false, showMinute: false, localTimezone: getTimezoneOffsetSeconds() ?>, - serverTimezoneSeconds:getStoreTimestamp() ?> + serverTimezoneSeconds:getStoreTimestamp() ?>, + yearRange: 'getYearRange() ?>' } }); })(jQuery); diff --git a/app/code/Magento/Backup/Controller/Adminhtml/Index.php b/app/code/Magento/Backup/Controller/Adminhtml/Index.php index 0447af34ced79..0bee25a18940e 100644 --- a/app/code/Magento/Backup/Controller/Adminhtml/Index.php +++ b/app/code/Magento/Backup/Controller/Adminhtml/Index.php @@ -52,24 +52,32 @@ class Index extends \Magento\Backend\App\Action */ protected $_backupModelFactory; + /** + * @var \Magento\Framework\App\State\MaintenanceMode + */ + protected $maintenanceMode; + /** * @param \Magento\Backend\App\Action\Context $context * @param \Magento\Framework\Registry $coreRegistry * @param \Magento\Framework\Backup\Factory $backupFactory * @param \Magento\Framework\App\Response\Http\FileFactory $fileFactory * @param \Magento\Backup\Model\BackupFactory $backupModelFactory + * @param \Magento\Framework\App\State\MaintenanceMode $maintenanceMode */ public function __construct( \Magento\Backend\App\Action\Context $context, \Magento\Framework\Registry $coreRegistry, \Magento\Framework\Backup\Factory $backupFactory, \Magento\Framework\App\Response\Http\FileFactory $fileFactory, - \Magento\Backup\Model\BackupFactory $backupModelFactory + \Magento\Backup\Model\BackupFactory $backupModelFactory, + \Magento\Framework\App\State\MaintenanceMode $maintenanceMode ) { $this->_coreRegistry = $coreRegistry; $this->_backupFactory = $backupFactory; $this->_fileFactory = $fileFactory; $this->_backupModelFactory = $backupModelFactory; + $this->maintenanceMode = $maintenanceMode; parent::__construct($context); } @@ -150,9 +158,7 @@ public function createAction() $this->_coreRegistry->register('backup_manager', $backupManager); if ($this->getRequest()->getParam('maintenance_mode')) { - $turnedOn = $helper->turnOnMaintenanceMode(); - - if (!$turnedOn) { + if (!$this->maintenanceMode->turnOn()) { $response->setError( __( 'You need more permissions to activate maintenance mode right now.' @@ -202,7 +208,7 @@ public function createAction() } if ($this->getRequest()->getParam('maintenance_mode')) { - $helper->turnOffMaintenanceMode(); + $this->maintenanceMode->turnOff(); } $this->getResponse()->setBody($response->toJson()); @@ -306,9 +312,7 @@ public function rollbackAction() } if ($this->getRequest()->getParam('maintenance_mode')) { - $turnedOn = $helper->turnOnMaintenanceMode(); - - if (!$turnedOn) { + if (!$this->maintenanceMode->turnOn()) { $response->setError( __( 'You need more permissions to activate maintenance mode right now.' @@ -373,7 +377,7 @@ public function rollbackAction() } if ($this->getRequest()->getParam('maintenance_mode')) { - $helper->turnOffMaintenanceMode(); + $this->maintenanceMode->turnOff(); } $this->getResponse()->setBody($response->toJson()); diff --git a/app/code/Magento/Backup/Helper/Data.php b/app/code/Magento/Backup/Helper/Data.php index f0811f751ee7c..faa0625d4794a 100644 --- a/app/code/Magento/Backup/Helper/Data.php +++ b/app/code/Magento/Backup/Helper/Data.php @@ -23,6 +23,8 @@ */ namespace Magento\Backup\Helper; +use Magento\Framework\App\State\MaintenanceMode; + /** * Backup data helper */ @@ -191,7 +193,7 @@ public function getBackupIgnorePaths() return array( '.git', '.svn', - 'maintenance.flag', + $this->_filesystem->getPath(MaintenanceMode::FLAG_DIR) . '/' . MaintenanceMode::FLAG_FILENAME, $this->_filesystem->getPath(\Magento\Framework\App\Filesystem::SESSION_DIR), $this->_filesystem->getPath(\Magento\Framework\App\Filesystem::CACHE_DIR), $this->_filesystem->getPath(\Magento\Framework\App\Filesystem::LOG_DIR), @@ -211,7 +213,7 @@ public function getRollbackIgnorePaths() return array( '.svn', '.git', - 'maintenance.flag', + $this->_filesystem->getPath(MaintenanceMode::FLAG_DIR) . '/' . MaintenanceMode::FLAG_FILENAME, $this->_filesystem->getPath(\Magento\Framework\App\Filesystem::SESSION_DIR), $this->_filesystem->getPath(\Magento\Framework\App\Filesystem::LOG_DIR), $this->_filesystem->getPath(\Magento\Framework\App\Filesystem::VAR_DIR) . '/locks', @@ -221,35 +223,6 @@ public function getRollbackIgnorePaths() ); } - /** - * Put store into maintenance mode - * - * @return bool - */ - public function turnOnMaintenanceMode() - { - $maintenanceFlagFile = $this->getMaintenanceFlagFilePath(); - $result = $this->_filesystem->getDirectoryWrite( - \Magento\Framework\App\Filesystem::ROOT_DIR - )->writeFile( - $maintenanceFlagFile, - 'maintenance' - ); - - return $result !== false; - } - - /** - * Turn off store maintenance mode - * - * @return void - */ - public function turnOffMaintenanceMode() - { - $maintenanceFlagFile = $this->getMaintenanceFlagFilePath(); - $this->_filesystem->getDirectoryWrite(\Magento\Framework\App\Filesystem::ROOT_DIR)->delete($maintenanceFlagFile); - } - /** * Get backup create success message by backup type * @@ -274,16 +247,6 @@ public function getCreateSuccessMessageByType($type) return $messagesMap[$type]; } - /** - * Get path to maintenance flag file - * - * @return string - */ - protected function getMaintenanceFlagFilePath() - { - return 'maintenance.flag'; - } - /** * Invalidate Cache * diff --git a/app/code/Magento/Backup/Model/Observer.php b/app/code/Magento/Backup/Model/Observer.php index 71af7b60dd733..afc884990cf82 100644 --- a/app/code/Magento/Backup/Model/Observer.php +++ b/app/code/Magento/Backup/Model/Observer.php @@ -84,6 +84,11 @@ class Observer */ protected $_backupFactory; + /** + * @var \Magento\Framework\App\State\MaintenanceMode + */ + protected $maintenanceMode; + /** * @param \Magento\Backup\Helper\Data $backupData * @param \Magento\Framework\Registry $coreRegistry @@ -91,6 +96,7 @@ class Observer * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param \Magento\Framework\App\Filesystem $filesystem * @param \Magento\Framework\Backup\Factory $backupFactory + * @param \Magento\Framework\App\State\MaintenanceMode $maintenanceMode */ public function __construct( \Magento\Backup\Helper\Data $backupData, @@ -98,7 +104,8 @@ public function __construct( \Magento\Framework\Logger $logger, \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, \Magento\Framework\App\Filesystem $filesystem, - \Magento\Framework\Backup\Factory $backupFactory + \Magento\Framework\Backup\Factory $backupFactory, + \Magento\Framework\App\State\MaintenanceMode $maintenanceMode ) { $this->_backupData = $backupData; $this->_coreRegistry = $coreRegistry; @@ -106,6 +113,7 @@ public function __construct( $this->_scopeConfig = $scopeConfig; $this->_filesystem = $filesystem; $this->_backupFactory = $backupFactory; + $this->maintenanceMode = $maintenanceMode; } /** @@ -120,7 +128,7 @@ public function scheduledBackup() } if ($this->_scopeConfig->isSetFlag(self::XML_PATH_BACKUP_MAINTENANCE_MODE, ScopeInterface::SCOPE_STORE)) { - $this->_backupData->turnOnMaintenanceMode(); + $this->maintenanceMode->turnOn(); } $type = $this->_scopeConfig->getValue(self::XML_PATH_BACKUP_TYPE, ScopeInterface::SCOPE_STORE); @@ -158,7 +166,7 @@ public function scheduledBackup() } if ($this->_scopeConfig->isSetFlag(self::XML_PATH_BACKUP_MAINTENANCE_MODE, ScopeInterface::SCOPE_STORE)) { - $this->_backupData->turnOffMaintenanceMode(); + $this->maintenanceMode->turnOff(); } return $this; diff --git a/app/code/Magento/Backup/view/adminhtml/backup/dialogs.phtml b/app/code/Magento/Backup/view/adminhtml/backup/dialogs.phtml index 65c6f0d90a243..a3d7602ce28f9 100644 --- a/app/code/Magento/Backup/view/adminhtml/backup/dialogs.phtml +++ b/app/code/Magento/Backup/view/adminhtml/backup/dialogs.phtml @@ -65,7 +65,7 @@ - diff --git a/app/code/Magento/Sales/Model/Order.php b/app/code/Magento/Sales/Model/Order.php index 176dc4ca2d1fa..c9b48275f7902 100644 --- a/app/code/Magento/Sales/Model/Order.php +++ b/app/code/Magento/Sales/Model/Order.php @@ -2464,7 +2464,7 @@ protected function _beforeSave() $this->unsShippingAddressId(); } - $this->setData('protect_code', substr(md5(uniqid(mt_rand(), true) . ':' . microtime(true)), 5, 6)); + $this->setData('protect_code', substr(md5(uniqid(\Magento\Framework\Math\Random::getRandomNumber(), true) . ':' . microtime(true)), 5, 6)); return $this; } diff --git a/app/code/Magento/Sales/view/adminhtml/layout/sales_order_grid_block.xml b/app/code/Magento/Sales/view/adminhtml/layout/sales_order_grid_block.xml index 58ac6acc42c30..3e7e62cbc8f1d 100644 --- a/app/code/Magento/Sales/view/adminhtml/layout/sales_order_grid_block.xml +++ b/app/code/Magento/Sales/view/adminhtml/layout/sales_order_grid_block.xml @@ -166,6 +166,7 @@ Grand Total (Base) currency base_currency_code + 1 base_grand_total col-gtbase col-gtbase diff --git a/app/code/Magento/Sales/view/email/shipment_new.html b/app/code/Magento/Sales/view/email/shipment_new.html index 68c65c5ebba01..4c0f8f332d606 100644 --- a/app/code/Magento/Sales/view/email/shipment_new.html +++ b/app/code/Magento/Sales/view/email/shipment_new.html @@ -96,7 +96,7 @@

Your Shipment #{{var s
{{layout handle="sales_email_order_shipment_items" shipment=$shipment order=$order}} - {{block type='Magento\\Framework\\View\\Element\\Template' area='frontend' template='Magento_Sales::email/shipment/track.phtml' shipment=$shipment order=$order}} + {{block class='Magento\\Framework\\View\\Element\\Template' area='frontend' template='Magento_Sales::email/shipment/track.phtml' shipment=$shipment order=$order}}

{{var comment}}

diff --git a/app/code/Magento/Sales/view/email/shipment_new_guest.html b/app/code/Magento/Sales/view/email/shipment_new_guest.html index e4bf8b235a3b7..334bfe7504fd7 100644 --- a/app/code/Magento/Sales/view/email/shipment_new_guest.html +++ b/app/code/Magento/Sales/view/email/shipment_new_guest.html @@ -94,7 +94,7 @@

Your Shipment #{{var s
{{layout handle="sales_email_order_shipment_items" shipment=$shipment order=$order}} - {{block type='Magento\\Framework\\View\\Element\\Template' area='frontend' template='Magento_Sales::email/shipment/track.phtml' shipment=$shipment order=$order}} + {{block class='Magento\\Framework\\View\\Element\\Template' area='frontend' template='Magento_Sales::email/shipment/track.phtml' shipment=$shipment order=$order}}

{{var comment}}

diff --git a/app/code/Magento/SalesRule/Model/Coupon/Massgenerator.php b/app/code/Magento/SalesRule/Model/Coupon/Massgenerator.php index 292c6ac602a1e..d47bb71a5afaa 100644 --- a/app/code/Magento/SalesRule/Model/Coupon/Massgenerator.php +++ b/app/code/Magento/SalesRule/Model/Coupon/Massgenerator.php @@ -129,7 +129,7 @@ public function generateCode() $code = ''; $charsetSize = count($charset); for ($i = 0; $i < $length; $i++) { - $char = $charset[mt_rand(0, $charsetSize - 1)]; + $char = $charset[\Magento\Framework\Math\Random::getRandomNumber(0, $charsetSize - 1)]; if ($split > 0 && $i % $split == 0 && $i != 0) { $char = $splitChar . $char; } diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment.php index 703c92391526d..89797072eaf91 100644 --- a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment.php +++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment.php @@ -740,7 +740,7 @@ protected function _createPdfPageFromImageString($imageString) $page = new \Zend_Pdf_Page($xSize, $ySize); imageinterlace($image, 0); - $tmpFileName = $directory->getAbsolutePath('shipping_labels_' . uniqid(mt_rand()) . time() . '.png'); + $tmpFileName = $directory->getAbsolutePath('shipping_labels_' . uniqid(\Magento\Framework\Math\Random::getRandomNumber()) . time() . '.png'); imagepng($image, $tmpFileName); $pdfImage = \Zend_Pdf_Image::imageWithPath($tmpFileName); $page->drawImage($pdfImage, 0, 0, $xSize, $ySize); diff --git a/app/code/Magento/Shipping/view/adminhtml/create/items.phtml b/app/code/Magento/Shipping/view/adminhtml/create/items.phtml index 4e11459c57ee9..055d69d0a798d 100644 --- a/app/code/Magento/Shipping/view/adminhtml/create/items.phtml +++ b/app/code/Magento/Shipping/view/adminhtml/create/items.phtml @@ -96,18 +96,15 @@ if (sendEmailCheckbox) { Event.observe(sendEmailCheckbox, 'change', bindSendEmail); bindSendEmail(); } -function bindSendEmail() -{ +function bindSendEmail() { if (sendEmailCheckbox.checked == true) { notifyCustomerCheckbox.disabled = false; - //shipmentCommentText.disabled = false; } else { notifyCustomerCheckbox.disabled = true; - //shipmentCommentText.disabled = true; } } -function toggleCreateLabelCheckbox(){ +function toggleCreateLabelCheckbox() { var checkbox = $('create_shipping_label'); var submitButton = checkbox.up('.order-totals').select('.submit-button span')[0]; if (checkbox.checked) { @@ -116,7 +113,11 @@ function toggleCreateLabelCheckbox(){ submitButton.innerText = submitButton.innerText.replace(/\.\.\.$/, ''); } } -function submitShipment(btn){ +function submitShipment(btn) { + if (!validQtyItems()) { + alert(''); + return; + } var checkbox = $(btn).up('.order-totals').select('#create_shipping_label')[0]; if (checkbox && checkbox.checked) { packaging.showWindow(); @@ -130,5 +131,15 @@ function submitShipment(btn){ jQuery('#edit_form').triggerHandler('save'); } } +function validQtyItems() { + var valid = true; + $$('.qty-item').each(function(item) { + var val = parseFloat(item.value); + if (isNaN(val) || val < 0) { + valid = false; + } + }); + return valid; +} //]]> diff --git a/app/code/Magento/Shipping/view/adminhtml/create/items/renderer/default.phtml b/app/code/Magento/Shipping/view/adminhtml/create/items/renderer/default.phtml index a46e9d55141e1..64d3910cbc163 100644 --- a/app/code/Magento/Shipping/view/adminhtml/create/items/renderer/default.phtml +++ b/app/code/Magento/Shipping/view/adminhtml/create/items/renderer/default.phtml @@ -28,7 +28,7 @@ getColumnHtml($_item, 'qty') ?> canShipPartiallyItem()): ?> - + getQty()*1 ?> diff --git a/app/code/Magento/Tax/Helper/Data.php b/app/code/Magento/Tax/Helper/Data.php index 63bd13db488cf..c3c4371f52800 100644 --- a/app/code/Magento/Tax/Helper/Data.php +++ b/app/code/Magento/Tax/Helper/Data.php @@ -32,12 +32,24 @@ */ class Data extends \Magento\Framework\App\Helper\AbstractHelper { + /** + * Price conversion constant for positive + */ const PRICE_CONVERSION_PLUS = 1; + /** + * Price conversion constant for negative + */ const PRICE_CONVERSION_MINUS = 2; + /** + * Default tax class for customers + */ const CONFIG_DEFAULT_CUSTOMER_TAX_CLASS = 'tax/classes/default_customer_tax_class'; + /** + * Default tax class for products + */ const CONFIG_DEFAULT_PRODUCT_TAX_CLASS = 'tax/classes/default_product_tax_class'; /** @@ -48,45 +60,12 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper protected $_config; /** + * Tax calculator + * * @var \Magento\Tax\Model\Calculation */ protected $_calculation; - /** - * @var mixed - */ - protected $_displayTaxColumn; - - /** - * @var mixed - */ - protected $_taxData; - - /** - * @var mixed - */ - protected $_priceIncludesTax; - - /** - * @var mixed - */ - protected $_shippingPriceIncludesTax; - - /** - * @var mixed - */ - protected $_applyTaxAfterDiscount; - - /** - * @var int - */ - protected $_priceDisplayType; - - /** - * @var mixed - */ - protected $_shippingPriceDisplayType; - /** * Postcode cut to this length when creating search templates * @@ -135,6 +114,11 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper */ protected $_taxItemFactory; + /** + * @var \Magento\Tax\Model\Resource\Sales\Order\Tax\CollectionFactory + */ + protected $_orderTaxCollectionFactory; + /** * @var \Magento\Framework\Locale\ResolverInterface */ @@ -151,6 +135,7 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper * @param \Magento\Framework\Locale\FormatInterface $localeFormat * @param \Magento\Eav\Model\Entity\AttributeFactory $attributeFactory * @param \Magento\Tax\Model\Resource\Sales\Order\Tax\ItemFactory $taxItemFactory + * @param \Magento\Tax\Model\Resource\Sales\Order\Tax\CollectionFactory $orderTaxCollectionFactory * @param \Magento\Framework\Locale\ResolverInterface $localeResolver */ public function __construct( @@ -164,6 +149,7 @@ public function __construct( \Magento\Framework\Locale\FormatInterface $localeFormat, \Magento\Eav\Model\Entity\AttributeFactory $attributeFactory, \Magento\Tax\Model\Resource\Sales\Order\Tax\ItemFactory $taxItemFactory, + \Magento\Tax\Model\Resource\Sales\Order\Tax\CollectionFactory $orderTaxCollectionFactory, \Magento\Framework\Locale\ResolverInterface $localeResolver ) { parent::__construct($context); @@ -176,6 +162,7 @@ public function __construct( $this->_localeFormat = $localeFormat; $this->_attributeFactory = $attributeFactory; $this->_taxItemFactory = $taxItemFactory; + $this->_orderTaxCollectionFactory = $orderTaxCollectionFactory; $this->_localeResolver = $localeResolver; } @@ -254,13 +241,12 @@ public function applyTaxAfterDiscount($store = null) } /** - * Output + * Retrieves the "including tax" or "excluding tax" label * * @param bool $flag - * @param null|int|string|Store $store * @return string */ - public function getIncExcText($flag, $store = null) + public function getIncExcText($flag) { return $flag ? __('Incl. Tax') : __('Excl. Tax'); } @@ -314,7 +300,7 @@ public function needPriceConversion($store = null) } if ($res === false) { - $res = $this->displayTaxColumn($store); + $res = $this->displayTaxColumn(); } return $res; } @@ -443,10 +429,9 @@ public function displaySalesSubtotalExclTax($store = null) /** * Check if need display tax column in for shopping cart/order items * - * @param null|string|bool|int|Store $store * @return bool */ - public function displayTaxColumn($store = null) + public function displayTaxColumn() { return $this->_config->displayCartPricesBoth(); } @@ -488,8 +473,8 @@ public function getAllRatesByProductClass($store = null) protected function _getAllRatesByProductClass($store = null) { $result = array(); - $originRate = $this->_calculation->getRateOriginRequest($store); - $rates = $this->_calculation->getRatesForAllProductTaxClasses($originRate); + $defaultRate = $this->_calculation->getDefaultRateRequest($store); + $rates = $this->_calculation->getRatesForAllProductTaxClasses($defaultRate); foreach ($rates as $class => $rate) { $result["value_{$class}"] = $rate; } @@ -507,6 +492,7 @@ protected function _getAllRatesByProductClass($store = null) * @param null|int $ctc customer tax class * @param null|string|bool|int|Store $store * @param bool $priceIncludesTax flag what price parameter contain tax + * @param bool $roundPrice * @return float */ public function getPrice( @@ -517,7 +503,8 @@ public function getPrice( $billingAddress = null, $ctc = null, $store = null, - $priceIncludesTax = null + $priceIncludesTax = null, + $roundPrice = true ) { if (!$price) { return $price; @@ -541,8 +528,12 @@ public function getPrice( } } if ($taxClassId && $priceIncludesTax) { - $request = $this->_calculation->getRateRequest(false, false, false, $store); - $includingPercent = $this->_calculation->getRate($request->setProductClassId($taxClassId)); + if ($this->isCrossBorderTradeEnabled($store)) { + $includingPercent = $percent; + } else { + $request = $this->_calculation->getRateOriginRequest($store); + $includingPercent = $this->_calculation->getRate($request->setProductClassId($taxClassId)); + } } if ($percent === false || is_null($percent)) { @@ -552,39 +543,34 @@ public function getPrice( } $product->setTaxPercent($percent); + if ($product->getAppliedRates() == null) { + $request = $this->_calculation->getRateRequest($shippingAddress, $billingAddress, $ctc, $store); + $request->setProductClassId($taxClassId); + $appliedRates = $this->_calculation->getAppliedRates($request); + $product->setAppliedRates($appliedRates); + } if (!is_null($includingTax)) { if ($priceIncludesTax) { if ($includingTax) { /** - * Recalculate price include tax in case of different rates + * Recalculate price include tax in case of different rates. Otherwise price remains the same. */ if ($includingPercent != $percent) { - $price = $this->_calculatePrice($price, $includingPercent, false); - /** - * Using regular rounding. Ex: - * price incl tax = 52.76 - * store tax rate = 19.6% - * customer tax rate= 19% - * - * price excl tax = 52.76 / 1.196 = 44.11371237 ~ 44.11 - * tax = 44.11371237 * 0.19 = 8.381605351 ~ 8.38 - * price incl tax = 52.49531773 ~ 52.50 != 52.49 - * - * that why we need round prices excluding tax before applying tax - * this calculation is used for showing prices on catalog pages - */ - if ($percent != 0) { - $price = $this->getCalculator()->round($price); - $price = $this->_calculatePrice($price, $percent, true); - } + // determine the customer's price that includes tax + $price = $this->_calculatePriceInclTax($price, $includingPercent, $percent, $store); } } else { $price = $this->_calculatePrice($price, $includingPercent, false); } } else { if ($includingTax) { - $price = $this->_calculatePrice($price, $percent, true); + $appliedRates = $product->getAppliedRates(); + if (count($appliedRates) > 1) { + $price = $this->_calculatePriceInclTaxWithMultipleRates($price, $appliedRates); + } else { + $price = $this->_calculatePrice($price, $percent, true); + } } } } else { @@ -592,7 +578,18 @@ public function getPrice( switch ($this->getPriceDisplayType($store)) { case Config::DISPLAY_TYPE_EXCLUDING_TAX: case Config::DISPLAY_TYPE_BOTH: - $price = $this->_calculatePrice($price, $includingPercent, false); + if ($includingPercent != $percent) { + // determine the customer's price that includes tax + $taxablePrice = $this->_calculatePriceInclTax($price, $includingPercent, $percent, $store); + // determine the customer's tax amount, + // round tax unless $roundPrice is set explicitly to false + $tax = $this->_calculation->calcTaxAmount($taxablePrice, $percent, true, $roundPrice); + // determine the customer's price without taxes + $price = $taxablePrice - $tax; + } else { + //round tax first unless $roundPrice is set to false explicitly + $price = $this->_calculatePrice($price, $includingPercent, false, $roundPrice); + } break; case Config::DISPLAY_TYPE_INCLUDING_TAX: $price = $this->_calculatePrice($price, $includingPercent, false); @@ -604,7 +601,12 @@ public function getPrice( } else { switch ($this->getPriceDisplayType($store)) { case Config::DISPLAY_TYPE_INCLUDING_TAX: - $price = $this->_calculatePrice($price, $percent, true); + $appliedRates = $product->getAppliedRates(); + if (count($appliedRates) > 1) { + $price = $this->_calculatePriceInclTaxWithMultipleRates($price, $appliedRates); + } else { + $price = $this->_calculatePrice($price, $percent, true); + } break; case Config::DISPLAY_TYPE_BOTH: case Config::DISPLAY_TYPE_EXCLUDING_TAX: @@ -614,7 +616,29 @@ public function getPrice( } } } - return $store->roundPrice($price); + if ($roundPrice) { + return $store->roundPrice($price); + } else { + 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 $storePercent + * @param float $customerPercent + * @param null|int|string|Store $store + * @return float + */ + protected function _calculatePriceInclTax($storePriceInclTax, $storePercent, $customerPercent, $store) + { + $priceExclTax = $this->_calculatePrice($storePriceInclTax, $storePercent, false, false); + $customerTax = $this->_calculation->calcTaxAmount($priceExclTax, $customerPercent, false, false); + $customerPriceInclTax = $store->roundPrice($priceExclTax + $customerTax); + return $customerPriceInclTax; } /** @@ -640,34 +664,55 @@ public function displayPriceExcludingTax() /** * Check if we have display in catalog prices including and excluding tax * + * @param null|int|string|Store $store * @return bool */ - public function displayBothPrices() + public function displayBothPrices($store = null) { - return $this->getPriceDisplayType() == Config::DISPLAY_TYPE_BOTH; + return $this->getPriceDisplayType($store) == Config::DISPLAY_TYPE_BOTH; } /** - * Calculate price including/excluding tax base on tax rate percent + * Calculate price including/excluding tax based on tax rate percent * * @param float $price * @param float $percent - * @param bool $type true - for calculate price including tax and false if price excluding tax + * @param bool $type - true to calculate the price including tax or false if calculating price to exclude tax + * @param bool $roundTaxFirst * @return float */ - protected function _calculatePrice($price, $percent, $type) + protected function _calculatePrice($price, $percent, $type, $roundTaxFirst = false) { if ($type) { - $taxAmount = $this->_calculation->calcTaxAmount($price, $percent, false, false); + $taxAmount = $this->_calculation->calcTaxAmount($price, $percent, false, $roundTaxFirst); return $price + $taxAmount; } else { - $taxAmount = $this->_calculation->calcTaxAmount($price, $percent, true, false); + $taxAmount = $this->_calculation->calcTaxAmount($price, $percent, true, $roundTaxFirst); return $price - $taxAmount; } } /** - * @param bool $flag + * Calculate price including tax when multiple taxes is applied and rounded independently. + * + * @param float $price + * @param array $appliedRates + * @return float + */ + protected function _calculatePriceInclTaxWithMultipleRates($price, $appliedRates) + { + $tax = 0; + foreach ($appliedRates as $appliedRate) { + $taxRate = $appliedRate['percent']; + $tax += $this->_calculation->round($price * $taxRate / 100); + } + return $tax + $price; + } + + /** + * Returns the include / exclude tax label + * + * @param bool $flag * @return string */ public function getIncExcTaxLabel($flag) @@ -677,6 +722,8 @@ public function getIncExcTaxLabel($flag) } /** + * Check if shipping prices include tax + * * @param null|string|bool|int|Store $store * @return bool */ @@ -686,6 +733,8 @@ public function shippingPriceIncludesTax($store = null) } /** + * Get shipping price display type + * * @param null|string|bool|int|Store $store * @return int */ @@ -695,6 +744,8 @@ public function getShippingPriceDisplayType($store = null) } /** + * Returns whether the shipping price should display with taxes included + * * @return bool */ public function displayShippingPriceIncludingTax() @@ -703,6 +754,8 @@ public function displayShippingPriceIncludingTax() } /** + * Returns whether the shipping price should display without taxes + * * @return bool */ public function displayShippingPriceExcludingTax() @@ -711,6 +764,8 @@ public function displayShippingPriceExcludingTax() } /** + * Returns whether the shipping price should display both with and without taxes + * * @return bool */ public function displayShippingBothPrices() @@ -719,6 +774,8 @@ public function displayShippingBothPrices() } /** + * Get tax class id specified for shipping tax estimation + * * @param null|string|bool|int|Store $store * @return int */ @@ -761,6 +818,8 @@ public function getShippingPrice($price, $includingTax = null, $shippingAddress } /** + * Returns the SQL for the price tax + * * @param string $priceField * @param string $taxClassField * @return string @@ -771,7 +830,7 @@ public function getPriceTaxSql($priceField, $taxClassField) return ''; } - $request = $this->_calculation->getRateRequest(false, false, false); + $request = $this->_calculation->getDefaultRateRequest(); $defaultTaxes = $this->_calculation->getRatesForAllProductTaxClasses($request); $request = $this->_calculation->getRateRequest(); @@ -779,7 +838,10 @@ public function getPriceTaxSql($priceField, $taxClassField) $defaultTaxString = $currentTaxString = ''; - $rateToVariable = array('defaultTaxString' => 'defaultTaxes', 'currentTaxString' => 'currentTaxes'); + $rateToVariable = array( + 'defaultTaxString' => 'defaultTaxes', + 'currentTaxString' => 'currentTaxes', + ); foreach ($rateToVariable as $rateVariable => $rateArray) { if (${$rateArray} && is_array(${$rateArray})) { ${$rateVariable} = ''; @@ -944,8 +1006,8 @@ public function getCalculationAgorithm($store = null) * $index => array( * 'tax_amount' => $taxAmount, * 'base_tax_amount' => $baseTaxAmount, - * 'hidden_tax_amount' => $hiddenTaxAmount - * 'title' => $title + * 'hidden_tax_amount' => $hiddenTaxAmount, + * 'title' => $title, * 'percent' => $percent * ) * ) @@ -965,33 +1027,55 @@ public function getCalculatedTaxes($source) $taxClassAmount = array(); if ($current && $source) { - /** @var $item \Magento\Sales\Model\Order\Item */ - foreach ($current->getItemsCollection() as $item) { - /** @var $taxCollection \Magento\Tax\Model\Resource\Sales\Order\Tax\Item */ - $taxCollection = $this->_taxItemFactory->create(); - $taxCollection->getTaxItemsByItemId( - $item->getOrderItemId() ? $item->getOrderItemId() : $item->getItemId() - ); - - foreach ($taxCollection as $tax) { - $taxClassId = $tax['tax_id']; - $percent = $tax['tax_percent']; - - $price = $item->getRowTotal(); - $basePrice = $item->getBaseRowTotal(); - if ($this->applyTaxAfterDiscount($item->getStoreId())) { - $price = $price - $item->getDiscountAmount() + $item->getHiddenTaxAmount(); - $basePrice = $basePrice - $item->getBaseDiscountAmount() + $item->getBaseHiddenTaxAmount(); - } + if ($current == $source) { + // use the actuals + $rates = $this->_getTaxRateSubtotals($source); + foreach ($rates['items'] as $rate) { + $taxClassId = $rate['tax_id']; + $taxClassAmount[$taxClassId]['tax_amount'] = $rate['amount']; + $taxClassAmount[$taxClassId]['base_tax_amount'] = $rate['base_amount']; + $taxClassAmount[$taxClassId]['title'] = $rate['title']; + $taxClassAmount[$taxClassId]['percent'] = $rate['percent']; + } + } else { + // regenerate tax subtotals + // Calculate taxes for shipping + $shippingTaxAmount = $current->getShippingTaxAmount(); + if ($shippingTaxAmount) { + $shippingTax = $this->getShippingTax($current); + $taxClassAmount = array_merge($taxClassAmount, $shippingTax); + } - if (isset($taxClassAmount[$taxClassId])) { - $taxClassAmount[$taxClassId]['tax_amount'] += $price * $percent / 100; - $taxClassAmount[$taxClassId]['base_tax_amount'] += $basePrice * $percent / 100; - } else { - $taxClassAmount[$taxClassId]['tax_amount'] = $price * $percent / 100; - $taxClassAmount[$taxClassId]['base_tax_amount'] = $basePrice * $percent / 100; - $taxClassAmount[$taxClassId]['title'] = $tax['title']; - $taxClassAmount[$taxClassId]['percent'] = $tax['percent']; + /** @var $item \Magento\Sales\Model\Order\Item */ + foreach ($current->getItemsCollection() as $item) { + /** @var $taxCollection \Magento\Tax\Model\Resource\Sales\Order\Tax\Item */ + $taxCollection = $this->_taxItemFactory->create(); + $taxCollection->getTaxItemsByItemId( + $item->getOrderItemId() ? $item->getOrderItemId() : $item->getItemId() + ); + + foreach ($taxCollection as $tax) { + $taxClassId = $tax['tax_id']; + $percent = $tax['tax_percent']; + + $price = $item->getRowTotal(); + $basePrice = $item->getBaseRowTotal(); + if ($this->applyTaxAfterDiscount($item->getStoreId())) { + $price = $price - $item->getDiscountAmount() + $item->getHiddenTaxAmount(); + $basePrice = $basePrice - $item->getBaseDiscountAmount() + $item->getBaseHiddenTaxAmount(); + } + $taxAmount = $price * $percent / 100; + $baseTaxAmount = $basePrice * $percent / 100; + + if (isset($taxClassAmount[$taxClassId])) { + $taxClassAmount[$taxClassId]['tax_amount'] += $taxAmount; + $taxClassAmount[$taxClassId]['base_tax_amount'] += $baseTaxAmount; + } else { + $taxClassAmount[$taxClassId]['tax_amount'] = $taxAmount; + $taxClassAmount[$taxClassId]['base_tax_amount'] = $baseTaxAmount; + $taxClassAmount[$taxClassId]['title'] = $tax['title']; + $taxClassAmount[$taxClassId]['percent'] = $tax['percent']; + } } } } @@ -1008,6 +1092,17 @@ public function getCalculatedTaxes($source) return $taxClassAmount; } + /** + * Returns the array of tax rates for the order + * + * @param \Magento\Sales\Model\Order $order + * @return array + */ + protected function _getTaxRateSubtotals($order) + { + return $this->_orderTaxCollectionFactory->create()->loadByOrder($order)->toArray(); + } + /** * Get calculated Shipping & Handling Tax * @@ -1075,4 +1170,15 @@ public function getDefaultProductTaxClass() \Magento\Store\Model\ScopeInterface::SCOPE_STORE ); } + + /** + * Return whether cross border trade is enabled or not + * + * @param null|int|string|Store $store + * @return bool + */ + public function isCrossBorderTradeEnabled($store = null) + { + return (bool)$this->_config->crossBorderTradeEnabled($store); + } } diff --git a/app/code/Magento/Tax/Model/Calculation.php b/app/code/Magento/Tax/Model/Calculation.php index f9896b5168edf..8570082ea315b 100644 --- a/app/code/Magento/Tax/Model/Calculation.php +++ b/app/code/Magento/Tax/Model/Calculation.php @@ -31,52 +31,86 @@ use Magento\Customer\Service\V1\CustomerGroupServiceInterface as GroupServiceInterface; use Magento\Customer\Service\V1\CustomerAccountServiceInterface; use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Tax\Model\Config; /** * Tax Calculation Model */ class Calculation extends \Magento\Framework\Model\AbstractModel { + /** + * Identifier constant for Tax calculation before discount excluding TAX + */ const CALC_TAX_BEFORE_DISCOUNT_ON_EXCL = '0_0'; + /** + * Identifier constant for Tax calculation before discount including TAX + */ const CALC_TAX_BEFORE_DISCOUNT_ON_INCL = '0_1'; + /** + * Identifier constant for Tax calculation after discount excluding TAX + */ const CALC_TAX_AFTER_DISCOUNT_ON_EXCL = '1_0'; + /** + * Identifier constant for Tax calculation after discount including TAX + */ const CALC_TAX_AFTER_DISCOUNT_ON_INCL = '1_1'; + /** + * 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'; /** + * Identifier constant for unit based calculation + * * @var array */ protected $_rates = array(); /** + * Identifier constant for row based calculation + * * @var array */ protected $_ctc = array(); /** + * Identifier constant for total based calculation + * * @var array */ protected $_ptc = array(); /** + * Cache to hold the rates + * * @var array */ protected $_rateCache = array(); /** + * Store the rate calculation process + * * @var array */ protected $_rateCalculationProcess = array(); /** + * Hold the customer + * * @var CustomerDataObject|bool */ protected $_customer; @@ -113,6 +147,13 @@ class Calculation extends \Magento\Framework\Model\AbstractModel */ protected $_classesFactory; + /** + * Tax configuration object + * + * @var Config + */ + protected $_config; + /** * @var GroupServiceInterface */ @@ -132,6 +173,7 @@ class Calculation extends \Magento\Framework\Model\AbstractModel * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig + * @param Config $taxConfig * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Magento\Customer\Model\Session $customerSession * @param \Magento\Customer\Model\CustomerFactory $customerFactory @@ -149,6 +191,7 @@ public function __construct( \Magento\Framework\Model\Context $context, \Magento\Framework\Registry $registry, \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, + Config $taxConfig, \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Customer\Model\Session $customerSession, \Magento\Customer\Model\CustomerFactory $customerFactory, @@ -162,6 +205,7 @@ public function __construct( array $data = array() ) { $this->_scopeConfig = $scopeConfig; + $this->_config = $taxConfig; $this->_storeManager = $storeManager; $this->_customerSession = $customerSession; $this->_customerFactory = $customerFactory; @@ -402,6 +446,33 @@ public function getRateOriginRequest($store = null) return $request; } + /** + * Return the default rate request. It can be either based on store address or customer address + * + * @param null|int|string|Store $store + * @return \Magento\Framework\Object + */ + public function getDefaultRateRequest($store = null) + { + if ($this->_isCrossBorderTradeEnabled($store)) { + //If cross border trade is enabled, we will use customer tax rate as store tax rate + return $this->getRateRequest(null, null, null, $store); + } else { + return $this->getRateOriginRequest($store); + } + } + + /** + * Return whether cross border trade is enabled or not + * + * @param null|int|string|Store $store + * @return bool + */ + protected function _isCrossBorderTradeEnabled($store = null) + { + return (bool)$this->_config->crossBorderTradeEnabled($store); + } + /** * Get request object with information necessary for getting tax rate * @@ -507,7 +578,7 @@ public function getRateRequest( if (is_null($customerTaxClass) && $customerData->getId()) { $customerTaxClass = $this->_groupService->getGroup($customerData->getGroupId())->getTaxClassId(); } elseif ($customerTaxClass === false || !$customerData->getId()) { - $customerTaxClass = $this->getDefaultCustomerTaxClass($store); + $customerTaxClass = $this->_groupService->getGroup(GroupServiceInterface::NOT_LOGGED_IN_ID)->getTaxClassId(); } $request = new \Magento\Framework\Object(); @@ -589,6 +660,8 @@ public function compareRequests($first, $second) } /** + * Gets the tax rates by type + * * @param \Magento\Framework\Object $request * @param string|array $fieldName * @param string|array $type @@ -608,6 +681,8 @@ protected function _getRates($request, $fieldName, $type) } /** + * Gets rates for all the product tax classes + * * @param \Magento\Framework\Object $request * @return array */ @@ -617,6 +692,8 @@ public function getRatesForAllProductTaxClasses($request) } /** + * Gets rates for all the customer tax classes + * * @param \Magento\Framework\Object $request * @return array */ @@ -633,6 +710,10 @@ public function getRatesForAllCustomerTaxClasses($request) */ public function getAppliedRates($request) { + if (!$request->getCountryId() || !$request->getCustomerClassId() || !$request->getProductClassId()) { + return array(); + } + $cacheKey = $this->_getRequestCacheKey($request); if (!isset($this->_rateCalculationProcess[$cacheKey])) { $this->_rateCalculationProcess[$cacheKey] = $this->_getResource()->getCalculationProcess($request); @@ -641,6 +722,8 @@ public function getAppliedRates($request) } /** + * Gets the calculation process + * * @param array $rates * @return array */ @@ -650,6 +733,8 @@ public function reproduceProcess($rates) } /** + * Get rates by customer tax class + * * @param int $customerTaxClass * @return array */ @@ -659,6 +744,8 @@ public function getRatesByCustomerTaxClass($customerTaxClass) } /** + * Get rates by customer and product classes + * * @param int $customerTaxClass * @param int $productTaxClass * @return array diff --git a/app/code/Magento/Tax/Model/Calculation/Rate.php b/app/code/Magento/Tax/Model/Calculation/Rate.php index 8a179c28e0bb6..fbb5f71e6241f 100644 --- a/app/code/Magento/Tax/Model/Calculation/Rate.php +++ b/app/code/Magento/Tax/Model/Calculation/Rate.php @@ -21,6 +21,7 @@ * @copyright Copyright (c) 2014 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; /** * Tax Rate Model @@ -44,17 +45,17 @@ * @method int getZipTo() * @method \Magento\Tax\Model\Calculation\Rate setZipTo(int $value) */ -namespace Magento\Tax\Model\Calculation; - class Rate extends \Magento\Framework\Model\AbstractModel { /** - * @var mixed + * List of tax titles + * + * @var array */ protected $_titles = null; /** - * @var mixed + * @var \Magento\Tax\Model\Calculation\Rate\Title */ protected $_titleModel = null; @@ -104,7 +105,7 @@ protected function _construct() /** * Prepare location settings and tax postcode before save rate * - * @return $this + * @return \Magento\Tax\Model\Calculation\Rate * @throws \Magento\Framework\Model\Exception */ protected function _beforeSave() @@ -120,7 +121,7 @@ protected function _beforeSave() throw new \Magento\Framework\Model\Exception(__('Please fill all required fields with valid information.')); } - if (!is_numeric($this->getRate()) || $this->getRate() <= 0) { + if (!is_numeric($this->getRate()) || $this->getRate() < 0) { throw new \Magento\Framework\Model\Exception(__('Rate Percent should be a positive number.')); } @@ -166,7 +167,7 @@ protected function _beforeSave() /** * Save rate titles * - * @return $this + * @return \Magento\Tax\Model\Calculation\Rate */ protected function _afterSave() { @@ -178,7 +179,7 @@ protected function _afterSave() /** * Processing object before delete data * - * @return $this + * @return \Magento\Tax\Model\Calculation\Rate * @throws \Magento\Framework\Model\Exception */ protected function _beforeDelete() @@ -193,7 +194,7 @@ protected function _beforeDelete() * After rate delete * redeclared for dispatch tax_settings_change_after event * - * @return $this + * @return \Magento\Tax\Model\Calculation\Rate */ protected function _afterDelete() { @@ -202,6 +203,8 @@ protected function _afterDelete() } /** + * Saves the tax titles + * * @param array|null $titles * @return void */ @@ -230,7 +233,9 @@ public function saveTitles($titles = null) } /** - * @return mixed + * Returns a tax title + * + * @return \Magento\Tax\Model\Calculation\Rate\Title */ public function getTitleModel() { @@ -241,7 +246,9 @@ public function getTitleModel() } /** - * @return mixed + * Returns the list of tax titles + * + * @return array */ public function getTitles() { @@ -252,7 +259,9 @@ public function getTitles() } /** - * @return $this + * Deletes all tax rates + * + * @return \Magento\Tax\Model\Calculation\Rate */ public function deleteAllRates() { @@ -265,7 +274,7 @@ public function deleteAllRates() * Load rate model by code * * @param string $code - * @return $this + * @return \Magento\Tax\Model\Calculation\Rate */ public function loadByCode($code) { diff --git a/app/code/Magento/Tax/Model/Calculation/Rule.php b/app/code/Magento/Tax/Model/Calculation/Rule.php index 0efad2bc0ff73..86bd3f79decda 100644 --- a/app/code/Magento/Tax/Model/Calculation/Rule.php +++ b/app/code/Magento/Tax/Model/Calculation/Rule.php @@ -21,6 +21,7 @@ * @copyright Copyright (c) 2014 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; /** * Tax Rule Model @@ -34,40 +35,8 @@ * @method int getPosition() * @method \Magento\Tax\Model\Calculation\Rule setPosition(int $value) */ -namespace Magento\Tax\Model\Calculation; - class Rule extends \Magento\Framework\Model\AbstractModel { - /** - * @var mixed - */ - protected $_ctcs = null; - - /** - * @var mixed - */ - protected $_ptcs = null; - - /** - * @var mixed - */ - protected $_rates = null; - - /** - * @var mixed - */ - protected $_ctcModel = null; - - /** - * @var mixed - */ - protected $_ptcModel = null; - - /** - * @var mixed - */ - protected $_rateModel = null; - /** * Prefix of model events names * @@ -125,7 +94,7 @@ public function __construct( /** * After save rule - * Redeclared for populate rate calculations + * Re-declared for populate rate calculations * * @return $this */ @@ -139,7 +108,7 @@ protected function _afterSave() /** * After rule delete - * re-declared for dispatch tax_settings_change_after event + * Re-declared for dispatch tax_settings_change_after event * * @return $this */ @@ -260,4 +229,18 @@ public function getAllOptionsForClass($classFilter) return $classes; } + + /** + * Fetches rules by rate, customer tax class and product tax class + * and product tax class combination + * + * @param array $rateId + * @param array $customerTaxClassIds + * @param array $productTaxClassIds + * @return array + */ + public function fetchRuleCodes($rateId, $customerTaxClassIds, $productTaxClassIds) + { + return $this->getResource()->fetchRuleCodes($rateId, $customerTaxClassIds, $productTaxClassIds); + } } diff --git a/app/code/Magento/Tax/Model/Config.php b/app/code/Magento/Tax/Model/Config.php index a660384ab1c12..83aae6075cfec 100644 --- a/app/code/Magento/Tax/Model/Config.php +++ b/app/code/Magento/Tax/Model/Config.php @@ -51,6 +51,8 @@ class Config const XML_PATH_ALGORITHM = 'tax/calculation/algorithm'; + const CONFIG_XML_PATH_CROSS_BORDER_TRADE_ENABLED = 'tax/calculation/cross_border_trade_enabled'; + // tax defaults const CONFIG_XML_PATH_DEFAULT_COUNTRY = 'tax/defaults/country'; @@ -107,6 +109,15 @@ class Config const DISPLAY_TYPE_BOTH = 3; + /** + * Indexes for FPT Configuration Types + */ + const FPT_NOT_TAXED = 0; + + const FPT_TAXED = 1; + + const FPT_LOADED_DISPLAY_WITH_TAX = 2; + /** * @var bool|null */ @@ -732,4 +743,19 @@ public function displaySalesZeroTax($store = null) $store ); } + + /** + * Return the config value for self::CONFIG_XML_PATH_CROSS_BORDER_TRADE_ENABLED + * + * @param null|string|bool|int|Store $store + * @return bool + */ + public function crossBorderTradeEnabled($store = null) + { + return (bool)$this->_scopeConfig->getValue( + self::CONFIG_XML_PATH_CROSS_BORDER_TRADE_ENABLED, + \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + $store + ); + } } diff --git a/app/code/Magento/Tax/Model/Rate/CsvImportHandler.php b/app/code/Magento/Tax/Model/Rate/CsvImportHandler.php index 2bb5942d8079c..a2b63a019e519 100644 --- a/app/code/Magento/Tax/Model/Rate/CsvImportHandler.php +++ b/app/code/Magento/Tax/Model/Rate/CsvImportHandler.php @@ -252,7 +252,7 @@ protected function _importRate(array $rateData, array $regionsCache, array $stor if (!empty($regionsCache[$countryCode][$regionCode])) { $regionId = $regionsCache[$countryCode][$regionCode] == '*' ? 0 : $regionsCache[$countryCode][$regionCode]; // data with index 3 must represent postcode - $postCode = empty($rateData[3]) || $rateData[3] == '*' ? null : $rateData[3]; + $postCode = empty($rateData[3]) ? null : $rateData[3]; $modelData = array( 'code' => $rateData[0], 'tax_country_id' => $rateData[1], diff --git a/app/code/Magento/Tax/Model/Resource/Calculation.php b/app/code/Magento/Tax/Model/Resource/Calculation.php index 8dd4d4a9f1312..46f270187aef1 100644 --- a/app/code/Magento/Tax/Model/Resource/Calculation.php +++ b/app/code/Magento/Tax/Model/Resource/Calculation.php @@ -207,13 +207,18 @@ public function getCalculationProcess($request, $rates = null) $rates[$i + 1]['process'] ) && $rates[$i + 1]['process'] != $rate['process'] ) { - $row['percent'] = (100 + $totalPercent) * ($currentRate / 100); + if (!empty($rates[$i]['calculate_subtotal'])) { + $row['percent'] = $currentRate; + $totalPercent += $currentRate; + } else { + $row['percent'] = $this->_collectPercent($totalPercent, $currentRate); + $totalPercent += $row['percent']; + } $row['id'] = implode($ids); $result[] = $row; $row = array(); $ids = array(); - $totalPercent += (100 + $totalPercent) * ($currentRate / 100); $currentRate = 0; } } @@ -221,6 +226,18 @@ public function getCalculationProcess($request, $rates = null) return $result; } + /** + * Return combined percent value + * + * @param float|int $percent + * @param float|int $rate + * @return float + */ + protected function _collectPercent($percent, $rate) + { + return (100 + $percent) * ($rate / 100); + } + /** * Create search templates for postcode * @@ -236,7 +253,7 @@ protected function _createSearchPostCodeTemplates($postcode) $strlen = $len; } - $strArr = array($postcode, $postcode . '*'); + $strArr = array((string)$postcode, $postcode . '*'); if ($strlen > 1) { for ($i = 1; $i < $strlen; $i++) { $strArr[] = sprintf('%s*', substr($postcode, 0, -$i)); @@ -305,7 +322,7 @@ protected function _getRates($request) $select->join( array('rule' => $this->getTable('tax_calculation_rule')), $ruleTableAliasName . ' = main_table.tax_calculation_rule_id', - array('rule.priority', 'rule.position') + array('rule.priority', 'rule.position', 'rule.calculate_subtotal') )->join( array('rate' => $this->getTable('tax_calculation_rate')), 'rate.tax_calculation_rate_id = main_table.tax_calculation_rate_id', @@ -417,7 +434,11 @@ protected function _calculateRate($rates) $currentRate += $value; if (!isset($rates[$i + 1]) || $rates[$i + 1]['priority'] != $priority) { - $result += (100 + $result) * ($currentRate / 100); + if (!empty($rates[$i]['calculate_subtotal'])) { + $result += $currentRate; + } else { + $result += $this->_collectPercent($result, $currentRate); + } $currentRate = 0; } } diff --git a/app/code/Magento/Tax/Model/Resource/Calculation/Rate/Collection.php b/app/code/Magento/Tax/Model/Resource/Calculation/Rate/Collection.php index e507eba83c0bd..4392e21914795 100644 --- a/app/code/Magento/Tax/Model/Resource/Calculation/Rate/Collection.php +++ b/app/code/Magento/Tax/Model/Resource/Calculation/Rate/Collection.php @@ -30,6 +30,11 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\AbstractCollection { + /** + * Value of fetched from DB of rules per cycle + */ + const TAX_RULES_CHUNK_SIZE = 1000; + /** * @var \Magento\Store\Model\StoreManagerInterface */ @@ -196,4 +201,32 @@ public function toOptionHashOptimized() } return $result; } + + /** + * Get rates array without memory leak + * + * @return array + */ + public function getOptionRates() + { + $size = self::TAX_RULES_CHUNK_SIZE; + $page = 1; + $rates = array(); + do { + $offset = $size * ($page - 1); + $this->getSelect()->reset(); + $this->getSelect() + ->from( + array('rates' => $this->getMainTable()), + array('tax_calculation_rate_id', 'code') + ) + ->limit($size, $offset); + + $rates = array_merge($rates, $this->toOptionArray()); + $this->clear(); + $page++; + } while ($this->getSize() > $offset); + + return $rates; + } } diff --git a/app/code/Magento/Tax/Model/Resource/Calculation/Rule.php b/app/code/Magento/Tax/Model/Resource/Calculation/Rule.php index 9b3e0f94bba6d..b16cd4bec9070 100644 --- a/app/code/Magento/Tax/Model/Resource/Calculation/Rule.php +++ b/app/code/Magento/Tax/Model/Resource/Calculation/Rule.php @@ -50,4 +50,30 @@ protected function _initUniqueFields() $this->_uniqueFields = array(array('field' => array('code'), 'title' => __('Code'))); return $this; } + + /** + * Fetches rules by rate, customer tax classes and product tax classes. Returns array of rule codes. + * + * @param array $rateId + * @param array $customerTaxClassIds + * @param array $productTaxClassIds + * @return array + */ + public function fetchRuleCodes($rateId, $customerTaxClassIds, $productTaxClassIds) + { + $adapter = $this->_getReadAdapter(); + $select = $adapter->select() + ->from(array('main' => $this->getTable('tax_calculation')), null) + ->joinLeft( + array('d' => $this->getTable('tax_calculation_rule')), + 'd.tax_calculation_rule_id = main.tax_calculation_rule_id', + array('d.code') + ) + ->where('main.tax_calculation_rate_id in (?)', $rateId) + ->where('main.customer_tax_class_id in (?)', $customerTaxClassIds) + ->where('main.product_tax_class_id in (?)', $productTaxClassIds) + ->distinct(true); + + return $adapter->fetchCol($select); + } } 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 fdbf31f0b8667..7b1d6683e6f4a 100644 --- a/app/code/Magento/Tax/Model/Sales/Total/Quote/Shipping.php +++ b/app/code/Magento/Tax/Model/Sales/Total/Quote/Shipping.php @@ -41,6 +41,13 @@ class Shipping extends \Magento\Sales\Model\Quote\Address\Total\AbstractTotal */ protected $_config = null; + /** + * Tax helper instance + * + * @var \Magento\Tax\Helper\Data|null + */ + protected $_taxHelper = null; + /** * Flag which is initialized when collect method is started and catalog prices include tax. * It is used for checking if store tax and customer tax requests are similar @@ -61,12 +68,17 @@ class Shipping extends \Magento\Sales\Model\Quote\Address\Total\AbstractTotal * * @param \Magento\Tax\Model\Calculation $calculation * @param \Magento\Tax\Model\Config $taxConfig + * @param \Magento\Tax\Helper\Data $taxHelper */ - public function __construct(\Magento\Tax\Model\Calculation $calculation, \Magento\Tax\Model\Config $taxConfig) - { + public function __construct( + \Magento\Tax\Model\Calculation $calculation, + \Magento\Tax\Model\Config $taxConfig, + \Magento\Tax\Helper\Data $taxHelper + ) { $this->setCode('shipping'); $this->_calculator = $calculation; $this->_config = $taxConfig; + $this->_taxHelper = $taxHelper; } /** @@ -94,7 +106,12 @@ public function collect(Address $address) $priceIncludesTax = $this->_config->shippingPriceIncludesTax($store); if ($priceIncludesTax) { - $this->_areTaxRequestsSimilar = $calc->compareRequests($addressTaxRequest, $storeTaxRequest); + if ($this->_taxHelper->isCrossBorderTradeEnabled($store)) { + $this->_areTaxRequestsSimilar = true; + } else { + $this->_areTaxRequestsSimilar = + $this->_calculator->compareRequests($storeTaxRequest, $addressTaxRequest); + } } $shipping = $taxShipping = $address->getShippingAmount(); @@ -111,36 +128,54 @@ public function collect(Address $address) $taxable = $taxShipping; $baseTaxable = $baseTaxShipping; $isPriceInclTax = true; + $address->setTotalAmount('shipping', $shipping); + $address->setBaseTotalAmount('shipping', $baseShipping); } else { $storeRate = $calc->getStoreRate($addressTaxRequest, $store); $storeTax = $calc->calcTaxAmount($shipping, $storeRate, true, false); $baseStoreTax = $calc->calcTaxAmount($baseShipping, $storeRate, true, false); $shipping = $calc->round($shipping - $storeTax); $baseShipping = $calc->round($baseShipping - $baseStoreTax); - $tax = $this->_round($calc->calcTaxAmount($shipping, $rate, false, false), $rate, false); + $tax = $this->_round($calc->calcTaxAmount($shipping, $rate, false, false), $rate, true); $baseTax = $this->_round( $calc->calcTaxAmount($baseShipping, $rate, false, false), $rate, - false, + true, 'base' ); $taxShipping = $shipping + $tax; $baseTaxShipping = $baseShipping + $baseTax; - $taxable = $shipping; - $baseTaxable = $baseShipping; - $isPriceInclTax = false; + $taxable = $taxShipping; + $baseTaxable = $baseTaxShipping; + $isPriceInclTax = true; + $address->setTotalAmount('shipping', $shipping); + $address->setBaseTotalAmount('shipping', $baseShipping); } } else { - $tax = $this->_round($calc->calcTaxAmount($shipping, $rate, false, false), $rate, false); - $baseTax = $this->_round($calc->calcTaxAmount($baseShipping, $rate, false, false), $rate, false, 'base'); + $appliedRates = $calc->getAppliedRates($addressTaxRequest); + $taxes = array(); + $baseTaxes = array(); + foreach ($appliedRates as $appliedRate) { + $taxRate = $appliedRate['percent']; + $taxId = $appliedRate['id']; + $taxes[] = $this->_round($calc->calcTaxAmount($shipping, $taxRate, false, false), $taxId, false); + $baseTaxes[] = $this->_round( + $calc->calcTaxAmount($baseShipping, $taxRate, false, false), + $taxId, + false, + 'base' + ); + } + $tax = array_sum($taxes); + $baseTax = array_sum($baseTaxes); $taxShipping = $shipping + $tax; $baseTaxShipping = $baseShipping + $baseTax; $taxable = $shipping; $baseTaxable = $baseShipping; $isPriceInclTax = false; + $address->setTotalAmount('shipping', $shipping); + $address->setBaseTotalAmount('shipping', $baseShipping); } - $address->setTotalAmount('shipping', $shipping); - $address->setBaseTotalAmount('shipping', $baseShipping); $address->setShippingInclTax($taxShipping); $address->setBaseShippingInclTax($baseTaxShipping); $address->setShippingTaxable($taxable); 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 25d3bfb0b5dde..c3a32e2eec2f4 100644 --- a/app/code/Magento/Tax/Model/Sales/Total/Quote/Subtotal.php +++ b/app/code/Magento/Tax/Model/Sales/Total/Quote/Subtotal.php @@ -29,6 +29,7 @@ use Magento\Sales\Model\Quote\Address; use Magento\Sales\Model\Quote\Item\AbstractItem; +use Magento\Tax\Model\Calculation; class Subtotal extends \Magento\Sales\Model\Quote\Address\Total\AbstractTotal { @@ -47,30 +48,12 @@ class Subtotal extends \Magento\Sales\Model\Quote\Address\Total\AbstractTotal protected $_config = null; /** + * Tax helper + * * @var \Magento\Tax\Helper\Data|null */ protected $_helper = null; - /** - * @var int - */ - protected $_subtotalInclTax = 0; - - /** - * @var int - */ - protected $_baseSubtotalInclTax = 0; - - /** - * @var int - */ - protected $_subtotal = 0; - - /** - * @var int - */ - protected $_baseSubtotal = 0; - /** * Flag which is initialized when collect method is started and catalog prices include tax. * Is used for checking if store tax and customer tax requests are similar @@ -100,13 +83,6 @@ class Subtotal extends \Magento\Sales\Model\Quote\Address\Total\AbstractTotal */ protected $_roundingDeltas = array(); - /** - * Tax data - * - * @var \Magento\Tax\Helper\Data - */ - protected $_taxData = null; - /** * Class constructor * @@ -119,9 +95,8 @@ public function __construct( \Magento\Tax\Model\Calculation $calculation, \Magento\Tax\Model\Config $taxConfig ) { - $this->_taxData = $taxData; $this->setCode('tax_subtotal'); - $this->_helper = $this->_taxData; + $this->_helper = $taxData; $this->_calculator = $calculation; $this->_config = $taxConfig; } @@ -139,10 +114,6 @@ public function collect(Address $address) $this->_store = $address->getQuote()->getStore(); $this->_address = $address; - $this->_subtotalInclTax = 0; - $this->_baseSubtotalInclTax = 0; - $this->_subtotal = 0; - $this->_baseSubtotal = 0; $this->_roundingDeltas = array(); $address->setSubtotalInclTax(0); @@ -155,9 +126,10 @@ public function collect(Address $address) return $this; } + $this->_calculator->setCustomerData($address->getQuote()->getCustomerData()); + $addressRequest = $this->_getAddressTaxRequest($address); $storeRequest = $this->_getStoreTaxRequest($address); - $this->_calculator->setCustomerData($address->getQuote()->getCustomerData()); if ($this->_config->priceIncludesTax($this->_store)) { $classIds = array(); foreach ($items as $item) { @@ -171,7 +143,11 @@ public function collect(Address $address) $classIds = array_unique($classIds); $storeRequest->setProductClassId($classIds); $addressRequest->setProductClassId($classIds); - $this->_areTaxRequestsSimilar = $this->_calculator->compareRequests($storeRequest, $addressRequest); + if ($this->_helper->isCrossBorderTradeEnabled($this->_store)) { + $this->_areTaxRequestsSimilar = true; + } else { + $this->_areTaxRequestsSimilar = $this->_calculator->compareRequests($storeRequest, $addressRequest); + } } foreach ($items as $item) { @@ -193,7 +169,7 @@ public function collect(Address $address) } /** - * Caclulate item price and row total with customized rounding level + * Calculate item price and row total with customized rounding level * * @param AbstractItem $item * @param \Magento\Framework\Object $taxRequest @@ -202,13 +178,13 @@ public function collect(Address $address) protected function _processItem($item, $taxRequest) { switch ($this->_config->getAlgorithm($this->_store)) { - case \Magento\Tax\Model\Calculation::CALC_UNIT_BASE: + case Calculation::CALC_UNIT_BASE: $this->_unitBaseCalculation($item, $taxRequest); break; - case \Magento\Tax\Model\Calculation::CALC_ROW_BASE: + case Calculation::CALC_ROW_BASE: $this->_rowBaseCalculation($item, $taxRequest); break; - case \Magento\Tax\Model\Calculation::CALC_TOTAL_BASE: + case Calculation::CALC_TOTAL_BASE: $this->_totalBaseCalculation($item, $taxRequest); break; default: @@ -230,69 +206,78 @@ protected function _unitBaseCalculation($item, $request) $rate = $this->_calculator->getRate($request); $qty = $item->getTotalQty(); - $price = $taxPrice = $item->getCalculationPriceOriginal(); - $basePrice = $baseTaxPrice = $item->getBaseCalculationPriceOriginal(); - $subtotal = $taxSubtotal = $item->getRowTotal(); - $baseSubtotal = $baseTaxSubtotal = $item->getBaseRowTotal(); + $price = $taxPrice = $this->_calculator->round($item->getCalculationPriceOriginal()); + $basePrice = $baseTaxPrice = $this->_calculator->round($item->getBaseCalculationPriceOriginal()); + $subtotal = $taxSubtotal = $this->_calculator->round($item->getRowTotal()); + $baseSubtotal = $baseTaxSubtotal = $this->_calculator->round($item->getBaseRowTotal()); + + // if we have a custom price, determine if tax should be based on the original price $taxOnOrigPrice = !$this->_helper->applyTaxOnCustomPrice($this->_store) && $item->hasCustomPrice(); if ($taxOnOrigPrice) { $origPrice = $item->getOriginalPrice(); $baseOrigPrice = $item->getBaseOriginalPrice(); } - $item->setTaxPercent($rate); if ($this->_config->priceIncludesTax($this->_store)) { if ($this->_sameRateAsStore($request)) { - $tax = $this->_calculator->calcTaxAmount($price, $rate, true); - $baseTax = $this->_calculator->calcTaxAmount($basePrice, $rate, true); - $taxPrice = $price; - $baseTaxPrice = $basePrice; - $taxSubtotal = $subtotal; + // determine which price to use when we calculate the tax + if ($taxOnOrigPrice) { + $taxable = $origPrice; + $baseTaxable = $baseOrigPrice; + } else { + $taxable = $price; + $baseTaxable = $basePrice; + } + $tax = $this->_calculator->calcTaxAmount($taxable, $rate, true); + $baseTax = $this->_calculator->calcTaxAmount($baseTaxable, $rate, true); + $taxPrice = $price; + $baseTaxPrice = $basePrice; + $taxSubtotal = $subtotal; $baseTaxSubtotal = $baseSubtotal; $price = $price - $tax; $basePrice = $basePrice - $baseTax; $subtotal = $price * $qty; $baseSubtotal = $basePrice * $qty; + $isPriceInclTax = true; + + $item->setRowTax($tax * $qty); + $item->setBaseRowTax($baseTax * $qty); + } else { + $storeRate = $this->_calculator->getStoreRate($request, $this->_store); if ($taxOnOrigPrice) { - $taxable = $origPrice; - $baseTaxable = $baseOrigPrice; + // the merchant already provided a customer's price that includes tax + $taxPrice = $price; + $baseTaxPrice = $basePrice; + // determine which price to use when we calculate the tax + $taxable = $this->_calculatePriceInclTax($origPrice, $storeRate, $rate); + $baseTaxable = $this->_calculatePriceInclTax($baseOrigPrice, $storeRate, $rate); } else { - $taxable = $taxPrice; - $baseTaxable = $baseTaxPrice; + // determine the customer's price that includes tax + $taxPrice = $this->_calculatePriceInclTax($price, $storeRate, $rate); + $baseTaxPrice = $this->_calculatePriceInclTax($basePrice, $storeRate, $rate); + // determine which price to use when we calculate the tax + $taxable = $taxPrice; + $baseTaxable = $baseTaxPrice; } - $isPriceInclTax = true; - } else { - $storeRate = $this->_calculator->getStoreRate($request, $this->_store); - $storeTax = $this->_calculator->calcTaxAmount($price, $storeRate, true); - $baseStoreTax = $this->_calculator->calcTaxAmount($basePrice, $storeRate, true); - $price = $price - $storeTax; - $basePrice = $basePrice - $baseStoreTax; + // determine the customer's tax amount + $tax = $this->_calculator->calcTaxAmount($taxable, $rate, true, true); + $baseTax = $this->_calculator->calcTaxAmount($baseTaxable, $rate, true, true); + // determine the customer's price without taxes + $price = $taxPrice - $tax; + $basePrice = $baseTaxPrice - $baseTax; + // determine subtotal amounts + $taxSubtotal = $taxPrice * $qty; + $baseTaxSubtotal = $baseTaxPrice * $qty; $subtotal = $price * $qty; $baseSubtotal = $basePrice * $qty; + $isPriceInclTax = true; - $tax = $this->_calculator->calcTaxAmount($price, $rate, false); - $baseTax = $this->_calculator->calcTaxAmount($basePrice, $rate, false); - $taxPrice = $price + $tax; - $baseTaxPrice = $basePrice + $baseTax; - $taxSubtotal = $taxPrice * $qty; - $baseTaxSubtotal = $baseTaxPrice * $qty; - if ($taxOnOrigPrice) { - $taxable = $origPrice - $storeTax; - $baseTaxable = $baseOrigPrice - $baseStoreTax; - } else { - $taxable = $price; - $baseTaxable = $basePrice; - } - $isPriceInclTax = false; + $item->setRowTax($tax * $qty); + $item->setBaseRowTax($baseTax * $qty); } } else { - $tax = $this->_calculator->calcTaxAmount($price, $rate, false); - $baseTax = $this->_calculator->calcTaxAmount($basePrice, $rate, false); - $taxPrice = $price + $tax; - $baseTaxPrice = $basePrice + $baseTax; - $taxSubtotal = $taxPrice * $qty; - $baseTaxSubtotal = $baseTaxPrice * $qty; + // determine which price to use when we calculate the tax if ($taxOnOrigPrice) { $taxable = $origPrice; $baseTaxable = $baseOrigPrice; @@ -300,7 +285,21 @@ protected function _unitBaseCalculation($item, $request) $taxable = $price; $baseTaxable = $basePrice; } - $isPriceInclTax = false; + $appliedRates = $this->_calculator->getAppliedRates($request); + $taxes = array(); + $baseTaxes = array(); + foreach ($appliedRates as $appliedRate) { + $taxRate = $appliedRate['percent']; + $taxes[] = $this->_calculator->calcTaxAmount($taxable, $taxRate, false); + $baseTaxes[] = $this->_calculator->calcTaxAmount($baseTaxable, $taxRate, false); + } + $tax = array_sum($taxes); + $baseTax = array_sum($baseTaxes); + $taxPrice = $price + $tax; + $baseTaxPrice = $basePrice + $baseTax; + $taxSubtotal = $taxPrice * $qty; + $baseTaxSubtotal = $baseTaxPrice * $qty; + $isPriceInclTax = false; } if ($item->hasCustomPrice()) { @@ -342,10 +341,12 @@ protected function _rowBaseCalculation($item, $request) $rate = $this->_calculator->getRate($request); $qty = $item->getTotalQty(); - $price = $taxPrice = $item->getCalculationPriceOriginal(); - $basePrice = $baseTaxPrice = $item->getBaseCalculationPriceOriginal(); - $subtotal = $taxSubtotal = $item->getRowTotal(); - $baseSubtotal = $baseTaxSubtotal = $item->getBaseRowTotal(); + $price = $taxPrice = $this->_calculator->round($item->getCalculationPriceOriginal()); + $basePrice = $baseTaxPrice = $this->_calculator->round($item->getBaseCalculationPriceOriginal()); + $subtotal = $taxSubtotal = $this->_calculator->round($item->getRowTotal()); + $baseSubtotal = $baseTaxSubtotal = $this->_calculator->round($item->getBaseRowTotal()); + + // if we have a custom price, determine if tax should be based on the original price $taxOnOrigPrice = !$this->_helper->applyTaxOnCustomPrice($this->_store) && $item->hasCustomPrice(); if ($taxOnOrigPrice) { $origSubtotal = $item->getOriginalPrice() * $qty; @@ -355,55 +356,67 @@ protected function _rowBaseCalculation($item, $request) $item->setTaxPercent($rate); if ($this->_config->priceIncludesTax($this->_store)) { if ($this->_sameRateAsStore($request)) { - $rowTax = $this->_calculator->calcTaxAmount($subtotal, $rate, true, false); - $baseRowTax = $this->_calculator->calcTaxAmount($baseSubtotal, $rate, true, false); - $taxPrice = $price; - $baseTaxPrice = $basePrice; - $taxSubtotal = $subtotal; - $baseTaxSubtotal = $baseSubtotal; - $subtotal = $this->_calculator->round($subtotal - $rowTax); - $baseSubtotal = $this->_calculator->round($baseSubtotal - $baseRowTax); - $price = $this->_calculator->round($subtotal / $qty); - $basePrice = $this->_calculator->round($baseSubtotal / $qty); + // determine which price to use when we calculate the tax if ($taxOnOrigPrice) { - $taxable = $origSubtotal; - $baseTaxable = $baseOrigSubtotal; + $taxable = $origSubtotal; + $baseTaxable = $baseOrigSubtotal; } else { - $taxable = $taxSubtotal; - $baseTaxable = $baseTaxSubtotal; + $taxable = $taxSubtotal; + $baseTaxable = $baseTaxSubtotal; } - $isPriceInclTax = true; - } else { - $storeRate = $this->_calculator->getStoreRate($request, $this->_store); - $storeTax = $this->_calculator->calcTaxAmount($subtotal, $storeRate, true, false); - $baseStoreTax = $this->_calculator->calcTaxAmount($baseSubtotal, $storeRate, true, false); - $subtotal = $this->_calculator->round($subtotal - $storeTax); - $baseSubtotal = $this->_calculator->round($baseSubtotal - $baseStoreTax); + $rowTax = $this->_calculator->calcTaxAmount($taxable, $rate, true, true); + $baseRowTax = $this->_calculator->calcTaxAmount($baseTaxable, $rate, true, true); + $taxPrice = $price; + $baseTaxPrice = $basePrice; + $taxSubtotal = $subtotal; + $baseTaxSubtotal = $baseSubtotal; + $subtotal = $this->_calculator->round($subtotal - $rowTax); + $baseSubtotal = $this->_calculator->round($baseSubtotal - $baseRowTax); $price = $this->_calculator->round($subtotal / $qty); $basePrice = $this->_calculator->round($baseSubtotal / $qty); + $isPriceInclTax = true; - $rowTax = $this->_calculator->calcTaxAmount($subtotal, $rate, false, false); - $baseRowTax = $this->_calculator->calcTaxAmount($baseSubtotal, $rate, false, false); - $taxSubtotal = $subtotal + $rowTax; - $baseTaxSubtotal = $baseSubtotal + $baseRowTax; - $taxPrice = $this->_calculator->round($taxSubtotal / $qty); - $baseTaxPrice = $this->_calculator->round($baseTaxSubtotal / $qty); + $item->setRowTax($rowTax); + $item->setBaseRowTax($baseRowTax); + } else { + $storeRate = $this->_calculator->getStoreRate($request, $this->_store); if ($taxOnOrigPrice) { - $taxable = $this->_calculator->round($origSubtotal - $storeTax); - $baseTaxable = $this->_calculator->round($baseOrigSubtotal - $baseStoreTax); + // the merchant already provided a customer's price that includes tax + $taxPrice = $price; + $baseTaxPrice = $basePrice; + // determine which price to use when we calculate the tax + $taxable = $this->_calculatePriceInclTax($item->getOriginalPrice(), $storeRate, $rate); + $baseTaxable = $this->_calculatePriceInclTax($item->getBaseOriginalPrice(), $storeRate, $rate); } else { - $taxable = $subtotal; - $baseTaxable = $baseSubtotal; + // determine the customer's price that includes tax + $taxPrice = $this->_calculatePriceInclTax($price, $storeRate, $rate); + $baseTaxPrice = $this->_calculatePriceInclTax($basePrice, $storeRate, $rate); + // determine which price to use when we calculate the tax + $taxable = $taxPrice; + $baseTaxable = $baseTaxPrice; } - $isPriceInclTax = false; + // determine the customer's tax amount + $tax = $this->_calculator->calcTaxAmount($taxable, $rate, true, true); + $baseTax = $this->_calculator->calcTaxAmount($baseTaxable, $rate, true, true); + // determine the customer's price without taxes + $price = $taxPrice - $tax; + $basePrice = $baseTaxPrice - $baseTax; + // determine subtotal amounts + $taxable *= $qty; + $baseTaxable *= $qty; + $taxSubtotal = $taxPrice * $qty; + $baseTaxSubtotal = $baseTaxPrice * $qty; + $rowTax = $this->_calculator->calcTaxAmount($taxable, $rate, true, true); + $baseRowTax = $this->_calculator->calcTaxAmount($baseTaxable, $rate, true, true); + $subtotal = $taxSubtotal - $rowTax; + $baseSubtotal = $baseTaxSubtotal - $baseRowTax; + $isPriceInclTax = true; + + $item->setRowTax($rowTax); + $item->setBaseRowTax($baseRowTax); } } else { - $rowTax = $this->_calculator->calcTaxAmount($subtotal, $rate, false, false); - $baseRowTax = $this->_calculator->calcTaxAmount($baseSubtotal, $rate, false, false); - $taxSubtotal = $subtotal + $rowTax; - $baseTaxSubtotal = $baseSubtotal + $baseRowTax; - $taxPrice = $this->_calculator->round($taxSubtotal / $qty); - $baseTaxPrice = $this->_calculator->round($baseTaxSubtotal / $qty); + // determine which price to use when we calculate the tax if ($taxOnOrigPrice) { $taxable = $origSubtotal; $baseTaxable = $baseOrigSubtotal; @@ -411,7 +424,22 @@ protected function _rowBaseCalculation($item, $request) $taxable = $subtotal; $baseTaxable = $baseSubtotal; } - $isPriceInclTax = false; + + $appliedRates = $this->_calculator->getAppliedRates($request); + $rowTaxes = array(); + $baseRowTaxes = array(); + foreach ($appliedRates as $appliedRate) { + $taxRate = $appliedRate['percent']; + $rowTaxes[] = $this->_calculator->calcTaxAmount($taxable, $taxRate, false, true); + $baseRowTaxes[] = $this->_calculator->calcTaxAmount($baseTaxable, $taxRate, false, true); + } + $rowTax = array_sum($rowTaxes); + $baseRowTax = array_sum($baseRowTaxes); + $taxSubtotal = $subtotal + $rowTax; + $baseTaxSubtotal = $baseSubtotal + $baseRowTax; + $taxPrice = $this->_calculator->round($taxSubtotal/$qty); + $baseTaxPrice = $this->_calculator->round($baseTaxSubtotal/$qty); + $isPriceInclTax = false; } if ($item->hasCustomPrice()) { @@ -458,119 +486,119 @@ protected function _totalBaseCalculation($item, $request) $rate = $calc->getRate($request); $qty = $item->getTotalQty(); - $price = $taxPrice = $item->getCalculationPriceOriginal(); - $basePrice = $baseTaxPrice = $item->getBaseCalculationPriceOriginal(); - $subtotal = $taxSubtotal = $item->getRowTotal(); - $baseSubtotal = $baseTaxSubtotal = $item->getBaseRowTotal(); + $price = $taxPrice = $this->_calculator->round($item->getCalculationPriceOriginal()); + $basePrice = $baseTaxPrice = $this->_calculator->round($item->getBaseCalculationPriceOriginal()); + $subtotal = $taxSubtotal = $this->_calculator->round($item->getRowTotal()); + $baseSubtotal = $baseTaxSubtotal = $this->_calculator->round($item->getBaseRowTotal()); + // if we have a custom price, determine if tax should be based on the original price $taxOnOrigPrice = !$this->_helper->applyTaxOnCustomPrice($this->_store) && $item->hasCustomPrice(); if ($taxOnOrigPrice) { $origSubtotal = $item->getOriginalPrice() * $qty; $baseOrigSubtotal = $item->getBaseOriginalPrice() * $qty; } + $item->setTaxPercent($rate); if ($this->_config->priceIncludesTax($this->_store)) { if ($this->_sameRateAsStore($request)) { + // determine which price to use when we calculate the tax if ($taxOnOrigPrice) { - $rowTax = $this->_deltaRound($calc->calcTaxAmount($origSubtotal, $rate, true, false), $rate, true); - $baseRowTax = $this->_deltaRound( - $calc->calcTaxAmount($baseOrigSubtotal, $rate, true, false), - $rate, - true, - 'base' - ); - $taxable = $origSubtotal; $baseTaxable = $baseOrigSubtotal; } else { - $rowTax = $this->_deltaRound($calc->calcTaxAmount($subtotal, $rate, true, false), $rate, true); - $baseRowTax = $this->_deltaRound( - $calc->calcTaxAmount($baseSubtotal, $rate, true, false), - $rate, - true, - 'base' - ); - $taxable = $subtotal; $baseTaxable = $baseSubtotal; } - $taxPrice = $price; - $baseTaxPrice = $basePrice; + $rowTaxExact = $calc->calcTaxAmount($taxable, $rate, true, false); + $rowTax = $this->_deltaRound($rowTaxExact, $rate, true); + $baseRowTaxExact = $calc->calcTaxAmount($baseTaxable, $rate, true, false); + $baseRowTax = $this->_deltaRound($baseRowTaxExact, $rate, true, 'base'); + $taxPrice = $price; + $baseTaxPrice = $basePrice; $taxSubtotal = $subtotal; $baseTaxSubtotal = $baseSubtotal; - $subtotal = $subtotal - $rowTax; - $baseSubtotal = $baseSubtotal - $baseRowTax; + $subtotal = $subtotal - $rowTax; + $baseSubtotal = $baseSubtotal - $baseRowTax; $price = $calc->round($subtotal / $qty); $basePrice = $calc->round($baseSubtotal / $qty); - $isPriceInclTax = true; + $isPriceInclTax = true; + + //Save the tax calculated + $item->setRowTax($rowTax); + $item->setBaseRowTax($baseRowTax); } else { $storeRate = $calc->getStoreRate($request, $this->_store); if ($taxOnOrigPrice) { - $storeTax = $calc->calcTaxAmount($origSubtotal, $storeRate, true, false); - $baseStoreTax = $calc->calcTaxAmount($baseOrigSubtotal, $storeRate, true, false); + // the merchant already provided a customer's price that includes tax + $taxPrice = $price; + $baseTaxPrice = $basePrice; + // determine which price to use when we calculate the tax + $taxable = $this->_calculatePriceInclTax($item->getOriginalPrice(), $storeRate, $rate); + $baseTaxable = $this->_calculatePriceInclTax($item->getBaseOriginalPrice(), $storeRate, $rate); } else { - $storeTax = $calc->calcTaxAmount($subtotal, $storeRate, true, false); - $baseStoreTax = $calc->calcTaxAmount($baseSubtotal, $storeRate, true, false); + // determine the customer's price that includes tax + $taxPrice = $this->_calculatePriceInclTax($price, $storeRate, $rate); + $baseTaxPrice = $this->_calculatePriceInclTax($basePrice, $storeRate, $rate); + // determine which price to use when we calculate the tax + $taxable = $taxPrice; + $baseTaxable = $baseTaxPrice; } - $subtotal = $calc->round($subtotal - $storeTax); - $baseSubtotal = $calc->round($baseSubtotal - $baseStoreTax); - - $price = $calc->round($subtotal / $qty); - $basePrice = $calc->round($baseSubtotal / $qty); - - $rowTax = $this->_deltaRound($calc->calcTaxAmount($subtotal, $rate, false, false), $rate, true); - $baseRowTax = $this->_deltaRound( - $calc->calcTaxAmount($baseSubtotal, $rate, false, false), - $rate, - true, - 'base' - ); - - $taxSubtotal = $subtotal + $rowTax; - $baseTaxSubtotal = $baseSubtotal + $baseRowTax; - - $taxPrice = $calc->round($taxSubtotal / $qty); - $baseTaxPrice = $calc->round($baseTaxSubtotal / $qty); - - $taxable = $subtotal; - $baseTaxable = $baseSubtotal; - - $isPriceInclTax = false; + // determine the customer's tax amount based on the taxable price + $tax = $this->_calculator->calcTaxAmount($taxable, $rate, true, true); + $baseTax = $this->_calculator->calcTaxAmount($baseTaxable, $rate, true, true); + // determine the customer's price without taxes + $price = $taxPrice - $tax; + $basePrice = $baseTaxPrice - $baseTax; + // determine subtotal amounts + $taxable *= $qty; + $baseTaxable *= $qty; + $taxSubtotal = $taxPrice * $qty; + $baseTaxSubtotal = $baseTaxPrice * $qty; + $rowTax = + $this->_deltaRound($calc->calcTaxAmount($taxable, $rate, true, false), $rate, true); + $baseRowTax = + $this->_deltaRound($calc->calcTaxAmount($baseTaxable, $rate, true, false), $rate, true, 'base'); + $subtotal = $taxSubtotal - $rowTax; + $baseSubtotal = $baseTaxSubtotal - $baseRowTax; + $isPriceInclTax = true; + + $item->setRowTax($rowTax); + $item->setBaseRowTax($baseRowTax); } } else { + // determine which price to use when we calculate the tax if ($taxOnOrigPrice) { - $rowTax = $this->_deltaRound($calc->calcTaxAmount($origSubtotal, $rate, false, false), $rate, true); - $baseRowTax = $this->_deltaRound( - $calc->calcTaxAmount($baseOrigSubtotal, $rate, false, false), - $rate, - true, - 'base' - ); - $taxable = $origSubtotal; $baseTaxable = $baseOrigSubtotal; } else { - $rowTax = $this->_deltaRound($calc->calcTaxAmount($subtotal, $rate, false, false), $rate, true); - $baseRowTax = $this->_deltaRound( - $calc->calcTaxAmount($baseSubtotal, $rate, false, false), - $rate, - true, + $taxable = $subtotal; + $baseTaxable = $baseSubtotal; + } + $appliedRates = $this->_calculator->getAppliedRates($request); + $rowTaxes = array(); + $baseRowTaxes = array(); + foreach ($appliedRates as $appliedRate) { + $taxId = $appliedRate['id']; + $taxRate = $appliedRate['percent']; + $rowTaxes[] = $this->_deltaRound($calc->calcTaxAmount($taxable, $taxRate, false, false), $taxId, false); + $baseRowTaxes[] = $this->_deltaRound( + $calc->calcTaxAmount($baseTaxable, $taxRate, false, false), + $taxId, + false, 'base' ); - $taxable = $subtotal; - $baseTaxable = $baseSubtotal; } - $taxSubtotal = $subtotal + $rowTax; - $baseTaxSubtotal = $baseSubtotal + $baseRowTax; + $taxSubtotal = $subtotal + array_sum($rowTaxes); + $baseTaxSubtotal = $baseSubtotal + array_sum($baseRowTaxes); - $taxPrice = $calc->round($taxSubtotal / $qty); - $baseTaxPrice = $calc->round($baseTaxSubtotal / $qty); + $taxPrice = $calc->round($taxSubtotal/$qty); + $baseTaxPrice = $calc->round($baseTaxSubtotal/$qty); $isPriceInclTax = false; } @@ -606,6 +634,25 @@ protected function _totalBaseCalculation($item, $request) return $this; } + /** + * 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; + } + /** * Checks whether request for an item has same rate as store one * Used only after collect() started, as far as uses optimized $_areTaxRequestsSimilar property @@ -641,7 +688,8 @@ protected function _deltaRound($price, $rate, $direction, $type = 'regular') if ($price) { $rate = (string)$rate; $type = $type . $direction; - $delta = isset($this->_roundingDeltas[$type][$rate]) ? $this->_roundingDeltas[$type][$rate] : 0; + // 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; $this->_roundingDeltas[$type][$rate] = $price - $this->_calculator->round($price); $price = $this->_calculator->round($price); @@ -657,32 +705,34 @@ protected function _deltaRound($price, $rate, $direction, $type = 'regular') */ protected function _recalculateParent(AbstractItem $item) { - $price = 0; - $basePrice = 0; $rowTotal = 0; $baseRowTotal = 0; - $priceInclTax = 0; - $basePriceInclTax = 0; $rowTotalInclTax = 0; $baseRowTotalInclTax = 0; + $rowTax = 0; + $baseRowTax = 0; + $store = $item->getStore(); + $qty = $item->getQty(); + foreach ($item->getChildren() as $child) { - $price += $child->getPrice() * $child->getQty(); - $basePrice += $child->getBasePrice() * $child->getQty(); $rowTotal += $child->getRowTotal(); $baseRowTotal += $child->getBaseRowTotal(); - $priceInclTax += $child->getPriceInclTax() * $child->getQty(); - $basePriceInclTax += $child->getBasePriceInclTax() * $child->getQty(); $rowTotalInclTax += $child->getRowTotalInclTax(); $baseRowTotalInclTax += $child->getBaseRowTotalInclTax(); + $rowTax += $child->getRowTax(); + $baseRowTax += $child->getBaseRowTax(); } - $item->setConvertedPrice($price); - $item->setPrice($basePrice); + + $item->setConvertedPrice($store->roundPrice($rowTotal) / $qty); + $item->setPrice($store->roundPrice($baseRowTotal) / $qty); $item->setRowTotal($rowTotal); $item->setBaseRowTotal($baseRowTotal); - $item->setPriceInclTax($priceInclTax); - $item->setBasePriceInclTax($basePriceInclTax); + $item->setPriceInclTax($store->roundPrice($rowTotalInclTax) / $qty); + $item->setBasePriceInclTax($store->roundPrice($baseRowTotalInclTax) / $qty); $item->setRowTotalInclTax($rowTotalInclTax); $item->setBaseRowTotalInclTax($baseRowTotalInclTax); + $item->setRowTax($rowTax); + $item->setBaseRowTax($baseRowTax); return $this; } @@ -726,8 +776,21 @@ protected function _getAddressTaxRequest($address) */ protected function _addSubtotalAmount(Address $address, $item) { - $address->setTotalAmount('subtotal', $address->getTotalAmount('subtotal') + $item->getRowTotal()); - $address->setBaseTotalAmount('subtotal', $address->getBaseTotalAmount('subtotal') + $item->getBaseRowTotal()); + if ($this->_config->priceIncludesTax($this->_store)) { + $subTotal = $item->getRowTotalInclTax() - $item->getRowTax(); + $baseSubTotal = $item->getBaseRowTotalInclTax() - $item->getBaseRowTax(); + $address->setTotalAmount('subtotal', $address->getTotalAmount('subtotal') + $subTotal); + $address->setBaseTotalAmount('subtotal', $address->getBaseTotalAmount('subtotal') + $baseSubTotal); + } else { + $address->setTotalAmount( + 'subtotal', + $address->getTotalAmount('subtotal') + $item->getRowTotal() + ); + $address->setBaseTotalAmount( + 'subtotal', + $address->getBaseTotalAmount('subtotal') + $item->getBaseRowTotal() + ); + } $address->setSubtotalInclTax($address->getSubtotalInclTax() + $item->getRowTotalInclTax()); $address->setBaseSubtotalInclTax($address->getBaseSubtotalInclTax() + $item->getBaseRowTotalInclTax()); 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 c43e6476973a8..fc1080efb468a 100644 --- a/app/code/Magento/Tax/Model/Sales/Total/Quote/Tax.php +++ b/app/code/Magento/Tax/Model/Sales/Total/Quote/Tax.php @@ -27,6 +27,7 @@ use Magento\Sales\Model\Quote\Address; use Magento\Sales\Model\Quote\Address\Total\AbstractTotal; use Magento\Sales\Model\Quote\Item\AbstractItem; +use Magento\Tax\Model\Calculation; /** * Tax totals calculation model @@ -139,20 +140,24 @@ public function collect(Address $address) ); if ($this->_config->priceIncludesTax($this->_store)) { - $this->_areTaxRequestsSimilar = $this->_calculator->compareRequests( - $this->_calculator->getRateOriginRequest($this->_store), - $request - ); + if ($this->_taxData->isCrossBorderTradeEnabled($this->_store)) { + $this->_areTaxRequestsSimilar = true; + } else { + $this->_areTaxRequestsSimilar = $this->_calculator->compareRequests( + $this->_calculator->getRateOriginRequest($this->_store), + $request + ); + } } switch ($this->_config->getAlgorithm($this->_store)) { - case \Magento\Tax\Model\Calculation::CALC_UNIT_BASE: + case Calculation::CALC_UNIT_BASE: $this->_unitBaseCalculation($address, $request); break; - case \Magento\Tax\Model\Calculation::CALC_ROW_BASE: + case Calculation::CALC_ROW_BASE: $this->_rowBaseCalculation($address, $request); break; - case \Magento\Tax\Model\Calculation::CALC_TOTAL_BASE: + case Calculation::CALC_TOTAL_BASE: $this->_totalBaseCalculation($address, $request); break; default: @@ -183,33 +188,18 @@ protected function _processHiddenTaxes() if (isset($taxInfoItem['item'])) { // Item hidden taxes $item = $taxInfoItem['item']; - $rateKey = $taxInfoItem['rate_key']; $hiddenTax = $taxInfoItem['value']; $baseHiddenTax = $taxInfoItem['base_value']; - $inclTax = $taxInfoItem['incl_tax']; $qty = $taxInfoItem['qty']; - if ($this->_config->getAlgorithm($this->_store) == \Magento\Tax\Model\Calculation::CALC_TOTAL_BASE) { - $hiddenTax = $this->_deltaRound($hiddenTax, $rateKey, $inclTax); - $baseHiddenTax = $this->_deltaRound($baseHiddenTax, $rateKey, $inclTax, 'base'); - } else { - $hiddenTax = $this->_calculator->round($hiddenTax); - $baseHiddenTax = $this->_calculator->round($baseHiddenTax); - } - $item->setHiddenTaxAmount(max(0, $qty * $hiddenTax)); $item->setBaseHiddenTaxAmount(max(0, $qty * $baseHiddenTax)); $this->_getAddress()->addTotalAmount('hidden_tax', $item->getHiddenTaxAmount()); $this->_getAddress()->addBaseTotalAmount('hidden_tax', $item->getBaseHiddenTaxAmount()); } else { // Shipping hidden taxes - $rateKey = $taxInfoItem['rate_key']; $hiddenTax = $taxInfoItem['value']; $baseHiddenTax = $taxInfoItem['base_value']; - $inclTax = $taxInfoItem['incl_tax']; - - $hiddenTax = $this->_deltaRound($hiddenTax, $rateKey, $inclTax); - $baseHiddenTax = $this->_deltaRound($baseHiddenTax, $rateKey, $inclTax, 'base'); $this->_getAddress()->setShippingHiddenTaxAmount(max(0, $hiddenTax)); $this->_getAddress()->setBaseShippingHiddenTaxAmnt(max(0, $baseHiddenTax)); @@ -220,34 +210,43 @@ protected function _processHiddenTaxes() } /** - * Tax caclulation for shipping price + * Calculate shipping tax for a single tax rate * - * @param Address $address - * @param \Magento\Framework\Object $taxRateRequest - * @return $this + * @param Address $address + * @param float $rate + * @param array $appliedRates + * @param string $taxId + * @return $this */ - protected function _calculateShippingTax(Address $address, $taxRateRequest) - { - $taxRateRequest->setProductClassId($this->_config->getShippingTaxClass($this->_store)); - $rate = $this->_calculator->getRate($taxRateRequest); + protected function _calculateShippingTaxByRate( + $address, + $rate, + $appliedRates, + $taxId = null + ) { $inclTax = $address->getIsShippingInclTax(); $shipping = $address->getShippingTaxable(); $baseShipping = $address->getBaseShippingTaxable(); - $rateKey = (string)$rate; + $rateKey = ($taxId == null) ? (string)$rate : $taxId; $hiddenTax = null; $baseHiddenTax = null; switch ($this->_taxData->getCalculationSequence($this->_store)) { - case \Magento\Tax\Model\Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_EXCL: - case \Magento\Tax\Model\Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_INCL: + case Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_EXCL: + case Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_INCL: $tax = $this->_calculator->calcTaxAmount($shipping, $rate, $inclTax, false); $baseTax = $this->_calculator->calcTaxAmount($baseShipping, $rate, $inclTax, false); break; - case \Magento\Tax\Model\Calculation::CALC_TAX_AFTER_DISCOUNT_ON_EXCL: - case \Magento\Tax\Model\Calculation::CALC_TAX_AFTER_DISCOUNT_ON_INCL: + case Calculation::CALC_TAX_AFTER_DISCOUNT_ON_EXCL: + case Calculation::CALC_TAX_AFTER_DISCOUNT_ON_INCL: $discountAmount = $address->getShippingDiscountAmount(); $baseDiscountAmount = $address->getBaseShippingDiscountAmount(); - $tax = $this->_calculator->calcTaxAmount($shipping - $discountAmount, $rate, $inclTax, false); + $tax = $this->_calculator->calcTaxAmount( + $shipping - $discountAmount, + $rate, + $inclTax, + false + ); $baseTax = $this->_calculator->calcTaxAmount( $baseShipping - $baseDiscountAmount, $rate, @@ -257,32 +256,188 @@ protected function _calculateShippingTax(Address $address, $taxRateRequest) break; } - if ($this->_config->getAlgorithm($this->_store) == \Magento\Tax\Model\Calculation::CALC_TOTAL_BASE) { - $tax = $this->_deltaRound($tax, $rate, $inclTax); - $baseTax = $this->_deltaRound($baseTax, $rate, $inclTax, 'base'); + if ($this->_config->getAlgorithm($this->_store) == Calculation::CALC_TOTAL_BASE) { + $tax = $this->_deltaRound($tax, $rateKey, $inclTax); + $baseTax = $this->_deltaRound($baseTax, $rateKey, $inclTax, 'base'); + $this->_addAmount(max(0, $tax)); + $this->_addBaseAmount(max(0, $baseTax)); } else { $tax = $this->_calculator->round($tax); $baseTax = $this->_calculator->round($baseTax); + $this->_addAmount(max(0, $tax)); + $this->_addBaseAmount(max(0, $baseTax)); } if ($inclTax && !empty($discountAmount)) { - $hiddenTax = $this->_calculator->calcTaxAmount($discountAmount, $rate, $inclTax, false); - $baseHiddenTax = $this->_calculator->calcTaxAmount($baseDiscountAmount, $rate, $inclTax, false); + $taxBeforeDiscount = $this->_calculator->calcTaxAmount( + $shipping, + $rate, + $inclTax, + false + ); + $baseTaxBeforeDiscount = $this->_calculator->calcTaxAmount( + $baseShipping, + $rate, + $inclTax, + false + ); + if ($this->_config->getAlgorithm($this->_store) == Calculation::CALC_TOTAL_BASE) { + $taxBeforeDiscount = $this->_deltaRound( + $taxBeforeDiscount, + $rateKey, + $inclTax, + 'tax_before_discount' + ); + $baseTaxBeforeDiscount = $this->_deltaRound( + $baseTaxBeforeDiscount, + $rateKey, + $inclTax, + 'tax_before_discount_base' + ); + } else { + $taxBeforeDiscount = $this->_calculator->round($taxBeforeDiscount); + $baseTaxBeforeDiscount = $this->_calculator->round($baseTaxBeforeDiscount); + } + $hiddenTax = max(0, $taxBeforeDiscount - max(0, $tax)); + $baseHiddenTax = max(0, $baseTaxBeforeDiscount - max(0, $baseTax)); $this->_hiddenTaxes[] = array( 'rate_key' => $rateKey, 'value' => $hiddenTax, 'base_value' => $baseHiddenTax, - 'incl_tax' => $inclTax + 'incl_tax' => $inclTax, ); } - $this->_addAmount(max(0, $tax)); - $this->_addBaseAmount(max(0, $baseTax)); - $address->setShippingTaxAmount(max(0, $tax)); - $address->setBaseShippingTaxAmount(max(0, $baseTax)); - $applied = $this->_calculator->getAppliedRates($taxRateRequest); - $this->_saveAppliedTaxes($address, $applied, $tax, $baseTax, $rate); + $address->setShippingTaxAmount($address->getShippingTaxAmount() + max(0, $tax)); + $address->setBaseShippingTaxAmount($address->getBaseShippingTaxAmount() + max(0, $baseTax)); + $this->_saveAppliedTaxes($address, $appliedRates, $tax, $baseTax, $rate); + + return $this; + } + + /** + * Tax calculation for shipping price + * + * @param Address $address + * @param \Magento\Framework\Object $taxRateRequest + * @return $this + */ + protected function _calculateShippingTax( + Address $address, + \Magento\Framework\Object $taxRateRequest + ) { + $taxRateRequest->setProductClassId($this->_config->getShippingTaxClass($this->_store)); + $rate = $this->_calculator->getRate($taxRateRequest); + $inclTax = $address->getIsShippingInclTax(); + $address->setShippingTaxAmount(0); + $address->setBaseShippingTaxAmount(0); + $address->setShippingHiddenTaxAmount(0); + $address->setBaseShippingHiddenTaxAmount(0); + $appliedRates = $this->_calculator->getAppliedRates($taxRateRequest); + if ($inclTax) { + $this->_calculateShippingTaxByRate($address, $rate, $appliedRates); + } else { + foreach ($appliedRates as $appliedRate) { + $taxRate = $appliedRate['percent']; + $taxId = $appliedRate['id']; + $this->_calculateShippingTaxByRate($address, $taxRate, array($appliedRate), $taxId); + } + } + return $this; + } + + /** + * Initialize tax related fields in item + * + * @param AbstractItem $item + * @param array $appliedRates + * @param float $rate + * @param bool $isUnitBasedCalculation + * @return bool + */ + protected function initializeItemTax( + AbstractItem $item, + $appliedRates, + $rate, + $isUnitBasedCalculation = false + ) { + $item->setTaxAmount(0); + $item->setBaseTaxAmount(0); + $item->setHiddenTaxAmount(0); + $item->setBaseHiddenTaxAmount(0); + $item->setTaxPercent($rate); + $item->setDiscountTaxCompensation(0); + $rowTotalInclTax = $item->getRowTotalInclTax(); + $recalculateRowTotalInclTax = false; + if (!isset($rowTotalInclTax)) { + if ($isUnitBasedCalculation) { + $qty = $item->getTotalQty(); + $item->setRowTotalInclTax($this->_store->roundPrice($item->getTaxableAmount() * $qty)); + $item->setBaseRowTotalInclTax($this->_store->roundPrice($item->getBaseTaxableAmount() * $qty)); + } else { + $item->setRowTotalInclTax($item->getTaxableAmount()); + $item->setBaseRowTotalInclTax($item->getBaseTaxableAmount()); + } + $recalculateRowTotalInclTax = true; + } + $item->setTaxRates($appliedRates); + + return $recalculateRowTotalInclTax; + } + + /** + * + * @param Address $address + * @param AbstractItem $item + * @param \Magento\Framework\Object $taxRateRequest + * @param array $itemTaxGroups + * @param boolean $catalogPriceInclTax + * @return $this + */ + protected function _unitBaseProcessItemTax( + Address $address, + AbstractItem $item, + \Magento\Framework\Object $taxRateRequest, + &$itemTaxGroups, + $catalogPriceInclTax + ) { + $taxRateRequest->setProductClassId($item->getProduct()->getTaxClassId()); + $appliedRates = $this->_calculator->getAppliedRates($taxRateRequest); + $rate = $this->_calculator->getRate($taxRateRequest); + + $recalculateRowTotalInclTax = $this->initializeItemTax($item, $appliedRates, $rate, true); + + if ($catalogPriceInclTax) { + $this->_calcUnitTaxAmount($item, $rate); + $this->_saveAppliedTaxes( + $address, + $appliedRates, + $item->getTaxAmount(), + $item->getBaseTaxAmount(), + $rate + ); + } else { + //need to calculate each tax separately + $taxGroups = array(); + foreach ($appliedRates as $appliedTax) { + $taxId = $appliedTax['id']; + $taxRate = $appliedTax['percent']; + $this->_calcUnitTaxAmount($item, $taxRate, $taxGroups, $taxId, $recalculateRowTotalInclTax); + $this->_saveAppliedTaxes( + $address, + array($appliedTax), + $taxGroups[$taxId]['tax'], + $taxGroups[$taxId]['base_tax'], + $taxRate + ); + } + } + if ($rate > 0) { + $itemTaxGroups[$item->getId()] = $appliedRates; + } + $this->_addAmount($item->getTaxAmount()); + $this->_addBaseAmount($item->getBaseTaxAmount()); return $this; } @@ -293,10 +448,15 @@ protected function _calculateShippingTax(Address $address, $taxRateRequest) * @param \Magento\Framework\Object $taxRateRequest * @return $this */ - protected function _unitBaseCalculation(Address $address, $taxRateRequest) - { + protected function _unitBaseCalculation( + Address $address, + \Magento\Framework\Object $taxRateRequest + ) { $items = $this->_getAddressItems($address); $itemTaxGroups = array(); + $store = $address->getQuote()->getStore(); + $catalogPriceInclTax = $this->_config->priceIncludesTax($store); + foreach ($items as $item) { if ($item->getParentItem()) { continue; @@ -304,37 +464,23 @@ protected function _unitBaseCalculation(Address $address, $taxRateRequest) if ($item->getHasChildren() && $item->isChildrenCalculated()) { foreach ($item->getChildren() as $child) { - $taxRateRequest->setProductClassId($child->getProduct()->getTaxClassId()); - $rate = $this->_calculator->getRate($taxRateRequest); - $this->_calcUnitTaxAmount($child, $rate); - $this->_addAmount($child->getTaxAmount()); - $this->_addBaseAmount($child->getBaseTaxAmount()); - $applied = $this->_calculator->getAppliedRates($taxRateRequest); - if ($rate > 0) { - $itemTaxGroups[$child->getId()] = $applied; - } - $this->_saveAppliedTaxes( + $this->_unitBaseProcessItemTax( $address, - $applied, - $child->getTaxAmount(), - $child->getBaseTaxAmount(), - $rate + $child, + $taxRateRequest, + $itemTaxGroups, + $catalogPriceInclTax ); - $child->setTaxRates($applied); } $this->_recalculateParent($item); } else { - $taxRateRequest->setProductClassId($item->getProduct()->getTaxClassId()); - $rate = $this->_calculator->getRate($taxRateRequest); - $this->_calcUnitTaxAmount($item, $rate); - $this->_addAmount($item->getTaxAmount()); - $this->_addBaseAmount($item->getBaseTaxAmount()); - $applied = $this->_calculator->getAppliedRates($taxRateRequest); - if ($rate > 0) { - $itemTaxGroups[$item->getId()] = $applied; - } - $this->_saveAppliedTaxes($address, $applied, $item->getTaxAmount(), $item->getBaseTaxAmount(), $rate); - $item->setTaxRates($applied); + $this->_unitBaseProcessItemTax( + $address, + $item, + $taxRateRequest, + $itemTaxGroups, + $catalogPriceInclTax + ); } } if ($address->getQuote()->getTaxesForItems()) { @@ -345,51 +491,60 @@ protected function _unitBaseCalculation(Address $address, $taxRateRequest) } /** - * Calculate unit tax anount based on unit price + * Calculate unit tax amount based on unit price * * @param AbstractItem $item * @param float $rate + * @param array $taxGroups + * @param string $taxId + * @param bool $recalculateRowTotalInclTax * @return $this */ - protected function _calcUnitTaxAmount(AbstractItem $item, $rate) - { + protected function _calcUnitTaxAmount( + AbstractItem $item, + $rate, + &$taxGroups = null, + $taxId = null, + $recalculateRowTotalInclTax = false + ) { $qty = $item->getTotalQty(); $inclTax = $item->getIsPriceInclTax(); $price = $item->getTaxableAmount() + $item->getExtraTaxableAmount(); $basePrice = $item->getBaseTaxableAmount() + $item->getBaseExtraTaxableAmount(); - $rateKey = (string)$rate; - $item->setTaxPercent($rate); + $rateKey = ($taxId == null) ? (string)$rate : $taxId; - $hiddenTax = null; - $baseHiddenTax = null; + $unitTaxBeforeDiscount = 0; + $baseUnitTaxBeforeDiscount = 0; switch ($this->_config->getCalculationSequence($this->_store)) { - case \Magento\Tax\Model\Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_EXCL: - case \Magento\Tax\Model\Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_INCL: - $unitTax = $this->_calculator->calcTaxAmount($price, $rate, $inclTax); - $baseUnitTax = $this->_calculator->calcTaxAmount($basePrice, $rate, $inclTax); + case Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_EXCL: + case Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_INCL: + $unitTaxBeforeDiscount = $this->_calculator->calcTaxAmount($price, $rate, $inclTax, false); + $baseUnitTaxBeforeDiscount = $this->_calculator->calcTaxAmount($basePrice, $rate, $inclTax, false); + $unitTaxBeforeDiscount = $unitTax = $this->_calculator->round($unitTaxBeforeDiscount); + $baseUnitTaxBeforeDiscount = $baseUnitTax = $this->_calculator->round($baseUnitTaxBeforeDiscount); break; - case \Magento\Tax\Model\Calculation::CALC_TAX_AFTER_DISCOUNT_ON_EXCL: - case \Magento\Tax\Model\Calculation::CALC_TAX_AFTER_DISCOUNT_ON_INCL: + case Calculation::CALC_TAX_AFTER_DISCOUNT_ON_EXCL: + case Calculation::CALC_TAX_AFTER_DISCOUNT_ON_INCL: $discountAmount = $item->getDiscountAmount() / $qty; $baseDiscountAmount = $item->getBaseDiscountAmount() / $qty; - $unitTax = $this->_calculator->calcTaxAmount($price, $rate, $inclTax); - $discountRate = $unitTax / $price * 100; - $unitTaxDiscount = $this->_calculator->calcTaxAmount($discountAmount, $discountRate, $inclTax, false); - $unitTax = max($unitTax - $unitTaxDiscount, 0); - $baseUnitTax = $this->_calculator->calcTaxAmount($basePrice, $rate, $inclTax); - $baseDiscountRate = $baseUnitTax / $basePrice * 100; - $baseUnitTaxDiscount = $this->_calculator->calcTaxAmount( - $baseDiscountAmount, - $baseDiscountRate, - $inclTax, - false - ); - $baseUnitTax = max($baseUnitTax - $baseUnitTaxDiscount, 0); + $unitTaxBeforeDiscount = $this->_calculator->calcTaxAmount($price, $rate, $inclTax, false); + $unitTaxDiscount = $this->_calculator->calcTaxAmount($discountAmount, $rate, $inclTax, false); + $unitTax = $this->_calculator->round(max($unitTaxBeforeDiscount - $unitTaxDiscount, 0)); + + $baseUnitTaxBeforeDiscount = $this->_calculator->calcTaxAmount($basePrice, $rate, $inclTax, false); + $baseUnitTaxDiscount = $this->_calculator->calcTaxAmount($baseDiscountAmount, $rate, $inclTax, false); + $baseUnitTax = $this->_calculator->round(max($baseUnitTaxBeforeDiscount - $baseUnitTaxDiscount, 0)); + + $unitTax = $this->_calculator->round($unitTax); + $baseUnitTax = $this->_calculator->round($baseUnitTax); + + $unitTaxBeforeDiscount = max(0, $this->_calculator->round($unitTaxBeforeDiscount)); + $baseUnitTaxBeforeDiscount = max(0, $this->_calculator->round($baseUnitTaxBeforeDiscount)); if ($inclTax && $discountAmount > 0) { - $hiddenTax = $this->_calculator->calcTaxAmount($discountAmount, $rate, $inclTax, false); - $baseHiddenTax = $this->_calculator->calcTaxAmount($baseDiscountAmount, $rate, $inclTax, false); + $hiddenTax = $unitTaxBeforeDiscount - $unitTax; + $baseHiddenTax = $baseUnitTaxBeforeDiscount - $baseUnitTax; $this->_hiddenTaxes[] = array( 'rate_key' => $rateKey, 'qty' => $qty, @@ -413,12 +568,79 @@ protected function _calcUnitTaxAmount(AbstractItem $item, $rate) } break; } - $item->setTaxAmount($this->_store->roundPrice(max(0, $qty * $unitTax))); - $item->setBaseTaxAmount($this->_store->roundPrice(max(0, $qty * $baseUnitTax))); + $rowTax = $this->_store->roundPrice(max(0, $qty * $unitTax)); + $baseRowTax = $this->_store->roundPrice(max(0, $qty * $baseUnitTax)); + $item->setTaxAmount($item->getTaxAmount() + $rowTax); + $item->setBaseTaxAmount($item->getBaseTaxAmount() + $baseRowTax); + if (is_array($taxGroups)) { + $taxGroups[$rateKey]['tax'] = max(0, $rowTax); + $taxGroups[$rateKey]['base_tax'] = max(0, $baseRowTax); + } + + $rowTotalInclTax = $item->getRowTotalInclTax(); + if (!isset($rowTotalInclTax) || $recalculateRowTotalInclTax) { + if ($this->_config->priceIncludesTax($this->_store)) { + $item->setRowTotalInclTax($price * $qty); + $item->setBaseRowTotalInclTax($basePrice * $qty); + } else { + $item->setRowTotalInclTax($item->getRowTotalInclTax() + $unitTaxBeforeDiscount * $qty); + $item->setBaseRowTotalInclTax($item->getBaseRowTotalInclTax() + $baseUnitTaxBeforeDiscount * $qty); + } + } return $this; } + /** + * + * @param Address $address + * @param AbstractItem $item + * @param \Magento\Framework\Object $taxRateRequest + * @param array $itemTaxGroups + * @param bool $catalogPriceInclTax + * @return $this + */ + protected function _rowBaseProcessItemTax( + Address $address, + AbstractItem $item, + \Magento\Framework\Object $taxRateRequest, + &$itemTaxGroups, + $catalogPriceInclTax + ) { + $taxRateRequest->setProductClassId($item->getProduct()->getTaxClassId()); + $appliedRates = $this->_calculator->getAppliedRates($taxRateRequest); + $rate = $this->_calculator->getRate($taxRateRequest); + + $recalculateRowTotalInclTax = $this->initializeItemTax($item, $appliedRates, $rate); + + if ($catalogPriceInclTax) { + $this->_calcRowTaxAmount($item, $rate); + $this->_saveAppliedTaxes($address, $appliedRates, $item->getTaxAmount(), $item->getBaseTaxAmount(), $rate); + } else { + //need to calculate each tax separately + $taxGroups = array(); + foreach ($appliedRates as $appliedTax) { + $taxId = $appliedTax['id']; + $taxRate = $appliedTax['percent']; + $this->_calcRowTaxAmount($item, $taxRate, $taxGroups, $taxId, $recalculateRowTotalInclTax); + $this->_saveAppliedTaxes( + $address, + array($appliedTax), + $taxGroups[$taxId]['tax'], + $taxGroups[$taxId]['base_tax'], + $taxRate + ); + } + + } + if ($rate > 0) { + $itemTaxGroups[$item->getId()] = $appliedRates; + } + $this->_addAmount($item->getTaxAmount()); + $this->_addBaseAmount($item->getBaseTaxAmount()); + return $this; + } + /** * Calculate address total tax based on row total * @@ -426,47 +648,38 @@ protected function _calcUnitTaxAmount(AbstractItem $item, $rate) * @param \Magento\Framework\Object $taxRateRequest * @return $this */ - protected function _rowBaseCalculation(Address $address, $taxRateRequest) - { + protected function _rowBaseCalculation( + Address $address, + \Magento\Framework\Object $taxRateRequest + ) { $items = $this->_getAddressItems($address); $itemTaxGroups = array(); + $store = $address->getQuote()->getStore(); + $catalogPriceInclTax = $this->_config->priceIncludesTax($store); + foreach ($items as $item) { if ($item->getParentItem()) { continue; } if ($item->getHasChildren() && $item->isChildrenCalculated()) { foreach ($item->getChildren() as $child) { - $taxRateRequest->setProductClassId($child->getProduct()->getTaxClassId()); - $rate = $this->_calculator->getRate($taxRateRequest); - $this->_calcRowTaxAmount($child, $rate); - $this->_addAmount($child->getTaxAmount()); - $this->_addBaseAmount($child->getBaseTaxAmount()); - $applied = $this->_calculator->getAppliedRates($taxRateRequest); - if ($rate > 0) { - $itemTaxGroups[$child->getId()] = $applied; - } - $this->_saveAppliedTaxes( + $this->_rowBaseProcessItemTax( $address, - $applied, - $child->getTaxAmount(), - $child->getBaseTaxAmount(), - $rate + $child, + $taxRateRequest, + $itemTaxGroups, + $catalogPriceInclTax ); - $child->setTaxRates($applied); } $this->_recalculateParent($item); } else { - $taxRateRequest->setProductClassId($item->getProduct()->getTaxClassId()); - $rate = $this->_calculator->getRate($taxRateRequest); - $this->_calcRowTaxAmount($item, $rate); - $this->_addAmount($item->getTaxAmount()); - $this->_addBaseAmount($item->getBaseTaxAmount()); - $applied = $this->_calculator->getAppliedRates($taxRateRequest); - if ($rate > 0) { - $itemTaxGroups[$item->getId()] = $applied; - } - $this->_saveAppliedTaxes($address, $applied, $item->getTaxAmount(), $item->getBaseTaxAmount(), $rate); - $item->setTaxRates($applied); + $this->_rowBaseProcessItemTax( + $address, + $item, + $taxRateRequest, + $itemTaxGroups, + $catalogPriceInclTax + ); } } @@ -482,26 +695,39 @@ protected function _rowBaseCalculation(Address $address, $taxRateRequest) * * @param AbstractItem $item * @param float $rate + * @param array $taxGroups + * @param string $taxId + * @param bool $recalculateRowTotalInclTax * @return $this */ - protected function _calcRowTaxAmount($item, $rate) - { + protected function _calcRowTaxAmount( + AbstractItem $item, + $rate, + &$taxGroups = null, + $taxId = null, + $recalculateRowTotalInclTax = false + ) { $inclTax = $item->getIsPriceInclTax(); - $subtotal = $item->getTaxableAmount() + $item->getExtraRowTaxableAmount(); - $baseSubtotal = $item->getBaseTaxableAmount() + $item->getBaseExtraRowTaxableAmount(); - $rateKey = (string)$rate; - $item->setTaxPercent($rate); + $subtotal = $taxSubtotal = $item->getTaxableAmount() + $item->getExtraRowTaxableAmount(); + $baseSubtotal = $baseTaxSubtotal = $item->getBaseTaxableAmount() + $item->getBaseExtraRowTaxableAmount(); + $rateKey = ($taxId == null) ? (string)$rate : $taxId; + + $hiddenTax = 0; + $baseHiddenTax = 0; + $rowTaxBeforeDiscount = 0; + $baseRowTaxBeforeDiscount = 0; - $hiddenTax = null; - $baseHiddenTax = null; switch ($this->_taxData->getCalculationSequence($this->_store)) { - case \Magento\Tax\Model\Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_EXCL: - case \Magento\Tax\Model\Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_INCL: - $rowTax = $this->_calculator->calcTaxAmount($subtotal, $rate, $inclTax); - $baseRowTax = $this->_calculator->calcTaxAmount($baseSubtotal, $rate, $inclTax); + case Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_EXCL: + case Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_INCL: + $rowTaxBeforeDiscount = $this->_calculator->calcTaxAmount($subtotal, $rate, $inclTax, false); + $baseRowTaxBeforeDiscount = $this->_calculator->calcTaxAmount($baseSubtotal, $rate, $inclTax, false); + + $rowTaxBeforeDiscount = $rowTax = $this->_calculator->round($rowTaxBeforeDiscount); + $baseRowTaxBeforeDiscount = $baseRowTax = $this->_calculator->round($baseRowTaxBeforeDiscount); break; - case \Magento\Tax\Model\Calculation::CALC_TAX_AFTER_DISCOUNT_ON_EXCL: - case \Magento\Tax\Model\Calculation::CALC_TAX_AFTER_DISCOUNT_ON_INCL: + case Calculation::CALC_TAX_AFTER_DISCOUNT_ON_EXCL: + case Calculation::CALC_TAX_AFTER_DISCOUNT_ON_INCL: $discountAmount = $item->getDiscountAmount(); $baseDiscountAmount = $item->getBaseDiscountAmount(); $rowTax = $this->_calculator->calcTaxAmount(max($subtotal - $discountAmount, 0), $rate, $inclTax); @@ -510,9 +736,29 @@ protected function _calcRowTaxAmount($item, $rate) $rate, $inclTax ); + $rowTax = $this->_calculator->round($rowTax); + $baseRowTax = $this->_calculator->round($baseRowTax); + + //Calculate the Row Tax before discount + $rowTaxBeforeDiscount = $this->_calculator->calcTaxAmount( + $subtotal, + $rate, + $inclTax, + false + ); + $baseRowTaxBeforeDiscount = $this->_calculator->calcTaxAmount( + $baseSubtotal, + $rate, + $inclTax, + false + ); + + $rowTaxBeforeDiscount = max(0, $this->_calculator->round($rowTaxBeforeDiscount)); + $baseRowTaxBeforeDiscount = max(0, $this->_calculator->round($baseRowTaxBeforeDiscount)); + if ($inclTax && $discountAmount > 0) { - $hiddenTax = $this->_calculator->calcTaxAmount($discountAmount, $rate, $inclTax, false); - $baseHiddenTax = $this->_calculator->calcTaxAmount($baseDiscountAmount, $rate, $inclTax, false); + $hiddenTax = $rowTaxBeforeDiscount - $rowTax; + $baseHiddenTax = $baseRowTaxBeforeDiscount - $baseRowTax; $this->_hiddenTaxes[] = array( 'rate_key' => $rateKey, 'qty' => 1, @@ -536,8 +782,23 @@ protected function _calcRowTaxAmount($item, $rate) } break; } - $item->setTaxAmount(max(0, $rowTax)); - $item->setBaseTaxAmount(max(0, $baseRowTax)); + $item->setTaxAmount($item->getTaxAmount() + max(0, $rowTax)); + $item->setBaseTaxAmount($item->getBaseTaxAmount() + max(0, $baseRowTax)); + if (is_array($taxGroups)) { + $taxGroups[$rateKey]['tax'] = max(0, $rowTax); + $taxGroups[$rateKey]['base_tax'] = max(0, $baseRowTax); + } + + $rowTotalInclTax = $item->getRowTotalInclTax(); + if (!isset($rowTotalInclTax) || $recalculateRowTotalInclTax) { + if ($this->_config->priceIncludesTax($this->_store)) { + $item->setRowTotalInclTax($subtotal); + $item->setBaseRowTotalInclTax($baseSubtotal); + } else { + $item->setRowTotalInclTax($item->getRowTotalInclTax() + $rowTaxBeforeDiscount); + $item->setBaseRowTotalInclTax($item->getBaseRowTotalInclTax() + $baseRowTaxBeforeDiscount); + } + } return $this; } @@ -548,12 +809,15 @@ protected function _calcRowTaxAmount($item, $rate) * @param \Magento\Framework\Object $taxRateRequest * @return $this */ - protected function _totalBaseCalculation(Address $address, $taxRateRequest) - { + protected function _totalBaseCalculation( + Address $address, + \Magento\Framework\Object $taxRateRequest + ) { $items = $this->_getAddressItems($address); $store = $address->getQuote()->getStore(); $taxGroups = array(); $itemTaxGroups = array(); + $catalogPriceInclTax = $this->_config->priceIncludesTax($store); foreach ($items as $item) { if ($item->getParentItem()) { @@ -562,27 +826,23 @@ protected function _totalBaseCalculation(Address $address, $taxRateRequest) if ($item->getHasChildren() && $item->isChildrenCalculated()) { foreach ($item->getChildren() as $child) { - $taxRateRequest->setProductClassId($child->getProduct()->getTaxClassId()); - $rate = $this->_calculator->getRate($taxRateRequest); - $applied_rates = $this->_calculator->getAppliedRates($taxRateRequest); - $taxGroups[(string)$rate]['applied_rates'] = $applied_rates; - $taxGroups[(string)$rate]['incl_tax'] = $child->getIsPriceInclTax(); - $this->_aggregateTaxPerRate($child, $rate, $taxGroups); - if ($rate > 0) { - $itemTaxGroups[$child->getId()] = $applied_rates; - } + $this->_totalBaseProcessItemTax( + $child, + $taxRateRequest, + $taxGroups, + $itemTaxGroups, + $catalogPriceInclTax + ); } $this->_recalculateParent($item); } else { - $taxRateRequest->setProductClassId($item->getProduct()->getTaxClassId()); - $rate = $this->_calculator->getRate($taxRateRequest); - $applied_rates = $this->_calculator->getAppliedRates($taxRateRequest); - $taxGroups[(string)$rate]['applied_rates'] = $applied_rates; - $taxGroups[(string)$rate]['incl_tax'] = $item->getIsPriceInclTax(); - $this->_aggregateTaxPerRate($item, $rate, $taxGroups); - if ($rate > 0) { - $itemTaxGroups[$item->getId()] = $applied_rates; - } + $this->_totalBaseProcessItemTax( + $item, + $taxRateRequest, + $taxGroups, + $itemTaxGroups, + $catalogPriceInclTax + ); } } @@ -591,14 +851,63 @@ protected function _totalBaseCalculation(Address $address, $taxRateRequest) } $address->getQuote()->setTaxesForItems($itemTaxGroups); - foreach ($taxGroups as $rateKey => $data) { - $rate = (double)$rateKey; - $inclTax = $data['incl_tax']; - $totalTax = $this->_calculator->calcTaxAmount(array_sum($data['totals']), $rate, $inclTax); - $baseTotalTax = $this->_calculator->calcTaxAmount(array_sum($data['base_totals']), $rate, $inclTax); + foreach ($taxGroups as $taxId => $data) { + if ($catalogPriceInclTax) { + $rate = (float)$taxId; + } else { + $rate = $data['applied_rates'][0]['percent']; + } + + $totalTax = array_sum($data['tax']); + $baseTotalTax = array_sum($data['base_tax']); $this->_addAmount($totalTax); $this->_addBaseAmount($baseTotalTax); - $this->_saveAppliedTaxes($address, $data['applied_rates'], $totalTax, $baseTotalTax, $rate); + $totalTaxRounded = $this->_calculator->round($totalTax); + $baseTotalTaxRounded = $this->_calculator->round($totalTaxRounded); + $this->_saveAppliedTaxes($address, $data['applied_rates'], $totalTaxRounded, $baseTotalTaxRounded, $rate); + } + + return $this; + } + + /** + * + * @param AbstractItem $item + * @param \Magento\Framework\Object $taxRateRequest + * @param array $taxGroups + * @param array $itemTaxGroups + * @param bool $catalogPriceInclTax + * @return $this + */ + protected function _totalBaseProcessItemTax( + AbstractItem $item, + \Magento\Framework\Object $taxRateRequest, + &$taxGroups, + &$itemTaxGroups, + $catalogPriceInclTax + ) { + $taxRateRequest->setProductClassId($item->getProduct()->getTaxClassId()); + $appliedRates = $this->_calculator->getAppliedRates($taxRateRequest); + $rate = $this->_calculator->getRate($taxRateRequest); + + $recalculateRowTotalInclTax = $this->initializeItemTax($item, $appliedRates, $rate); + + if ($catalogPriceInclTax) { + $taxGroups[(string)$rate]['applied_rates'] = $appliedRates; + $taxGroups[(string)$rate]['incl_tax'] = $item->getIsPriceInclTax(); + $this->_aggregateTaxPerRate($item, $rate, $taxGroups); + } else { + //need to calculate each tax separately + foreach ($appliedRates as $appliedTax) { + $taxId = $appliedTax['id']; + $taxRate = $appliedTax['percent']; + $taxGroups[$taxId]['applied_rates'] = array($appliedTax); + $taxGroups[$taxId]['incl_tax'] = $item->getIsPriceInclTax(); + $this->_aggregateTaxPerRate($item, $taxRate, $taxGroups, $taxId, $recalculateRowTotalInclTax); + } + } + if ($rate > 0) { + $itemTaxGroups[$item->getId()] = $appliedRates; } return $this; } @@ -609,12 +918,19 @@ protected function _totalBaseCalculation(Address $address, $taxRateRequest) * @param AbstractItem $item * @param float $rate * @param array &$taxGroups + * @param string $taxId + * @param bool $recalculateRowTotalInclTax * @return $this */ - protected function _aggregateTaxPerRate($item, $rate, &$taxGroups) - { + protected function _aggregateTaxPerRate( + AbstractItem $item, + $rate, + &$taxGroups, + $taxId = null, + $recalculateRowTotalInclTax = false + ) { $inclTax = $item->getIsPriceInclTax(); - $rateKey = (string)$rate; + $rateKey = ($taxId == null) ? (string)$rate : $taxId; $taxSubtotal = $subtotal = $item->getTaxableAmount() + $item->getExtraRowTaxableAmount(); $baseTaxSubtotal = $baseSubtotal = $item->getBaseTaxableAmount() + $item->getBaseExtraRowTaxableAmount(); $item->setTaxPercent($rate); @@ -626,14 +942,27 @@ protected function _aggregateTaxPerRate($item, $rate, &$taxGroups) $hiddenTax = null; $baseHiddenTax = null; + $discount = 0; + $rowTaxBeforeDiscount = 0; + $baseRowTaxBeforeDiscount = 0; switch ($this->_taxData->getCalculationSequence($this->_store)) { - case \Magento\Tax\Model\Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_EXCL: - case \Magento\Tax\Model\Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_INCL: - $rowTax = $this->_calculator->calcTaxAmount($subtotal, $rate, $inclTax, false); - $baseRowTax = $this->_calculator->calcTaxAmount($baseSubtotal, $rate, $inclTax, false); + case Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_EXCL: + case Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_INCL: + $rowTaxBeforeDiscount = $this->_calculator->calcTaxAmount($subtotal, $rate, $inclTax, false); + $baseRowTaxBeforeDiscount = $this->_calculator->calcTaxAmount($baseSubtotal, $rate, $inclTax, false); + + $taxBeforeDiscountRounded = $rowTax = $this->_deltaRound($rowTaxBeforeDiscount, $rateKey, $inclTax); + $baseTaxBeforeDiscountRounded = $baseRowTax = $this->_deltaRound( + $baseRowTaxBeforeDiscount, + $rateKey, + $inclTax, + 'base' + ); + $item->setTaxAmount($item->getTaxAmount() + max(0, $rowTax)); + $item->setBaseTaxAmount($item->getBaseTaxAmount() + max(0, $baseRowTax)); break; - case \Magento\Tax\Model\Calculation::CALC_TAX_AFTER_DISCOUNT_ON_EXCL: - case \Magento\Tax\Model\Calculation::CALC_TAX_AFTER_DISCOUNT_ON_INCL: + case Calculation::CALC_TAX_AFTER_DISCOUNT_ON_EXCL: + case Calculation::CALC_TAX_AFTER_DISCOUNT_ON_INCL: if ($this->_taxData->applyTaxOnOriginalPrice($this->_store)) { $discount = $item->getOriginalDiscountAmount(); $baseDiscount = $item->getBaseOriginalDiscountAmount(); @@ -644,21 +973,43 @@ protected function _aggregateTaxPerRate($item, $rate, &$taxGroups) $taxSubtotal = max($subtotal - $discount, 0); $baseTaxSubtotal = max($baseSubtotal - $baseDiscount, 0); + $rowTax = $this->_calculator->calcTaxAmount($taxSubtotal, $rate, $inclTax, false); $baseRowTax = $this->_calculator->calcTaxAmount($baseTaxSubtotal, $rate, $inclTax, false); - if (!$item->getNoDiscount() && $item->getWeeeTaxApplied()) { - $rowTaxBeforeDiscount = $this->_calculator->calcTaxAmount($subtotal, $rate, $inclTax, false); - $baseRowTaxBeforeDiscount = $this->_calculator->calcTaxAmount( - $baseSubtotal, - $rate, - $inclTax, - false - ); - } + + $rowTax = $this->_deltaRound($rowTax, $rateKey, $inclTax); + $baseRowTax = $this->_deltaRound($baseRowTax, $rateKey, $inclTax, 'base'); + + $item->setTaxAmount($item->getTaxAmount() + max(0, $rowTax)); + $item->setBaseTaxAmount($item->getBaseTaxAmount() + max(0, $baseRowTax)); + + //Calculate the Row taxes before discount + $rowTaxBeforeDiscount = $this->_calculator->calcTaxAmount( + $subtotal, + $rate, + $inclTax, + false + ); + $baseRowTaxBeforeDiscount = $this->_calculator->calcTaxAmount( + $baseSubtotal, + $rate, + $inclTax, + false + ); + + $taxBeforeDiscountRounded = max( + 0, + $this->_deltaRound($rowTaxBeforeDiscount, $rateKey, $inclTax, 'tax_before_discount') + ); + $baseTaxBeforeDiscountRounded = max( + 0, + $this->_deltaRound($baseRowTaxBeforeDiscount, $rateKey, $inclTax, 'tax_before_discount_base') + ); + if ($inclTax && $discount > 0) { - $hiddenTax = $this->_calculator->calcTaxAmount($discount, $rate, $inclTax, false); - $baseHiddenTax = $this->_calculator->calcTaxAmount($baseDiscount, $rate, $inclTax, false); + $hiddenTax = $taxBeforeDiscountRounded - max(0, $rowTax); + $baseHiddenTax = $baseTaxBeforeDiscountRounded - max(0, $baseRowTax); $this->_hiddenTaxes[] = array( 'rate_key' => $rateKey, 'qty' => 1, @@ -671,21 +1022,22 @@ protected function _aggregateTaxPerRate($item, $rate, &$taxGroups) break; } - $rowTax = $this->_deltaRound($rowTax, $rateKey, $inclTax); - $baseRowTax = $this->_deltaRound($baseRowTax, $rateKey, $inclTax, 'base'); - $item->setTaxAmount(max(0, $rowTax)); - $item->setBaseTaxAmount(max(0, $baseRowTax)); - - if (isset($rowTaxBeforeDiscount) && isset($baseRowTaxBeforeDiscount)) { - $taxBeforeDiscount = max(0, $this->_deltaRound($rowTaxBeforeDiscount, $rateKey, $inclTax)); - $baseTaxBeforeDiscount = max(0, $this->_deltaRound($baseRowTaxBeforeDiscount, $rateKey, $inclTax, 'base')); - - $item->setDiscountTaxCompensation($taxBeforeDiscount - max(0, $rowTax)); - $item->setBaseDiscountTaxCompensation($baseTaxBeforeDiscount - max(0, $baseRowTax)); + $rowTotalInclTax = $item->getRowTotalInclTax(); + if (!isset($rowTotalInclTax) || $recalculateRowTotalInclTax) { + if ($this->_config->priceIncludesTax($this->_store)) { + $item->setRowTotalInclTax($subtotal); + $item->setBaseRowTotalInclTax($baseSubtotal); + } else { + $item->setRowTotalInclTax($item->getRowTotalInclTax() + $taxBeforeDiscountRounded); + $item->setBaseRowTotalInclTax($item->getBaseRowTotalInclTax() + $baseTaxBeforeDiscountRounded); + } } $taxGroups[$rateKey]['totals'][] = max(0, $taxSubtotal); $taxGroups[$rateKey]['base_totals'][] = max(0, $baseTaxSubtotal); + $taxGroups[$rateKey]['tax'][] = max(0, $rowTax); + $taxGroups[$rateKey]['base_tax'][] = max(0, $baseRowTax); + return $this; } @@ -703,7 +1055,8 @@ protected function _deltaRound($price, $rate, $direction, $type = 'regular') if ($price) { $rate = (string)$rate; $type = $type . $direction; - $delta = isset($this->_roundingDeltas[$type][$rate]) ? $this->_roundingDeltas[$type][$rate] : 0; + // 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; $this->_roundingDeltas[$type][$rate] = $price - $this->_calculator->round($price); $price = $this->_calculator->round($price); @@ -740,8 +1093,13 @@ protected function _recalculateParent(AbstractItem $item) * @param float $rate * @return void */ - protected function _saveAppliedTaxes(Address $address, $applied, $amount, $baseAmount, $rate) - { + protected function _saveAppliedTaxes( + Address $address, + $applied, + $amount, + $baseAmount, + $rate + ) { $previouslyAppliedTaxes = $address->getAppliedTaxes(); $process = count($previouslyAppliedTaxes); @@ -771,7 +1129,6 @@ protected function _saveAppliedTaxes(Address $address, $applied, $amount, $baseA } } - if ($appliedAmount || $previouslyAppliedTaxes[$row['id']]['amount']) { $previouslyAppliedTaxes[$row['id']]['amount'] += $appliedAmount; $previouslyAppliedTaxes[$row['id']]['base_amount'] += $baseAppliedAmount; @@ -855,7 +1212,7 @@ public function processConfigArray($config, $store) { $calculationSequence = $this->_taxData->getCalculationSequence($store); switch ($calculationSequence) { - case \Magento\Tax\Model\Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_INCL: + case Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_INCL: $config['before'][] = 'discount'; break; default: diff --git a/app/code/Magento/Tax/Model/System/Config/Source/Tax/Region.php b/app/code/Magento/Tax/Model/System/Config/Source/Tax/Region.php index bd1eef6366858..721588daf9a9d 100644 --- a/app/code/Magento/Tax/Model/System/Config/Source/Tax/Region.php +++ b/app/code/Magento/Tax/Model/System/Config/Source/Tax/Region.php @@ -25,11 +25,6 @@ class Region implements \Magento\Framework\Option\ArrayInterface { - /** - * @var array - */ - protected $_options; - /** * @var \Magento\Directory\Model\Resource\Region\CollectionFactory */ @@ -44,6 +39,8 @@ public function __construct(\Magento\Directory\Model\Resource\Region\CollectionF } /** + * Return list of country's regions as array + * * @param bool $noEmpty * @param string|array|null $country * @return array @@ -58,9 +55,9 @@ public function toOptionArray($noEmpty = false, $country = null) unset($options[0]); } else { if ($options) { - $options[0]['label'] = '*'; + $options[0] = array('value' => '0', 'label' => '*'); } else { - $options = array(array('value' => '', 'label' => '*')); + $options = array(array('value' => '0', 'label' => '*')); } } diff --git a/app/code/Magento/Tax/etc/module.xml b/app/code/Magento/Tax/etc/module.xml index 099b9fe5254ed..11fadea58db84 100644 --- a/app/code/Magento/Tax/etc/module.xml +++ b/app/code/Magento/Tax/etc/module.xml @@ -24,7 +24,7 @@ */ --> - + diff --git a/app/code/Magento/Tax/sql/tax_setup/upgrade-1.6.0.5-1.6.0.6.php b/app/code/Magento/Tax/sql/tax_setup/upgrade-1.6.0.5-1.6.0.6.php new file mode 100644 index 0000000000000..580eecb848ce1 --- /dev/null +++ b/app/code/Magento/Tax/sql/tax_setup/upgrade-1.6.0.5-1.6.0.6.php @@ -0,0 +1,62 @@ +getConnection(); +$adminRuleTable = $installer->getTable('admin_rule'); +$aclRulesDelete = array( + 'Magento_Tax::classes_customer', + 'Magento_Tax::classes_product', + 'Magento_Tax::import_export', + 'Magento_Tax::tax_rates', + 'Magento_Tax::rules' +); + +/** + * Remove unneeded ACL rules + */ +$connection->delete($adminRuleTable, $connection->quoteInto('resource_id IN (?)', $aclRulesDelete)); + +$connection->update( + $adminRuleTable, + array('resource_id' => 'Magento_Tax::manage_tax'), + array('resource_id = ?' => 'Magento_Tax::sales_tax') +); + +/** + * Add new field to 'tax_calculation_rule' + */ +$connection->addColumn( + $this->getTable('tax_calculation_rule'), + 'calculate_subtotal', + [ + 'TYPE' => \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER, + 'NULLABLE' => false, + 'COMMENT' => 'Calculate off subtotal option', + ] +); diff --git a/app/code/Magento/Theme/Block/Adminhtml/System/Design/Theme/Edit/Tab/General.php b/app/code/Magento/Theme/Block/Adminhtml/System/Design/Theme/Edit/Tab/General.php index dd605251675fa..c9863c226b453 100644 --- a/app/code/Magento/Theme/Block/Adminhtml/System/Design/Theme/Edit/Tab/General.php +++ b/app/code/Magento/Theme/Block/Adminhtml/System/Design/Theme/Edit/Tab/General.php @@ -220,9 +220,12 @@ protected function _addThemeFieldset($form, $formData) 'label' => __('Theme Preview Image'), 'title' => __('Theme Preview Image'), 'name' => 'preview', - 'after_element_html' => '_themeImagePath->getPreviewImageDirectoryUrl() - . $formData['preview_image'] . '" />' + . $formData['preview_image'] . '" onclick="imagePreview(\'theme_preview_image\'); return false;">' + . '' ) ); } diff --git a/app/code/Magento/Theme/view/frontend/1column.phtml b/app/code/Magento/Theme/view/frontend/1column.phtml index f4c8a575b92ae..0b2ac06ad088a 100644 --- a/app/code/Magento/Theme/view/frontend/1column.phtml +++ b/app/code/Magento/Theme/view/frontend/1column.phtml @@ -43,7 +43,7 @@ $bodyCss = $this->getBodyClass() ? $this->getBodyClass() : ''; getChildHtml('after_body_start') ?>
getChildHtml('global_notices') ?> - getChildHtml('header-container') ?> + getChildHtml('header_container') ?> getChildHtml('page_top') ?>
getChildHtml('columns_top') ?> diff --git a/app/code/Magento/Theme/view/frontend/2columns-left.phtml b/app/code/Magento/Theme/view/frontend/2columns-left.phtml index ce0f4a8be6942..fa8ea0aa9cbfc 100644 --- a/app/code/Magento/Theme/view/frontend/2columns-left.phtml +++ b/app/code/Magento/Theme/view/frontend/2columns-left.phtml @@ -43,7 +43,7 @@ $bodyCss = $this->getBodyClass() ? $this->getBodyClass() : ''; getChildHtml('after_body_start') ?>
getChildHtml('global_notices') ?> - getChildHtml('header-container') ?> + getChildHtml('header_container') ?> getChildHtml('page_top') ?>
getChildHtml('columns_top') ?> diff --git a/app/code/Magento/Theme/view/frontend/2columns-right.phtml b/app/code/Magento/Theme/view/frontend/2columns-right.phtml index fe652d2a1c8e4..f227734024ea5 100644 --- a/app/code/Magento/Theme/view/frontend/2columns-right.phtml +++ b/app/code/Magento/Theme/view/frontend/2columns-right.phtml @@ -43,7 +43,7 @@ $bodyCss = $this->getBodyClass() ? $this->getBodyClass() : ''; getChildHtml('after_body_start') ?>
getChildHtml('global_notices') ?> - getChildHtml('header-container') ?> + getChildHtml('header_container') ?> getChildHtml('page_top') ?>
getChildHtml('columns_top') ?> diff --git a/app/code/Magento/Theme/view/frontend/3columns.phtml b/app/code/Magento/Theme/view/frontend/3columns.phtml index 60b3a6886b71f..320b9240ba8d8 100644 --- a/app/code/Magento/Theme/view/frontend/3columns.phtml +++ b/app/code/Magento/Theme/view/frontend/3columns.phtml @@ -43,7 +43,7 @@ $bodyCss = $this->getBodyClass() ? $this->getBodyClass() : ''; getChildHtml('after_body_start') ?>
getChildHtml('global_notices') ?> - getChildHtml('header-container') ?> + getChildHtml('header_container') ?> getChildHtml('page_top') ?>
getChildHtml('columns_top') ?> diff --git a/app/code/Magento/Theme/view/frontend/layout/default.xml b/app/code/Magento/Theme/view/frontend/layout/default.xml index 91912a5ae7ea7..059f50dcc4bfa 100644 --- a/app/code/Magento/Theme/view/frontend/layout/default.xml +++ b/app/code/Magento/Theme/view/frontend/layout/default.xml @@ -31,7 +31,7 @@ - + @@ -66,16 +66,6 @@ - diff --git a/app/code/Magento/Theme/view/frontend/page.phtml b/app/code/Magento/Theme/view/frontend/page.phtml deleted file mode 100644 index f07b7e363a6e7..0000000000000 --- a/app/code/Magento/Theme/view/frontend/page.phtml +++ /dev/null @@ -1,59 +0,0 @@ - -getBodyClass() ? $this->getBodyClass() : ''; -?> - - - - - - - getChildHtml('head') ?> - -getAddAttribute() ?> - data-mage-init='{"loaderAjax": {}, "loader": {}}'> - getChildHtml('after_body_start') ?> -
- getChildHtml('global_notices') ?> - getChildHtml('header-container') ?> - getChildHtml('page_top') ?> -
- getChildHtml('page_main') ?> -
- getChildHtml('page_bottom') ?> - - getChildHtml('footer') ?> - - getChildHtml('before_body_end') ?> -
- getAbsoluteFooter() ?> - - diff --git a/app/code/Magento/Theme/view/frontend/print.phtml b/app/code/Magento/Theme/view/frontend/print.phtml index 88525aad918c7..d303d183fd264 100644 --- a/app/code/Magento/Theme/view/frontend/print.phtml +++ b/app/code/Magento/Theme/view/frontend/print.phtml @@ -36,23 +36,24 @@ data-container="body" getAddAttribute() ?> data-mage-init='{"loaderAjax": {}, "loader": {}}'> -getChildHtml('after_body_start') ?> -
-
- - getPrintLogoText()):?> -
escapeHtml($this->getPrintLogoText())) ?>
- -
-
- getChildHtml('content') ?> -
-
-
- + getChildHtml('after_body_start') ?> +
+
+ + getPrintLogoText()):?> +
escapeHtml($this->getPrintLogoText())) ?>
+ +
+
+ getChildHtml('main') ?>
-
+
+
+ +
+
+ getChildHtml('before_body_end') ?> +
getAbsoluteFooter() ?> -
diff --git a/app/code/Magento/Translation/Model/Js/DataProvider.php b/app/code/Magento/Translation/Model/Js/DataProvider.php index 291e9fd1f7f95..7bfc9a5dd1884 100644 --- a/app/code/Magento/Translation/Model/Js/DataProvider.php +++ b/app/code/Magento/Translation/Model/Js/DataProvider.php @@ -173,6 +173,7 @@ public function getData() 'Your order cannot be completed at this time as there is no payment methods available for it.' => __('Your order cannot be completed at this time as there is no payment methods available for it.'), 'Edit Order' => __('Edit Order'), 'Ok' => __('Ok'), + 'Please specify at least one search term.' => __('Please specify at least one search term.'), ); } } diff --git a/app/code/Magento/Wishlist/etc/module.xml b/app/code/Magento/Wishlist/etc/module.xml index 525db7a1cd460..b34f798969b62 100644 --- a/app/code/Magento/Wishlist/etc/module.xml +++ b/app/code/Magento/Wishlist/etc/module.xml @@ -42,7 +42,8 @@ - + + diff --git a/app/code/Magento/Wishlist/view/frontend/js/components.phtml b/app/code/Magento/Wishlist/view/frontend/js/components.phtml index 55af731fd1edf..223538be23d16 100644 --- a/app/code/Magento/Wishlist/view/frontend/js/components.phtml +++ b/app/code/Magento/Wishlist/view/frontend/js/components.phtml @@ -34,10 +34,6 @@ ], wishlistSearch: [ 'getViewFileUrl('Magento_Wishlist::js/search.js') ?>' - ], - configurable: [ - 'getViewFileUrl('jquery/jquery.parsequery.js') ?>', - 'getViewFileUrl('Magento_ConfigurableProduct::js/configurable.js') ?>' ] }); })(jQuery); diff --git a/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_configure_type_configurable.xml b/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_configure_type_configurable.xml index 4fcfe46d66654..7f1375379d7c0 100644 --- a/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_configure_type_configurable.xml +++ b/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_configure_type_configurable.xml @@ -26,6 +26,7 @@ + diff --git a/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_configure_type_downloadable.xml b/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_configure_type_downloadable.xml new file mode 100644 index 0000000000000..69d5d249d2a91 --- /dev/null +++ b/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_configure_type_downloadable.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + product.price.render.default + link_price + 1 + + + + + diff --git a/app/code/Magento/Wishlist/view/frontend/shared.phtml b/app/code/Magento/Wishlist/view/frontend/shared.phtml index 915728ca6e58d..77974db97539d 100644 --- a/app/code/Magento/Wishlist/view/frontend/shared.phtml +++ b/app/code/Magento/Wishlist/view/frontend/shared.phtml @@ -66,12 +66,12 @@ $imageBlock = $this->getLayout()->createBlock('Magento\Catalog\Block\Product\Im isSaleable()): ?> - - + @@ -86,7 +86,7 @@ $imageBlock = $this->getLayout()->createBlock('Magento\Catalog\Block\Product\Im
diff --git a/app/design/adminhtml/Magento/backend/Magento_Backend/css/source/module.less b/app/design/adminhtml/Magento/backend/Magento_Backend/css/source/module.less index 69a1c5a06fe91..09c58867ae828 100644 --- a/app/design/adminhtml/Magento/backend/Magento_Backend/css/source/module.less +++ b/app/design/adminhtml/Magento/backend/Magento_Backend/css/source/module.less @@ -25,7 +25,7 @@ .search-global { &.miniform { position: relative; - z-index: 2; + z-index: 1000; display: inline-block; vertical-align: top; margin:6px 10px 0; @@ -384,51 +384,47 @@ color: #9ba8b5; } -.suggest-expandable .action-dropdown .action-toggle { - display: inline-block; - max-width: 500px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - background: none; - border: none; - box-shadow: none; - color: #676056; - font-size: 12px; - padding: 5px 4px; - filter: none; -} - -.suggest-expandable .action-dropdown .action-toggle span { - display: inline; -} - -.suggest-expandable .action-dropdown .action-toggle:before { - display: inline-block; - float: right; - margin-left: 4px; - font-size: 13px; - color: #b2b0ad; -} - -.suggest-expandable .action-dropdown .action-toggle:hover:before { - color: #7e7e7e; -} - -.suggest-expandable .dropdown-menu { - margin: 1px 0 0; - left: 0; - right: auto; - width: 221px; -} - .suggest-expandable { + .action-dropdown .action-toggle { + display: inline-block; + max-width: 500px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + background: none; + border: none; + box-shadow: none; + color: #676056; + font-size: 12px; + padding: 5px 4px; + filter: none; + span { + display: inline; + } + &:before { + display: inline-block; + float: right; + margin-left: 4px; + font-size: 13px; + color: #b2b0ad; + } + &:hover:before { + color: #7e7e7e; + } + } + .dropdown-menu { + margin: 1px 0 0; + left: 0; + right: auto; + width: 245px; + z-index: 4; + } .mage-suggest { border: none; border-radius: 3px 3px 0 0; &:after { - top: 6px; - right: 6px; + top: 10px; + right: 8px; } } .mage-suggest-inner { @@ -446,7 +442,7 @@ margin: 6px 5px 5px; padding-right: 20px; border: 1px solid #ada89e; - width: 211px; + width: 236px; z-index: 1; } > input.ui-autocomplete-loading, diff --git a/app/design/adminhtml/Magento/backend/Magento_Core/css/source/module.less b/app/design/adminhtml/Magento/backend/Magento_Core/css/source/module.less new file mode 100644 index 0000000000000..85554dabcb89b --- /dev/null +++ b/app/design/adminhtml/Magento/backend/Magento_Core/css/source/module.less @@ -0,0 +1,30 @@ +// /** +// // * 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. +// * +// * @category design +// * @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) +// */ + +.debugging-hints { + .page-actions { + position: relative; + z-index: 1; + } +} diff --git a/app/design/adminhtml/Magento/backend/Magento_Tax/css/source/module.less b/app/design/adminhtml/Magento/backend/Magento_Tax/css/source/module.less new file mode 100644 index 0000000000000..56cebcafeb028 --- /dev/null +++ b/app/design/adminhtml/Magento/backend/Magento_Tax/css/source/module.less @@ -0,0 +1,40 @@ +///** +// // * 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) +// */ + +.action-add.mselect-button-add { + &:extend(button all); +} + +.block.mselect-list { + .mselect-input { + width: 100%; + } + .mselect-input-container { + .mselect-save { + top: 4px; + } + .mselect-cancel { + top: 4px; + } + } +} diff --git a/app/design/adminhtml/Magento/backend/Magento_Theme/css/source/module.less b/app/design/adminhtml/Magento/backend/Magento_Theme/css/source/module.less index fcc6ba9439433..3f8ddff06b025 100644 --- a/app/design/adminhtml/Magento/backend/Magento_Theme/css/source/module.less +++ b/app/design/adminhtml/Magento/backend/Magento_Theme/css/source/module.less @@ -304,7 +304,8 @@ body { @_icon-font-color-hover: @page-main-action-color, @_icon-font-color-active: @page-main-action-color, @_dropdown-list-item-hover: transparent, - @_dropdown-list-item-padding: 0 + @_dropdown-list-item-padding: 0, + @_dropdown-list-min-width: 195px ); .action.toggle { .button-reset(); @@ -316,7 +317,6 @@ body { margin-top: 4px; padding-top: 5px; left: 0; - min-width: 195px; li { border: 0; cursor: default; @@ -464,7 +464,8 @@ button { @_toggle-selector: ~".action-toggle", @_button-selector: ~".action-default", @_options-selector : ~".dropdown-menu", - @_dropdown-split-button-border-radius-fix: true + @_dropdown-split-button-border-radius-fix: true, + @_dropdown-split-list-min-width: 175px ); vertical-align: middle; } @@ -533,3 +534,7 @@ button { width: 100%; } } + +.ui-widget-overlay { + position: fixed; +} diff --git a/app/design/adminhtml/Magento/backend/css/admin.less b/app/design/adminhtml/Magento/backend/css/admin.less index 40733464ee9ad..3a9e4d2cc3552 100644 --- a/app/design/adminhtml/Magento/backend/css/admin.less +++ b/app/design/adminhtml/Magento/backend/css/admin.less @@ -3368,7 +3368,7 @@ tr.dynamic-grid input.input-text { border-top: none; } -.attribute-popup .fieldset-wrapper .fieldset-wrapper-title { +.attribute-popup .fieldset-wrapper:not(.collapsable-wrapper) .fieldset-wrapper-title { border-bottom: none; } @@ -3761,7 +3761,6 @@ tr.dynamic-grid input.input-text { } } - // Clearfix .clearfix:before, .clearfix:after, diff --git a/app/design/adminhtml/Magento/backend/css/source/abstract.less b/app/design/adminhtml/Magento/backend/css/source/abstract.less index 442ff06ac83d0..5fb30761d9c68 100644 --- a/app/design/adminhtml/Magento/backend/css/source/abstract.less +++ b/app/design/adminhtml/Magento/backend/css/source/abstract.less @@ -146,3 +146,11 @@ width: 250px; } } + +.h-scroll { + overflow-x: auto; +} + +.add-clearer { + .clearer(); +} diff --git a/app/design/adminhtml/Magento/backend/css/source/navigation.less b/app/design/adminhtml/Magento/backend/css/source/navigation.less index ab0498e10c32e..3ef24330dadb8 100644 --- a/app/design/adminhtml/Magento/backend/css/source/navigation.less +++ b/app/design/adminhtml/Magento/backend/css/source/navigation.less @@ -22,12 +22,14 @@ // * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) // */ -/* - Global Navigation --------------------------------------- */ +// +// Global Navigation +// -------------------------------------- .navigation { background-color: @color-middle; + position: relative; + z-index: 5; } .navigation .level-0.reverse > .submenu { @@ -36,9 +38,9 @@ .navigation > ul { &:extend(._layout-width all); + &:extend(.add-clearer all); position: relative; text-align: right; - z-index: 900; } .navigation .level-0 > .submenu { @@ -91,7 +93,6 @@ .navigation .level-0 > a { background: none; - //position: relative; display: block; padding: 12px 13px 0; .style15(); @@ -115,7 +116,6 @@ } } -//.navigation .level-0:hover > a, .navigation .level-0.hover.recent > a { background: #fff; .style15I(); @@ -201,9 +201,9 @@ margin-left: 15px; } -/* - Admin and Store Settings --------------------------------------- */ +// +// Admin and Store Settings +// -------------------------------------- .navigation .level-0.item-system, .navigation .level-0.item-stores { float: none; diff --git a/app/design/adminhtml/Magento/backend/css/source/table.less b/app/design/adminhtml/Magento/backend/css/source/table.less index fd207398b4f7f..78bb5dd66fd3a 100644 --- a/app/design/adminhtml/Magento/backend/css/source/table.less +++ b/app/design/adminhtml/Magento/backend/css/source/table.less @@ -852,10 +852,12 @@ td.col-sku { font-size: 13px; line-height: 28px; padding: 15px 15px 0; + &:extend(.add-clearer all); > .entry-edit { float: right; .field-row { display: inline-block; + vertical-align: top; } .validation-advice { display: none !important; @@ -956,6 +958,11 @@ td.col-sku { .grid { padding: 0; } + .massaction { + padding: 0; + border-top: none; + margin-bottom: 15px; + } } .accordion .grid { @@ -1088,13 +1095,6 @@ td.col-sku { &:extend(.ellipsis all); &:extend(.col-110-max all); } - .col-reason { - &:extend(.ellipsis all); - &:extend(.col-70-max all); - a { - display: block; - } - } } .col-actions { a { @@ -1124,7 +1124,7 @@ td.col-sku { .catalog-product-edit .ui-tabs-panel .grid { .hor-scroll { - overflow-x: auto; + &:extend(.h-scroll); } .col-name, .col-type, @@ -1236,7 +1236,7 @@ td.col-sku { .review-product-index { .grid { .hor-scroll { - overflow-x: auto; + &:extend(.h-scroll); } .col-name { &:extend(.col-110-max all); @@ -1406,6 +1406,11 @@ td.col-sku { } } } +.adminhtml-rma-edit { + .hor-scroll { + &:extend(.h-scroll); + } +} // // Stores -> All Stores diff --git a/app/design/adminhtml/Magento/backend/mui/form.css b/app/design/adminhtml/Magento/backend/mui/form.css index e266d2317bc68..4acdd9d45f7fb 100644 --- a/app/design/adminhtml/Magento/backend/mui/form.css +++ b/app/design/adminhtml/Magento/backend/mui/form.css @@ -147,6 +147,10 @@ span.required { width: auto; } +.addon select + .addafter { + border: none; +} + .ie .addon textarea, .ie .addon select { display:inline-block; diff --git a/app/design/frontend/Magento/blank/Magento_Theme/css/source/module.less b/app/design/frontend/Magento/blank/Magento_Theme/css/source/module.less index b040f3a31a0a0..03dcf370b01f6 100644 --- a/app/design/frontend/Magento/blank/Magento_Theme/css/source/module.less +++ b/app/design/frontend/Magento/blank/Magento_Theme/css/source/module.less @@ -51,33 +51,6 @@ body { margin-bottom: 20px; } -.customer.welcome { - .dropdown( - @_toggle-selector : ~".action.switch", - @_options-selector : ~"ul", - @_dropdown-actions-padding: 0, - @_dropdown-list-item-padding: 8px, - @_dropdown-toggle-icon-content: @icon-down, - @_dropdown-toggle-active-icon-content: @icon-up, - @_icon-font-text-hide: true, - @_icon-font-size: 22px, - @_icon-font-line-height: 22px - ); - .action.switch { - .button-reset(); - } - li { - &:extend(.switcher li all); - min-width: 120px; - a { - &:extend(.page.header .panel.header .switcher all); - } - } - .header.links & ~ li { - display: none; - } -} - .header { &.content { padding-top: 10px; @@ -219,10 +192,10 @@ body { @_dropdown-toggle-active-icon-content: @icon-up, @_icon-font-text-hide: true, @_icon-font-size: 22px, - @_icon-font-line-height: 22px + @_icon-font-line-height: 22px, + @_dropdown-list-min-width: 160px ); ul.dropdown { - min-width: 160px; a { display: block; padding: 8px; diff --git a/dev/tests/functional/composer.json.dist b/dev/tests/functional/composer.json.dist index 0aa8ef282c543..99368dbb49ebd 100644 --- a/dev/tests/functional/composer.json.dist +++ b/dev/tests/functional/composer.json.dist @@ -6,7 +6,7 @@ } ], "require": { - "magento/mtf": "dev-develop", + "magento/mtf": "dev-master", "php": ">=5.4.0", "phpunit/phpunit": "3.7.*", "phpunit/phpunit-selenium": ">=1.2", 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 new file mode 100644 index 0000000000000..2f6a7c38982d4 --- /dev/null +++ b/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/JquerytreeElement.php @@ -0,0 +1,180 @@ + ul'; + + /** + * Css class for detecting tree nodes. + * + * @var string + */ + protected $nodeSelector = 'li[data-id]'; + + /** + * Css class for detecting tree nodes. + * + * @var string + */ + protected $checkedNodeSelector = 'li.jstree-checked[data-id]'; + + /** + * Css class for fetching node's name. + * + * @var string + */ + protected $nodeName = 'a'; + + /** + * Array, which holds all selected elements paths. + * + * @var array + */ + protected $checkedNodesPaths = []; + + /** + * Returns structure of the jquerytree element. + * + * @return array + */ + public function getStructure() + { + return $this->_getNodeContent($this, 'div[class*=jstree] > ul'); + } + + /** + * Recursive walks tree + * + * @param Element $node + * @param string $parentCssClass + * @return array + */ + protected function _getNodeContent($node, $parentCssClass) + { + $counter = 1; + $nextNodeSelector = $parentCssClass . " > " . $this->nodeSelector . ":nth-of-type($counter)"; + $nodeArray = []; + //Get list of all children nodes to work with + $newNode = $node->find($nextNodeSelector); + while ($newNode->isVisible()) { + $nextCheckedNodeSelector = $parentCssClass . " > " . $this->checkedNodeSelector . ":nth-of-type($counter)"; + $nodesNames = $newNode->find($this->nodeName); + $text = ltrim($nodesNames->getText()); + $childNodeSelector = $nextNodeSelector . $this->nodeCssClass; + $nodesContents = $newNode->find($childNodeSelector); + $subNodes = null; + if ($nodesContents->isVisible()) { + $subNodes = $this->_getNodeContent($nodesContents, $childNodeSelector); + } + $nodeArray[] = [ + 'name' => $text, + 'isChecked' => $node->find($nextCheckedNodeSelector)->isVisible() ? true : false, + 'element' => $newNode, + 'subnodes' => $subNodes, + ]; + ++$counter; + $nextNodeSelector = $parentCssClass . " > " . $this->nodeSelector . ":nth-of-type($counter)"; + $newNode = $node->find($nextNodeSelector); + } + return $nodeArray; + } + + /** + * Retrieve array of checked nodes from structure array. + * + * @param array $structure + * @return array|null + */ + protected function getCheckedNodes($structure) + { + $pathArray = []; + if ($structure['isChecked'] == true) { + array_push($pathArray, $structure['name']); + if (is_array($structure['subnodes'])) { + foreach ($structure['subnodes'] as $node) { + array_push($pathArray, $this->getCheckedNodes($node)); + } + } + return $pathArray; + } + return null; + } + + /** + * Method for recursive walk array of checked elements. + * If element haven't subnodes, adds element's path to $checkedNodesPaths + * + * @param array $pathArray + * @param string $rootPath + * @return string + */ + protected function getPathFromArray($pathArray, $rootPath = '') + { + $path = ''; + $rootPath = $rootPath == '' ? $pathArray[0] : $rootPath . '/' . $pathArray[0]; + if (count($pathArray) > 1) { + for ($counter = 1; $counter < count($pathArray); $counter++) { + $path .= $this->getPathFromArray($pathArray[$counter], $rootPath); + } + } else { + $path = $rootPath; + $this->checkedNodesPaths[] = $path; + } + return $path; + } + + /** + * Returns array of paths of all selected elements. + * + * @return array + */ + public function getValue() + { + $pathsArray = []; + $structure = $this->getStructure(); + foreach ($structure as $structureChunk) { + $pathsArray[] = $this->getCheckedNodes($structureChunk); + } + foreach ($pathsArray as $pathArray) { + $this->getPathFromArray($pathArray); + } + return $this->checkedNodesPaths; + } +} diff --git a/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/MultiselectlistElement.php b/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/MultiselectlistElement.php new file mode 100644 index 0000000000000..0b2526fa6f667 --- /dev/null +++ b/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/MultiselectlistElement.php @@ -0,0 +1,126 @@ +getOptions(); + $values = is_array($values) ? $values : [$values]; + + foreach ($options as $option) { + /** @var Element $option */ + $optionText = $option->getText(); + $isChecked = $option->find($this->optionCheckedElement, Locator::SELECTOR_XPATH)->isVisible(); + $inArray = in_array($optionText, $values); + if (($isChecked && !$inArray) || (!$isChecked && $inArray)) { + $option->click(); + } + } + } + + /** + * Method that returns array with checked options in multiple select list + * + * @return array|string + */ + public function getValue() + { + $checkedOptions = []; + $options = $this->getOptions(); + + foreach ($options as $option) { + /** @var Element $option */ + $checkedOption = $option->find($this->optionCheckedElement, Locator::SELECTOR_XPATH); + if ($checkedOption->isVisible()) { + $checkedOptions[] = $checkedOption->getText(); + } + } + + return $checkedOptions; + } + + /** + * Getting all options in multi select list + * + * @return array + */ + protected function getOptions() + { + $options = []; + $counter = 1; + + $newOption = $this->find(sprintf($this->optionElement, $counter), Locator::SELECTOR_XPATH); + while ($newOption->isVisible()) { + $options[] = $newOption; + $counter++; + $newOption = $this->find(sprintf($this->optionElement, $counter), Locator::SELECTOR_XPATH); + } + + return $options; + } +} diff --git a/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/Tree.php b/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/Tree.php new file mode 100644 index 0000000000000..03e11557086e2 --- /dev/null +++ b/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/Tree.php @@ -0,0 +1,181 @@ +getStructure(); //Set the root of a structure as a first structure chunk + foreach ($pathArray as $pathChunk) { + $structureChunk = $this->deep($pathChunk, $structureChunk); + $structureChunk = ($pathChunkCounter == $pathArrayLength - 1) ? + $structureChunk['element'] : $structureChunk['subnodes']; + ++$pathChunkCounter; + } + if ($structureChunk) { + $needleElement = $structureChunk->find($this->nodeName); + $needleElement->click(); + } else { + throw new \InvalidArgumentException('The path specified for tree is invalid'); + } + } + + /** + * Internal function for deeping in hierarchy of the tree structure + * Return the nested array if it exists or object of class Element if this is the final part of structure + * + * @param string $pathChunk + * @param array $structureChunk + * @return array|Element||false + */ + protected function deep($pathChunk, $structureChunk) + { + if (is_array($structureChunk)) { + foreach ($structureChunk as $structureNode) { + $pattern = '/' . $pathChunk . '\s\([\d]+\)|' . $pathChunk . '/'; + if (isset($structureNode) && preg_match($pattern, $structureNode['name'])) { + return $structureNode; + } + } + } + return false; + } + + /** + * Recursive walks tree + * + * @param Element $node + * @param string $parentCssClass + * @return array + */ + protected function _getNodeContent($node, $parentCssClass) + { + $nodeArray = []; + $nodeList = []; + $counter = 1; + $newNode = $node->find($parentCssClass . ' > ' . $this->nodeSelector . ':nth-of-type(' . $counter . ')'); + //Get list of all children nodes to work with + while ($newNode->isVisible()) { + $nodeList[] = $newNode; + ++$counter; + $newNode = $node->find($parentCssClass . ' > ' . $this->nodeSelector . ':nth-of-type(' . $counter . ')'); + } + //Write to array values of current node + foreach ($nodeList as $currentNode) { + /** @var Element $currentNode */ + $nodesNames = $currentNode->find($this->nodeName); + $nodesContents = $currentNode->find($this->nodeCssClass); + $text = ltrim($nodesNames->getText()); + $nodeArray[] = [ + 'name' => $text, + 'element' => $currentNode, + 'subnodes' => $nodesContents->isVisible() ? + $this->_getNodeContent($nodesContents, $this->nodeCssClass) : null + ]; + } + return $nodeArray; + } +} diff --git a/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/TreeElement.php b/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/TreeElement.php index 7ece75ae2926d..4fbbe575a59f4 100644 --- a/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/TreeElement.php +++ b/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/TreeElement.php @@ -24,16 +24,12 @@ namespace Mtf\Client\Driver\Selenium\Element; -use Mtf\Client\Element as ElementInterface; -use Mtf\Client\Driver\Selenium\Element; -use Mtf\Client\Element\Locator; - /** * Class TreeElement * Typified element class for Tree elements * */ -class TreeElement extends Element +class TreeElement extends Tree { /** * Css class for finding tree nodes @@ -43,96 +39,18 @@ class TreeElement extends Element protected $nodeCssClass = '.x-tree-node > .x-tree-node-ct'; /** - * Drag'n'drop method is not accessible in this class. - * Throws exception if used. - * - * @param ElementInterface $target - * @throws \BadMethodCallException - */ - public function dragAndDrop(ElementInterface $target) - { - throw new \BadMethodCallException('Not applicable for this class of elements (TreeElement)'); - } - - /** - * setValue method is not accessible in this class. - * Throws exception if used. - * - * @param string|array $value - * @throws \BadMethodCallException - */ - public function setValue($value) - { - throw new \BadMethodCallException('Not applicable for this class of elements (TreeElement)'); - } - - /** - * getValue method is not accessible in this class. - * Throws exception if used. + * Css class for detecting tree nodes * - * @throws \BadMethodCallException - */ - public function getValue() - { - throw new \BadMethodCallException('Not applicable for this class of elements (TreeElement)'); - - } - - /** - * keys method is not accessible in this class. - * Throws exception if used. - * - * @param array $keys - * @throws \BadMethodCallException - */ - public function keys(array $keys) - { - throw new \BadMethodCallException('Not applicable for this class of elements (TreeElement)'); - } - - /** - * Click a tree element by its path (Node names) in tree - * - * @param string $path - * @throws \InvalidArgumentException + * @var string */ - public function clickByPath($path) - { - $pathChunkCounter = 0; - $pathArray = explode('/', $path); - $pathArrayLength = count($pathArray); - $structureChunk = $this->getStructure(); //Set the root of a structure as a first structure chunk - foreach ($pathArray as $pathChunk) { - $structureChunk = $this->deep($pathChunk, $structureChunk); - $structureChunk = ($pathChunkCounter == $pathArrayLength - 1) ? - $structureChunk['element'] : $structureChunk['subnodes']; - ++$pathChunkCounter; - } - if ($structureChunk) { - $needleElement = $structureChunk->find('div > a'); - $needleElement->click(); - } else { - throw new \InvalidArgumentException('The path specified for tree is invalid'); - } - } + protected $nodeSelector = '.x-tree-node'; /** - * Internal function for deeping in hierarchy of the tree structure - * Return the nested array if it exists or object of class Element if this is the final part of structure + * Css class for fetching node's name * - * @param string $pathChunk - * @param array $structureChunk - * @return array|Element||false + * @var string */ - protected function deep($pathChunk, $structureChunk) - { - foreach ($structureChunk as $structureNode) { - if (isset($structureNode) && preg_match('/' . $pathChunk . ' \(\d+\)/', $structureNode['name'])) { - return $structureNode; - } - } - return false; - } + protected $nodeName = 'div > a'; /** * Get structure of the tree element @@ -143,43 +61,4 @@ public function getStructure() { return $this->_getNodeContent($this, '.x-tree-root-node'); } - - /** - * Get recursive structure of the tree content - * - * @param Element $node - * @param string $parentCssClass - * @return array - */ - protected function _getNodeContent($node, $parentCssClass) - { - $nodeArray = array(); - $nodeList = array(); - $counter = 1; - - $newNode = $node->find($parentCssClass .' > .x-tree-node:nth-of-type(' . $counter . ')'); - - //Get list of all children nodes to work with - while ($newNode->isVisible()) { - $nodeList[] = $newNode; - ++$counter; - $newNode = $node->find($parentCssClass .' > .x-tree-node:nth-of-type(' . $counter . ')'); - } - - //Write to array values of current node - foreach ($nodeList as $currentNode) { - /** @var Element $currentNode */ - $nodesNames = $currentNode->find('div > a > span'); - $nodesContents = $currentNode->find($this->nodeCssClass); - $text = $nodesNames->getText(); - $nodeArray[] = array( - 'name' => $text, - 'element' => $currentNode, - 'subnodes' => $nodesContents->isVisible() ? - $this->_getNodeContent($nodesContents, '.x-tree-node > .x-tree-node-ct') : null - ); - } - - return $nodeArray; - } } diff --git a/dev/tests/functional/lib/Mtf/Util/Generate/testcase.xml b/dev/tests/functional/lib/Mtf/Util/Generate/testcase.xml index 954a17a51142c..19edcac777463 100644 --- a/dev/tests/functional/lib/Mtf/Util/Generate/testcase.xml +++ b/dev/tests/functional/lib/Mtf/Util/Generate/testcase.xml @@ -1,4 +1,4 @@ - + + + + + [name='new-attribute-set-name'] + + + 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 index 7f612055742d3..192f4ea671de1 100644 --- 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 @@ -24,64 +24,95 @@ namespace Magento\Catalog\Test\Block\Adminhtml\Product\Edit; +use Mtf\ObjectManager; use Mtf\Client\Element; -use Mtf\Client\Element\Locator; use Magento\Backend\Test\Block\Widget\Tab; -use Mtf\Factory\Factory; /** - * Custom Options Tab - * + * Class AdvancedPricingTab + * Product advanced pricing tab */ class AdvancedPricingTab extends Tab { /** - * Fill group price options + * Class name 'Subform' of the main tab form + * + * @var array + */ + protected $childrenForm = [ + 'group_price' => 'AdvancedPricingTab\OptionGroup', + 'tier_price' => 'AdvancedPricingTab\OptionTier' + ]; + + /** + * Fill 'Advanced price' product form on tab * * @param array $fields - * @param Element $element + * @param Element|null $element * @return $this */ - public function fillFormTab(array $fields, Element $element) + public function fillFormTab(array $fields, Element $element = null) { - $root = $element; - $this->_rootElement->waitUntil( - function () use ($root) { - return $root->find('[data-tab-panel=advanced-pricing]')->isVisible(); - } - ); - if (isset($fields['special_price']['value'])) { - $container = $root->find('#attribute-special_price-container'); - Factory::getBlockFactory() - ->getMagentoCatalogAdminhtmlProductEditAdvancedPricingTabSpecialOption($container) - ->fill($fields['special_price']); - } + foreach ($fields as $fieldName => $field) { + // Fill form + if (isset($this->childrenForm[$fieldName]) && is_array($field['value'])) { + /** @var \Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Options $optionsForm */ + $optionsForm = $this->blockFactory->create( + __NAMESPACE__ . '\\' . $this->childrenForm[$fieldName], + ['element' => $this->_rootElement] + ); - if (isset($fields['group_price']['value'])) { - $button = $root->find('[title="Add Group Price"]'); - $container = $root->find('#attribute-group_price-container'); - foreach ($fields['group_price']['value'] as $rowId => $data) { - $rowPrefix = 'group_price_row_' . $rowId; - $button->click(); - $row = $container->find('//tr[td[select[@id="' . $rowPrefix . '_website"]]]', Locator::SELECTOR_XPATH); - Factory::getBlockFactory() - ->getMagentoCatalogAdminhtmlProductEditAdvancedPricingTabGroupOption($row) - ->fill($rowPrefix, $data); + foreach ($field['value'] as $key => $option) { + ++$key; + $optionsForm->fillOptions( + $option, + $this->_rootElement->find( + '#attribute-' . $fieldName . '-container tbody tr:nth-child(' . $key . ')' + ) + ); + } + } elseif (!empty($field['value'])) { + $data = $this->dataMapping([$fieldName => $field]); + $this->_fill($data, $this->_rootElement); } } - if (isset($fields['tier_price']['value'])) { - $button = $root->find('[title="Add Tier"]'); - $container = $root->find('#attribute-tier_price-container'); - foreach ($fields['tier_price']['value'] as $rowId => $data) { - $rowPrefix = 'tier_price_row_' . $rowId; - $button->click(); - $row = $container->find('//tr[td[select[@id="' . $rowPrefix . '_website"]]]', Locator::SELECTOR_XPATH); - Factory::getBlockFactory() - ->getMagentoCatalogAdminhtmlProductEditAdvancedPricingTabGroupOption($row) - ->fill($rowPrefix, $data); + return $this; + } + + /** + * Get data of tab + * + * @param array|null $fields + * @param Element|null $element + * @return array + */ + public function getDataFormTab($fields = null, Element $element = null) + { + $formData = []; + foreach ($fields as $fieldName => $field) { + // Data collection forms + if (isset($this->childrenForm[$fieldName]) && is_array($field['value'])) { + /** @var \Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Options $optionsForm */ + $optionsForm = $this->blockFactory->create( + __NAMESPACE__ . '\\' . $this->childrenForm[$fieldName], + ['element' => $this->_rootElement] + ); + + foreach ($field['value'] as $key => $option) { + $formData[$fieldName][$key++] = $optionsForm->getDataOptions( + $option, + $this->_rootElement->find( + '#attribute-' . $fieldName . '-container tbody tr:nth-child(' . $key . ')' + ) + ); + } + } elseif (!empty($field['value'])) { + $data = $this->dataMapping([$fieldName => $field]); + $formData[$fieldName] = $this->_getData($data, $this->_rootElement); } } - return $this; + + return $formData; } } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab/GroupOption.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab/GroupOption.php deleted file mode 100644 index 45ee4077a581b..0000000000000 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab/GroupOption.php +++ /dev/null @@ -1,61 +0,0 @@ -_rootElement - ->find('#' . $rowPrefix . '_website', Locator::SELECTOR_CSS, 'select') - ->setValue($data['website']); - } - if (isset($data['customer_group'])) { - $this->_rootElement - ->find('#' . $rowPrefix . '_cust_group', Locator::SELECTOR_CSS, 'select') - ->setValue($data['customer_group']); - } - if (isset($data['quantity'])) { - $this->_rootElement->find('#' . $rowPrefix . '_qty')->setValue($data['quantity']); - } - if (isset($data['price'])) { - $this->_rootElement->find('#' . $rowPrefix . '_price')->setValue($data['price']); - } - } -} 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 new file mode 100644 index 0000000000000..9d98751f39284 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab/OptionGroup.php @@ -0,0 +1,55 @@ +_rootElement->find($this->buttonFormLocator)->click(); + return parent::fillOptions($fields, $element); + } +} diff --git a/app/code/Magento/Persistent/view/frontend/remember_me_tooltip.phtml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab/OptionGroup.xml similarity index 62% rename from app/code/Magento/Persistent/view/frontend/remember_me_tooltip.phtml rename to dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab/OptionGroup.xml index 8d8d5d5ffa584..a6577bd2c3474 100644 --- a/app/code/Magento/Persistent/view/frontend/remember_me_tooltip.phtml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab/OptionGroup.xml @@ -1,4 +1,5 @@ - + + + + + [id$="_price"] + + + [id$="_website"] + select + + + [id$="_cust_group"] + select + + + 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 new file mode 100644 index 0000000000000..f62941712b8a1 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab/OptionTier.php @@ -0,0 +1,55 @@ +_rootElement->find($this->buttonFormLocator)->click(); + return parent::fillOptions($fields, $element); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab/OptionTier.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab/OptionTier.xml new file mode 100644 index 0000000000000..69c25f9a7c1d9 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab/OptionTier.xml @@ -0,0 +1,43 @@ + + + + + + [id$="_price"] + + + [id$="_website"] + select + + + [id$="_cust_group"] + select + + + [id$="_qty"] + + + diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab/TierOption.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab/TierOption.php deleted file mode 100644 index b57b6e2fdbef4..0000000000000 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab/TierOption.php +++ /dev/null @@ -1,61 +0,0 @@ -_rootElement - ->find('#' . $rowPrefix . '_website', Locator::SELECTOR_CSS, 'select') - ->setValue($data['website']); - } - if (isset($data['customer_group'])) { - $this->_rootElement - ->find('#' . $rowPrefix . '_cust_group', Locator::SELECTOR_CSS, 'select') - ->setValue($data['customer_group']); - } - if (isset($data['price'])) { - $this->_rootElement->find('#' . $rowPrefix . '_price')->setValue($data['price']); - } - if (isset($data['quantity'])) { - $this->_rootElement->find('#' . $rowPrefix . '_qty')->setValue($data['quantity']); - } - } -} 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/CustomOptionsTab.php index 442339d6cd69c..7de6ebe8edd27 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/CustomOptionsTab.php @@ -24,49 +24,138 @@ namespace Magento\Catalog\Test\Block\Adminhtml\Product\Edit; +use Mtf\ObjectManager; use Mtf\Client\Element; use Magento\Backend\Test\Block\Widget\Tab; -use Mtf\Factory\Factory; /** - * Custom Options Tab - * + * Class CustomOptionsTab + * Product custom options tab */ class CustomOptionsTab extends Tab { /** - * Fill custom options + * Custom option row CSS locator + * + * @var string + */ + 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 + * + * @var string + */ + protected $buttonFormLocator = '[data-ui-id="admin-product-options-add-button"]'; + + /** + * Fill custom options form on tab * * @param array $fields - * @param Element $element + * @param Element|null $element * @return $this */ - public function fillFormTab(array $fields, Element $element) + public function fillFormTab(array $fields, Element $element = null) { - if (!isset($fields['custom_options'])) { + $fields = reset($fields); + if (empty($fields['value'])) { return $this; } - $root = $element; - $this->_rootElement->waitUntil( - function () use ($root) { - return $root->find('#Custom_Options')->isVisible(); + + foreach ($fields['value'] as $keyRoot => $field) { + $options = null; + $this->_rootElement->find($this->buttonFormLocator)->click(); + if (!empty($field['options'])) { + $options = $field['options']; + unset($field['options']); } - ); - $button = $root->find('[data-ui-id="admin-product-options-add-button"]'); + $rootElement = $this->_rootElement->find(sprintf($this->customOptionRow, $keyRoot + 1)); + $data = $this->dataMapping($field); + $this->_fill($data, $rootElement); - $container = $root->find('#product_options_container'); + // Fill subform + if (isset($field['type']) && isset($this->childrenForm[$field['type']]) + && !empty($options) + ) { + /** @var \Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Options $optionsForm */ + $optionsForm = $this->blockFactory->create( + __NAMESPACE__ . '\\' . $this->childrenForm[$field['type']], + ['element' => $rootElement] + ); - if (isset($fields['custom_options']['value'])) { - foreach ($fields['custom_options']['value'] as $index => $data) { - $button->click(); - $row = $container->find('.fieldset-wrapper:nth-child(' . ($index + 1) . ')'); - Factory::getBlockFactory() - ->getMagentoCatalogAdminhtmlProductEditCustomOptionsTabOption($row) - ->fill($data); + foreach ($options as $key => $option) { + ++$key; + $optionsForm->fillOptions( + $option, + $rootElement->find('.fieldset .data-table tbody tr:nth-child(' . $key . ')') + ); + } } } return $this; } + + /** + * Get data of tab + * + * @param array|null $fields + * @param Element|null $element + * @return array + */ + public function getDataFormTab($fields = null, Element $element = null) + { + $fields = reset($fields); + $formData = []; + if (empty($fields['value'])) { + return $formData; + } + + foreach ($fields['value'] as $keyRoot => $field) { + $formDataItem = null; + $options = null; + if (!empty($field['options'])) { + $options = $field['options']; + unset($field['options']); + } + + $rootLocator = sprintf($this->customOptionRow, $keyRoot + 1); + $rootElement = $this->_rootElement->find($rootLocator); + $this->waitForElementVisible($rootLocator); + $data = $this->dataMapping($field); + $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 */ + $optionsForm = $this->blockFactory->create( + __NAMESPACE__ . '\\' . $this->childrenForm[$field['type']], + ['element' => $rootElement] + ); + + foreach ($options as $key => $option) { + $formDataItem['options'][$key++] = $optionsForm->getDataOptions( + $option, + $rootElement->find('.fieldset .data-table tbody tr:nth-child(' . $key . ')') + ); + } + } + $formData[$fields['attribute_code']][$keyRoot] = $formDataItem; + } + + return $formData; + } } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab/Option.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab/Option.php deleted file mode 100644 index d84c296dc9b0d..0000000000000 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab/Option.php +++ /dev/null @@ -1,77 +0,0 @@ -getMagentoCatalogAdminhtmlProductEditCustomOptionsTabTypeSelect($element); - break; - default: - throw new \InvalidArgumentException('Option type is not set'); - } - } - - /** - * Fill - * - * @param array $data - */ - public function fill($data) - { - $this->_rootElement->find('.fieldset-alt [name$="[title]"]') - ->setValue($data['title']); - $this->_rootElement->find('.fieldset-alt [name$="[type]"]', Locator::SELECTOR_CSS, 'select') - ->setValue($data['type']); - - $addButton = $this->_rootElement->find('.add-select-row'); - $table = $this->_rootElement->find('.data-table'); - foreach ($data['options'] as $index => $value) { - $addButton->click(); - $subRow = $table->find('tbody tr:nth-child(' . ($index + 1) . ')'); - $this->factory($data['type'], $subRow)->fill($value); - } - } -} 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/CustomOptionsTab/OptionDropDown.php new file mode 100644 index 0000000000000..54a92ab01bd5c --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab/OptionDropDown.php @@ -0,0 +1,55 @@ +_rootElement->find($this->buttonAddLocator)->click(); + return parent::fillOptions($fields, $element); + } +} 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/CustomOptionsTab/OptionDropDown.xml new file mode 100644 index 0000000000000..4dac6efd003d6 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab/OptionDropDown.xml @@ -0,0 +1,42 @@ + + + + + + <selector>[id$="_title"]</selector> + + + [id$="_price"] + + + [id$="_price_type"] + select + + + [name$='[sku]'] + + + diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab/TypeSelect.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab/OptionField.php similarity index 64% rename from dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab/TypeSelect.php rename to dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab/OptionField.php index 331c36ec28314..702715d0ba801 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab/TypeSelect.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab/OptionField.php @@ -21,23 +21,16 @@ * @copyright Copyright (c) 2014 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\CustomOptionsTab; -use Mtf\Client\Element; -use Mtf\Client\Element\Locator; -use Mtf\Block\Block; +use Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Options; /** - * Select Type + * Class OptionField + * Form "Text field" on tab product "Custom options" */ -class TypeSelect extends Block +class OptionField extends Options { - public function fill($data) - { - $this->_rootElement->find('[name$="[title]"]')->setValue($data['title']); - $this->_rootElement->find('[name$="[price]"]')->setValue($data['price']); - $this->_rootElement->find('[name$="[price_type]"]', Locator::SELECTOR_CSS, 'select') - ->setValue($data['price_type']); - $this->_rootElement->find('[name$="[sku]"]')->setValue($data['sku']); - } + // 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/CustomOptionsTab/OptionField.xml new file mode 100644 index 0000000000000..e5b42e7e52488 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab/OptionField.xml @@ -0,0 +1,42 @@ + + + + + + [id$='_price'] + + + [id$='_price_type'] + select + + + [name$='[sku]'] + + + [name$='[max_characters]'] + + + 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/Options.php new file mode 100644 index 0000000000000..f24a3a59eaa02 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Options.php @@ -0,0 +1,64 @@ +_rootElement : $element; + $mapping = $this->dataMapping($fields); + $this->_fill($mapping, $element); + return $this; + } + + /** + * Getting options data form on the product form + * + * @param array $fields + * @param Element $element + * @return $this + */ + public function getDataOptions(array $fields = null, Element $element = null) + { + $element = $element === null ? $this->_rootElement : $element; + $mapping = $this->dataMapping($fields); + return $this->_getData($mapping, $element); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Crosssell.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Crosssell.php index 8343bd02ff7c6..15519e22b001c 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Crosssell.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Crosssell.php @@ -41,7 +41,7 @@ class Crosssell extends Tab * Select cross-sells products * * @param array $products - * @param Element $context + * @param Element|null $context * @return $this */ public function fillFormTab(array $products, Element $context = null) diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Related.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Related.php index 20495e32a27eb..93f5243e9b632 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Related.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Related.php @@ -41,7 +41,7 @@ class Related extends Tab * Select related products * * @param array $products - * @param Element $context + * @param Element|null $context * @return $this */ public function fillFormTab(array $products, Element $context = null) diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Super/Config.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Super/Config.php index 1adca6b97826a..592ed95817c33 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Super/Config.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Super/Config.php @@ -61,7 +61,7 @@ class Config extends Tab * * @var string */ - protected $loader = '[data-role=loader]'; + protected $loader = './ancestor::body//*[contains(@data-role,"loader")]'; /** * Attribute Opened @@ -116,7 +116,7 @@ public function generateVariations() $loaderSelector = $this->loader; $browser->waitUntil( function () use ($browser, $loaderSelector) { - $loaderElement = $browser->find($loaderSelector); + $loaderElement = $browser->find($loaderSelector, Locator::SELECTOR_XPATH); return $loaderElement->isVisible() == false ? true : null; } ); @@ -126,10 +126,10 @@ function () use ($browser, $loaderSelector) { * Fill variations fieldset * * @param array $fields - * @param Element $element + * @param Element|null $element * @return $this */ - public function fillFormTab(array $fields, Element $element) + public function fillFormTab(array $fields, Element $element = null) { if (!isset($fields['configurable_attributes_data'])) { return $this; diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Upsell.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Upsell.php index e55cd06a9613b..752d50ecb1977 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Upsell.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Upsell.php @@ -41,7 +41,7 @@ class Upsell extends Tab * Select up-sell products * * @param array $products - * @param Element $context + * @param Element|null $context * @return $this */ public function fillFormTab(array $products, Element $context = null) diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Form.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Form.php new file mode 100644 index 0000000000000..a600e6af39c31 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Form.php @@ -0,0 +1,291 @@ +category = $category; + $this->fillCategory($fixture); + return parent::fill($fixture, $element); + } + + /** + * Fill product variations + * + * @param ConfigurableProduct $variations + * @return void + */ + public function fillVariations(ConfigurableProduct $variations) + { + $variationsBlock = Factory::getBlockFactory()->getMagentoCatalogAdminhtmlProductEditTabSuperConfig( + $this->_rootElement->find($this->variationsWrapper) + ); + $variationsBlock->fillAttributeOptions($variations->getConfigurableAttributes()); + $variationsBlock->generateVariations(); + $variationsBlock->fillVariationsMatrix($variations->getVariationsMatrix()); + } + + /** + * Select category + * + * @param FixtureInterface $fixture + * @return void|null + */ + protected function fillCategory(FixtureInterface $fixture) + { + // TODO should be removed after suggest widget implementation as typified element + $categoryName = $this->category + ? $this->category->getCategoryName() + : ($fixture->getCategoryName() ? $fixture->getCategoryName() : ''); + + if (!$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"]' + ); + } + } + + /** + * Fills select category field + * + * @param string $name + * @param string $elementId + * @param string $parentLocation + * @return void + */ + protected function fillCategoryField($name, $elementId, $parentLocation) + { + // 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(); + } + + /** + * Save new category + * + * @param Product $fixture + * @return void + */ + public function addNewCategory(Product $fixture) + { + $this->openNewCategoryDialog(); + $this->_rootElement->find('input#new_category_name', Locator::SELECTOR_CSS) + ->setValue($fixture->getNewCategoryName()); + + $this->clearCategorySelect(); + $this->selectParentCategory(); + + $this->_rootElement->find('div.ui-dialog-buttonset button.action-create')->click(); + $this->waitForElementNotVisible('div.ui-dialog-buttonset button.action-create'); + } + + /** + * Select parent category for new one + * + * @return void + */ + protected function selectParentCategory() + { + // TODO should be removed after suggest widget implementation as typified element + $this->fillCategoryField( + 'Default Category', + 'new_category_parent-suggest', + '//*[@id="new_category_form_fieldset"]' + ); + } + + /** + * Clear category field + * + * @return void + */ + public function clearCategorySelect() + { + $selectedCategory = 'li.mage-suggest-choice span.mage-suggest-choice-close'; + if ($this->_rootElement->find($selectedCategory)->isVisible()) { + $this->_rootElement->find($selectedCategory)->click(); + } + } + + /** + * Open new category dialog + * + * @return void + */ + protected function openNewCategoryDialog() + { + $this->_rootElement->find('#add_category_button', Locator::SELECTOR_CSS)->click(); + $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; + $advancedTabList = $this->advancedTabList; + $tab = $this->_rootElement->find($selector, $strategy); + $advancedSettings = $this->_rootElement->find($this->advancedSettings); + + // Wait until all tabs will load + $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)->isVisible(); + } + ); + // Wait until needed tab will appear + $this->_rootElement->waitUntil( + function () use ($rootElement, $selector, $strategy) { + return $rootElement->find($selector, $strategy)->isVisible(); + } + ); + $tab->click(); + } else { + return false; + } + + return $this; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Form.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Form.xml new file mode 100644 index 0000000000000..6e9319187ff4d --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Form.xml @@ -0,0 +1,151 @@ + + + + + \Magento\Backend\Test\Block\Widget\Tab + #product_info_tabs_product-details + css selector + product + + + select + + + checkbox + + + [name='product[quantity_and_stock_status][qty]'] + + + [name='product[quantity_and_stock_status][is_in_stock]'] + select + + + #description + textarea + + + + + \Magento\Backend\Test\Block\Widget\Tab + #product_info_tabs_websites + css selector + product + + + [name='product[website_ids][]'] + checkbox + + + + + \Magento\Catalog\Test\Block\Adminhtml\Product\Edit\AdvancedPricingTab + #product_info_tabs_advanced-pricing + css selector + product + + + #special_price + + + + + \Magento\Backend\Test\Block\Widget\Tab + #product_info_tabs_advanced-inventory + css selector + product[stock_data] + + + [name='product[stock_data][manage_stock]'] + select + + + [name='product[stock_data][qty]'] + + + + + \Magento\Backend\Test\Block\Widget\Tab + #product_info_tabs_autosettings + css selector + product + + + select + + + #short_description + textarea + + + + + \Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Super\Config + #product_info_tabs_product-details + css selector + + + \Magento\Catalog\Test\Block\Product\Grouped\AssociatedProducts + #product_info_tabs_product-details + css selector + + + \Magento\Catalog\Test\Block\Adminhtml\Product\Edit\CustomOptionsTab + #product_info_tabs_customer_options + css selector + + + <selector>.field [id$='_title']</selector> + <strategy>css selector</strategy> + + + .field input[id$='_required'] + css selector + checkbox + + + .field [id$='_type'] + css selector + select + + + + + \Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Related + #product_info_tabs_related + css selector + + + \Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Upsell + #product_info_tabs_upsell + css selector + + + \Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Crosssell + #product_info_tabs_crosssell + css selector + + 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 new file mode 100644 index 0000000000000..467ad465bc955 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/FormPageActions.php @@ -0,0 +1,58 @@ +getAffectedAttributeSetForm(); + $affectedAttributeSetForm->fill($product)->confirm(); + } +} 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 new file mode 100644 index 0000000000000..55376f2f69d16 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Grid.php @@ -0,0 +1,67 @@ + array( + 'selector' => '#productGrid_product_filter_name' + ), + 'sku' => array( + 'selector' => '#productGrid_product_filter_sku' + ), + 'type' => array( + 'selector' => '#productGrid_product_filter_type', + 'input' => 'select' + ), + 'price_from' => array( + 'selector' => '#productGrid_product_filter_price_from' + ), + 'price_to' => array( + 'selector' => '#productGrid_product_filter_price_to' + ) + ); + + /** + * Update attributes for selected items + * + * @param array $items + * @return void + */ + public function updateAttributes(array $items = array()) + { + $this->massaction('Update Attributes', $items); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Backend/Product/Attribute/Edit.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Backend/Product/Attribute/Edit.php index 67b7178f6acea..bc56affda4c87 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Backend/Product/Attribute/Edit.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Backend/Product/Attribute/Edit.php @@ -82,7 +82,7 @@ public function saveAttribute() * Fill form with attribute options * * @param FixtureInterface $fixture - * @param null|Element $element + * @param Element|null $element * @return $this */ public function fill(FixtureInterface $fixture, Element $element = null) diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Backend/ProductForm.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Backend/ProductForm.php index 357df855f7533..4972a686f670c 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Backend/ProductForm.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Backend/ProductForm.php @@ -37,7 +37,6 @@ /** * Class ProductForm * Product creation form - * */ class ProductForm extends FormTabs { @@ -105,6 +104,15 @@ class ProductForm extends FormTabs protected $advancedTabPanel = '[role="tablist"] [role="tabpanel"][aria-expanded="true"]:not("overflow")'; /** + * Selector popups 'New category' + * + * @var string + */ + protected $newCategoryPopup = "./ancestor::body//div[div[contains(@id,'new-category')]]"; + + /** + * Category fixture + * * @var Category */ protected $category; @@ -122,7 +130,10 @@ protected function getAffectedAttributeSetBlock() } /** + * Set category + * * @param Category $category + * @return void */ public function setCategory(Category $category) { @@ -189,18 +200,22 @@ public function save(FixtureInterface $fixture = null) * Save new category * * @param Product $fixture + * @return void */ public function addNewCategory(Product $fixture) { $this->openNewCategoryDialog(); - $this->_rootElement->find('input#new_category_name', Locator::SELECTOR_CSS) - ->setValue($fixture->getNewCategoryName()); - - $this->clearCategorySelect(); - $this->selectParentCategory(); + $popupElement = $this->_rootElement->find($this->newCategoryPopup, Locator::SELECTOR_XPATH); + + if ($popupElement->isVisible()) { + $popupElement->find('input#new_category_name', Locator::SELECTOR_CSS) + ->setValue($fixture->getNewCategoryName()); + $this->clearCategorySelect($popupElement); + $this->selectParentCategory($popupElement); + $popupElement->find('div.ui-dialog-buttonset button.action-create')->click(); + $this->waitForElementNotVisible('div.ui-dialog-buttonset button.action-create'); + } - $this->_rootElement->find('div.ui-dialog-buttonset button.action-create')->click(); - $this->waitForElementNotVisible('div.ui-dialog-buttonset button.action-create'); } /** @@ -219,6 +234,7 @@ protected function getVariationsBlock() * Fill product variations * * @param ConfigurableProduct $variations + * @return void */ public function fillVariations(ConfigurableProduct $variations) { @@ -230,6 +246,8 @@ public function fillVariations(ConfigurableProduct $variations) /** * Open variations tab + * + * @return void */ public function openVariationsTab() { @@ -238,6 +256,8 @@ public function openVariationsTab() /** * Click on 'Create New Variation Set' button + * + * @return void */ public function clickCreateNewVariationSet() { @@ -246,25 +266,34 @@ public function clickCreateNewVariationSet() /** * Clear category field + * + * @param Element $element + * @return void */ - public function clearCategorySelect() + public function clearCategorySelect(Element $element = null) { + $element = $element === null ? $this->_rootElement : $element; $selectedCategory = 'li.mage-suggest-choice span.mage-suggest-choice-close'; - if ($this->_rootElement->find($selectedCategory)->isVisible()) { - $this->_rootElement->find($selectedCategory)->click(); + if ($element->find($selectedCategory)->isVisible()) { + $element->find($selectedCategory)->click(); } } /** * Select parent category for new one + * + * @param Element $element + * @return void */ - protected function selectParentCategory() + protected function selectParentCategory(Element $element = null) { + $element = $element === null ? $this->_rootElement : $element; // TODO should be removed after suggest widget implementation as typified element $this->fillCategoryField( 'Default Category', 'new_category_parent-suggest', - '//*[@id="new_category_form_fieldset"]' + '//*[@id="new_category_form_fieldset"]', + $element ); } @@ -274,25 +303,30 @@ protected function selectParentCategory() * @param string $name * @param string $elementId * @param string $parentLocation + * @param Element $element + * @return void */ - protected function fillCategoryField($name, $elementId, $parentLocation) + protected function fillCategoryField($name, $elementId, $parentLocation, Element $element = null) { + $element = $element === null ? $this->_rootElement : $element; // TODO should be removed after suggest widget implementation as typified element - $this->_rootElement->find($elementId, Locator::SELECTOR_ID)->setValue($name); + $element->find($elementId, Locator::SELECTOR_ID)->setValue($name); //*[@id="attribute-category_ids-container"] //*[@id="new_category_form_fieldset"] $categoryListLocation = $parentLocation . '//div[@class="mage-suggest-dropdown"]'; // $this->waitForElementVisible($categoryListLocation, Locator::SELECTOR_XPATH); $categoryLocation = $parentLocation . '//li[contains(@data-suggest-option, \'"label":"' . $name . '",\')]//a'; - $this->_rootElement->find($categoryLocation, Locator::SELECTOR_XPATH)->click(); + $element->find($categoryLocation, Locator::SELECTOR_XPATH)->click(); } /** * Open new category dialog + * + * @return void */ protected function openNewCategoryDialog() { $this->_rootElement->find('#add_category_button', Locator::SELECTOR_CSS)->click(); - $this->waitForElementVisible('input#new_category_name'); + $this->waitForElementVisible($this->newCategoryPopup, Locator::SELECTOR_XPATH); } /** diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Grouped/AssociatedProducts.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Grouped/AssociatedProducts.php index a178cc7e26831..bc639021f2dc1 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Grouped/AssociatedProducts.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Grouped/AssociatedProducts.php @@ -26,11 +26,12 @@ use Mtf\Client\Element; use Mtf\Factory\Factory; +use Mtf\Client\Element\Locator; use Magento\Backend\Test\Block\Widget\Tab; /** * Class AssociatedProducts - * + * Associated products tab */ class AssociatedProducts extends Tab { @@ -42,11 +43,11 @@ class AssociatedProducts extends Tab protected $addNewOption = '#grouped-product-container>button'; /** - * Associated products grid + * Associated products grid locator * * @var string */ - protected $productSearchGrid = '[role=dialog][style*="display: block;"]'; + protected $productSearchGrid = "./ancestor::body//div[div[contains(@data-role,'add-product-dialog')]]"; /** * Associated products list block @@ -58,15 +59,12 @@ class AssociatedProducts extends Tab /** * Get search grid * - * @param Element $context * @return AssociatedProducts\Search\Grid */ - protected function getSearchGridBlock(Element $context = null) + protected function getSearchGridBlock() { - $element = $context ? : $this->_rootElement; - return Factory::getBlockFactory()->getMagentoCatalogProductGroupedAssociatedProductsSearchGrid( - $element->find($this->productSearchGrid) + $this->_rootElement->find($this->productSearchGrid, Locator::SELECTOR_XPATH) ); } @@ -89,15 +87,15 @@ protected function getListAssociatedProductsBlock(Element $context = null) * Fill data to fields on tab * * @param array $fields - * @param Element $element + * @param Element|null $element * @return $this */ - public function fillFormTab(array $fields, Element $element) + public function fillFormTab(array $fields, Element $element = null) { if (isset($fields['grouped_products'])) { foreach ($fields['grouped_products']['value'] as $groupedProduct) { $element->find($this->addNewOption)->click(); - $searchBlock = $this->getSearchGridBlock($element); + $searchBlock = $this->getSearchGridBlock(); $searchBlock->searchAndSelect($groupedProduct['search_data']); $searchBlock->addProducts(); $this->getListAssociatedProductsBlock()->fillProductOptions($groupedProduct['data']); diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Grouped/AssociatedProducts/ListAssociatedProducts.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Grouped/AssociatedProducts/ListAssociatedProducts.php index fe576653619ac..468309c831ae1 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Grouped/AssociatedProducts/ListAssociatedProducts.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Grouped/AssociatedProducts/ListAssociatedProducts.php @@ -32,11 +32,13 @@ /** * Class ListAssociatedProducts - * + * List associated products on the page */ class ListAssociatedProducts extends Block { /** + * Getting block products + * * @param string $productId * @param Element $context * @return ListAssociatedProducts\Product @@ -54,6 +56,8 @@ private function getProductBlock($productId, Element $context = null) } /** + * Filling options products + * * @param array $data * @param Element $element */ diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ListProduct.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ListProduct.php index 1a6f7df7207af..838888f3db374 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ListProduct.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ListProduct.php @@ -18,21 +18,20 @@ * 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\Catalog\Test\Block\Product; use Mtf\Block\Block; use Mtf\Client\Element; -use Mtf\Client\Element\Locator; use Mtf\Factory\Factory; +use Mtf\Client\Element\Locator; /** * Class SearchResultsList * Product list - * */ class ListProduct extends Block { @@ -78,6 +77,13 @@ class ListProduct extends Block */ protected $oldPrice = ".old-price .price"; + /** + * 'Add to Card' button + * + * @var string + */ + protected $addToCard = "button.action.tocart"; + /** * This method returns the price box block for the named product. * @@ -95,6 +101,7 @@ public function getProductPriceBlock($productName) * Check if product with specified name is visible * * @param string $productName + * * @return bool */ public function isProductVisible($productName) @@ -126,6 +133,7 @@ public function openProductViewPage($productName) * This method returns the element representing the product details for the named product. * * @param string $productName String containing the name of the product + * * @return Element */ protected function getProductDetailsElement($productName) @@ -140,6 +148,7 @@ protected function getProductDetailsElement($productName) * This method returns the element on the page associated with the product name. * * @param string $productName String containing the name of the product + * * @return Element */ protected function getProductNameElement($productName) @@ -155,6 +164,10 @@ protected function getProductNameElement($productName) /** * Open MAP block on category page + * + * @param $productName + * + * @return void */ public function openMapBlockOnCategoryPage($productName) { @@ -175,6 +188,7 @@ public function getOldPriceCategoryPage() * Retrieve product price by specified Id * * @param int $productId + * * @return string */ public function getPrice($productId) @@ -184,4 +198,14 @@ public function getPrice($productId) Locator::SELECTOR_CSS )->getText(); } + + /** + * Check 'Add To Card' button availability + * + * @return bool + */ + public function checkAddToCardButton() + { + return $this->_rootElement->find($this->addToCard, Locator::SELECTOR_CSS)->isVisible(); + } } 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 index 0f16c3bdbe673..dbb3c7a717e6c 100644 --- 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 @@ -29,9 +29,7 @@ /** * Class Price - * - * This class is used to access the price related information from the storefront. - * + * This class is used to access the price related information from the storefront */ class Price extends Block { @@ -40,28 +38,28 @@ class Price extends Block * * @var string */ - protected $oldPriceClass = 'old-price'; + protected $oldPriceClass = '.old-price'; /** * This member holds the class name of the price block that contains the actual price value. * * @var string */ - protected $priceClass = 'price'; + protected $priceClass = '.price'; /** * This member holds the class name of the regular price block. * * @var string */ - protected $regularPriceClass = "regular-price"; + protected $regularPriceClass = '.price-final_price'; /** * This member holds the class name of the special price block. * * @var string */ - protected $specialPriceClass = 'special-price'; + protected $specialPriceClass = '.special-price'; /** * Minimum Advertised Price @@ -106,31 +104,35 @@ class Price extends Block protected $priceToSelector = 'p.price-to span.price'; /** + * Getting prices + * * @param string $currency - * @return string|array + * @return array */ public function getPrice($currency = '$') { //@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) { - return floatval(trim($prices[0], $currency)); + if (count($prices) === 1) { + return ['price_regular_price' => trim($prices[0], $currency)]; } return $this->formatPricesData($prices, $currency); } /** + * Formatting data prices + * * @param array $prices * @param string $currency * @return array */ private function formatPricesData(array $prices, $currency = '$') { - $formatted = array(); + $formatted = []; foreach ($prices as $price) { list($name, $price) = explode($currency, $price); - $name = trim(preg_replace('#[^0-9a-z]+#i', ' ', strtolower($name)), ' '); - $formatted['price_' . $name] = floatval($price); + $name = str_replace(' ', '_', trim(preg_replace('#[^0-9a-z]+#i', ' ', strtolower($name)), ' ')); + $formatted['price_' . $name] = $price; } return $formatted; } @@ -145,15 +147,15 @@ private function formatPricesData(array $prices, $currency = '$') public function getEffectivePrice() { // if a special price is available, then return that - $priceElement = $this->_rootElement->find($this->specialPriceClass, Locator::SELECTOR_CLASS_NAME); + $priceElement = $this->_rootElement->find($this->specialPriceClass, Locator::SELECTOR_CSS); if (!$priceElement->isVisible()) { - $priceElement = $this->_rootElement->find($this->regularPriceClass, Locator::SELECTOR_CLASS_NAME); + $priceElement = $this->_rootElement->find($this->regularPriceClass, Locator::SELECTOR_CSS); if (!$priceElement->isVisible()) { - $priceElement = $this->_rootElement->find($this->oldPriceClass, Locator::SELECTOR_CLASS_NAME); + $priceElement = $this->_rootElement->find($this->oldPriceClass, Locator::SELECTOR_CSS); } } // return the actual value of the price - return $priceElement->find($this->priceClass, Locator::SELECTOR_CLASS_NAME)->getText(); + return $priceElement->find($this->priceClass, Locator::SELECTOR_CSS)->getText(); } /** @@ -164,12 +166,12 @@ public function getEffectivePrice() public function getRegularPrice() { // either return the old price (implies special price display or a regular price - $priceElement = $this->_rootElement->find($this->oldPriceClass, Locator::SELECTOR_CLASS_NAME); + $priceElement = $this->_rootElement->find($this->oldPriceClass, Locator::SELECTOR_CSS); if (!$priceElement->isVisible()) { - $priceElement = $this->_rootElement->find($this->regularPriceClass, Locator::SELECTOR_CLASS_NAME); + $priceElement = $this->_rootElement->find($this->regularPriceClass, Locator::SELECTOR_CSS); } // return the actual value of the price - return $priceElement->find($this->priceClass, Locator::SELECTOR_CLASS_NAME)->getText(); + return $priceElement->find($this->priceClass, Locator::SELECTOR_CSS)->getText(); } /** @@ -181,10 +183,10 @@ public function getSpecialPrice() { return $this->_rootElement->find( $this->specialPriceClass, - Locator::SELECTOR_CLASS_NAME + Locator::SELECTOR_CSS )->find( $this->priceClass, - Locator::SELECTOR_CLASS_NAME + Locator::SELECTOR_CSS )->getText(); } @@ -195,7 +197,7 @@ public function getSpecialPrice() */ public function isRegularPriceVisible() { - return $this->_rootElement->find($this->regularPriceClass, Locator::SELECTOR_CLASS_NAME)->isVisible(); + return $this->_rootElement->find($this->regularPriceClass, Locator::SELECTOR_CSS)->isVisible(); } /** @@ -205,13 +207,13 @@ public function isRegularPriceVisible() */ public function isSpecialPriceVisible() { - return $this->_rootElement->find($this->specialPriceClass, Locator::SELECTOR_CLASS_NAME)->isVisible(); + return $this->_rootElement->find($this->specialPriceClass, Locator::SELECTOR_CSS)->isVisible(); } /** * Get Minimum Advertised Price value * - * @return array|string + * @return string */ public function getOldPrice() { @@ -229,7 +231,7 @@ public function getActualPrice($currency = '$') { //@TODO it have to rewrite when will be possibility to divide it to different blocks(by product type) $prices = explode("\n", trim($this->_rootElement->find($this->actualPrice, Locator::SELECTOR_CSS)->getText())); - if (count($prices) == 1) { + if (count($prices) === 1) { return floatval(trim($prices[0], $currency)); } return $this->formatPricesData($prices, $currency); @@ -238,6 +240,7 @@ public function getActualPrice($currency = '$') /** * Add product to shopping cart from MAP Block * + * @return void */ public function addToCartFromMap() { @@ -247,6 +250,7 @@ public function addToCartFromMap() /** * Close MAP Block * + * @return void */ public function closeMapBlock() { @@ -256,7 +260,7 @@ public function closeMapBlock() /** * Get price from * - * @return array|string + * @return string */ public function getPriceFrom() { @@ -266,7 +270,7 @@ public function getPriceFrom() /** * Get price to * - * @return array|string + * @return string */ public function getPriceTo() { diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ProductList/Crosssell.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ProductList/Crosssell.php index 0061e16d5e529..3793f42964185 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ProductList/Crosssell.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ProductList/Crosssell.php @@ -22,14 +22,17 @@ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ - namespace Magento\Catalog\Test\Block\Product\ProductList; -use Magento\Catalog\Test\Fixture\AbstractProduct; use Mtf\Block\Block; +use Mtf\Client\Element; use Mtf\Client\Element\Locator; use \Magento\Catalog\Test\Fixture\Product; +/** + * Class Crosssell + * Crosssell product block on the page + */ class Crosssell extends Block { /** @@ -58,8 +61,7 @@ public function verifyProductCrosssell(Product $crosssell) * Click on cross-sell product link * * @param Product $product - * @return \Mtf\Client\Element - * @throws \Exception + * @return Element */ public function clickLink($product) { diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ProductList/Related.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ProductList/Related.php index 05f50a5123f4a..1e24159100246 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ProductList/Related.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ProductList/Related.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) */ @@ -26,14 +25,25 @@ namespace Magento\Catalog\Test\Block\Product\ProductList; use Mtf\Block\Block; -use Mtf\Factory\Factory; +use Mtf\Client\Element; use Mtf\Client\Element\Locator; +/** + * Class Related + * Related product block on the page + */ class Related extends Block { + /** + * Related product locator on the page + * + * @var string + */ protected $relatedProduct = "//div[normalize-space(div//a)='%s']"; /** + * Checking related product visibility + * * @param string $productName * @return bool */ @@ -43,6 +53,8 @@ public function isRelatedProductVisible($productName) } /** + * Verify that you can choose the related products + * * @param string $productName * @return bool */ @@ -52,7 +64,10 @@ public function isRelatedProductSelectable($productName) } /** + * Open related product + * * @param string $productName + * @return void */ public function openRelatedProduct($productName) { @@ -60,7 +75,10 @@ public function openRelatedProduct($productName) } /** + * Select related product + * * @param string $productName + * @return void */ public function selectProductForAddToCart($productName) { @@ -70,8 +88,10 @@ public function selectProductForAddToCart($productName) } /** + * Get related product element + * * @param string $productName - * @return mixed|\Mtf\Client\Element + * @return Element */ private function getProductElement($productName) { diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ProductList/Toolbar.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ProductList/Toolbar.php new file mode 100644 index 0000000000000..f1e7ce1b27a75 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ProductList/Toolbar.php @@ -0,0 +1,57 @@ +_rootElement->find($this->nextPageSelector); + if ($nextPageItem->isVisible()) { + $nextPageItem->click(); + return true; + } + + return false; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ProductList/Upsell.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ProductList/Upsell.php index 2bfa88f9a5953..ebe98223223b3 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ProductList/Upsell.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ProductList/Upsell.php @@ -25,14 +25,25 @@ namespace Magento\Catalog\Test\Block\Product\ProductList; use Mtf\Block\Block; -use Mtf\Factory\Factory; +use Mtf\Client\Element; use Mtf\Client\Element\Locator; +/** + * Class Upsell + * Upsell product block on the page + */ class Upsell extends Block { + /** + * Upsell product locator on the page + * + * @var string + */ protected $upsellProduct = "//div[normalize-space(div//a)='%s']"; /** + * Checking upsell product visibility + * * @param string $productName * @return bool */ @@ -42,6 +53,8 @@ public function isUpsellProductVisible($productName) } /** + * Open upsell product + * * @param string $productName */ public function openUpsellProduct($productName) @@ -50,8 +63,10 @@ public function openUpsellProduct($productName) } /** + * Get a the product + * * @param string $productName - * @return mixed|\Mtf\Client\Element + * @return Element */ private function getProductElement($productName) { 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 3bec840a1ade2..2eceac5d6d0eb 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 @@ -21,21 +21,19 @@ * @copyright Copyright (c) 2014 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; use Mtf\Block\Block; use Mtf\Factory\Factory; use Mtf\Client\Element\Locator; -use Magento\Catalog\Test\Fixture\Product; -use Magento\Catalog\Test\Fixture\ConfigurableProduct; -use Magento\Catalog\Test\Fixture\GroupedProduct; -use Magento\Bundle\Test\Fixture\Bundle as BundleFixture; use Mtf\Fixture\FixtureInterface; +use Magento\Catalog\Test\Fixture\GroupedProduct; +use Magento\Catalog\Test\Fixture\ConfigurableProduct; /** * Class View - * Product View block - * + * Product view block on the product page */ class View extends Block { @@ -67,6 +65,27 @@ class View extends Block */ protected $productName = '.page.title.product span'; + /** + * Product sku element + * + * @var string + */ + protected $productSku = '[itemprop="sku"]'; + + /** + * Product description element + * + * @var string + */ + protected $productDescription = '.product.attibute.description'; + + /** + * Product short-description element + * + * @var string + */ + protected $productShortDescription = '.product.attibute.overview'; + /** * Product price element * @@ -109,6 +128,13 @@ class View extends Block */ protected $customizeButton = '.action.primary.customize'; + /** + * This member holds the class name of the tier price block. + * + * @var string + */ + protected $tierPricesSelector = "//ul[contains(@class,'tier')]//*[@class='item'][%line-number%]"; + /** * Get bundle options block * @@ -122,6 +148,8 @@ public function getBundleBlock() } /** + * Get block price + * * @return \Magento\Catalog\Test\Block\Product\Price */ protected function getPriceBlock() @@ -135,6 +163,7 @@ protected function getPriceBlock() * Add product to shopping cart * * @param FixtureInterface $product + * @return void */ public function addToCart(FixtureInterface $product) { @@ -142,16 +171,40 @@ public function addToCart(FixtureInterface $product) $this->clickAddToCart(); } + /** + * Find button 'Add to cart' + * + * @return boolean + */ + public function addToCartIsVisible() + { + return $this->_rootElement->find($this->addToCart, Locator::SELECTOR_CSS)->isVisible(); + } + /** * Click link + * + * @return void */ public function clickAddToCart() { $this->_rootElement->find($this->addToCart, Locator::SELECTOR_CSS)->click(); } + /** + * Find Add To Cart button + * + * @return bool + */ + public function isVisibleAddToCart() + { + return $this->_rootElement->find($this->addToCart, Locator::SELECTOR_CSS)->isVisible(); + } + /** * Press 'Check out with PayPal' button + * + * @return void */ public function paypalCheckout() { @@ -168,6 +221,16 @@ public function getProductName() return $this->_rootElement->find($this->productName, Locator::SELECTOR_CSS)->getText(); } + /** + * Get product sku displayed on page + * + * @return string + */ + public function getProductSku() + { + return $this->_rootElement->find($this->productSku, Locator::SELECTOR_CSS)->getText(); + } + /** * This method returns the price box block. * @@ -190,6 +253,32 @@ public function getProductPrice() return $this->getPriceBlock()->getPrice(); } + /** + * Return product short description on page + * + * @return string|null + */ + public function getProductShortDescription() + { + if ($this->_rootElement->find($this->productShortDescription, Locator::SELECTOR_CSS)->isVisible()) { + return $this->_rootElement->find($this->productShortDescription, Locator::SELECTOR_CSS)->getText(); + } + return null; + } + + /** + * Return product description on page + * + * @return string|null + */ + public function getProductDescription() + { + if ($this->_rootElement->find($this->productDescription, Locator::SELECTOR_CSS)->isVisible()) { + return $this->_rootElement->find($this->productDescription, Locator::SELECTOR_CSS)->getText(); + } + return null; + } + /** * Return configurable product options * @@ -234,9 +323,10 @@ public function verifyProductOptions(ConfigurableProduct $product) /** * Fill in the option specified for the product * - * @param BundleFixture|Product $product + * @param FixtureInterface $product + * @return void */ - public function fillOptions($product) + public function fillOptions(FixtureInterface $product) { $configureButton = $this->_rootElement->find($this->customizeButton); $configureSection = $this->_rootElement->find('.product.options.wrapper'); @@ -252,8 +342,24 @@ public function fillOptions($product) } } + /** + * This method return array tier prices + * + * @param int $lineNumber + * @return array + */ + public function getTierPrices($lineNumber = 1) + { + return $this->_rootElement->find( + str_replace('%line-number%', $lineNumber, $this->tierPricesSelector), + Locator::SELECTOR_XPATH + )->getText(); + } + /** * Click "Customize and add to cart button" + * + * @return void */ public function clickCustomize() { @@ -263,6 +369,8 @@ public function clickCustomize() /** * Click "ADD TO CART" button + * + * @return void */ public function clickAddToCartButton() { @@ -270,6 +378,8 @@ public function clickAddToCartButton() } /** + * Verification of group products + * * @param GroupedProduct $product * @return bool */ @@ -289,6 +399,8 @@ public function verifyGroupedProducts(GroupedProduct $product) /** * Open MAP block on Product View page + * + * @return void */ public function openMapBlockOnProductPage() { @@ -297,11 +409,11 @@ public function openMapBlockOnProductPage() } /** - * Is 'ADD TO CART' button visible + * Check 'Add to card' button visible * * @return bool */ - public function isAddToCartButtonVisible() + public function checkAddToCardButton() { return $this->_rootElement->find($this->addToCart, Locator::SELECTOR_CSS)->isVisible(); } @@ -309,7 +421,7 @@ public function isAddToCartButtonVisible() /** * Get text of Stock Availability control * - * @return array|string + * @return string */ public function stockAvailability() { 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 index cdede23e765ee..958aa9fda7cd3 100644 --- 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 @@ -27,52 +27,182 @@ use Mtf\Block\Block; use Mtf\Client\Element; use Mtf\Client\Element\Locator; -use Mtf\Factory\Factory; /** * Class Custom Options - * + * Block of custom options product */ class CustomOptions extends Block { - protected $fieldsetSelector = '.fieldset'; - protected $rowSelector = '.field'; + /** + * Regexp price pattern + * + * @var string + */ + protected $pricePattern = '#\$([\d,]+\.\d+)$#'; + + /** + * Field set XPath locator + * + * @var string + */ + protected $fieldsetLocator = '//*[@id="product-options-wrapper"]//*[@class="fieldset"]'; + + /** + * Field XPath locator + * + * @var string + */ + protected $fieldLocator = '/div[not(contains(@class,"downloads")) and contains(@class,"field")%s][%d]'; + + /** + * Required field XPath locator + * + * @var string + */ + protected $requiredLocator = ' and contains(@class,"required")'; /** - * Get options + * Select field XPath locator + * + * @var string + */ + protected $selectLocator = '//div[contains(@class,"control")]//select'; + + /** + * Title value CSS locator + * + * @var string + */ + protected $titleLocator = '.label span:not(.price-notice)'; + + /** + * Price value CSS locator + * + * @var string + */ + protected $priceLocator = '.label .price-notice'; + + /** + * Option XPath locator + * + * @var string + */ + protected $optionLocator = '//option[%d]'; + + /** + * Option XPath locator by value + * + * @var string + */ + protected $optionByValueLocator = '//*[@class="product options wrapper"]//option[text()="%s"]/..'; + + /** + * Select XPath locator by title + * + * @var string + */ + protected $selectByTitleLocator = '//*[*[@class="product options wrapper"]//span[text()="%s"]]//select'; + + /** + * Bundle field CSS locator + * + * @var string + */ + protected $bundleFieldLocator = '#product-options-wrapper > .fieldset > .field'; + + /** + * Get product options * * @return array */ - public function get() + public function getOptions() { - $optionsFieldset = $this->_rootElement->find($this->fieldsetSelector); - $fieldsetIndex = 1; - $options = array(); - //@todo move to separate block - $field = $optionsFieldset->find($this->rowSelector . ':nth-of-type(' . $fieldsetIndex . ')'); - while ($field->isVisible()) { - $optionFieldset = []; - $optionFieldset['title'] = $field->find('.label')->getText(); - $optionFieldset['is_require'] = $field->find('select.required')->isVisible(); - $options[] = & $optionFieldset; - $optionIndex = 1; - //@todo move to separate block - $option = $field->find('select > option:nth-of-type(' . $optionIndex . ')'); - while ($option->isVisible()) { - if (preg_match('~^(?.+) .?\$(?P<price>\d+\.\d*)$~', $option->getText(), $matches) !== false - && !empty($matches['price']) + $options = []; + $index = 1; + + $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() ) { - $optionFieldset['options'][] = [ - 'title' => $matches['title'], - 'price' => $matches['price'], - ]; - }; - $optionIndex++; - $option = $field->find('select > option:nth-of-type(' . $optionIndex . ')'); + $matches = []; + $value = $price->getText(); + if (preg_match($this->pricePattern, $value, $matches)) { + $option['value'][] = $value; + $option['price'][] = $matches[1]; + } + } } - $fieldsetIndex++; - $field = $optionsFieldset->find($this->rowSelector . ':nth-of-type(' . $fieldsetIndex . ')'); + $options[$option['title']] = $option; + ++$index; + $fieldElement = $this->_rootElement->find( + $this->fieldsetLocator . sprintf($this->fieldLocator, '', $index), + Locator::SELECTOR_XPATH + ); } + return $options; } + + /** + * Fill configurable product options + * + * @param array $productOptions + * @return void + */ + public function fillProductOptions($productOptions) + { + foreach ($productOptions as $attributeLabel => $attributeValue) { + $select = $this->_rootElement->find( + sprintf($this->selectByTitleLocator, $attributeLabel), + Locator::SELECTOR_XPATH, + 'select' + ); + $select->setValue($attributeValue); + } + } + + /** + * Choose custom option in a drop down + * + * @param string $productOption + * @return void + */ + public function selectProductCustomOption($productOption) + { + $select = $this->_rootElement->find( + sprintf($this->optionByValueLocator, $productOption), + Locator::SELECTOR_XPATH, + 'select' + ); + $select->setValue($productOption); + } } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View/Options.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View/Options.php deleted file mode 100644 index aeaeea05b0ff3..0000000000000 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View/Options.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\Block\Product\View; - -use Mtf\Block\Block; -use Mtf\Client\Element; -use Mtf\Client\Element\Locator; - -/** - * Class Bundle - * Catalog bundle product info block - * - */ -class Options extends Block -{ - /** - * Get product custom options - * - * @return array - */ - public function getProductCustomOptions() - { - return $this->getOptions('.fieldset > .field'); - } - - /** - * Get bundle custom options - * - * @return array - */ - public function getBundleCustomOptions() - { - return $this->getOptions('#product-options-wrapper > .fieldset > .field'); - } - - /** - * Get bundle options - * - * @return array - */ - public function getBundleOptions() - { - return $this->getOptions('.fieldset.bundle.options > .field'); - } - - /** - * Get options from specified fieldset using specified fieldDiv selector - * - * @param string $fieldSelector - * @return array - */ - protected function getOptions($fieldSelector = '.fieldset.bundle.options') - { - $index = 1; - $options = []; - $field = $this->_rootElement->find($fieldSelector . ':nth-of-type(' . $index . ')'); - while ($field->isVisible()) { - $optionName = $field->find('label > span')->getText(); - $options[$optionName] = []; - $productIndex = 1; - $productOption = $field->find('select > option:nth-of-type(' . $productIndex . ')'); - while ($productOption->isVisible()) { - $options[$optionName][] = trim($productOption->getText()); - $productIndex++; - $productOption = $field->find('select > option:nth-of-type(' . $productIndex . ')'); - } - $index++; - $field = $this->_rootElement->find($fieldSelector . ':nth-of-type(' . $index . ')'); - } - return $options; - } - - /** - * Fill configurable product options - * - * @param array $productOptions - */ - public function fillProductOptions($productOptions) - { - foreach ($productOptions as $attributeLabel => $attributeValue) { - $select = $this->_rootElement->find( - '//*[*[@class="product options wrapper"]//span[text()="' . - $attributeLabel . - '"]]//select', - Locator::SELECTOR_XPATH, - 'select' - ); - $select->setValue($attributeValue); - } - } - - /** - * Choose custom option in a drop down - * - * @param string $productOption - */ - public function selectProductCustomOption($productOption) - { - $select = $this->_rootElement->find( - '//*[@class="product options wrapper"]//option[text()="' . $productOption . '"]/..', - Locator::SELECTOR_XPATH, - 'select' - ); - $select->setValue($productOption); - } -} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Search.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Search.php index b1efb82c13063..24029a7351bbc 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Search.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Search.php @@ -30,7 +30,6 @@ /** * Class Search * Block for search field - * */ class Search extends Block { @@ -59,6 +58,7 @@ class Search extends Block * Search products by a keyword * * @param string $keyword + * @return void */ public function search($keyword) { 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 new file mode 100644 index 0000000000000..f3bd7ca030106 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertAddToCartButtonAbsent.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\Catalog\Test\Constraint; + +use Magento\Cms\Test\Page\CmsIndex; +use Mtf\Constraint\AbstractConstraint; +use Magento\Catalog\Test\Fixture\CatalogProductSimple; +use Magento\Catalog\Test\Page\Product\CatalogProductView; +use Magento\Catalog\Test\Page\Category\CatalogCategoryView; + +/** + * Class AssertAddToCartButtonAbsent + * Checks the button on the category/product pages + */ +class AssertAddToCartButtonAbsent extends AbstractConstraint +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Category Page + * + * @var CatalogCategoryView + */ + protected $catalogCategoryView; + + /** + * Index Page + * + * @var CmsIndex + */ + protected $cmsIndex; + + /** + * Product simple fixture + * + * @var CatalogProductSimple + */ + protected $catalogProductSimple; + + /** + * Product Page on Frontend + * + * @var CatalogProductView + */ + protected $catalogProductView; + + /** + * Assert that "Add to cart" button is not display on page. + * + * @param CmsIndex $cmsIndex + * @param CatalogCategoryView $catalogCategoryView + * @param CatalogProductSimple $catalogProductSimple + * @param CatalogProductView $catalogProductView + * + * @return void + */ + public function processAssert( + CmsIndex $cmsIndex, + CatalogCategoryView $catalogCategoryView, + CatalogProductSimple $catalogProductSimple, + CatalogProductView $catalogProductView + ) { + $this->catalogCategoryView = $catalogCategoryView; + $this->cmsIndex = $cmsIndex; + $this->catalogProductSimple = $catalogProductSimple; + $this->catalogProductView = $catalogProductView; + + $this->addToCardAbsentOnCategory(); + $this->addToCardAbsentOnProduct(); + } + + /** + * "Add to cart" button is not displayed on Category page + * + * @return void + */ + protected function addToCardAbsentOnCategory() + { + $this->cmsIndex->open(); + $this->cmsIndex->getTopmenu()->selectCategoryByName( + $this->catalogProductSimple->getCategoryIds()[0]['name'] + ); + \PHPUnit_Framework_Assert::assertFalse( + $this->catalogCategoryView->getListProductBlock()->checkAddToCardButton(), + "Button 'Add to Card' is present on Category page" + ); + } + + /** + * "Add to cart" button is not display on Product page + * + * @return void + */ + protected function addToCardAbsentOnProduct() + { + $this->cmsIndex->open(); + $this->cmsIndex->getTopmenu()->selectCategoryByName( + $this->catalogProductSimple->getCategoryIds()[0]['name'] + ); + $this->catalogCategoryView->getListProductBlock()->openProductViewPage($this->catalogProductSimple->getName()); + \PHPUnit_Framework_Assert::assertFalse( + $this->catalogProductView->getViewBlock()->checkAddToCardButton(), + "Button 'Add to Card' is present on Product page" + ); + } + + /** + * Text absent button "Add to Cart" on the category/product pages + * + * @return string + */ + public function toString() + { + return "Button 'Add to Card' is absent on Category page and Product Page."; + } +} 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 new file mode 100644 index 0000000000000..60b6febce2924 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertAddToCartButtonPresent.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\Catalog\Test\Constraint; + +use Magento\Cms\Test\Page\CmsIndex; +use Mtf\Constraint\AbstractConstraint; +use Magento\Catalog\Test\Fixture\CatalogProductSimple; +use Magento\Catalog\Test\Page\Product\CatalogProductView; +use Magento\Catalog\Test\Page\Category\CatalogCategoryView; + +/** + * Class AssertAddToCartButtonPresent + * Checks the button on the category/product pages + */ +class AssertAddToCartButtonPresent extends AbstractConstraint +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Category Page on Frontend + * + * @var CatalogCategoryView + */ + protected $catalogCategoryView; + + /** + * Index Page + * + * @var CmsIndex + */ + protected $cmsIndex; + + /** + * Product simple fixture + * + * @var CatalogProductSimple + */ + protected $catalogProductSimple; + + /** + * Product Page on Frontend + * + * @var CatalogProductView + */ + protected $catalogProductView; + + /** + * Assert that "Add to cart" button is present on page. + * + * @param CmsIndex $cmsIndex + * @param CatalogCategoryView $catalogCategoryView + * @param CatalogProductSimple $catalogProductSimple + * @param CatalogProductView $catalogProductView + * + * @return void + */ + public function processAssert( + CmsIndex $cmsIndex, + CatalogCategoryView $catalogCategoryView, + CatalogProductSimple $catalogProductSimple, + CatalogProductView $catalogProductView + ) { + $this->catalogCategoryView = $catalogCategoryView; + $this->cmsIndex = $cmsIndex; + $this->catalogProductSimple = $catalogProductSimple; + $this->catalogProductView = $catalogProductView; + + $this->addToCardPresentOnCategory(); + $this->addToCardPresentOnProduct(); + } + + /** + * "Add to cart" button is display on Category page + * + * @return void + */ + protected function addToCardPresentOnCategory() + { + $this->cmsIndex->open(); + $this->cmsIndex->getTopmenu()->selectCategoryByName( + $this->catalogProductSimple->getCategoryIds()[0]['name'] + ); + \PHPUnit_Framework_Assert::assertTrue( + $this->catalogCategoryView->getListProductBlock()->checkAddToCardButton(), + "Button 'Add to Card' is absent on Category page" + ); + } + + /** + * "Add to cart" button is display on Product page + * + * @return void + */ + protected function addToCardPresentOnProduct() + { + $this->cmsIndex->open(); + $this->cmsIndex->getTopmenu()->selectCategoryByName( + $this->catalogProductSimple->getCategoryIds()[0]['name'] + ); + $this->catalogCategoryView->getListProductBlock()->openProductViewPage($this->catalogProductSimple->getName()); + \PHPUnit_Framework_Assert::assertTrue( + $this->catalogProductView->getViewBlock()->checkAddToCardButton(), + "Button 'Add to Card' is absent on Product page" + ); + } + + /** + * Text present button "Add to Cart" on the category/product pages + * + * @return string + */ + public function toString() + { + return "Button 'Add to Card' is present on Category page."; + } +} 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 new file mode 100644 index 0000000000000..288629bbdcee7 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertCustomOptionsOnProductPage.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\Catalog\Test\Constraint; + +use Mtf\Fixture\FixtureInterface; +use Mtf\Constraint\AbstractConstraint; +use Magento\Catalog\Test\Page\Product\CatalogProductView; + +/** + * Class AssertCustomOptionsOnProductPage + * + * @package Magento\Catalog\Test\Constraint + */ +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(); + $customOptions = $catalogProductView->getCustomOptionsBlock()->getOptions(); + $compareOptions = $this->product->getCustomOptions(); + + $compareOptions = $this->prepareOptionArray($compareOptions); + ksort($compareOptions); + ksort($customOptions); + $noError = array_keys($compareOptions) === array_keys($customOptions); + + if ($noError) { + $noError = $this->compareOptions($customOptions, $compareOptions); + } + + \PHPUnit_Framework_Assert::assertTrue( + $noError, + 'Incorrect display of custom product options on the product page.' + ); + } + + /** + * Comparison of options + * + * @param array $options + * @param array $compareOptions + * @return bool + */ + protected function compareOptions(array $options, array $compareOptions) + { + foreach ($options as $key => $option) { + sort($option['price']); + if (!isset($compareOptions[$key]['price'])) { + return false; + } + sort($compareOptions[$key]['price']); + if ($option['is_require'] !== $compareOptions[$key]['is_require'] + || $option['price'] !== $compareOptions[$key]['price'] + ) { + return false; + } + } + + return true; + } + + /** + * Preparation options before comparing + * + * @param array $options + * @return array + */ + protected function prepareOptionArray(array $options) + { + $result = []; + $productPrice = $this->product->getPrice(); + $placeholder = ['Yes' => true, 'No' => false]; + foreach ($options as $option) { + $result[$option['title']]['is_require'] = $placeholder[$option['is_require']]; + $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/AssertGroupedPriceOnProductPage.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertGroupedPriceOnProductPage.php new file mode 100644 index 0000000000000..f6b68f85742cd --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertGroupedPriceOnProductPage.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\Catalog\Test\Constraint; + +use Mtf\Fixture\FixtureInterface; +use Mtf\Constraint\AbstractConstraint; +use Magento\Catalog\Test\Page\Product\CatalogProductView; + +/** + * Class AssertGroupedPriceOnProductPage + */ +class AssertGroupedPriceOnProductPage extends AbstractConstraint +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * 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(); + $fields = $product->getData(); + $groupPrice = $catalogProductView->getViewBlock()->getProductPrice(); + $groupPrice = empty($groupPrice['price_special_price']) ? null : $groupPrice['price_special_price']; + if (!empty($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.' + ); + } + } + } + + /** + * 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/AssertProductForm.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductForm.php new file mode 100644 index 0000000000000..654a826c0c321 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductForm.php @@ -0,0 +1,169 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 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\CatalogProductEdit; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex; + +/** + * Class AssertProductForm + */ +class AssertProductForm extends AbstractConstraint +{ + /** + * 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); + + $fixtureData = $productPage->getForm()->getData($product); + $formData = $this->prepareFixtureData($product); + + $errors = $this->compareArray($fixtureData, $formData); + \PHPUnit_Framework_Assert::assertTrue( + empty($errors), + "These data must be equal to each other:\n" . implode("\n - ", $errors) + ); + } + + /** + * Prepares and returns data to the fixture, ready for comparison + * + * @param FixtureInterface $product + * @return array + */ + protected function prepareFixtureData(FixtureInterface $product) + { + $compareData = $product->getData(); + $compareData = array_filter($compareData); + + $compareData['price'] = $this->priceFormat($compareData['price']); + $compareData['qty'] = number_format($compareData['qty'], 4, '.', ''); + $compareData['weight'] = number_format($compareData['weight'], 4, '.', ''); + unset($compareData['url_key']); + + if (!empty($compareData['tier_price'])) { + foreach ($compareData['tier_price'] as &$value) { + $value['price'] = $this->priceFormat($value['price']); + } + unset($value); + } + if (!empty($compareData['group_price'])) { + foreach ($compareData['group_price'] as &$value) { + $value['price'] = $this->priceFormat($value['price']); + } + unset($value); + } + if (!empty($compareData['custom_options'])) { + $placeholder = ['Yes' => true, 'No' => false]; + foreach ($compareData['custom_options'] as &$option) { + $option['is_require'] = $placeholder[$option['is_require']]; + foreach ($option['options'] as &$value) { + $value['price'] = $this->priceFormat($value['price']); + } + unset($value); + } + unset($option); + } + + return $compareData; + } + + /** + * Comparison of multidimensional arrays + * + * @param array $fixtureData + * @param array $formData + * @return array + */ + protected function compareArray(array $fixtureData, array $formData) + { + $errors = []; + ksort($fixtureData); + ksort($formData); + if (array_keys($fixtureData) !== array_keys($formData)) { + return ['arrays do not correspond to each other in composition']; + } + + 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; + } + + /** + * Formatting prices + * + * @param $price + * @return string + */ + protected function priceFormat($price) + { + return number_format($price, 2, '.', ''); + } + + /** + * Returns a string representation of the object. + * + * @return string + */ + public function toString() + { + return 'Form data equal the fixture data.'; + } +} 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 index 55362a5afd49f..9ea5b04180518 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductInCart.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductInCart.php @@ -24,10 +24,10 @@ namespace Magento\Catalog\Test\Constraint; -use Magento\Catalog\Test\Page\Product\CatalogProductView; -use Magento\Checkout\Test\Page\CheckoutCart; +use Mtf\Fixture\FixtureInterface; use Mtf\Constraint\AbstractConstraint; -use Magento\Catalog\Test\Fixture\CatalogProductSimple; +use Magento\Checkout\Test\Page\CheckoutCart; +use Magento\Catalog\Test\Page\Product\CatalogProductView; /** * Class AssertProductInCart @@ -42,13 +42,16 @@ class AssertProductInCart extends AbstractConstraint protected $severeness = 'low'; /** + * Assertion that the product is correctly displayed in cart + * * @param CatalogProductView $catalogProductView - * @param CatalogProductSimple $product + * @param FixtureInterface $product * @param CheckoutCart $checkoutCart + * @return void */ public function processAssert( CatalogProductView $catalogProductView, - CatalogProductSimple $product, + FixtureInterface $product, CheckoutCart $checkoutCart ) { //Add product to cart @@ -56,43 +59,74 @@ public function processAssert( $catalogProductView->open(); $productOptions = $product->getCustomOptions(); if ($productOptions) { - $customOption = $catalogProductView->getOptionsBlock(); - $options = $customOption->getProductCustomOptions(); + $customOption = $catalogProductView->getCustomOptionsBlock(); + $options = $customOption->getOptions(); $key = $productOptions[0]['title']; - $customOption->selectProductCustomOption($options[$key][1]); + $customOption->selectProductCustomOption(reset($options[$key]['value'])); } $catalogProductView->getViewBlock()->clickAddToCart(); + // Check price $this->assertOnShoppingCart($product, $checkoutCart); } /** - * Assert prices on the shopping Cart + * Assert prices on the shopping cart * - * @param CatalogProductSimple $product + * @param FixtureInterface $product * @param CheckoutCart $checkoutCart + * @return void */ - protected function assertOnShoppingCart(CatalogProductSimple $product, CheckoutCart $checkoutCart) + protected function assertOnShoppingCart(FixtureInterface $product, CheckoutCart $checkoutCart) { - /** @var \Magento\Catalog\Test\Fixture\CatalogProductSimple\Price $priceFixture */ - $priceFixture = $product->getDataFieldConfig('price')['source']; - $pricePresetData = $priceFixture->getPreset(); + $cartBlock = $checkoutCart->getCartBlock(); + $productName = $product->getName(); + $productOptions = $product->getCustomOptions(); + $priceComparing = $product->getPrice(); + + if ($groupPrice = $product->getGroupPrice()) { + $groupPrice = reset($groupPrice); + $priceComparing = $groupPrice['price']; + } + + if ($specialPrice = $product->getSpecialPrice()) { + $priceComparing = $specialPrice; + } + + if (!empty($productOptions)) { + $productOption = reset($productOptions); + $optionsData = reset($productOption['options']); + $optionName = $cartBlock->getCartItemOptionsNameByProductName($productName); + $optionValue = $cartBlock->getCartItemOptionsValueByProductName($productName); + + \PHPUnit_Framework_Assert::assertTrue( + trim($optionName) === $productOption['title'] + && trim($optionValue) === $optionsData['title'], + 'In the cart wrong option product.' + ); + + if ($optionsData['price_type'] === 'Percent') { + $priceComparing = $priceComparing * (1 + $optionsData['price'] / 100); + } else { + $priceComparing += $optionsData['price']; + } + } - $price = $checkoutCart->getCartBlock()->getProductPriceByName($product->getName()); + $price = $checkoutCart->getCartBlock()->getProductPriceByName($productName); \PHPUnit_Framework_Assert::assertEquals( - $pricePresetData['cart_price'], + '$' . number_format($priceComparing, 2), $price, 'Product price in shopping cart is not correct.' ); } /** - * Text of Visible in category assert + * Returns a string representation of the object. * * @return string */ public function toString() { - return 'Product price in shopping cart is not correct.'; + return 'Product is correctly displayed in cart.'; } } 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 0697b26cb6a14..24097b3170328 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 @@ -24,11 +24,11 @@ namespace Magento\Catalog\Test\Constraint; -use Mtf\Constraint\AbstractConstraint; -use Magento\Catalog\Test\Page\Category\CatalogCategoryView; +use Mtf\Fixture\FixtureInterface; use Magento\Cms\Test\Page\CmsIndex; +use Mtf\Constraint\AbstractConstraint; use Magento\Catalog\Test\Fixture\Category; -use Magento\Catalog\Test\Fixture\CatalogProductSimple; +use Magento\Catalog\Test\Page\Category\CatalogCategoryView; /** * Class AssertProductInCategory @@ -43,74 +43,65 @@ class AssertProductInCategory extends AbstractConstraint protected $severeness = 'low'; /** + * Checking the product in the page of its price + * * @param CatalogCategoryView $catalogCategoryView * @param CmsIndex $cmsIndex - * @param CatalogProductSimple $product + * @param FixtureInterface $product * @param Category $category + * @return void */ public function processAssert( CatalogCategoryView $catalogCategoryView, CmsIndex $cmsIndex, - CatalogProductSimple $product, + FixtureInterface $product, Category $category ) { - //Open category view page + //Open category view page and check visible product $cmsIndex->open(); $cmsIndex->getTopmenu()->selectCategoryByName($category->getCategoryName()); - //process asserts + $isProductVisible = $catalogCategoryView->getListProductBlock()->isProductVisible($product->getName()); + while (!$isProductVisible && $catalogCategoryView->getToolbar()->nextPage()) { + $isProductVisible = $catalogCategoryView->getListProductBlock()->isProductVisible($product->getName()); + } + + \PHPUnit_Framework_Assert::assertTrue( + $isProductVisible, + 'Product is absent on category page.' + ); + + //Process price asserts $this->assertPrice($product, $catalogCategoryView); } /** * Verify product price on category view page * - * @param CatalogProductSimple $product + * @param FixtureInterface $product * @param CatalogCategoryView $catalogCategoryView + * @return void */ - protected function assertPrice(CatalogProductSimple $product, CatalogCategoryView $catalogCategoryView) + protected function assertPrice(FixtureInterface $product, CatalogCategoryView $catalogCategoryView) { - /** @var \Magento\Catalog\Test\Fixture\CatalogProductSimple\Price $priceFixture */ - $priceFixture = $product->getDataFieldConfig('price')['source']; - $pricePresetData = $priceFixture->getPreset(); + $price = $catalogCategoryView->getListProductBlock()->getProductPriceBlock($product->getName()) + ->getRegularPrice(); - //Regular price verification - if (isset($pricePresetData['category_special_price'])) { - $regularPrice = $catalogCategoryView->getListProductBlock()->getProductPriceBlock($product->getName()) - ->getRegularPrice(); - \PHPUnit_Framework_Assert::assertEquals( - $pricePresetData['category_price'], - $regularPrice, - 'Product regular price on category page is not correct.' - ); - //Special price verification - $specialPrice = $catalogCategoryView->getListProductBlock()->getProductPriceBlock( - $product->getName() - )->getSpecialPrice(); - \PHPUnit_Framework_Assert::assertEquals( - $pricePresetData['category_special_price'], - $specialPrice, - 'Product special price on category page is not correct.' - ); - } else { - //Price verification - $price = $catalogCategoryView->getListProductBlock()->getProductPriceBlock($product->getName()) - ->getPrice(); - \PHPUnit_Framework_Assert::assertContains( - (string)$price, - $pricePresetData['category_price'], - 'Product price on category page is not correct.' - ); - } + $priceComparing = '$' . number_format($product->getPrice(), 2); + \PHPUnit_Framework_Assert::assertEquals( + $priceComparing, + $price, + 'Product regular price on category page is not correct.' + ); } /** - * Text of Visible in category assert + * Returns a string representation of the object. * * @return string */ public function toString() { - return 'Product price on category page is not correct.'; + return 'Product price on category page correct.'; } } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductInGrid.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductInGrid.php index dc126271b68a4..0b069ffcaff42 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductInGrid.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductInGrid.php @@ -24,13 +24,12 @@ namespace Magento\Catalog\Test\Constraint; +use Mtf\Fixture\FixtureInterface; use Mtf\Constraint\AbstractConstraint; -use Magento\Catalog\Test\Fixture\CatalogProductSimple; use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex; /** * Class AssertProductInGrid - * */ class AssertProductInGrid extends AbstractConstraint { @@ -42,27 +41,29 @@ class AssertProductInGrid extends AbstractConstraint protected $severeness = 'high'; /** - * Assert product availability in Products Grid + * Assert product availability in products grid * - * @param CatalogProductSimple $product - * @param CatalogProductIndex $productPageGrid + * @param FixtureInterface $product + * @param CatalogProductIndex $productGrid * @return void */ - public function processAssert(CatalogProductSimple $product, CatalogProductIndex $productPageGrid) + public function processAssert(FixtureInterface $product, CatalogProductIndex $productGrid) { $filter = ['sku' => $product->getSku()]; - $productPageGrid->open(); + $productGrid->open(); \PHPUnit_Framework_Assert::assertTrue( - $productPageGrid->getProductGrid()->isRowVisible($filter), + $productGrid->getProductGrid()->isRowVisible($filter), 'Product with sku \'' . $product->getSku() . '\' is absent in Products grid.' ); } /** - * @inheritdoc + * Returns a string representation of the object. + * + * @return string */ public function toString() { - return 'Product is present in Products grid.'; + return 'Product is present in products grid.'; } } 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 index c2899188b9568..ebfff102de1dc 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductInStock.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductInStock.php @@ -24,13 +24,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\Fixture\CatalogProductSimple; /** * Class AssertProductInStock - * */ class AssertProductInStock extends AbstractConstraint { @@ -50,11 +49,12 @@ class AssertProductInStock extends AbstractConstraint * Assert that In Stock status is displayed on product page * * @param CatalogProductView $catalogProductView - * @param CatalogProductSimple $product + * @param FixtureInterface $product * @return void */ - public function processAssert(CatalogProductView $catalogProductView, CatalogProductSimple $product) + public function processAssert(CatalogProductView $catalogProductView, FixtureInterface $product) { + // TODO fix initialization url for frontend page $catalogProductView->init($product); $catalogProductView->open(); \PHPUnit_Framework_Assert::assertEquals( @@ -65,7 +65,7 @@ public function processAssert(CatalogProductView $catalogProductView, CatalogPro } /** - * Text of In Stock assertion + * Returns a string representation of the object. * * @return string */ 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 index 28c575f0392aa..bda4162dc0647 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductOutOfStock.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductOutOfStock.php @@ -24,13 +24,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\Fixture\CatalogProductSimple; /** * Class AssertProductOutOfStock - * */ class AssertProductOutOfStock extends AbstractConstraint { @@ -50,10 +49,10 @@ class AssertProductOutOfStock extends AbstractConstraint * Assert that Out of Stock status is displayed on product page * * @param CatalogProductView $catalogProductView - * @param CatalogProductSimple $product + * @param FixtureInterface $product * @return void */ - public function processAssert(CatalogProductView $catalogProductView, CatalogProductSimple $product) + public function processAssert(CatalogProductView $catalogProductView, FixtureInterface $product) { $catalogProductView->init($product); $catalogProductView->open(); @@ -65,7 +64,7 @@ public function processAssert(CatalogProductView $catalogProductView, CatalogPro } /** - * Text of Out of Stock assert + * Returns a string representation of the object. * * @return string */ 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 new file mode 100644 index 0000000000000..90d03847b8e8e --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductPage.php @@ -0,0 +1,154 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 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 AssertProductPage + */ +class AssertProductPage extends AbstractConstraint +{ + /** + * Product fixture + * + * @var FixtureInterface + */ + protected $product; + + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Assertion that the product page is 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($product); + $catalogProductView->open(); + + //Process assertions + $this->assertOnProductView($catalogProductView); + } + + /** + * Assert prices on the product view page + * + * @param CatalogProductView $catalogProductView + * @return void + */ + protected function assertOnProductView(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'] + ]; + $compareData = [ + 'name' => $this->product->getName(), + 'sku' => $this->product->getSku(), + 'regular_price' => number_format($this->product->getPrice(), 2), + + ]; + + if ($productShortDescription = $this->product->getShortDescription()) { + $compareData['short_description'] = $productShortDescription; + $dataOnPage['short_description'] = $viewBlock->getProductShortDescription(); + } + if ($productDescription = $this->product->getDescription()) { + $compareData['description'] = $productDescription; + $dataOnPage['description'] = $viewBlock->getProductDescription(); + } + + $badValues = array_diff($dataOnPage, $compareData); + $errorsMessages = array_merge( + $this->assertSpecialPrice($price), + array_intersect_key($errorsMessages, array_keys($badValues)) + ); + + \PHPUnit_Framework_Assert::assertTrue( + empty($errorsMessages), + PHP_EOL . 'Found the following errors:' . PHP_EOL + . implode(' ' . PHP_EOL, $errorsMessages) + ); + } + + /** + * Checking the special product price + * + * @param array $price + * @return array + */ + protected function assertSpecialPrice(array $price) + { + $priceComparing = false; + if ($specialPrice = $this->product->getSpecialPrice()) { + $priceComparing = $specialPrice; + } + if ($groupPrice = $this->product->getGroupPrice()) { + $groupPrice = reset($groupPrice); + $priceComparing = $groupPrice['price']; + } + if ($priceComparing && isset($price['price_special_price']) + && number_format($priceComparing, 2) !== $price['price_special_price'] + ) { + return ['special_price' => '- product special price on product view page is not correct.']; + } + + return []; + } + + /** + * Returns a string representation of the object. + * + * @return string + */ + public function toString() + { + return 'Product on product view page is not correct.'; + } +} 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 a79f146ab5d26..0c0795556a468 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 @@ -25,14 +25,16 @@ namespace Magento\Catalog\Test\Constraint; use Mtf\Constraint\AbstractConstraint; -use Magento\Catalog\Test\Page\Product\CatalogProductEdit; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductEdit; /** * Class AssertProductSaveMessage - * */ class AssertProductSaveMessage extends AbstractConstraint { + /** + * Text value to be checked + */ const SUCCESS_MESSAGE = 'You saved the product.'; /** @@ -61,7 +63,9 @@ public function processAssert(CatalogProductEdit $productPage) } /** - * @inheritdoc + * Returns a string representation of the object. + * + * @return string */ public function toString() { 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 fdb1eae2c879d..aff6b2713f390 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 @@ -24,14 +24,13 @@ 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; -use Magento\Cms\Test\Page\CmsIndex; -use Magento\Catalog\Test\Fixture\CatalogProductSimple; /** * Class AssertProductSearchableBySku - * */ class AssertProductSearchableBySku extends AbstractConstraint { @@ -47,13 +46,13 @@ class AssertProductSearchableBySku extends AbstractConstraint * * @param CatalogsearchResult $catalogSearchResult * @param CmsIndex $cmsIndex - * @param CatalogProductSimple $product + * @param FixtureInterface $product * @return void */ public function processAssert( CatalogsearchResult $catalogSearchResult, CmsIndex $cmsIndex, - CatalogProductSimple $product + FixtureInterface $product ) { $cmsIndex->open(); $cmsIndex->getSearchBlock()->search($product->getSku()); @@ -64,7 +63,7 @@ public function processAssert( } /** - * Text of Searchable assert + * Returns a string representation of the object. * * @return string */ diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductView.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductView.php deleted file mode 100644 index 93e0c24e0065c..0000000000000 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductView.php +++ /dev/null @@ -1,108 +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 Magento\Catalog\Test\Page\Product\CatalogProductView; -use Magento\Checkout\Test\Page\CheckoutCart; -use Mtf\Constraint\AbstractConstraint; -use Magento\Catalog\Test\Page\Category\CatalogCategoryView; -use Magento\Cms\Test\Page\CmsIndex; -use Magento\Catalog\Test\Fixture\Category; -use Magento\Catalog\Test\Fixture\CatalogProductSimple; - -/** - * Class AssertProductView - */ -class AssertProductView extends AbstractConstraint -{ - /** - * Constraint severeness - * - * @var string - */ - protected $severeness = 'low'; - - /** - * @param CatalogProductView $catalogProductView - * @param CatalogProductSimple $product - */ - public function processAssert( - CatalogProductView $catalogProductView, - CatalogProductSimple $product - ) { - //Open product view page - $catalogProductView->init($product); - $catalogProductView->open(); - - //Process assertions - $this->assertOnProductView($product, $catalogProductView); - } - - /** - * Assert prices on the product view Page - * - * @param CatalogProductSimple $product - * @param CatalogProductView $catalogProductView - */ - protected function assertOnProductView(CatalogProductSimple $product, CatalogProductView $catalogProductView) - { - /** @var \Magento\Catalog\Test\Fixture\CatalogProductSimple\Price $priceFixture */ - $priceFixture = $product->getDataFieldConfig('price')['source']; - $pricePresetData = $priceFixture->getPreset(); - - if (isset($pricePresetData['product_special_price'])) { - $regularPrice = $catalogProductView->getViewBlock()->getProductPriceBlock()->getRegularPrice(); - \PHPUnit_Framework_Assert::assertEquals( - $pricePresetData['product_price'], - $regularPrice, - 'Product regular price on product view page is not correct.' - ); - - $specialPrice = $catalogProductView->getViewBlock()->getProductPriceBlock()->getSpecialPrice(); - \PHPUnit_Framework_Assert::assertEquals( - $pricePresetData['product_special_price'], - $specialPrice, - 'Product special price on product view page is not correct.' - ); - } else { - $price = $catalogProductView->getViewBlock()->getProductPriceBlock()->getPrice(); - \PHPUnit_Framework_Assert::assertContains( - (string)$price, - $pricePresetData['product_price'], - 'Product price on product view page is not correct.' - ); - } - } - - /** - * Text of Visible in category assert - * - * @return string - */ - public function toString() - { - return 'Product price on product view page is not correct.'; - } -} 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 c2a58f7942f91..db04ab19a913a 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 @@ -24,15 +24,14 @@ namespace Magento\Catalog\Test\Constraint; -use Mtf\Constraint\AbstractConstraint; -use Magento\Catalog\Test\Page\Category\CatalogCategoryView; +use Mtf\Fixture\FixtureInterface; use Magento\Cms\Test\Page\CmsIndex; +use Mtf\Constraint\AbstractConstraint; use Magento\Catalog\Test\Fixture\Category; -use Magento\Catalog\Test\Fixture\CatalogProductSimple; +use Magento\Catalog\Test\Page\Category\CatalogCategoryView; /** * Class AssertProductVisibleInCategory - * */ class AssertProductVisibleInCategory extends AbstractConstraint { @@ -48,26 +47,32 @@ class AssertProductVisibleInCategory extends AbstractConstraint * * @param CatalogCategoryView $catalogCategoryView * @param CmsIndex $cmsIndex - * @param CatalogProductSimple $product + * @param FixtureInterface $product * @param Category $category * @return void */ public function processAssert( CatalogCategoryView $catalogCategoryView, CmsIndex $cmsIndex, - CatalogProductSimple $product, + FixtureInterface $product, Category $category ) { $cmsIndex->open(); $cmsIndex->getTopmenu()->selectCategoryByName($category->getCategoryName()); + + $isProductVisible = $catalogCategoryView->getListProductBlock()->isProductVisible($product->getName()); + while (!$isProductVisible && $catalogCategoryView->getToolbar()->nextPage()) { + $isProductVisible = $catalogCategoryView->getListProductBlock()->isProductVisible($product->getName()); + } + \PHPUnit_Framework_Assert::assertTrue( - $catalogCategoryView->getListProductBlock()->isProductVisible($product->getName()), + $isProductVisible, 'Product is absent on category page.' ); } /** - * Text of Visible in category assert + * Returns a string representation of the object. * * @return string */ diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertSpecialPriceOnProductPage.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertSpecialPriceOnProductPage.php new file mode 100644 index 0000000000000..3bdec2b01e2bf --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertSpecialPriceOnProductPage.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 Mtf\Constraint\AbstractConstraint; +use Magento\Catalog\Test\Page\Product\CatalogProductView; + +/** + * Class AssertSpecialPriceOnProductPage + */ +class AssertSpecialPriceOnProductPage extends AbstractConstraint +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Assert that displayed special 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(); + $fields = $product->getData(); + $specialPrice = $catalogProductView->getViewBlock()->getProductPrice(); + $specialPrice = isset($specialPrice['price_special_price']) ? $specialPrice['price_special_price'] : null; + if (!empty($fields['special_price'])) { + \PHPUnit_Framework_Assert::assertEquals( + $fields['special_price'], + $specialPrice, + 'Assert that displayed special price on product page NOT equals passed from fixture.' + ); + } + } + + /** + * Returns a string representation of the object. + * + * @return string + */ + public function toString() + { + return "Assert that displayed special price on product page equals passed from fixture"; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertTierPriceOnProductPage.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertTierPriceOnProductPage.php new file mode 100644 index 0000000000000..a7642631be0b9 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertTierPriceOnProductPage.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\Constraint; + +use Mtf\Fixture\FixtureInterface; +use Mtf\Constraint\AbstractConstraint; +use Magento\Catalog\Test\Page\Product\CatalogProductView; + +/** + * Class AssertTierPriceOnProductPage + */ +class AssertTierPriceOnProductPage extends AbstractConstraint +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Assertion that tier prices 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(); + + //Process assertions + $this->assertTierPrice($product, $catalogProductView); + } + + /** + * Verify product tier price on product view page + * + * @param FixtureInterface $product + * @param CatalogProductView $catalogProductView + * @return void + */ + protected function assertTierPrice(FixtureInterface $product, CatalogProductView $catalogProductView) + { + $noError = true; + $match = []; + $index = 1; + $viewBlock = $catalogProductView->getViewBlock(); + $tierPrices = $product->getTierPrice(); + + foreach ($tierPrices as $tierPrice) { + $text = $viewBlock->getTierPrices($index++); + $noError = (bool)preg_match('#^[^\d]+(\d+)[^\d]+(\d+(?:(?:,\d+)*)+(?:.\d+)*).*#i', $text, $match); + if (!$noError) { + break; + } + if (count($match) < 2 + && $match[1] != $tierPrice['price_qty'] + || $match[2] !== number_format($tierPrice['price'], 2) + ) { + $noError = false; + break; + } + } + + \PHPUnit_Framework_Assert::assertTrue($noError, 'Product tier price on product page is not correct.'); + } + + /** + * Returns a string representation of the object. + * + * @return string + */ + public function toString() + { + return 'Tier price is displayed on the product page'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogCategoryEntity.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogCategoryEntity.php new file mode 100644 index 0000000000000..395510caa9049 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogCategoryEntity.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\Test\Fixture; + +use Mtf\Fixture\InjectableFixture; + +/** + * Class CatalogCategoryEntity + * Category fixture + */ +class CatalogCategoryEntity extends InjectableFixture +{ + /** + * @var string + */ + protected $repositoryClass = 'Magento\Catalog\Test\Repository\CatalogCategoryEntity'; + + /** + * @var string + */ + protected $handlerInterface = 'Magento\Catalog\Test\Handler\CatalogCategoryEntity\CatalogCategoryEntityInterface'; + + protected $defaultDataSet = [ + 'name' => 'Category%isolation%', + 'path' => 'Default Category', + 'url_key' => 'category%isolation%', + 'is_active' => 'Yes', + 'include_in_menu' => 'Yes', + 'parent_id' => 2, + ]; + + protected $entity_id = [ + 'attribute_code' => 'entity_id', + 'backend_type' => 'int', + 'is_required' => '1', + 'default_value' => '', + 'input' => '', + ]; + + protected $entity_type_id = [ + 'attribute_code' => 'entity_type_id', + 'backend_type' => 'smallint', + 'is_required' => '', + 'default_value' => '0', + 'input' => '', + ]; + + protected $attribute_set_id = [ + 'attribute_code' => 'attribute_set_id', + 'backend_type' => 'smallint', + 'is_required' => '', + 'default_value' => '0', + 'input' => '', + ]; + + protected $parent_id = [ + 'attribute_code' => 'parent_id', + 'backend_type' => 'int', + 'is_required' => '', + 'default_value' => '0', + 'input' => '', + ]; + + protected $created_at = [ + 'attribute_code' => 'created_at', + 'backend_type' => 'timestamp', + 'is_required' => '', + 'default_value' => '', + 'input' => '', + ]; + + protected $updated_at = [ + 'attribute_code' => 'updated_at', + 'backend_type' => 'timestamp', + 'is_required' => '', + 'default_value' => '', + 'input' => '', + ]; + + protected $path = [ + 'attribute_code' => 'path', + 'backend_type' => 'varchar', + 'is_required' => '', + 'default_value' => '', + 'input' => '', + ]; + + protected $position = [ + 'attribute_code' => 'position', + 'backend_type' => 'int', + 'is_required' => '', + 'default_value' => '', + 'input' => '', + ]; + + protected $level = [ + 'attribute_code' => 'level', + 'backend_type' => 'int', + 'is_required' => '', + 'default_value' => '0', + 'input' => '', + ]; + + protected $children_count = [ + 'attribute_code' => 'children_count', + 'backend_type' => 'int', + 'is_required' => '', + 'default_value' => '', + 'input' => '', + ]; + + protected $id = [ + 'attribute_code' => 'id', + 'backend_type' => 'virtual', + ]; + + protected $name = [ + 'attribute_code' => 'name', + 'backend_type' => 'virtual', + ]; + + protected $is_active = [ + 'attribute_code' => 'is_active', + 'backend_type' => 'virtual', + ]; + + protected $url_key = [ + 'attribute_code' => 'url_key', + 'backend_type' => 'virtual', + ]; + + protected $include_in_menu = [ + 'attribute_code' => 'include_in_menu', + 'backend_type' => 'virtual', + ]; + + public function getEntityId() + { + return $this->getData('entity_id'); + } + + public function getEntityTypeId() + { + return $this->getData('entity_type_id'); + } + + public function getAttributeSetId() + { + return $this->getData('attribute_set_id'); + } + + public function getParentId() + { + return $this->getData('parent_id'); + } + + public function getCreatedAt() + { + return $this->getData('created_at'); + } + + public function getUpdatedAt() + { + return $this->getData('updated_at'); + } + + public function getPath() + { + return $this->getData('path'); + } + + public function getPosition() + { + return $this->getData('position'); + } + + public function getLevel() + { + return $this->getData('level'); + } + + public function getChildrenCount() + { + return $this->getData('children_count'); + } + + public function getId() + { + return $this->getData('id'); + } + + public function getName() + { + return $this->getData('name'); + } + + public function getIsActive() + { + return $this->getData('is_active'); + } + + public function getUrlKey() + { + return $this->getData('url_key'); + } + + public function getIncludeInMenu() + { + return $this->getData('include_in_menu'); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogCategoryEntity.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogCategoryEntity.xml new file mode 100644 index 0000000000000..cc8301ed27d50 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogCategoryEntity.xml @@ -0,0 +1,125 @@ +<?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\Catalog\Test\Fixture\CatalogCategoryEntity"> + <module>Magento_Catalog</module> + <type>flat</type> + <entity_type>catalog_category_entity</entity_type> + <collection>Magento\Catalog\Model\Resource\Category\Collection</collection> + <fields> + <entity_id> + <attribute_code>entity_id</attribute_code> + <backend_type>int</backend_type> + <is_required>1</is_required> + <default_value></default_value> + <input></input> + </entity_id> + <entity_type_id> + <attribute_code>entity_type_id</attribute_code> + <backend_type>smallint</backend_type> + <is_required></is_required> + <default_value>0</default_value> + <input></input> + </entity_type_id> + <attribute_set_id> + <attribute_code>attribute_set_id</attribute_code> + <backend_type>smallint</backend_type> + <is_required></is_required> + <default_value>0</default_value> + <input></input> + </attribute_set_id> + <parent_id> + <attribute_code>parent_id</attribute_code> + <backend_type>int</backend_type> + <is_required></is_required> + <default_value>0</default_value> + <input></input> + </parent_id> + <created_at> + <attribute_code>created_at</attribute_code> + <backend_type>timestamp</backend_type> + <is_required></is_required> + <default_value></default_value> + <input></input> + </created_at> + <updated_at> + <attribute_code>updated_at</attribute_code> + <backend_type>timestamp</backend_type> + <is_required></is_required> + <default_value></default_value> + <input></input> + </updated_at> + <path> + <attribute_code>path</attribute_code> + <backend_type>varchar</backend_type> + <is_required></is_required> + <default_value></default_value> + <input></input> + </path> + <position> + <attribute_code>position</attribute_code> + <backend_type>int</backend_type> + <is_required></is_required> + <default_value></default_value> + <input></input> + </position> + <level> + <attribute_code>level</attribute_code> + <backend_type>int</backend_type> + <is_required></is_required> + <default_value>0</default_value> + <input></input> + </level> + <children_count> + <attribute_code>children_count</attribute_code> + <backend_type>int</backend_type> + <is_required></is_required> + <default_value></default_value> + <input></input> + </children_count> + <id> + <attribute_code>id</attribute_code> + <backend_type>virtual</backend_type> + </id> + <name> + <attribute_code>name</attribute_code> + <backend_type>virtual</backend_type> + </name> + <is_active> + <attribute_code>is_active</attribute_code> + <backend_type>virtual</backend_type> + </is_active> + <url_key> + <attribute_code>url_key</attribute_code> + <backend_type>virtual</backend_type> + </url_key> + <include_in_menu> + <attribute_code>include_in_menu</attribute_code> + <backend_type>virtual</backend_type> + </include_in_menu> + </fields> + <repository_class>Magento\Catalog\Test\Repository\CatalogCategoryEntity</repository_class> + <handler_interface>Magento\Catalog\Test\Handler\CatalogCategoryEntity\CatalogCategoryEntityInterface</handler_interface> +</fixture> 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 index 670aaeb09b42e..802363d4ba229 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.php @@ -32,7 +32,7 @@ /** * Class CatalogProductSimple - * + * Product Simple fixture */ class CatalogProductSimple extends InjectableFixture { @@ -90,14 +90,11 @@ public function __construct( ]; protected $defaultDataSet = [ - 'enable_googlecheckout' => null, - 'msrp_display_actual_price_type' => null, - 'msrp_enabled' => null, - 'options_container' => null, - 'quantity_and_stock_status' => null, - 'status' => null, - 'tax_class_id' => null, - 'visibility' => null, + 'name' => 'Test simple product %isolation%', + 'sku' => 'test_simple_sku_%isolation%', + 'price' => ['value' => 100.00], + 'weight' => 12.0000, + 'qty' => 10 ]; protected $category_ids = [ @@ -106,7 +103,7 @@ public function __construct( 'is_required' => '0', 'default_value' => '', 'input' => 'text', - 'fixture' => 'Magento\Catalog\Test\Fixture\CategoryIds' + 'source' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\CategoryIds', ]; protected $color = [ @@ -171,14 +168,7 @@ public function __construct( 'is_required' => '0', 'default_value' => '', 'input' => 'textarea', - ]; - - protected $enable_googlecheckout = [ - 'attribute_code' => 'enable_googlecheckout', - 'backend_type' => 'int', - 'is_required' => '0', - 'default_value' => 'No', - 'input' => 'select', + 'group' => 'product-details', ]; protected $gallery = [ @@ -204,7 +194,7 @@ public function __construct( 'default_value' => '', 'input' => 'text', 'group' => 'advanced-pricing', - 'fixture' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\GroupPriceOptions' + 'source' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\GroupPriceOptions', ]; protected $has_options = [ @@ -260,6 +250,7 @@ public function __construct( 'backend_type' => 'varchar', 'is_required' => '0', 'default_value' => '', + 'group' => 'search-optimization', 'input' => 'textarea', ]; @@ -268,6 +259,7 @@ public function __construct( 'backend_type' => 'text', 'is_required' => '0', 'default_value' => '', + 'group' => 'search-optimization', 'input' => 'textarea', ]; @@ -276,6 +268,7 @@ public function __construct( 'backend_type' => 'varchar', 'is_required' => '0', 'default_value' => '', + 'group' => 'search-optimization', 'input' => 'text', ]; @@ -299,7 +292,7 @@ public function __construct( 'attribute_code' => 'msrp_display_actual_price_type', 'backend_type' => 'varchar', 'is_required' => '0', - 'default_value' => '', + 'default_value' => 'Use config', 'input' => 'select', ]; @@ -307,7 +300,7 @@ public function __construct( 'attribute_code' => 'msrp_enabled', 'backend_type' => 'varchar', 'is_required' => '0', - 'default_value' => '', + 'default_value' => 'In Cart', 'input' => 'select', ]; @@ -348,7 +341,8 @@ public function __construct( 'attribute_code' => 'options_container', 'backend_type' => 'varchar', 'is_required' => '0', - 'default_value' => '', + 'default_value' => 'Block after Info Column', + 'default_value' => 'Block after Info Column', 'input' => 'select', ]; @@ -367,14 +361,14 @@ public function __construct( 'default_value' => '', 'input' => 'price', 'group' => 'product-details', - 'fixture' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\Price' + 'source' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\Price', ]; protected $quantity_and_stock_status = [ 'attribute_code' => 'quantity_and_stock_status', 'backend_type' => 'int', 'is_required' => '0', - 'default_value' => '', + 'default_value' => 'In Stock', 'input' => 'select', 'group' => 'product-details', ]; @@ -395,14 +389,6 @@ public function __construct( 'input' => 'text', ]; - protected $short_description = [ - 'attribute_code' => 'short_description', - 'backend_type' => 'text', - 'is_required' => '0', - 'default_value' => '', - 'input' => 'textarea', - ]; - protected $sku = [ 'attribute_code' => 'sku', 'backend_type' => 'static', @@ -436,13 +422,22 @@ public function __construct( 'input' => 'date', ]; + protected $short_description = [ + 'attribute_code' => 'short_description', + 'backend_type' => 'text', + 'is_required' => '0', + 'default_value' => '', + 'input' => 'textarea', + 'group' => 'autosettings', + ]; + protected $special_price = [ 'attribute_code' => 'special_price', 'backend_type' => 'decimal', 'is_required' => '0', 'default_value' => '', 'input' => 'price', - 'group' => 'advanced-pricing' + 'group' => 'advanced-pricing', ]; protected $special_to_date = [ @@ -457,7 +452,7 @@ public function __construct( 'attribute_code' => 'status', 'backend_type' => 'int', 'is_required' => '0', - 'default_value' => '', + 'default_value' => '1', 'input' => 'select', ]; @@ -467,6 +462,7 @@ public function __construct( 'is_required' => '0', 'default_value' => 'Taxable Goods', 'input' => 'select', + 'group' => 'product-details', ]; protected $thumbnail = [ @@ -492,7 +488,7 @@ public function __construct( 'default_value' => '', 'input' => 'text', 'group' => 'advanced-pricing', - 'fixture' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\TierPriceOptions' + 'source' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\TierPriceOptions', ]; protected $updated_at = [ @@ -563,7 +559,7 @@ public function __construct( 'backend_type' => 'virtual', 'is_required' => '0', 'group' => 'customer-options', - 'fixture' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\CustomOptions', + 'source' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\CustomOptions', ]; public function getCategoryIds() @@ -611,11 +607,6 @@ public function getDescription() return $this->getData('description'); } - public function getEnableGooglecheckout() - { - return $this->getData('enable_googlecheckout'); - } - public function getGallery() { return $this->getData('gallery'); @@ -746,11 +737,6 @@ public function getRequiredOptions() return $this->getData('required_options'); } - public function getShortDescription() - { - return $this->getData('short_description'); - } - public function getSku() { return $this->getData('sku'); @@ -771,6 +757,11 @@ public function getSpecialFromDate() return $this->getData('special_from_date'); } + public function getShortDescription() + { + return $this->getData('short_description'); + } + public function getSpecialPrice() { return $this->getData('special_price'); diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.xml index 634973de5e923..d0fe5a35c437b 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.xml @@ -37,6 +37,7 @@ <is_required>0</is_required> <default_value></default_value> <input>text</input> + <fixture>Magento\Catalog\Test\Fixture\CatalogProductSimple\CategoryIds</fixture> </category_ids> <color> <attribute_code>color</attribute_code> @@ -93,14 +94,8 @@ <is_required>0</is_required> <default_value></default_value> <input>textarea</input> + <group>product-details</group> </description> - <enable_googlecheckout> - <attribute_code>enable_googlecheckout</attribute_code> - <backend_type>int</backend_type> - <is_required>0</is_required> - <default_value>1</default_value> - <input>select</input> - </enable_googlecheckout> <gallery> <attribute_code>gallery</attribute_code> <backend_type>varchar</backend_type> @@ -171,6 +166,7 @@ <backend_type>varchar</backend_type> <is_required>0</is_required> <default_value></default_value> + <group>search-optimization</group> <input>textarea</input> </meta_description> <meta_keyword> @@ -178,6 +174,7 @@ <backend_type>text</backend_type> <is_required>0</is_required> <default_value></default_value> + <group>search-optimization</group> <input>textarea</input> </meta_keyword> <meta_title> @@ -185,6 +182,7 @@ <backend_type>varchar</backend_type> <is_required>0</is_required> <default_value></default_value> + <group>search-optimization</group> <input>text</input> </meta_title> <minimal_price> @@ -205,14 +203,14 @@ <attribute_code>msrp_display_actual_price_type</attribute_code> <backend_type>varchar</backend_type> <is_required>0</is_required> - <default_value>4</default_value> + <default_value>Use config</default_value> <input>select</input> </msrp_display_actual_price_type> <msrp_enabled> <attribute_code>msrp_enabled</attribute_code> <backend_type>varchar</backend_type> <is_required>0</is_required> - <default_value>2</default_value> + <default_value>In Cart</default_value> <input>select</input> </msrp_enabled> <name> @@ -221,7 +219,7 @@ <is_required>1</is_required> <default_value></default_value> <input>text</input> - <group>product_info_tabs_product-details</group> + <group>product-details</group> </name> <news_from_date> <attribute_code>news_from_date</attribute_code> @@ -248,7 +246,7 @@ <attribute_code>options_container</attribute_code> <backend_type>varchar</backend_type> <is_required>0</is_required> - <default_value>container2</default_value> + <default_value>Block after Info Column</default_value> <input>select</input> </options_container> <page_layout> @@ -264,16 +262,16 @@ <is_required>1</is_required> <default_value></default_value> <input>price</input> - <group>product_info_tabs_product-details</group> + <group>product-details</group> <fixture>Magento\Catalog\Test\Fixture\CatalogProductSimple\Price</fixture> </price> <quantity_and_stock_status> <attribute_code>quantity_and_stock_status</attribute_code> <backend_type>int</backend_type> <is_required>0</is_required> - <default_value>1</default_value> + <default_value>In Stock</default_value> <input>select</input> - <group>product_info_tabs_product-details</group> + <group>product-details</group> </quantity_and_stock_status> <recurring_profile> <attribute_code>recurring_profile</attribute_code> @@ -289,20 +287,13 @@ <default_value></default_value> <input>text</input> </required_options> - <short_description> - <attribute_code>short_description</attribute_code> - <backend_type>text</backend_type> - <is_required>0</is_required> - <default_value></default_value> - <input>textarea</input> - </short_description> <sku> <attribute_code>sku</attribute_code> <backend_type>static</backend_type> <is_required>1</is_required> <default_value></default_value> <input>text</input> - <group>product_info_tabs_product-details</group> + <group>product-details</group> </sku> <small_image> <attribute_code>small_image</attribute_code> @@ -325,6 +316,14 @@ <default_value></default_value> <input>date</input> </special_from_date> + <short_description> + <attribute_code>short_description</attribute_code> + <backend_type>text</backend_type> + <is_required>0</is_required> + <default_value></default_value> + <input>textarea</input> + <group>autosettings</group> + </short_description> <special_price> <attribute_code>special_price</attribute_code> <backend_type>decimal</backend_type> @@ -351,8 +350,9 @@ <attribute_code>tax_class_id</attribute_code> <backend_type>int</backend_type> <is_required>0</is_required> - <default_value>2</default_value> + <default_value>Taxable Goods</default_value> <input>select</input> + <group>product-details</group> </tax_class_id> <thumbnail> <attribute_code>thumbnail</attribute_code> @@ -375,6 +375,7 @@ <default_value></default_value> <input>text</input> <group>advanced-pricing</group> + <fixture>Magento\Catalog\Test\Fixture\CatalogProductSimple\TierPriceOptions</fixture> </tier_price> <updated_at> <attribute_code>updated_at</attribute_code> @@ -401,7 +402,7 @@ <attribute_code>visibility</attribute_code> <backend_type>int</backend_type> <is_required>0</is_required> - <default_value>4</default_value> + <default_value>Catalog, Search</default_value> <input>select</input> <group>autosettings</group> </visibility> @@ -411,7 +412,7 @@ <is_required>0</is_required> <default_value></default_value> <input>weight</input> - <group>product_info_tabs_product-details</group> + <group>product-details</group> </weight> <id> <attribute_code>id</attribute_code> @@ -428,13 +429,14 @@ <qty> <attribute_code>qty</attribute_code> <input>input</input> - <group>product_info_tabs_product-details</group> + <group>product-details</group> </qty> <custom_options> <attribute_code>custom_options</attribute_code> <backend_type>virtual</backend_type> <group>product_info_tabs_customer_options</group> <is_required>0</is_required> + <group>customer-options</group> <fixture>Magento\Catalog\Test\Fixture\CatalogProductSimple\CustomOptions</fixture> </custom_options> </fields> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CategoryIds.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/CategoryIds.php similarity index 68% rename from dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CategoryIds.php rename to dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/CategoryIds.php index ea8ca67823d19..9c62c829c9565 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CategoryIds.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/CategoryIds.php @@ -22,51 +22,57 @@ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ -namespace Magento\Catalog\Test\Fixture; +namespace Magento\Catalog\Test\Fixture\CatalogProductSimple; +use Magento\Catalog\Test\Fixture\CatalogCategoryEntity; use Mtf\Fixture\FixtureFactory; use Mtf\Fixture\FixtureInterface; /** - * Class Price - * - * Data keys: - * - preset (Price verification preset name) - * - value (Price value) - * + * Class CategoryIds + * Create and return Category */ class CategoryIds implements FixtureInterface { /** + * Names and Ids of the created categories + * * @var array */ protected $data; /** - * @var \Mtf\Fixture\FixtureFactory - */ - protected $fixtureFactory; - - /** - * @var Category + * New categories + * + * @var array */ protected $category; /** - * @param Category $category + * @param FixtureFactory $fixtureFactory * @param array $params * @param array $data */ - public function __construct(Category $category, array $params, array $data = []) - { + 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) { - $category->switchData($preset); + $category = $fixtureFactory->createByCode('catalogCategoryEntity', ['dataSet' => $preset]); $category->persist(); - $this->category = $category; - $this->data[] = $category->getCategoryId(); + + /** @var CatalogCategoryEntity $category */ + $this->data = [ + [ + 'id' => $category->getId(), + 'name' => $category->getName(), + ], + ]; + $this->category[] = $category; } } } @@ -95,7 +101,7 @@ public function getData($key = null) /** * Return data set configuration settings * - * @return string + * @return array */ public function getDataConfig() { @@ -103,9 +109,9 @@ public function getDataConfig() } /** - * Retrieve source category fixture + * Return category array * - * @return Category + * @return array */ public function getCategory() { 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 index c3c74aa45ad1c..7aead4aac1176 100644 --- 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 @@ -24,16 +24,15 @@ namespace Magento\Catalog\Test\Fixture\CatalogProductSimple; -use Mtf\Fixture\FixtureFactory; use Mtf\Fixture\FixtureInterface; /** * Class CustomOptions + * Custom options fixture * * Data keys: * - preset (Custom options preset name) * - products (comma separated sku identifiers) - * */ class CustomOptions implements FixtureInterface { @@ -95,7 +94,7 @@ protected function getPreset($name) 'MAGETWO-23062' => [ [ 'title' => 'custom option drop down', - 'is_require' => true, + 'is_require' => 'Yes', 'type' => 'Drop-down', 'options' => [ [ @@ -110,7 +109,7 @@ protected function getPreset($name) 'MAGETWO-23063' => [ [ 'title' => 'custom option drop down', - 'is_require' => true, + 'is_require' => 'Yes', 'type' => 'Drop-down', 'options' => [ [ @@ -125,7 +124,7 @@ protected function getPreset($name) 'MAGETWO-23066' => [ [ 'title' => 'custom option drop down', - 'is_require' => true, + 'is_require' => 'Yes', 'type' => 'Drop-down', 'options' => [ [ @@ -140,7 +139,7 @@ protected function getPreset($name) 'MAGETWO-23069' => [ [ 'title' => 'custom option drop down', - 'is_require' => true, + 'is_require' => 'Yes', 'type' => 'Drop-down', 'options' => [ [ @@ -151,6 +150,72 @@ protected function getPreset($name) ] ] ] + ], + 'options-suite' => [ + [ + 'title' => 'Test1 option %isolation%', + 'is_require' => 'Yes', + 'type' => 'Field', + 'options' => [ + [ + 'price' => 120.03, + 'price_type' => 'Fixed', + 'sku' => 'sku1_%isolation%', + 'max_characters' => 45 + ] + ] + ], + [ + 'title' => 'Test2 option %isolation%', + 'is_require' => 'Yes', + 'type' => 'Field', + 'options' => [ + [ + 'price' => 120.03, + 'price_type' => 'Fixed', + 'sku' => 'sku1_%isolation%', + 'max_characters' => 45 + ] + ] + ], + [ + 'title' => 'Test3 option %isolation%', + 'is_require' => 'Yes', + 'type' => 'Drop-down', + 'options' => [ + [ + 'title' => 'Test1 %isolation%', + 'price' => 10.01, + 'price_type' => 'Percent', + 'sku' => 'sku2_%isolation%' + ], + [ + 'title' => 'Test2 %isolation%', + 'price' => 20.02, + 'price_type' => 'Fixed', + 'sku' => 'sku3_%isolation%' + ] + ] + ], + [ + 'title' => 'Test4 option %isolation%', + 'is_require' => 'Yes', + 'type' => 'Drop-down', + 'options' => [ + [ + 'title' => 'Test1 %isolation%', + 'price' => 10.01, + 'price_type' => 'Percent', + 'sku' => 'sku2_%isolation%' + ], + [ + 'title' => 'Test2 %isolation%', + 'price' => 20.02, + 'price_type' => 'Fixed', + 'sku' => 'sku3_%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 7319e7cbcecfc..38d0010f5228d 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 @@ -87,21 +87,20 @@ public function getDataConfig() /** * @param string $name - * @return mixed - * @throws \Exception + * @return mixed|null */ protected function getPreset($name) { $presets = [ 'MAGETWO-23055' => [ - '0' => [ + [ 'price' => 90, 'website' => 'All Websites [USD]', 'customer_group' => 'NOT LOGGED IN' ] ], 'MAGETWO-23061' => [ - '0' => [ + [ 'price' => 20, 'website' => 'All Websites [USD]', 'customer_group' => 'NOT LOGGED IN' 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 2367f6ce970e6..34445ea841fba 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 @@ -24,7 +24,6 @@ namespace Magento\Catalog\Test\Fixture\CatalogProductSimple; -use Mtf\Fixture\FixtureFactory; use Mtf\Fixture\FixtureInterface; /** @@ -37,11 +36,6 @@ */ class TierPriceOptions implements FixtureInterface { - /** - * @var \Mtf\Fixture\FixtureFactory - */ - protected $fixtureFactory; - /** * @param array $params * @param array $data @@ -87,21 +81,35 @@ public function getDataConfig() /** * @param string $name - * @return mixed - * @throws \Exception + * @return mixed|null */ protected function getPreset($name) { $presets = [ + 'default' => [ + 0 => [ + 'price' => 150, + 'website' => 'All Websites [USD]', + 'price_qty' => 3, + 'customer_group' => 'ALL GROUPS' + ], + 1 => [ + 'price' => 24, + 'website' => 'All Websites [USD]', + 'price_qty' => 15, + 'customer_group' => 'ALL GROUPS' + ] + ], 'MAGETWO-23002' => [ - '0' => [ + 0 => [ 'price' => 90, 'website' => 'All Websites [USD]', - 'quantity' => '1', + 'price_qty' => 2, 'customer_group' => 'ALL GROUPS' ] ] ]; + if (!isset($presets[$name])) { return null; } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductEdit.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogCategoryEntity/CatalogCategoryEntityInterface.php old mode 100755 new mode 100644 similarity index 79% rename from dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductEdit.php rename to dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogCategoryEntity/CatalogCategoryEntityInterface.php index 04202e137db38..27feac56803da --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductEdit.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogCategoryEntity/CatalogCategoryEntityInterface.php @@ -22,16 +22,14 @@ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ -namespace Magento\Catalog\Test\Page\Product; +namespace Magento\Catalog\Test\Handler\CatalogCategoryEntity; + +use Mtf\Handler\HandlerInterface; /** - * Class CatalogProductEdit - * Edit product page + * Interface CatalogCategoryEntityInterface */ -class CatalogProductEdit extends CatalogProductNew +interface CatalogCategoryEntityInterface extends HandlerInterface { - /** - * URL for product creation - */ - const MCA = 'catalog/product/edit'; + // } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogCategoryEntity/Curl.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogCategoryEntity/Curl.php new file mode 100644 index 0000000000000..f814fe009e5fd --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogCategoryEntity/Curl.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\Handler\CatalogCategoryEntity; + +use Mtf\System\Config; +use Mtf\Fixture\FixtureInterface; +use Mtf\Util\Protocol\CurlInterface; +use Mtf\Util\Protocol\CurlTransport; +use Mtf\Handler\Curl as AbstractCurl; +use Mtf\Util\Protocol\CurlTransport\BackendDecorator; + +/** + * Class Curl + * Create new category via curl + */ +class Curl extends AbstractCurl implements CatalogCategoryEntityInterface +{ + /** + * Data use config for category + * + * @var array + */ + protected $dataUseConfig = [ + 'available_sort_by', + 'default_sort_by', + 'filter_price_range', + ]; + + /** + * Post request for creating Subcategory + * + * @param FixtureInterface $fixture [optional] + * @return mixed|string + */ + 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; + } + } + + $diff = array_diff($this->dataUseConfig, array_keys($data['general'])); + if (!empty($diff)) { + $data['use_config'] = $diff; + } + $parentCategoryId = $data['general']['parent_id']; + + $url = $_ENV['app_backend_url'] . 'catalog/category/save/store/0/parent/' . $parentCategoryId . '/'; + $curl = new BackendDecorator(new CurlTransport(), new Config); + $curl->write(CurlInterface::POST, $url, '1.0', array(), $data); + $response = $curl->read(); + $curl->close(); + + preg_match('#http://.+/id/(\d+).+store/#m', $response, $matches); + $id = isset($matches[1]) ? $matches[1] : null; + return ['id' => $id]; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/CatalogProductSimpleInterface.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/CatalogProductSimpleInterface.php index e6ba07e209ce8..17a11a39c6018 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/CatalogProductSimpleInterface.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/CatalogProductSimpleInterface.php @@ -27,7 +27,6 @@ /** * Interface CatalogProductSimpleInterface - * */ interface CatalogProductSimpleInterface extends HandlerInterface { 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 0c22de6fd4ee0..f88ff3ff58e74 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 @@ -35,6 +35,7 @@ /** * Class CreateProduct + * Create new simple product via curl */ class Curl extends AbstractCurl implements CatalogProductSimpleInterface { diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Ui.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Ui.php index 4e730c38da3aa..bbd64bfc12f60 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Ui.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Ui.php @@ -18,21 +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\Catalog\Test\Handler\CatalogProductSimple; +use Mtf\Factory\Factory; use Mtf\Handler\Ui as AbstractUi; use Mtf\Fixture\FixtureInterface; -use Mtf\Factory\Factory; /** * Class CreateProduct * Create a product - * */ class Ui extends AbstractUi implements CatalogProductSimpleInterface { @@ -50,9 +48,9 @@ public function persist(FixtureInterface $fixture = null) $createProductPage->init($fixture); $createProductPage->open(); - $productBlockForm = $createProductPage->getProductBlockForm(); - $productBlockForm->fill($fixture); - $productBlockForm->save($fixture); + $productForm = $createProductPage->getProductForm(); + $productForm->fill($fixture); + $createProductPage->getFormAction()->save(); $createProductPage->getMessagesBlock()->assertSuccessMessage(); } } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/Ui/CreateProduct.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/Ui/CreateProduct.php index 5f35313e3c4d1..e90e178902b60 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/Ui/CreateProduct.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/Ui/CreateProduct.php @@ -18,21 +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\Catalog\Test\Handler\Ui; -use Mtf\Fixture\FixtureInterface; use Mtf\Handler\Ui; use Mtf\Factory\Factory; +use Mtf\Fixture\FixtureInterface; /** * Class CreateProduct * Create a product - * */ class CreateProduct extends Ui { @@ -50,9 +48,9 @@ public function persist(FixtureInterface $fixture = null) $createProductPage->init($fixture); $createProductPage->open(); - $productBlockForm = $createProductPage->getProductBlockForm(); - $productBlockForm->fill($fixture); - $productBlockForm->save($fixture); + $productForm = $createProductPage->getProductForm(); + $productForm->fill($fixture); + $createProductPage->getFormAction()->save(); $createProductPage->getMessagesBlock()->assertSuccessMessage(); } } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogCategoryIndex.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogCategoryIndex.php new file mode 100644 index 0000000000000..4f90fb29492d0 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogCategoryIndex.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\Page\Adminhtml; + +use Mtf\Page\BackendPage; + +/** + * Class CatalogCategoryIndex + * Category page on the Backend + */ +class CatalogCategoryIndex extends BackendPage +{ + const MCA = 'catalog/category/index/index'; // TODO: Fix after resolving issue with factory page generation + + protected $_blocks = [ + 'treeCategories' => [ + 'name' => 'treeCategories', + 'class' => 'Magento\Catalog\Test\Block\Adminhtml\Category\Tree', + 'locator' => '[id="page:left"]', + 'strategy' => 'css selector', + ], + ]; + + /** + * @return \Magento\Catalog\Test\Block\Adminhtml\Category\Tree + */ + public function getTreeCategories() + { + return $this->getBlockInstance('treeCategories'); + } +} diff --git a/app/code/Magento/Persistent/view/frontend/js/components.phtml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogCategoryIndex.xml similarity index 68% rename from app/code/Magento/Persistent/view/frontend/js/components.phtml rename to dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogCategoryIndex.xml index 941db16146d1f..d292e92a93c35 100644 --- a/app/code/Magento/Persistent/view/frontend/js/components.phtml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogCategoryIndex.xml @@ -1,4 +1,5 @@ -<?php +<?xml version="1.0" ?> +<!-- /** * Magento * @@ -21,18 +22,12 @@ * @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) */ -?> -<script type="text/javascript"> - (function($) { - "use strict"; - /** - * Declaration of resources needed for defined components - */ - $.mage.component({ - rememberMePopup: [ - '<?php echo $this->getViewFileUrl('Magento_Persistent::remember-me-popup.js')?>' - ] - }); - })(jQuery); -</script> -<?php echo $this->getChildHtml() ?> +--> +<page mca="catalog/category/index"> + <block> + <name>treeCategories</name> + <class>Magento\Catalog\Test\Block\Adminhtml\Category\Tree</class> + <locator>[id="page:left"]</locator> + <strategy>css selector</strategy> + </block> +</page> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductEdit.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductEdit.php new file mode 100644 index 0000000000000..5b8c8adce318e --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductEdit.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\Catalog\Test\Page\Adminhtml; + +use Mtf\Page\BackendPage; + +/** + * Class CatalogProductEdit + */ +class CatalogProductEdit extends BackendPage +{ + const MCA = 'catalog/product/edit'; + + protected $_blocks = [ + 'form' => [ + 'name' => 'form', + 'class' => 'Magento\Catalog\Test\Block\Adminhtml\Product\Form', + 'locator' => '[id="page:main-container"]', + 'strategy' => 'css selector', + ], + 'productForm' => [ + 'name' => 'productForm', + 'class' => 'Magento\Catalog\Test\Block\Backend\ProductForm', + 'locator' => '[id="page:main-container"]', + 'strategy' => 'css selector', + ], + 'configurableProductForm' => [ + 'name' => 'configurableProductForm', + 'class' => 'Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\ProductForm', + 'locator' => '[id="page:main-container"]', + 'strategy' => 'css selector', + ], + 'formAction' => [ + 'name' => 'formAction', + 'class' => 'Magento\Catalog\Test\Block\Adminhtml\Product\FormPageActions', + 'locator' => '.page-main-actions', + 'strategy' => 'css selector', + ], + 'messagesBlock' => [ + 'name' => 'messagesBlock', + 'class' => 'Magento\Core\Test\Block\Messages', + 'locator' => '#messages .messages', + 'strategy' => 'css selector', + ], + ]; + + /** + * @return \Magento\Catalog\Test\Block\Backend\ProductForm + */ + public function getProductForm() + { + return $this->getBlockInstance('productForm'); + } + + /** + * @return \Magento\Catalog\Test\Block\Adminhtml\Product\Form + */ + public function getForm() + { + return $this->getBlockInstance('form'); + } + + /** + * @return \Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\ProductForm + */ + public function getConfigurableProductForm() + { + return $this->getBlockInstance('configurableProductForm'); + } + + /** + * @return \Magento\Catalog\Test\Block\Adminhtml\Product\FormPageActions + */ + public function getFormAction() + { + return $this->getBlockInstance('formAction'); + } + + /** + * @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/Adminhtml/CatalogProductEdit.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductEdit.xml new file mode 100644 index 0000000000000..e4817fb850761 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductEdit.xml @@ -0,0 +1,57 @@ +<?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/edit" > + <block> + <name>form</name> + <class>Magento\Catalog\Test\Block\Adminhtml\Product\Form</class> + <locator>[id="page:main-container"]</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>productForm</name> + <class>Magento\Catalog\Test\Block\Backend\ProductForm</class> + <locator>[id="page:main-container"]</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>configurableProductForm</name> + <class>Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\ProductForm</class> + <locator>[id="page:main-container"]</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>formAction</name> + <class>Magento\Catalog\Test\Block\Adminhtml\Product\FormPageActions</class> + <locator>.page-main-actions</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>messagesBlock</name> + <class>Magento\Core\Test\Block\Messages</class> + <locator>#messages .messages</locator> + <strategy>css selector</strategy> + </block> +</page> 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 c4f5e80a6e89d..8513d19dc21d8 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 @@ -28,7 +28,7 @@ /** * Class CatalogProductIndex - * + * Products page on the Backend */ class CatalogProductIndex extends BackendPage { @@ -37,12 +37,12 @@ class CatalogProductIndex extends BackendPage protected $_blocks = [ 'productGrid' => [ 'name' => 'productGrid', - 'class' => 'Magento\Catalog\Test\Block\Backend\ProductGrid', + 'class' => 'Magento\Catalog\Test\Block\Adminhtml\Product\Grid', 'locator' => '#productGrid', 'strategy' => 'css selector', ], - 'messageBlock' => [ - 'name' => 'messageBlock', + 'messagesBlock' => [ + 'name' => 'messagesBlock', 'class' => 'Magento\Core\Test\Block\Messages', 'locator' => '#messages', 'strategy' => 'css selector', @@ -68,7 +68,7 @@ class CatalogProductIndex extends BackendPage ]; /** - * @return \Magento\Catalog\Test\Block\Backend\ProductGrid + * @return \Magento\Catalog\Test\Block\Adminhtml\Product\Grid */ public function getProductGrid() { @@ -78,9 +78,9 @@ public function getProductGrid() /** * @return \Magento\Core\Test\Block\Messages */ - public function getMessageBlock() + public function getMessagesBlock() { - return $this->getBlockInstance('messageBlock'); + return $this->getBlockInstance('messagesBlock'); } /** 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 c1e62e819fe1a..b5c18b67a0944 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 @@ -26,12 +26,12 @@ <page mca="catalog/product/index" > <block> <name>productGrid</name> - <class>Magento\Catalog\Test\Block\Backend\ProductGrid</class> + <class>Magento\Catalog\Test\Block\Adminhtml\Product\Grid</class> <locator>#productGrid</locator> <strategy>css selector</strategy> </block> <block> - <name>messageBlock</name> + <name>messagesBlock</name> <class>Magento\Core\Test\Block\Messages</class> <locator>#messages</locator> <strategy>css selector</strategy> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductNew.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductNew.php new file mode 100644 index 0000000000000..18ce4f877aa34 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductNew.php @@ -0,0 +1,153 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 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\Adminhtml; + +use Mtf\Page\BackendPage; +use Mtf\Fixture\FixtureInterface; + +/** + * Class CatalogProductNew + */ +class CatalogProductNew extends BackendPage +{ + const MCA = 'catalog/product/new'; + + protected $_blocks = [ + 'form' => [ + 'name' => 'form', + 'class' => 'Magento\Catalog\Test\Block\Adminhtml\Product\Form', + 'locator' => '[id="page:main-container"]', + 'strategy' => 'css selector', + ], + 'productForm' => [ + 'name' => 'productForm', + 'class' => 'Magento\Catalog\Test\Block\Backend\ProductForm', + 'locator' => '[id="page:main-container"]', + 'strategy' => 'css selector', + ], + 'configurableProductForm' => [ + 'name' => 'configurableProductForm', + 'class' => 'Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\ProductForm', + 'locator' => 'body', + 'strategy' => 'css selector', + ], + 'formAction' => [ + 'name' => 'formAction', + 'class' => 'Magento\Catalog\Test\Block\Adminhtml\Product\FormPageActions', + 'locator' => '.page-main-actions', + 'strategy' => 'css selector', + ], + 'affectedAttributeSetForm' => [ + 'name' => 'affectedAttributeSetForm', + 'class' => 'Magento\Catalog\Test\Block\Adminhtml\Product\AffectedAttributeSetForm', + 'locator' => '#affected-attribute-set-form', + 'strategy' => 'css selector', + ], + 'messagesBlock' => [ + 'name' => 'messagesBlock', + 'class' => 'Magento\Core\Test\Block\Messages', + 'locator' => '#messages .messages', + 'strategy' => 'css selector', + ], + ]; + + /** + * Custom constructor + */ + protected function _init() + { + $this->_url = $_ENV['app_backend_url'] . static::MCA; + } + + /** + * + * @param FixtureInterface $fixture + */ + public function init(FixtureInterface $fixture) + { + $dataConfig = $fixture->getDataConfig(); + + $params = isset($dataConfig['create_url_params']) ? $dataConfig['create_url_params'] : array(); + foreach ($params as $paramName => $paramValue) { + $this->_url .= '/' . $paramName . '/' . $paramValue; + } + } + + /** + * @return \Magento\Catalog\Test\Block\Backend\ProductForm + */ + public function getProductForm() + { + return $this->getBlockInstance('productForm'); + } + + /** + * @return \Magento\Catalog\Test\Block\Adminhtml\Product\Form + */ + public function getForm() + { + return $this->getBlockInstance('form'); + } + + /** + * @return \Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\ProductForm + */ + public function getConfigurableProductForm() + { + return $this->getBlockInstance('configurableProductForm'); + } + + /** + * @return \Magento\Catalog\Test\Block\Adminhtml\Product\FormPageActions + */ + public function getFormAction() + { + return $this->getBlockInstance('formAction'); + } + + /** + * @return \Magento\Catalog\Test\Block\Adminhtml\Product\AffectedAttributeSetForm + */ + public function getAffectedAttributeSetForm() + { + return $this->getBlockInstance('affectedAttributeSetForm'); + } + + /** + * @return \Magento\Core\Test\Block\Messages + */ + public function getMessagesBlock() + { + return $this->getBlockInstance('messagesBlock'); + } + + /** + * Switch back to main page from iframe + */ + public function switchToMainPage() + { + $this->_browser->switchToFrame(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductNew.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductNew.xml new file mode 100644 index 0000000000000..a9b7418dceb49 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductNew.xml @@ -0,0 +1,63 @@ +<?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/new" > + <block> + <name>form</name> + <class>Magento\Catalog\Test\Block\Adminhtml\Product\Form</class> + <locator>[id="page:main-container"]</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>productForm</name> + <class>Magento\Catalog\Test\Block\Backend\ProductForm</class> + <locator>[id="page:main-container"]</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>configurableProductForm</name> + <class>Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\ProductForm</class> + <locator>[id="page:main-container"]</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>formAction</name> + <class>Magento\Catalog\Test\Block\Adminhtml\Product\FormPageActions</class> + <locator>.page-main-actions</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>affectedAttributeSetForm</name> + <class>Magento\Catalog\Test\Block\Adminhtml\Product\AffectedAttributeSetForm</class> + <locator>#affected-attribute-set-form</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>messagesBlock</name> + <class>Magento\Core\Test\Block\Messages</class> + <locator>#messages .messages</locator> + <strategy>css selector</strategy> + </block> +</page> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Category/CatalogCategory.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Category/CatalogCategory.php index 0632320983ec3..168a44778ccb6 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Category/CatalogCategory.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Category/CatalogCategory.php @@ -59,7 +59,7 @@ class CatalogCategory extends Page * * @var string */ - protected $messageBlock = '#messages .messages'; + protected $messagesBlock = '#messages .messages'; /** * Backend abstract block @@ -118,10 +118,10 @@ public function getTreeBlock() * * @return \Magento\Core\Test\Block\Messages */ - public function getMessageBlock() + public function getMessagesBlock() { return Factory::getBlockFactory()->getMagentoCoreMessages( - $this->_browser->find($this->messageBlock, Locator::SELECTOR_CSS) + $this->_browser->find($this->messagesBlock, Locator::SELECTOR_CSS) ); } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Category/CatalogCategoryEdit.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Category/CatalogCategoryEdit.php index 94ddb2661bae2..3dc39db826d97 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Category/CatalogCategoryEdit.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Category/CatalogCategoryEdit.php @@ -60,7 +60,7 @@ class CatalogCategoryEdit extends Page * * @var string */ - protected $messageBlock = '#messages .messages'; + protected $messagesBlock = '#messages .messages'; /** * Backend abstract block @@ -126,10 +126,10 @@ public function getTreeBlock() * * @return \Magento\Core\Test\Block\Messages */ - public function getMessageBlock() + public function getMessagesBlock() { return Factory::getBlockFactory()->getMagentoCoreMessages( - $this->_browser->find($this->messageBlock, Locator::SELECTOR_CSS) + $this->_browser->find($this->messagesBlock, Locator::SELECTOR_CSS) ); } 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 0110e2280afc8..d0376a8e0f048 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 @@ -24,84 +24,72 @@ namespace Magento\Catalog\Test\Page\Category; -use Mtf\Client\Element\Locator; -use Mtf\Factory\Factory; -use Mtf\Page\Page; +use Mtf\Page\FrontendPage; /** * Class CatalogCategoryView - * Category page on frontend - * + * Catalog Category page */ -class CatalogCategoryView extends Page +class CatalogCategoryView extends FrontendPage { - /** - * URL for category page - */ const MCA = 'catalog/category/view'; - /** - * List of results of product search - * - * @var string - */ - protected $listProductBlock = '.products.wrapper.grid'; - - /** - * MAP popup - * - * @var string - */ - protected $mapBlock = '#map-popup-content'; - - /** - * Layered navigation block - * - * @var string - */ - protected $layeredNavigationBlock = '.block.filter'; + protected $_blocks = [ + 'listProductBlock' => [ + 'name' => 'listProductBlock', + 'class' => 'Magento\Catalog\Test\Block\Product\ListProduct', + 'locator' => '.products.wrapper.grid', + 'strategy' => 'css selector', + ], + 'mapBlock' => [ + 'name' => 'mapBlock', + 'class' => 'Magento\Catalog\Test\Block\Product\Price', + 'locator' => '#map-popup-content', + 'strategy' => 'css selector', + ], + 'layeredNavigationBlock' => [ + 'name' => 'layeredNavigationBlock', + 'class' => 'Magento\LayeredNavigation\Test\Block\Navigation', + 'locator' => '.block.filter', + 'strategy' => 'css selector', + ], + 'toolbar' => [ + 'name' => 'toolbar', + 'class' => 'Magento\Catalog\Test\Block\Product\ProductList\Toolbar', + 'locator' => '.pages .items', + 'strategy' => 'css selector', + ], + ]; /** - * Custom constructor - */ - protected function _init() - { - $this->_url = $_ENV['app_frontend_url'] . self::MCA; - } - - /** - * Get product list block - * * @return \Magento\Catalog\Test\Block\Product\ListProduct */ public function getListProductBlock() { - return Factory::getBlockFactory()->getMagentoCatalogProductListProduct( - $this->_browser->find($this->listProductBlock, Locator::SELECTOR_CSS) - ); + return $this->getBlockInstance('listProductBlock'); } /** - * Get product price block - * * @return \Magento\Catalog\Test\Block\Product\Price */ public function getMapBlock() { - return Factory::getBlockFactory()->getMagentoCatalogProductPrice( - $this->_browser->find($this->mapBlock, Locator::SELECTOR_CSS) - ); + return $this->getBlockInstance('mapBlock'); } /** - * Get layered navigation block - * - * @return \Magento\Search\Test\Block\Catalog\Layer\View + * @return \Magento\LayeredNavigation\Test\Block\Navigation */ public function getLayeredNavigationBlock() { - return Factory::getBlockFactory()->getMagentoSearchCatalogLayerView( - $this->_browser->find($this->layeredNavigationBlock, Locator::SELECTOR_CSS) - ); + return $this->getBlockInstance('layeredNavigationBlock'); + } + + /** + * @return \Magento\Catalog\Test\Block\Product\ProductList\Toolbar + */ + public function getToolbar() + { + return $this->getBlockInstance('toolbar'); } } 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 new file mode 100644 index 0000000000000..659960ed355e0 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Category/CatalogCategoryView.xml @@ -0,0 +1,51 @@ +<?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/category/view" > + <block> + <name>listProductBlock</name> + <class>Magento\Catalog\Test\Block\Product\ListProduct</class> + <locator>.products.wrapper.grid</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>mapBlock</name> + <class>Magento\Catalog\Test\Block\Product\Price</class> + <locator>#map-popup-content</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>layeredNavigationBlock</name> + <class>Magento\LayeredNavigation\Test\Block\Navigation</class> + <locator>.block.filter</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>toolbar</name> + <class>\Magento\Catalog\Test\Block\Product\ProductList\Toolbar</class> + <locator>.pages .items</locator> + <strategy>css selector</strategy> + </block> +</page> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductNew.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductNew.php deleted file mode 100644 index 75e58fa299358..0000000000000 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductNew.php +++ /dev/null @@ -1,173 +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\Page\Product; - -use Mtf\Page\Page; -use Mtf\Factory\Factory; -use Mtf\Fixture\FixtureInterface; -use Mtf\Client\Element\Locator; - -/** - * Class CatalogProductNew - * Create product page - * - */ -class CatalogProductNew extends Page -{ - /** - * URL for product creation - */ - const MCA = 'catalog/product/new'; - - /** - * New attribute selector - * - * @var string - */ - protected $newAttribute = 'body'; - - /** - * New attribute frame selector - * - * @var string - */ - protected $newAttributeFrame = '#create_new_attribute_container'; - - /** - * Product form block - * - * @var string - */ - protected $productFormBlock = 'body'; - - /** - * Global messages block - * - * @var string - */ - protected $messagesBlock = '#messages .messages'; - - /** - * Custom constructor - */ - protected function _init() - { - $this->_url = $_ENV['app_backend_url'] . static::MCA; - } - - /** - * @param FixtureInterface $fixture - */ - public function init(FixtureInterface $fixture) - { - $dataConfig = $fixture->getDataConfig(); - - $params = isset($dataConfig['create_url_params']) ? $dataConfig['create_url_params'] : array(); - foreach ($params as $paramName => $paramValue) { - $this->_url .= '/' . $paramName . '/' . $paramValue; - } - } - - /** - * Get product form block - * - * @return \Magento\Catalog\Test\Block\Backend\ProductForm - */ - public function getProductBlockForm() - { - return Factory::getBlockFactory()->getMagentoCatalogBackendProductForm( - $this->_browser->find($this->productFormBlock, Locator::SELECTOR_CSS) - ); - } - - /** - * Get product form block - * - * @return \Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\ProductForm - */ - public function getConfigurableBlockForm() - { - return Factory::getBlockFactory()->getMagentoConfigurableProductAdminhtmlProductProductForm( - $this->_browser->find($this->productFormBlock, Locator::SELECTOR_CSS) - ); - } - - /** - * Get global messages block - * - * @return \Magento\Core\Test\Block\Messages - */ - public function getMessagesBlock() - { - return Factory::getBlockFactory()->getMagentoCoreMessages( - $this->_browser->find($this->messagesBlock, Locator::SELECTOR_CSS) - ); - } - - /** - * Get attribute edit block - * - * @return \Magento\Catalog\Test\Block\Backend\Product\Attribute\Edit - */ - public function getAttributeEditBlock() - { - $this->_browser->switchToFrame(new Locator($this->newAttributeFrame)); - return Factory::getBlockFactory()->getMagentoCatalogBackendProductAttributeEdit( - $this->_browser->find($this->newAttribute, Locator::SELECTOR_TAG_NAME) - ); - } - - /** - * Switch back to main page from iframe - */ - public function switchToMainPage() - { - $this->_browser->switchToFrame(); - } - - /** - * Get upsell block - * - * @return \Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Upsell - */ - public function getUpsellBlock() - { - return Factory::getBlockFactory()->getMagentoCatalogAdminhtmlProductEditTabUpsell( - $this->_browser->find('up_sell_product_grid', Locator::SELECTOR_ID) - ); - } - - /** - * Get the backend catalog product block - * - * @return \Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Related - */ - public function getRelatedBlock() - { - return Factory::getBlockFactory()->getMagentoCatalogAdminhtmlProductEditTabRelated( - $this->_browser->find('related_product_grid', Locator::SELECTOR_ID) - ); - } -} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductReview.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductReview.php index 89aea218d17fa..a6e377dee180b 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductReview.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductReview.php @@ -93,7 +93,7 @@ public function getEditForm() * * @return \Magento\Core\Test\Block\Messages */ - public function getMessageBlock() + public function getMessagesBlock() { return Factory::getBlockFactory()->getMagentoCoreMessages($this->_browser->find($this->messageWrapperSelector)); } 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 9a8a91f830004..3ed4bb16f8448 100644 --- 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 @@ -24,126 +24,90 @@ namespace Magento\Catalog\Test\Page\Product; -use Magento\GiftCard\Test\Block\Catalog\Product\View\Type\GiftCard; -use Magento\Catalog\Test\Block\Product\ProductList\Crosssell; -use Magento\Catalog\Test\Block\Product\Price; -use Magento\Catalog\Test\Block\Product\ProductList\Related; -use Magento\Catalog\Test\Block\Product\ProductList\Upsell; -use Magento\Catalog\Test\Block\Product\View; -use Magento\Catalog\Test\Block\Product\View\Options; -use Magento\Catalog\Test\Block\Product\View\CustomOptions; -use Magento\Downloadable\Test\Block\Catalog\Product\Links; -use Magento\Review\Test\Block\Product\View\Summary; -use Magento\Review\Test\Block\Form; -use Magento\Review\Test\Block\Product\View as ReviewView; -use Mtf\Page\Page; -use Mtf\Factory\Factory; +use Mtf\Page\FrontendPage; use Mtf\Fixture\FixtureInterface; -use Mtf\Client\Element\Locator; /** * Class CatalogProductView * Frontend product view page - * */ -class CatalogProductView extends Page +class CatalogProductView extends FrontendPage { - /** - * URL for catalog product grid - */ const MCA = 'catalog/product/view'; - /** - * Review summary selector - * - * @var string - */ - protected $reviewSummarySelector = '.product.reviews.summary'; - - /** - * Review form - * - * @var string - */ - protected $reviewFormBlock = '#review-form'; - - /** - * Customer reviews block - * - * @var string - */ - protected $customerReviewBlock = '#customer-reviews'; - - /** - * Messages selector - * - * @var string - */ - protected $messagesSelector = '.page.messages .messages'; - - /** - * Product View block - * - * @var string - */ - protected $viewBlock = '.column.main'; - - /** - * Product options block - * - * @var string - */ - protected $optionsBlock = '#product-options-wrapper'; - - /** - * Related product selector - * - * @var string - */ - protected $relatedProductSelector = '.block.related'; - - /** - * Upsell selector - * - * @var string - */ - protected $upsellSelector = '.block.upsell'; - - /** - * Gift Card Block selector - * - * @var string - */ - protected $giftCardBlockSelector = '[data-container-for=giftcard_info]'; - - /** - * Gift Card Amount Block selector - * - * @var string - */ - protected $giftCardBlockAmountSelector = '.fieldset.giftcard.amount'; - - /** - * Cross-sell selector - * - * @var string - */ - protected $crosssellSelector = '.block.crosssell'; - - /** - * @var string - */ - protected $downloadableLinksSelector = '[data-container-for=downloadable-links]'; - - /** - * MAP popup - * - * @var string - */ - protected $mapBlock = '#map-popup'; + protected $_blocks = [ + 'viewBlock' => [ + 'name' => 'viewBlock', + 'class' => 'Magento\Catalog\Test\Block\Product\View', + 'locator' => '#maincontent', + 'strategy' => 'css selector', + ], + 'customOptionsBlock' => [ + 'name' => 'customOptionsBlock', + 'class' => 'Magento\Catalog\Test\Block\Product\View\CustomOptions', + 'locator' => '#product-options-wrapper', + 'strategy' => 'css selector', + ], + 'relatedProductBlock' => [ + 'name' => 'relatedProductBlock', + 'class' => 'Magento\Catalog\Test\Block\Product\ProductList\Related', + 'locator' => '.block.related', + 'strategy' => 'css selector', + ], + 'upsellBlock' => [ + 'name' => 'upsellBlock', + 'class' => 'Magento\Catalog\Test\Block\Product\ProductList\Upsell', + 'locator' => '.block.upsell', + 'strategy' => 'css selector', + ], + 'crosssellBlock' => [ + 'name' => 'crosssellBlock', + 'class' => 'Magento\Catalog\Test\Block\Product\ProductList\Crosssell', + 'locator' => '.block.crosssell', + 'strategy' => 'css selector', + ], + 'messagesBlock' => [ + 'name' => 'messagesBlock', + 'class' => 'Magento\Core\Test\Block\Messages', + 'locator' => '.page.messages .messages', + 'strategy' => 'css selector', + ], + 'reviewSummary' => [ + 'name' => 'reviewSummary', + 'class' => 'Magento\Review\Test\Block\Product\View\Summary', + 'locator' => '.product.reviews.summary', + 'strategy' => 'css selector', + ], + 'reviewFormBlock' => [ + 'name' => 'reviewFormBlock', + 'class' => 'Magento\Review\Test\Block\Form', + 'locator' => '#review-form', + 'strategy' => 'css selector', + ], + 'customerReviewBlock' => [ + 'name' => 'customerReviewBlock', + 'class' => 'Magento\Review\Test\Block\Product\View', + 'locator' => '#customer-reviews', + 'strategy' => 'css selector', + ], + 'downloadableLinksBlock' => [ + 'name' => 'downloadableLinksBlock', + 'class' => 'Magento\Downloadable\Test\Block\Catalog\Product\Links', + 'locator' => '[data-container-for=downloadable-links]', + 'strategy' => 'css selector', + ], + 'mapBlock' => [ + 'name' => 'mapBlock', + 'class' => 'Magento\Catalog\Test\Block\Product\Price', + 'locator' => '#map-popup', + 'strategy' => 'css selector', + ] + ]; /** * Custom constructor + * + * @return void */ protected function _init() { @@ -154,6 +118,7 @@ protected function _init() * Page initialization * * @param FixtureInterface $fixture + * @return void */ public function init(FixtureInterface $fixture) { @@ -161,166 +126,90 @@ public function init(FixtureInterface $fixture) } /** - * Get product view block - * - * @return View + * @return \Magento\Catalog\Test\Block\Product\View */ public function getViewBlock() { - return Factory::getBlockFactory()->getMagentoCatalogProductView( - $this->_browser->find($this->viewBlock, Locator::SELECTOR_CSS) - ); + return $this->getBlockInstance('viewBlock'); } /** - * Get product options block - * - * @return View + * @return \Magento\Catalog\Test\Block\Product\View\CustomOptions */ - public function getOptionsBlock() + public function getCustomOptionsBlock() { - return Factory::getBlockFactory()->getMagentoCatalogProductViewOptions( - $this->_browser->find($this->optionsBlock, Locator::SELECTOR_CSS) - ); + return $this->getBlockInstance('customOptionsBlock'); } /** - * Get product options block - * - * @return Options + * @return \Magento\Catalog\Test\Block\Product\ProductList\Related */ - public function getCustomOptionBlock() + public function getRelatedProductBlock() { - return Factory::getBlockFactory()->getMagentoCatalogProductViewCustomOptions( - $this->_browser->find('#product-options-wrapper') - ); + return $this->getBlockInstance('relatedProductBlock'); } /** - * Get customer reviews block - * - * @return CustomOptions + * @return \Magento\Review\Test\Block\Form */ public function getReviewFormBlock() { - return Factory::getBlockFactory()->getMagentoReviewForm($this->_browser->find($this->reviewFormBlock)); + return $this->getBlockInstance('reviewFormBlock'); } /** - * Get customer reviews block - * - * @return Form + * @return \Magento\Review\Test\Block\Product\View */ public function getCustomerReviewBlock() { - return Factory::getBlockFactory()->getMagentoReviewProductView( - $this->_browser->find($this->customerReviewBlock) - ); + return $this->getBlockInstance('customerReviewBlock'); } /** - * Get review summary block - * - * @return ReviewView - */ - public function getReviewSummaryBlock() - { - return Factory::getBlockFactory()->getMagentoReviewProductViewSummary( - $this->_browser->find($this->reviewSummarySelector, Locator::SELECTOR_CSS) - ); - } - - /** - * Get upsell block - * - * @return Summary + * @return \Magento\Core\Test\Block\Messages */ - public function getUpsellProductBlock() + public function getMessagesBlock() { - return Factory::getBlockFactory()->getMagentoCatalogProductProductListUpsell( - $this->_browser->find($this->upsellSelector, Locator::SELECTOR_CSS) - ); + return $this->getBlockInstance('messagesBlock'); } /** - * Get messages block - * - * @return Upsell + * @return \Magento\Review\Test\Block\Product\View\Summary */ - public function getMessagesBlock() + public function getReviewSummaryBlock() { - return Factory::getBlockFactory()->getMagentoCoreMessages( - $this->_browser->find($this->messagesSelector, Locator::SELECTOR_CSS) - ); + return $this->getBlockInstance('reviewSummary'); } /** - * Get related product block - * - * @return GiftCard + * @return \Magento\Catalog\Test\Block\Product\ProductList\Upsell */ - public function getRelatedProductBlock() + public function getUpsellBlock() { - return Factory::getBlockFactory()->getMagentoCatalogProductProductListRelated( - $this->_browser->find($this->relatedProductSelector, Locator::SELECTOR_CSS) - ); + return $this->getBlockInstance('upsellBlock'); } /** - * Get gift card options block - * - * @return Related + * @return \Magento\Catalog\Test\Block\Product\ProductList\Crosssell */ - public function getGiftCardBlock() + public function getCrosssellBlock() { - return Factory::getBlockFactory()->getMagentoGiftCardCatalogProductViewTypeGiftCard( - $this->_browser->find($this->giftCardBlockSelector, Locator::SELECTOR_CSS) - ); + return $this->getBlockInstance('crosssellBlock'); } /** - * @return Links + * @return \Magento\Downloadable\Test\Block\Catalog\Product\Links */ public function getDownloadableLinksBlock() { - return Factory::getBlockFactory()->getMagentoDownloadableCatalogProductLinks( - $this->_browser->find($this->downloadableLinksSelector) - ); + return $this->getBlockInstance('downloadableLinksBlock'); } /** - * Get product price block - * - * @return Price + * @return \Magento\Catalog\Test\Block\Product\Price */ public function getMapBlock() { - return Factory::getBlockFactory()->getMagentoCatalogProductPrice( - $this->_browser->find($this->mapBlock, Locator::SELECTOR_CSS) - ); - } - - /** - * Retrieve cross-sell block - * - * @return Crosssell - */ - public function getCrosssellBlock() - { - return Factory::getBlockFactory()->getMagentoCatalogProductProductListCrosssell( - $this->_browser->find($this->crosssellSelector, Locator::SELECTOR_CSS) - ); - } - - /** - * Get gift card amount block - * - * @return GiftCard - */ - public function getGiftCardAmountBlock() - { - return Factory::getBlockFactory()->getMagentoGiftCardCatalogProductViewTypeGiftCard( - $this->_browser->find($this->giftCardBlockAmountSelector, Locator::SELECTOR_CSS) - ); + return $this->getBlockInstance('mapBlock'); } } 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 new file mode 100644 index 0000000000000..dc483885bca92 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductView.xml @@ -0,0 +1,93 @@ +<?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>viewBlock</name> + <class>Magento\Catalog\Test\Block\Product\View</class> + <locator>#maincontent</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>customOptionsBlock</name> + <class>Magento\Catalog\Test\Block\Product\View\CustomOptions</class> + <locator>#product-options-wrapper</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>relatedProductBlock</name> + <class>Magento\Catalog\Test\Block\Product\ProductList\Related</class> + <locator>.block.related</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>upsellBlock</name> + <class>Magento\Catalog\Test\Block\Product\ProductList\Upsell</class> + <locator>.block.upsell</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>crosssellBlock</name> + <class>Magento\Catalog\Test\Block\Product\ProductList\Crosssell</class> + <locator>.block.crosssell</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>downloadableLinksBlock</name> + <class>Magento\Downloadable\Test\Block\Catalog\Product\Links</class> + <locator>[data-container-for=downloadable-links]</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>mapBlock</name> + <class>Magento\Catalog\Test\Block\Product\Price</class> + <locator>#map-popup</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> + <block> + <name>reviewSummary</name> + <class>Magento\Review\Test\Block\Product\View\Summary</class> + <locator>.product.reviews.summary</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>customerReviewBlock</name> + <class>Magento\Review\Test\Block\Product\View</class> + <locator>#customer-reviews</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>reviewFormBlock</name> + <class>Magento\Review\Test\Block\Form</class> + <locator>#review-form</locator> + <strategy>css selector</strategy> + </block> +</page> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogCategoryEntity.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogCategoryEntity.php new file mode 100644 index 0000000000000..d46e139e67524 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogCategoryEntity.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\Catalog\Test\Repository; + +use Mtf\Repository\AbstractRepository; + +/** + * Class CatalogCategoryEntity + * Data for creation Category + */ +class CatalogCategoryEntity extends AbstractRepository +{ + public function __construct(array $defaultConfig = [], array $defaultData = []) + { + $this->_data['default_subcategory'] = [ + 'name' => 'Subcategory%isolation%', + 'path' => 'Default Category', + 'parent_id' => 2, + 'is_active' => 'Yes', + 'include_in_menu' => 'Yes', + ]; + } +} 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 index adce7b1b968c6..c07b521f749c5 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.php @@ -28,7 +28,7 @@ /** * Class CatalogProductSimple - * + * Data for creation Catalog Product Simple */ class CatalogProductSimple extends AbstractRepository { @@ -55,13 +55,11 @@ public function __construct(array $defaultConfig = [], array $defaultData = []) ]; $this->_data['100_dollar_product'] = [ - 'sku' => '100_dollar_product', - 'name' => '100_dollar_product', + 'sku' => '100_dollar_product%isolation%', + 'name' => '100_dollar_product%isolation%', 'type_id' => 'simple', 'attribute_set_id' => '4', 'price' => ['value' => 100, 'preset' => '-'], - 'id' => '2', - 'mtf_dataset_name' => '100_dollar_product' ]; $this->_data['40_dollar_product'] = [ @@ -82,7 +80,16 @@ public function __construct(array $defaultConfig = [], array $defaultData = []) 'price' => ['value' => 100, 'preset' => 'MAGETWO-23036'], 'id' => '3', 'category_ids' => ['presets' => 'default'], - 'mtf_dataset_name' => 'simple_with_category', + 'mtf_dataset_name' => 'simple_with_category' + ]; + + $this->_data['product_with_category'] = [ + 'sku' => 'simple_product_with_category_%isolation%', + 'name' => 'Simple product with category %isolation%', + 'type_id' => 'simple', + 'attribute_set_id' => '4', + 'price' => ['value' => 100, 'preset' => ''], + 'category_ids' => ['presets' => 'default_subcategory'] ]; } } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/AssignProductTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/AssignProductTest.php index 19f43d8217b76..06d357e7ee368 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/AssignProductTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/AssignProductTest.php @@ -59,7 +59,7 @@ public function testAssignProducts() $catalogCategoryEditPage = Factory::getPageFactory()->getCatalogCategoryEditId(); $treeBlock = $catalogCategoryPage->getTreeBlock(); $formBlock = $catalogCategoryPage->getFormBlock(); - $messageBlock = $catalogCategoryPage->getMessageBlock(); + $messagesBlock = $catalogCategoryPage->getMessagesBlock(); $actionsBlock = $catalogCategoryEditPage->getPageActionsBlock(); //Steps Factory::getApp()->magentoBackendLoginUser(); @@ -73,7 +73,7 @@ public function testAssignProducts() $categoryProductsGrid->searchAndSelect(['sku' => $product->getProductSku()]); } $actionsBlock->save(); - $messageBlock->assertSuccessMessage(); + $messagesBlock->assertSuccessMessage(); //Clean Cache $cachePage = Factory::getPageFactory()->getAdminCache(); $cachePage->open(); diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateTest.php index daebae20ca7ce..0e1da3da5f99e 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateTest.php @@ -52,7 +52,7 @@ public function testWithRequiredFields() $treeBlockEdit = $catalogCategoryEditPage->getTreeBlock(); $formBlock = $catalogCategoryEditPage->getFormBlock(); $actionsBlock = $catalogCategoryEditPage->getPageActionsBlock(); - $messageBlock = $catalogCategoryEditPage->getMessageBlock(); + $messagesBlock = $catalogCategoryEditPage->getMessagesBlock(); //Steps Factory::getApp()->magentoBackendLoginUser(); $catalogCategoryPage->open(); @@ -61,7 +61,7 @@ public function testWithRequiredFields() $formBlock->fill($category); $actionsBlock->save(); //Verifying - $messageBlock->assertSuccessMessage(); + $messagesBlock->assertSuccessMessage(); //Flush cache $cachePage = Factory::getPageFactory()->getAdminCache(); $cachePage->open(); 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 f8dc029048054..2faf3d85e14f5 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 @@ -31,13 +31,15 @@ use Magento\Catalog\Test\Fixture\ConfigurableProduct; /** + * Class CreateWithAttributeTest * Configurable product with creating new category and new attribute - * */ class CreateWithAttributeTest extends Functional { /** * Login into backend area before test + * + * @return void */ protected function setUp() { @@ -48,6 +50,7 @@ protected function setUp() * Creating configurable product with creating new category and new attribute (required fields only) * * @ZephyrId MAGETWO-13361 + * @return void */ public function testCreateConfigurableProductWithNewAttribute() { @@ -77,36 +80,38 @@ public function testCreateConfigurableProductWithNewAttribute() * Fill required fields for simple product with category creation * * @param Product $product + * @return void */ protected function fillSimpleProductWithNewCategory($product) { //Page & Blocks $manageProductsGrid = Factory::getPageFactory()->getCatalogProductIndex(); $createProductPage = Factory::getPageFactory()->getCatalogProductNew(); - $productBlockForm = $createProductPage->getProductBlockForm(); + $productForm = $createProductPage->getProductForm(); //Steps $manageProductsGrid->open(); $manageProductsGrid->getProductBlock()->addProduct(); - $productBlockForm->fill($product); - $productBlockForm->openTab(Product::GROUP_PRODUCT_DETAILS); - $productBlockForm->addNewCategory($product); + $productForm->fill($product); + $productForm->openTab(Product::GROUP_PRODUCT_DETAILS); + $productForm->addNewCategory($product); } /** * Add new attribute to product * * @param ProductAttribute $attribute + * @return void */ protected function addNewAttribute(ProductAttribute $attribute) { $createProductPage = Factory::getPageFactory()->getCatalogProductNew(); - $productBlockForm = $createProductPage->getProductBlockForm(); - $productBlockForm->openVariationsTab(); - $productBlockForm->clickCreateNewVariationSet(); + $productForm = $createProductPage->getConfigurableProductForm(); + $productForm->openVariationsTab(); + $productForm->clickCreateNewVariationSet(); - $newAttributeForm = $createProductPage->getAttributeEditBlock(); + $newAttributeForm = $productForm->getConfigurableAttributeEditBlock(); $this->assertTrue($newAttributeForm->isVisible(), '"New attribute" window is not opened'); $newAttributeForm->openFrontendProperties(); @@ -119,17 +124,20 @@ protected function addNewAttribute(ProductAttribute $attribute) * Fill product variations and save product * * @param ConfigurableProduct $variations + * @return void */ protected function fillProductVariationsAndSave(ConfigurableProduct $variations) { $createProductPage = Factory::getPageFactory()->getCatalogProductNew(); - $productBlockForm = $createProductPage->getProductBlockForm(); - $productBlockForm->fillVariations($variations); - $productBlockForm->save($variations); + $createProductPage->getProductForm() + ->fillVariations($variations); + $createProductPage->getFormAction()->saveProduct($createProductPage, $variations); } /** * Assert product was saved + * + * @return void */ protected function assertProductSaved() { @@ -145,6 +153,7 @@ protected function assertProductSaved() * Assert existing product on backend product grid * * @param Product $product + * @return void */ protected function assertOnGrid(Product $product) { @@ -163,6 +172,7 @@ protected function assertOnGrid(Product $product) * * @param Product $product * @param ConfigurableProduct $variations + * @return void */ protected function assertOnFrontend(Product $product, ConfigurableProduct $variations) { @@ -187,9 +197,10 @@ protected function assertOnFrontend(Product $product, ConfigurableProduct $varia $productViewBlock->getProductName(), 'Product name does not correspond to specified.' ); + $price = $productViewBlock->getProductPrice(); $this->assertEquals( - $product->getProductPrice(), - $productViewBlock->getProductPrice(), + number_format($product->getProductPrice(), 2), + $price['price_regular_price'], 'Product price does not correspond to specified.' ); $this->assertTrue( diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/Configurable/EditConfigurableTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/Configurable/EditConfigurableTest.php index 8f21bfef21909..8c687f37ca045 100755 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/Configurable/EditConfigurableTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/Configurable/EditConfigurableTest.php @@ -24,13 +24,12 @@ namespace Magento\Catalog\Test\TestCase\Product\Configurable; -use Magento\Catalog\Test\TestCase\Product\CreateConfigurableTest; use Mtf\Factory\Factory; +use Magento\Catalog\Test\TestCase\Product\CreateConfigurableTest; /** * Class EditConfigurableTest * Edit Configurable product - * */ class EditConfigurableTest extends CreateConfigurableTest { @@ -38,6 +37,7 @@ class EditConfigurableTest extends CreateConfigurableTest * Edit configurable product and add new options to attribute * * @ZephyrId MAGETWO-12840 + * @return void */ public function testCreateConfigurableProduct() { @@ -51,7 +51,7 @@ public function testCreateConfigurableProduct() $editProduct = $configurable->getEditData(); //Steps $createProductPage = Factory::getPageFactory()->getCatalogProductNew(); - $productBlockForm = $createProductPage->getProductBlockForm(); + $productForm = $createProductPage->getProductForm(); //Login Factory::getApp()->magentoBackendLoginUser(); $productGridPage = Factory::getPageFactory()->getCatalogProductIndex(); @@ -59,8 +59,8 @@ public function testCreateConfigurableProduct() //Search and open original configurable product $productGridPage->getProductGrid()->searchAndOpen(array('sku' => $productSku)); //Editing product options - $productBlockForm->fill($editProduct); - $productBlockForm->save($editProduct); + $productForm->fill($editProduct); + $createProductPage->getFormAction()->save(); //Verifying $createProductPage->getMessagesBlock()->assertSuccessMessage(); //Flush cache 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 7b96fb862c578..f33fb2cdf623d 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 @@ -31,12 +31,13 @@ /** * Class CreateConfigurableTest * Configurable product - * */ class CreateConfigurableTest extends Functional { /** * Login into backend area before test + * + * @return void */ protected function setUp() { @@ -47,6 +48,7 @@ protected function setUp() * Creating configurable product and assigning it to category * * @ZephyrId MAGETWO-12620 + * @return void */ public function testCreateConfigurableProduct() { @@ -56,12 +58,12 @@ public function testCreateConfigurableProduct() //Page & Blocks $manageProductsGrid = Factory::getPageFactory()->getCatalogProductIndex(); $createProductPage = Factory::getPageFactory()->getCatalogProductNew(); - $productBlockForm = $createProductPage->getProductBlockForm(); //Steps $manageProductsGrid->open(); $manageProductsGrid->getProductBlock()->addProduct('configurable'); - $productBlockForm->fill($product); - $productBlockForm->save($product); + $productForm = $createProductPage->getProductForm(); + $productForm->fill($product); + $createProductPage->getFormAction()->saveProduct($createProductPage, $product); //Verifying $createProductPage->getMessagesBlock()->assertSuccessMessage(); //Flush cache @@ -78,6 +80,7 @@ public function testCreateConfigurableProduct() * Assert existing product on admin product grid * * @param ConfigurableProduct $product + * @return void */ protected function assertOnGrid($product) { @@ -90,7 +93,7 @@ protected function assertOnGrid($product) //Page & Block $productGridPage = Factory::getPageFactory()->getCatalogProductIndex(); $productGridPage->open(); - /** @var \Magento\Catalog\Test\Block\Backend\ProductGrid */ + /** @var \Magento\Catalog\Test\Block\Adminhtml\Product\Grid */ $gridBlock = $productGridPage->getProductGrid(); //Assertion $this->assertTrue($gridBlock->isRowVisible($configurableSearch), 'Configurable product was not found.'); @@ -106,6 +109,7 @@ protected function assertOnGrid($product) * Assert configurable product on Frontend * * @param ConfigurableProduct $product + * @return void */ protected function assertOnFrontend(ConfigurableProduct $product) { @@ -130,9 +134,11 @@ protected function assertOnFrontend(ConfigurableProduct $product) $productViewBlock->getProductName(), 'Product name does not correspond to specified.' ); + $price = $product->getProductPrice(); + $blockPrice = $productViewBlock->getProductPrice(); $this->assertEquals( - $product->getProductPrice(), - $productViewBlock->getProductPrice(), + number_format($price, 2), + number_format($blockPrice['price_regular_price'], 2), 'Product price does not correspond to specified.' ); $this->assertTrue($productViewBlock->verifyProductOptions($product), 'Added configurable options are absent'); 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 8dc5b49e71424..6b264249942c2 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 @@ -37,6 +37,8 @@ class CreateGroupedTest extends Functional { /** * Login into backend area before test + * + * @return void */ protected function setUp() { @@ -47,6 +49,7 @@ protected function setUp() * Creating Grouped product and assigning it to category * * @ZephyrId MAGETWO-13610 + * @return void */ public function testCreateGroupedProduct() { @@ -56,12 +59,12 @@ public function testCreateGroupedProduct() //Page & Blocks $manageProductsGrid = Factory::getPageFactory()->getCatalogProductIndex(); $createProductPage = Factory::getPageFactory()->getCatalogProductNew(); - $productBlockForm = $createProductPage->getProductBlockForm(); + $productForm = $createProductPage->getProductForm(); //Steps $manageProductsGrid->open(); $manageProductsGrid->getProductBlock()->addProduct('grouped'); - $productBlockForm->fill($product); - $productBlockForm->save($product); + $productForm->fill($product); + $createProductPage->getFormAction()->save(); //Verifying $createProductPage->getMessagesBlock()->assertSuccessMessage(); // Flush cache @@ -77,6 +80,7 @@ public function testCreateGroupedProduct() * Assert existing product on admin product grid * * @param GroupedProduct $product + * @return void */ protected function assertOnGrid($product) { @@ -88,7 +92,7 @@ protected function assertOnGrid($product) //Page & Block $productGridPage = Factory::getPageFactory()->getCatalogProductIndex(); $productGridPage->open(); - /** @var \Magento\Catalog\Test\Block\Backend\ProductGrid */ + /** @var \Magento\Catalog\Test\Block\Adminhtml\Product\Grid $gridBlock */ $gridBlock = $productGridPage->getProductGrid(); //Assertion $this->assertTrue($gridBlock->isRowVisible($search), 'Grouped product was not found.'); @@ -98,6 +102,7 @@ protected function assertOnGrid($product) * Assert Grouped product on Frontend * * @param GroupedProduct $product + * @return void */ protected function assertOnFrontend(GroupedProduct $product) { diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateProductTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateProductTest.php index 2530d9a787e3f..d4c90ab961796 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateProductTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateProductTest.php @@ -29,13 +29,15 @@ use Magento\Catalog\Test\Fixture\SimpleProduct; /** - * Create product - * + * Class CreateProductTest + * Create product test */ class CreateProductTest extends Functional { /** * Login into backend area before test + * + * @return void */ protected function setUp() { @@ -46,6 +48,7 @@ protected function setUp() * Create simple product with settings in advanced inventory tab * * @ZephyrId MAGETWO-12914 + * @return void */ public function testCreateProductAdvancedInventory() { @@ -54,11 +57,11 @@ public function testCreateProductAdvancedInventory() //Data $createProductPage = Factory::getPageFactory()->getCatalogProductNew(); $createProductPage->init($product); - $productBlockForm = $createProductPage->getProductBlockForm(); + $productForm = $createProductPage->getProductForm(); //Steps $createProductPage->open(); - $productBlockForm->fill($product); - $productBlockForm->save($product); + $productForm->fill($product); + $createProductPage->getFormAction()->save(); $createProductPage->getMessagesBlock()->assertSuccessMessage(); //Flush cache $cachePage = Factory::getPageFactory()->getAdminCache(); @@ -74,8 +77,9 @@ public function testCreateProductAdvancedInventory() * Assert existing product on admin product grid * * @param SimpleProduct $product + * @return void */ - protected function assertOnGrid($product) + protected function assertOnGrid(SimpleProduct $product) { $productGridPage = Factory::getPageFactory()->getCatalogProductIndex(); $productGridPage->open(); @@ -87,8 +91,9 @@ protected function assertOnGrid($product) * Assert product data on category and product pages * * @param SimpleProduct $product + * @return void */ - protected function assertOnCategory($product) + protected function assertOnCategory(SimpleProduct $product) { //Pages $frontendHomePage = Factory::getPageFactory()->getCmsIndexIndex(); @@ -104,6 +109,7 @@ protected function assertOnCategory($product) //Verification on product detail page $productViewBlock = $productPage->getViewBlock(); $this->assertEquals($product->getProductName(), $productViewBlock->getProductName()); - $this->assertEquals($product->getProductPrice(), $productViewBlock->getProductPrice()); + $price = $productViewBlock->getProductPrice(); + $this->assertEquals(number_format($product->getProductPrice(), 2), $price['price_regular_price']); } } 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 c0b855d4d1bfb..c4b06bd2cc271 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 @@ -31,12 +31,13 @@ /** * Class CreateSimpleWithCategoryTest * Test simple product and category creation - * */ class CreateSimpleWithCategoryTest extends Functional { /** * Login into backend area before test + * + * @return void */ protected function setUp() { @@ -47,6 +48,7 @@ protected function setUp() * Test product create * * @ZephyrId MAGETWO-13345 + * @return void */ public function testCreateProduct() { @@ -58,14 +60,14 @@ public function testCreateProduct() $productListPage = Factory::getPageFactory()->getCatalogProductIndex(); $createProductPage = Factory::getPageFactory()->getCatalogProductNew(); $addProductBlock = $productListPage->getProductBlock(); - $productBlockForm = $createProductPage->getProductBlockForm(); + $productForm = $createProductPage->getProductForm(); //Steps $productListPage->open(); $addProductBlock->addProduct(); - $productBlockForm->addNewCategory($product); - $productBlockForm->fill($product); - $productBlockForm->save($product); + $productForm->addNewCategory($product); + $productForm->fill($product); + $createProductPage->getFormAction()->save(); //Verifying $this->assertSuccessMessage("You saved the product."); @@ -98,6 +100,7 @@ protected function assertSuccessMessage($messageText) * Assert simple product on Frontend * * @param SimpleProduct $product + * @return void */ protected function assertProductOnFrontend(SimpleProduct $product) { @@ -120,6 +123,7 @@ protected function assertProductOnFrontend(SimpleProduct $product) $productViewBlock = $productPage->getViewBlock(); $productListBlock->openProductViewPage($product->getProductName()); $this->assertEquals($product->getProductName(), $productViewBlock->getProductName()); - $this->assertEquals($product->getProductPrice(), $productViewBlock->getProductPrice()); + $price = $productViewBlock->getProductPrice(); + $this->assertEquals(number_format($product->getProductPrice(), 2), $price['price_regular_price']); } } 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 index 78979b322e657..b649e5c9ff70e 100644 --- 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 @@ -29,13 +29,15 @@ use Magento\Catalog\Test\Fixture\Product; /** + * Class CreateSimpleWithCustomOptionsAndCategoryTest * Create simple product with custom options - * */ class CreateSimpleWithCustomOptionsAndCategoryTest extends Functional { /** * Login into backend area before test + * + * @return void */ protected function setUp() { @@ -46,6 +48,7 @@ protected function setUp() * Creating simple product with custom options and assigning it to the category * * @ZephyrId MAGETWO-12703 + * @return void */ public function testCreateProduct() { @@ -54,11 +57,11 @@ public function testCreateProduct() //Data $createProductPage = Factory::getPageFactory()->getCatalogProductNew(); $createProductPage->init($product); - $productBlockForm = $createProductPage->getProductBlockForm(); + $productForm = $createProductPage->getForm(); //Steps $createProductPage->open(); - $productBlockForm->fill($product); - $productBlockForm->save($product); + $productForm->fillProduct($product); + $createProductPage->getFormAction()->save(); //Verifying $createProductPage->getMessagesBlock()->assertSuccessMessage(); // Flush cache @@ -74,12 +77,13 @@ public function testCreateProduct() * Assert existing product on admin product grid * * @param Product $product + * @return void */ protected function assertOnGrid($product) { $productGridPage = Factory::getPageFactory()->getCatalogProductIndex(); $productGridPage->open(); - //@var Magento\Catalog\Test\Block\Backend\ProductGrid + /** @var \Magento\Catalog\Test\Block\Adminhtml\Product\Grid $gridBlock */ $gridBlock = $productGridPage->getProductGrid(); $this->assertTrue($gridBlock->isRowVisible(array('sku' => $product->getProductSku()))); } @@ -88,6 +92,7 @@ protected function assertOnGrid($product) * Assert product data on category and product pages * * @param Product $product + * @return void */ protected function assertOnCategory($product) { @@ -105,12 +110,14 @@ protected function assertOnCategory($product) //Verification on product detail page $productViewBlock = $productPage->getViewBlock(); $this->assertEquals($product->getProductName(), $productViewBlock->getProductName()); - $this->assertEquals($product->getProductPrice(), $productViewBlock->getProductPrice()); + $price = $productViewBlock->getProductPrice(); + $this->assertEquals(number_format($product->getProductPrice(), 2), $price['price_regular_price']); - $productOptionsBlock = $productPage->getCustomOptionBlock(); + $productOptionsBlock = $productPage->getCustomOptionsBlock(); $fixture = $product->getData('fields/custom_options/value'); - $actualOptions = $productOptionsBlock->get(); + $actualOptions = $productOptionsBlock->getOptions(); $this->assertCount(count($fixture), $actualOptions); - $this->assertEquals($fixture[0]['title'], $actualOptions[0]['title']); + $this->assertTrue(isset($actualOptions[$fixture[0]['title']]['title'])); + $this->assertEquals($fixture[0]['title'], $actualOptions[$fixture[0]['title']]['title']); } } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateTest.php index dc88247e53ded..b9b0eae2e3fac 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateTest.php @@ -29,13 +29,15 @@ use Magento\Catalog\Test\Fixture\SimpleProduct; /** + * Class CreateTest * Create simple product for BAT - * */ class CreateTest extends Functional { /** * Login into backend area before test + * + * @return void */ protected function setUp() { @@ -46,6 +48,7 @@ protected function setUp() * Creating simple product and assigning it to category * * @ZephyrId MAGETWO-12514 + * @return void */ public function testCreateProduct() { @@ -54,11 +57,11 @@ public function testCreateProduct() //Data $createProductPage = Factory::getPageFactory()->getCatalogProductNew(); $createProductPage->init($product); - $productBlockForm = $createProductPage->getProductBlockForm(); + $productForm = $createProductPage->getProductForm(); //Steps $createProductPage->open(); - $productBlockForm->fill($product); - $productBlockForm->save($product); + $productForm->fill($product); + $createProductPage->getFormAction()->save(); //Verifying $createProductPage->getMessagesBlock()->assertSuccessMessage(); //Flush cache @@ -75,12 +78,13 @@ public function testCreateProduct() * Assert existing product on admin product grid * * @param SimpleProduct $product + * @return void */ - protected function assertOnGrid($product) + protected function assertOnGrid(SimpleProduct $product) { $productGridPage = Factory::getPageFactory()->getCatalogProductIndex(); $productGridPage->open(); - //@var Magento\Catalog\Test\Block\Backend\ProductGrid + /** @var \Magento\Catalog\Test\Block\Adminhtml\Product\Grid $gridBlock */ $gridBlock = $productGridPage->getProductGrid(); $this->assertTrue($gridBlock->isRowVisible(array('sku' => $product->getProductSku()))); } @@ -89,8 +93,9 @@ protected function assertOnGrid($product) * Assert product data on category and product pages * * @param SimpleProduct $product + * @return void */ - protected function assertOnCategory($product) + protected function assertOnCategory(SimpleProduct $product) { //Pages $frontendHomePage = Factory::getPageFactory()->getCmsIndexIndex(); @@ -106,6 +111,7 @@ protected function assertOnCategory($product) //Verification on product detail page $productViewBlock = $productPage->getViewBlock(); $this->assertEquals($product->getProductName(), $productViewBlock->getProductName()); - $this->assertEquals($product->getProductPrice(), $productViewBlock->getProductPrice()); + $price = $productViewBlock->getProductPrice(); + $this->assertEquals(number_format($product->getProductPrice(), 2), $price['price_regular_price']); } } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateVirtualTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateVirtualTest.php index 201e02f43c958..c2d9d56316fb7 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateVirtualTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateVirtualTest.php @@ -31,12 +31,13 @@ /** * Class CreateTest * Test product creation - * */ class CreateVirtualTest extends Functional { /** * Login into backend area before test + * + * @return void */ protected function setUp() { @@ -47,6 +48,7 @@ protected function setUp() * Creating Virtual product with required fields only and assign it to the category * * @ZephyrId MAGETWO-13593 + * @return void */ public function testCreateProduct() { @@ -55,11 +57,11 @@ public function testCreateProduct() //Data $createProductPage = Factory::getPageFactory()->getCatalogProductNew(); $createProductPage->init($product); - $productBlockForm = $createProductPage->getProductBlockForm(); + $productForm = $createProductPage->getProductForm(); //Steps $createProductPage->open(); - $productBlockForm->fill($product); - $productBlockForm->save($product); + $productForm->fill($product); + $createProductPage->getFormAction()->save(); //Verifying $createProductPage->getMessagesBlock()->assertSuccessMessage(); //Flush cache @@ -76,12 +78,13 @@ public function testCreateProduct() * Assert existing product on admin product grid * * @param VirtualProduct $product + * @return void */ - protected function assertOnGrid($product) + protected function assertOnGrid(VirtualProduct $product) { $productGridPage = Factory::getPageFactory()->getCatalogProductIndex(); $productGridPage->open(); - //@var Magento\Catalog\Test\Block\Backend\ProductGrid + /** @var \Magento\Catalog\Test\Block\Adminhtml\Product\Grid $gridBlock */ $gridBlock = $productGridPage->getProductGrid(); $this->assertTrue($gridBlock->isRowVisible(array('sku' => $product->getProductSku()))); } @@ -90,8 +93,9 @@ protected function assertOnGrid($product) * Assert product data on category and product pages * * @param VirtualProduct $product + * @return void */ - protected function assertOnCategory($product) + protected function assertOnCategory(VirtualProduct $product) { //Pages $frontendHomePage = Factory::getPageFactory()->getCmsIndexIndex(); @@ -107,6 +111,7 @@ protected function assertOnCategory($product) $productPage = Factory::getPageFactory()->getCatalogProductView(); $productViewBlock = $productPage->getViewBlock(); $this->assertEquals($product->getProductName(), $productViewBlock->getProductName()); - $this->assertEquals($product->getProductPrice(), $productViewBlock->getProductPrice()); + $price = $productViewBlock->getProductPrice(); + $this->assertEquals(number_format($product->getProductPrice(), 2), $price['price_regular_price']); } } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/EditSimpleProductTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/EditSimpleProductTest.php index 66fa1d5934cfd..e9fb1f950368f 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/EditSimpleProductTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/EditSimpleProductTest.php @@ -36,6 +36,8 @@ class EditSimpleProductTest extends Functional { /** * Login into backend area before test + * + * @return void */ protected function setUp() { @@ -46,6 +48,7 @@ protected function setUp() * Edit simple product * * @ZephyrId MAGETWO-12428 + * @return void */ public function testEditProduct() { @@ -58,7 +61,7 @@ public function testEditProduct() $productGridPage = Factory::getPageFactory()->getCatalogProductIndex(); $gridBlock = $productGridPage->getProductGrid(); $editProductPage = Factory::getPageFactory()->getCatalogProductEdit(); - $productBlockForm = $editProductPage->getProductBlockForm(); + $productForm = $editProductPage->getProductForm(); $cachePage = Factory::getPageFactory()->getAdminCache(); $productGridPage->open(); @@ -68,8 +71,8 @@ public function testEditProduct() 'type' => 'Simple Product' ) ); - $productBlockForm->fill($editProduct); - $productBlockForm->save($editProduct); + $productForm->fill($editProduct); + $editProductPage->getFormAction()->save(); //Verifying $editProductPage->getMessagesBlock()->assertSuccessMessage(); // Flush cache @@ -85,8 +88,9 @@ public function testEditProduct() * Assert existing product on admin product grid * * @param SimpleProduct $product + * @return void */ - protected function assertOnGrid($product) + protected function assertOnGrid(SimpleProduct $product) { $productGridPage = Factory::getPageFactory()->getCatalogProductIndex(); $productGridPage->open(); @@ -99,8 +103,9 @@ protected function assertOnGrid($product) * * @param SimpleProduct $product * @param string $categoryName + * @return void */ - protected function assertOnCategoryPage($product, $categoryName) + protected function assertOnCategoryPage(SimpleProduct $product, $categoryName) { //Pages $frontendHomePage = Factory::getPageFactory()->getCmsIndexIndex(); @@ -119,8 +124,9 @@ protected function assertOnCategoryPage($product, $categoryName) * * @param SimpleProduct $productOld * @param SimpleProduct $productEdited + * @return void */ - protected function assertOnProductPage($productOld, $productEdited) + protected function assertOnProductPage(SimpleProduct $productOld, SimpleProduct $productEdited) { $productPage = Factory::getPageFactory()->getCatalogProductView(); $productPage->init($productOld); @@ -128,6 +134,7 @@ protected function assertOnProductPage($productOld, $productEdited) $productViewBlock = $productPage->getViewBlock(); $this->assertEquals($productEdited->getProductName(), $productViewBlock->getProductName()); - $this->assertEquals($productEdited->getProductPrice(), $productViewBlock->getProductPrice()); + $price = $productViewBlock->getProductPrice(); + $this->assertEquals(number_format($productEdited->getProductPrice(), 2), $price['price_regular_price']); } } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UnassignCategoryTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UnassignCategoryTest.php index 9d49fd1baaf58..9d75889bb72ba 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UnassignCategoryTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UnassignCategoryTest.php @@ -29,13 +29,15 @@ use Magento\Catalog\Test\Fixture\Product; /** + * Class UnassignCategoryTest * Unassign product from category on Product page - * */ class UnassignCategoryTest extends Functional { /** * Login into backend area before test + * + * @return void */ protected function setUp() { @@ -46,6 +48,7 @@ protected function setUp() * Unassigning products from the category on Product Information page * * @ZephyrId MAGETWO-12417 + * @return void */ public function testUnassignOnProductPage() { @@ -56,8 +59,9 @@ public function testUnassignOnProductPage() //Steps $editProductPage = Factory::getPageFactory()->getCatalogProductEdit(); $editProductPage->open(array('id' => $simple->getProductId())); - $editProductPage->getProductBlockForm()->clearCategorySelect(); - $editProductPage->getProductBlockForm()->save($simple); + $productForm = $editProductPage->getProductForm(); + $productForm->clearCategorySelect(); + $editProductPage->getFormAction()->save(); //Verifying $editProductPage->getMessagesBlock()->assertSuccessMessage(); //Flush cache @@ -73,8 +77,9 @@ public function testUnassignOnProductPage() * Assert absence product on category page (frontend) * * @param Product $product + * @return void */ - protected function assertAbsenceOnCategory($product) + protected function assertAbsenceOnCategory(Product $product) { //Pages $frontendHomePage = Factory::getPageFactory()->getCmsIndexIndex(); diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/curl/di.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/curl/di.xml index 330a2ed29cd00..a9767c006017e 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/curl/di.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/curl/di.xml @@ -25,4 +25,5 @@ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../../../lib/Magento/Framework/ObjectManager/etc/config.xsd"> <preference for="Magento\Catalog\Test\Handler\CatalogProductSimple\CatalogProductSimpleInterface" type="\Magento\Catalog\Test\Handler\CatalogProductSimple\Curl" /> + <preference for="Magento\Catalog\Test\Handler\CatalogCategoryEntity\CatalogCategoryEntityInterface" type="\Magento\Catalog\Test\Handler\CatalogCategoryEntity\Curl" /> </config> 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 index 4393f757e174f..f2055f359c4d9 100644 --- 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,28 +27,28 @@ <assertProductInGrid module="Magento_Catalog"> <severeness>high</severeness> <require> - <manageProductsPage class="Magento\Catalog\Test\Page\Product\CatalogProductIndex" /> - <product class="Magento\Catalog\Test\Fixture\CatalogProductSimple" /> + <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\Product\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" /> - <simple class="Magento\Catalog\Test\Fixture\CatalogProductSimple" /> + <product class="Mtf\Fixture\FixtureInterface" /> </require> </assertProductOutOfStock> <assertProductInStock module="Magento_Catalog"> <severeness>low</severeness> <require> <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" /> - <simple class="Magento\Catalog\Test\Fixture\CatalogProductSimple" /> + <product class="Mtf\Fixture\FixtureInterface" /> </require> </assertProductInStock> <assertProductVisibleInCategory module="Magento_Catalog"> @@ -57,7 +57,7 @@ <catalogCategoryView class="Magento\Catalog\Test\Page\Category\CatalogCategoryView" /> <cmsIndex class="Magento\Cms\Test\Page\CmsIndex" /> <category class="Magento\Catalog\Test\Fixture\Category" /> - <simple class="Magento\Catalog\Test\Fixture\CatalogProductSimple" /> + <product class="Mtf\Fixture\FixtureInterface" /> </require> </assertProductVisibleInCategory> <assertProductSearchableBySku module="Magento_Catalog"> @@ -65,7 +65,7 @@ <require> <catalogSearchResult class="Magento\CatalogSearch\Test\Page\CatalogsearchResult" /> <cmsIndex class="Magento\Cms\Test\Page\CmsIndex" /> - <simple class="Magento\Catalog\Test\Fixture\CatalogProductSimple" /> + <product class="Mtf\Fixture\FixtureInterface" /> </require> </assertProductSearchableBySku> <assertProductInCategory module="Magento_Catalog"> @@ -73,7 +73,7 @@ <require> <catalogCategoryView class="Magento\Catalog\Test\Page\Category\CatalogCategoryView" /> <cmsIndex class="Magento\Cms\Test\Page\CmsIndex" /> - <product class="Magento\Catalog\Test\Fixture\CatalogProductSimple" /> + <product class="Mtf\Fixture\FixtureInterface" /> <category class="Magento\Catalog\Test\Fixture\Category" /> </require> </assertProductInCategory> @@ -81,15 +81,55 @@ <severeness>low</severeness> <require> <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" /> - <product class="Magento\Catalog\Test\Fixture\CatalogProductSimple" /> + <product class="Mtf\Fixture\FixtureInterface" /> </require> </assertProductView> <assertProductInCart module="Magento_Catalog"> <severeness>low</severeness> <require> <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" /> - <product class="Magento\Catalog\Test\Fixture\CatalogProductSimple" /> + <product class="Mtf\Fixture\FixtureInterface" /> <checkoutCart class="Magento\Checkout\Test\Page\CheckoutCart" /> </require> </assertProductInCart> + <assertProductPage module="Magento_Catalog"> + <severeness>low</severeness> + <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" /> + <product class="Mtf\Fixture\FixtureInterface" /> + </assertProductPage> + <assertGroupedPriceOnProductPage module="Magento_Catalog"> + <severeness>low</severeness> + <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" /> + <product class="Mtf\Fixture\FixtureInterface" /> + </assertGroupedPriceOnProductPage> + <assertSpecialPriceOnProductPage module="Magento_Catalog"> + <severeness>low</severeness> + <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" /> + <product class="Mtf\Fixture\FixtureInterface" /> + </assertSpecialPriceOnProductPage> + <assertTierPriceOnProductPage module="Magento_Catalog"> + <severeness>low</severeness> + <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" /> + <product class="Mtf\Fixture\FixtureInterface" /> + </assertTierPriceOnProductPage> + <assertCustomOptionsOnProductPage module="Magento_Catalog"> + <severeness>low</severeness> + <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" /> + <product class="Mtf\Fixture\FixtureInterface" /> + </assertCustomOptionsOnProductPage> + <assertProductForm module="Magento_Catalog"> + <severeness>low</severeness> + <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" /> + <product class="Mtf\Fixture\FixtureInterface" /> + </assertProductForm> + <assertAddToCartButtonAbsent module="Magento_Catalog"> + <severeness>low</severeness> + <require> + </require> + </assertAddToCartButtonAbsent> + <assertAddToCartButtonPresent module="Magento_Catalog"> + <severeness>low</severeness> + <require> + </require> + </assertAddToCartButtonPresent> </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 2da82fdd737cb..05f1ac8cb595d 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 @@ -169,4 +169,9 @@ <input_prefix>product</input_prefix> </data_config> </catalogProductGrouped> + <catalogCategoryEntity module="Magento_Catalog"> + <type>flat</type> + <entity_type>catalog_category_entity</entity_type> + <collection>Magento\Catalog\Model\Resource\Category\Collection</collection> + </catalogCategoryEntity> </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 8dae4a2d026da..6fb0c3f0a4de2 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 @@ -29,4 +29,24 @@ <area>adminhtml</area> <class>Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex</class> </catalogProductIndex> + <catalogProductNew> + <mca>catalog/product/new</mca> + <area>adminhtml</area> + <class>Magento\Catalog\Test\Page\Adminhtml\CatalogProductNew</class> + </catalogProductNew> + <catalogProductEdit> + <mca>catalog/product/edit</mca> + <area>adminhtml</area> + <class>Magento\Catalog\Test\Page\Adminhtml\CatalogProductEdit</class> + </catalogProductEdit> + <catalogProductViewPage> + <mca>catalog/product/view</mca> + <area>product</area> + <class>Magento\Catalog\Test\Page\Product\CatalogProductView</class> + </catalogProductViewPage> + <catalogCategoryView> + <mca>catalog/category/view</mca> + <area>category</area> + <class>Magento\Catalog\Test\Page\Category\CatalogCategoryView</class> + </catalogCategoryView> </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 0e68574feb801..8b5a513031685 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 @@ -35,7 +35,6 @@ /** * Class Cart * Shopping cart block - * */ class Cart extends Block { @@ -88,12 +87,23 @@ public function getCartItemSubTotal($product) return $this->_rootElement->find($selector, Locator::SELECTOR_XPATH)->getText(); } + /** + * Get sub-total for the specified item in the cart by product name + * + * @param string $productName + * @return string + */ + public function getCartItemSubTotalByProductName($productName) + { + $selector = '//tr[normalize-space(td)="' . $productName . '"]' . $this->itemSubTotalSelector; + return $this->_rootElement->find($selector, Locator::SELECTOR_XPATH)->getText(); + } + /** * Get unit price for the specified item in the cart * * @param Product $product * @param string $currency - * * @return float */ public function getCartItemUnitPrice($product, $currency = '$') @@ -113,7 +123,7 @@ public function getCartItemUnitPrice($product, $currency = '$') * Get product options in the cart * * @param Product $product - * @return array|string + * @return string */ public function getCartItemOptions($product) { @@ -127,6 +137,40 @@ public function getCartItemOptions($product) return $optionsBlock->getText(); } + /** + * Get product options value in the cart by product name + * + * @param string $productName + * @return string + */ + public function getCartItemOptionsNameByProductName($productName) + { + $selector = '//tr[string(td/div/strong/a)="' . $productName . '"]//dl[@class="cart item options"]//dt'; + + $optionsBlock = $this->_rootElement->find($selector, Locator::SELECTOR_XPATH); + if (!$optionsBlock->isVisible()) { + return ''; + } + return $optionsBlock->getText(); + } + + /** + * Get product options value in the cart by product name + * + * @param string $productName + * @return string + */ + public function getCartItemOptionsValueByProductName($productName) + { + $selector = '//tr[string(td/div/strong/a)="' . $productName . '"]//dl[@class="cart item options"]//dd'; + + $optionsBlock = $this->_rootElement->find($selector, Locator::SELECTOR_XPATH); + if (!$optionsBlock->isVisible()) { + return ''; + } + return $optionsBlock->getText(); + } + /** * Get proceed to checkout block * @@ -141,6 +185,8 @@ public function getOnepageLinkBlock() /** * Press 'Check out with PayPal' button + * + * @return void */ public function paypalCheckout() { @@ -170,6 +216,8 @@ public function getDiscountTotal() /** * Clear shopping cart + * + * @return void */ public function clearShoppingCart() { diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Page/CheckoutCart.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Page/CheckoutCart.php index 09a1fb34b02b6..93aaab1e0e27e 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Page/CheckoutCart.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Page/CheckoutCart.php @@ -85,7 +85,7 @@ public function getCartBlock() * * @return Messages */ - public function getMessageBlock() + public function getMessagesBlock() { return Factory::getBlockFactory()->getMagentoCoreMessages( $this->_browser->find('.messages .messages', Locator::SELECTOR_CSS) 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 87209ae47c0c9..bb5ac47b01c9a 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 @@ -24,139 +24,101 @@ namespace Magento\Cms\Test\Page; -use Mtf\Page\Page; -use Mtf\Factory\Factory; -use Mtf\Client\Element\Locator; +use Mtf\Page\FrontendPage; /** * Class CmsIndex - * Home page for frontend * + * @package Magento\Cms\Test\Page */ -class CmsIndex extends Page +class CmsIndex extends FrontendPage { - /** - * URL for home page - */ const MCA = 'cms/index/index'; - /** - * Search block - * - * @var string - */ - protected $searchBlock = '#search_mini_form'; - - /** - * Top menu navigation block - * - * @var string - */ - protected $topmenuBlock = '[role=navigation]'; - - /** - * Page title block - * - * @var string - */ - protected $titleBlock = '.page.title'; - - /** - * Footer block - * - * @var string - */ - protected $footerBlock = 'footer.footer'; - - /** - * Page Top Links block - * - * @var string - */ - protected $linksBlock = '.header .links'; - - /** - * Store switcher block path - */ - private $storeSwitcherBlock = '//*[@data-ui-id="language-switcher"]'; - - /** - * Custom constructor - */ - protected function _init() - { - $this->_url = $_ENV['app_frontend_url']; - } + protected $_blocks = [ + 'searchBlock' => [ + 'name' => 'searchBlock', + 'class' => 'Magento\Catalog\Test\Block\Search', + 'locator' => '#search_mini_form', + 'strategy' => 'css selector', + ], + 'topmenu' => [ + 'name' => 'topmenu', + 'class' => 'Magento\Theme\Test\Block\Html\Topmenu', + 'locator' => '[role=navigation]', + 'strategy' => 'css selector', + ], + 'titleBlock' => [ + 'name' => 'titleBlock', + 'class' => 'Magento\Theme\Test\Block\Html\Title', + 'locator' => '.page.title', + 'strategy' => 'css selector', + ], + 'footerBlock' => [ + 'name' => 'footerBlock', + 'class' => 'Magento\Theme\Test\Block\Html\Footer', + 'locator' => 'footer.footer', + 'strategy' => 'css selector', + ], + 'linksBlock' => [ + 'name' => 'linksBlock', + 'class' => 'Magento\Theme\Test\Block\Links', + 'locator' => '.header .links', + 'strategy' => 'css selector', + ], + 'storeSwitcherBlock' => [ + 'name' => 'storeSwitcherBlock', + 'class' => 'Magento\Store\Test\Block\Switcher', + 'locator' => '[data-ui-id="language-switcher"]', + 'strategy' => 'css selector', + ], + ]; /** - * Get the search block - * * @return \Magento\Catalog\Test\Block\Search */ public function getSearchBlock() { - return Factory::getBlockFactory()->getMagentoCatalogSearch( - $this->_browser->find($this->searchBlock, Locator::SELECTOR_CSS) - ); + return $this->getBlockInstance('searchBlock'); } /** - * Get category title block - * * @return \Magento\Theme\Test\Block\Html\Topmenu */ public function getTopmenu() { - return Factory::getBlockFactory()->getMagentoThemeHtmlTopmenu( - $this->_browser->find($this->topmenuBlock, Locator::SELECTOR_CSS) - ); + return $this->getBlockInstance('topmenu'); } /** - * Get title block - * * @return \Magento\Theme\Test\Block\Html\Title */ public function getTitleBlock() { - return Factory::getBlockFactory()->getMagentoThemeHtmlTitle( - $this->_browser->find($this->titleBlock, Locator::SELECTOR_CSS) - ); + return $this->getBlockInstance('titleBlock'); } /** - * Get footer block - * * @return \Magento\Theme\Test\Block\Html\Footer */ public function getFooterBlock() { - return Factory::getBlockFactory()->getMagentoThemeHtmlFooter( - $this->_browser->find($this->footerBlock, Locator::SELECTOR_CSS) - ); + return $this->getBlockInstance('footerBlock'); } /** - * Get Top Links block - * * @return \Magento\Theme\Test\Block\Links */ public function getLinksBlock() { - return Factory::getBlockFactory()->getMagentoThemeLinks( - $this->_browser->find($this->linksBlock, Locator::SELECTOR_CSS) - ); + return $this->getBlockInstance('linksBlock'); } /** - * Get store switcher - * * @return \Magento\Store\Test\Block\Switcher */ public function getStoreSwitcherBlock() { - return Factory::getBlockFactory()->getMagentoStoreSwitcher( - $this->_browser->find($this->storeSwitcherBlock, Locator::SELECTOR_XPATH) - ); + return $this->getBlockInstance('storeSwitcherBlock'); } } 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 new file mode 100644 index 0000000000000..a28d9698d8828 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Cms/Test/Page/CmsIndex.xml @@ -0,0 +1,63 @@ +<?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/index/index"> + <block> + <name>searchBlock</name> + <class>Magento\Catalog\Test\Block\Search</class> + <locator>#search_mini_form</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>topmenu</name> + <class>Magento\Theme\Test\Block\Html\Topmenu</class> + <locator>[role=navigation]</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>titleBlock</name> + <class>Magento\Theme\Test\Block\Html\Title</class> + <locator>.page.title</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>footerBlock</name> + <class>Magento\Theme\Test\Block\Html\Footer</class> + <locator>footer.footer</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>linksBlock</name> + <class>Magento\Theme\Test\Block\Links</class> + <locator>.header .links</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>storeSwitcherBlock</name> + <class>Magento\Store\Test\Block\Switcher</class> + <locator>//*[@data-ui-id="language-switcher"]</locator> + <strategy>css selector</strategy> + </block> +</page> diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Super/Attribute.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Super/Attribute.php index 327063cec2575..d01ea227cc65c 100644 --- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Super/Attribute.php +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Super/Attribute.php @@ -31,7 +31,6 @@ /** * Class Attribute * Attribute block in Variation section - * */ class Attribute extends Block { 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 03c6023a915de..0a5f9f8a3099f 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 @@ -31,7 +31,6 @@ /** * Class Variations * Adminhtml catalog super product configurable tab - * */ class Config extends Tab { @@ -61,7 +60,7 @@ class Config extends Tab * * @var string */ - protected $loader = '[data-role=loader]'; + protected $loader = './ancestor::body//*[contains(@data-role,"loader")]'; /** * Attribute Opened @@ -75,7 +74,7 @@ class Config extends Tab * * @var string */ - protected $attributeTab = '//*[@data-role="configurable-attribute"]//*[text()="%attributeTab%"]'; + protected $attributeTab = './/*[@data-role="configurable-attribute"]//*[text()="%attributeTab%"]'; /** * Get attribute block @@ -111,19 +110,18 @@ protected function getMatrixBlock() */ public function generateVariations() { - $browser = $this->_rootElement; - $browser->find($this->generateVariations, Locator::SELECTOR_CSS)->click(); - $this->waitForElementVisible($this->matrixBlock); + $this->_rootElement->find($this->generateVariations, Locator::SELECTOR_CSS)->click(); + $this->waitForElementVisible($this->matrixBlock, Locator::SELECTOR_CSS); } /** * Fill variations fieldset * * @param array $fields - * @param Element $element + * @param Element|null $element * @return $this */ - public function fillFormTab(array $fields, Element $element) + public function fillFormTab(array $fields, Element $element = null) { if (!isset($fields['configurable_attributes_data'])) { return $this; diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Super/Config/Matrix.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Super/Config/Matrix.php index f7f62a664b2a4..60f6e94fbde69 100644 --- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Super/Config/Matrix.php +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Super/Config/Matrix.php @@ -31,7 +31,6 @@ /** * Class Matrix * Product variations matrix block - * */ class Matrix extends Form { @@ -39,6 +38,7 @@ class Matrix extends Form * Fill qty to current variations * * @param array $variations + * @return void */ public function fillVariation(array $variations) { @@ -60,7 +60,7 @@ public function fillVariation(array $variations) * Define row that clarifies which line in Current Variations grid will be used * * @param array $variationData - * @return Element + * @return string */ private function getVariationRow(array $variationData) { 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 index 8dd63b07b65e1..ea902660a7da4 100644 --- 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,18 +28,18 @@ use Mtf\Client\Element; use Mtf\Client\Browser; use Mtf\Factory\Factory; +use Mtf\Util\XmlConverter; +use Mtf\Block\BlockFactory; use Mtf\Client\Element\Locator; use Mtf\Fixture\FixtureInterface; use Magento\Catalog\Test\Fixture\Product; use Magento\Catalog\Test\Fixture\Category; use Magento\Backend\Test\Block\Widget\Tab; use Magento\Backend\Test\Block\Widget\FormTabs; -use Mtf\Util\XmlConverter; /** * Class ProductForm * Product creation form - * */ class ProductForm extends FormTabs { @@ -128,6 +128,8 @@ class ProductForm extends FormTabs protected $advancedTabPanel = '[role="tablist"] [role="tabpanel"][aria-expanded="true"]:not("overflow")'; /** + * Category fixture + * * @var Category */ protected $category; @@ -143,16 +145,18 @@ class ProductForm extends FormTabs * @param Element $element * @param Mapper $mapper * @param XmlConverter $xmlConverter + * @param BlockFactory $blockFactory * @param Browser $browser */ public function __construct( Element $element, Mapper $mapper, XmlConverter $xmlConverter, + BlockFactory $blockFactory, Browser $browser ) { $this->browser = $browser; - parent::__construct($element, $mapper, $xmlConverter); + parent::__construct($element, $mapper, $blockFactory, $xmlConverter); } /** @@ -181,7 +185,10 @@ public function getConfigurableAttributeEditBlock() } /** + * Initialization categories before use in the form of + * * @param Category $category + * @return void */ public function setCategory(Category $category) { @@ -192,7 +199,7 @@ public function setCategory(Category $category) * Fill the product form * * @param FixtureInterface $fixture - * @param Element $element + * @param Element|null $element * @return $this */ public function fill(FixtureInterface $fixture, Element $element = null) diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Backend/Product/AffectedAttributeSet.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Backend/Product/AffectedAttributeSet.php index 8febd8571095c..53fa7fbd1b592 100644 --- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Backend/Product/AffectedAttributeSet.php +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Backend/Product/AffectedAttributeSet.php @@ -32,7 +32,6 @@ /** * Class AffectedAttributeSet * Choose affected attribute set dialog popup window - * */ class AffectedAttributeSet extends Block { diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Backend/Product/Attribute/Edit.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Backend/Product/Attribute/Edit.php index ca9aa487fc4fe..81a2926052b8f 100644 --- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Backend/Product/Attribute/Edit.php +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Backend/Product/Attribute/Edit.php @@ -24,15 +24,13 @@ namespace Magento\ConfigurableProduct\Test\Block\Backend\Product\Attribute; -use Magento\ConfigurableProduct\Test\Fixture\CatalogProductConfigurable; -use Mtf\Fixture\FixtureInterface; use Mtf\Client\Element; use Magento\Backend\Test\Block\Widget\Form; -use Mtf\Factory\Factory; +use Magento\ConfigurableProduct\Test\Fixture\CatalogProductConfigurable; /** + * Class Edit * Product attribute edit page - * */ class Edit extends Form { @@ -66,6 +64,8 @@ class Edit extends Form /** * Open frontend properties + * + * @return void */ public function openFrontendProperties() { @@ -74,6 +74,8 @@ public function openFrontendProperties() /** * Save attribute + * + * @return void */ public function saveAttribute() { @@ -83,9 +85,10 @@ public function saveAttribute() /** * Fill attribute options * - * @param $data + * @param array $data + * @return void */ - public function fillAttributeOption($data) + public function fillAttributeOption(array $data) { $this->_rootElement->find('#attribute_label') ->setValue($data['attribute_options']['attribute_label']); 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 index 612f3d535c1eb..70953f1bde5b6 100644 --- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableInCart.php +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableInCart.php @@ -24,10 +24,9 @@ namespace Magento\ConfigurableProduct\Test\Constraint; -use Magento\Catalog\Test\Page\Product\CatalogProductView; -use Magento\Checkout\Test\Page\CheckoutCart; use Mtf\Constraint\AbstractConstraint; -use Magento\Catalog\Test\Page\Category\CatalogCategoryView; +use Magento\Checkout\Test\Page\CheckoutCart; +use Magento\Catalog\Test\Page\Product\CatalogProductView; use Magento\ConfigurableProduct\Test\Fixture\CatalogProductConfigurable; /** @@ -43,9 +42,12 @@ class AssertConfigurableInCart extends AbstractConstraint protected $severeness = 'low'; /** + * Assert configurable product, corresponds to the product in the cart + * * @param CatalogProductView $catalogProductView * @param CatalogProductConfigurable $configurable * @param CheckoutCart $checkoutCart + * @return void */ public function processAssert( CatalogProductView $catalogProductView, @@ -57,10 +59,10 @@ public function processAssert( $catalogProductView->open(); $productOptions = $configurable->getConfigurableOptions(); if ($productOptions) { - $configurableOption = $catalogProductView->getOptionsBlock(); - $options = $configurableOption->getProductCustomOptions(); + $configurableOption = $catalogProductView->getCustomOptionsBlock(); + $options = $configurableOption->getOptions(); $key = $productOptions['value']['label']['value']; - $configurableOption->selectProductCustomOption($options[$key][1]); + $configurableOption->selectProductCustomOption(reset($options[$key]['value'])); } $catalogProductView->getViewBlock()->clickAddToCart(); @@ -72,6 +74,7 @@ public function processAssert( * * @param CatalogProductConfigurable $configurable * @param CheckoutCart $checkoutCart + * @return void */ protected function assertOnShoppingCart(CatalogProductConfigurable $configurable, CheckoutCart $checkoutCart) { diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableInCategory.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableInCategory.php index af0866f3aeb8b..52dabb996b5e9 100644 --- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableInCategory.php +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableInCategory.php @@ -43,10 +43,13 @@ class AssertConfigurableInCategory extends AbstractConstraint protected $severeness = 'low'; /** + * Assert configurable product, corresponds to the category page + * * @param CatalogCategoryView $catalogCategoryView * @param CmsIndex $cmsIndex * @param CatalogProductConfigurable $configurable * @param Category $category + * @return void */ public function processAssert( CatalogCategoryView $catalogCategoryView, @@ -67,6 +70,7 @@ public function processAssert( * * @param CatalogProductConfigurable $configurable * @param CatalogCategoryView $catalogCategoryView + * @return void */ protected function assertPrice( CatalogProductConfigurable $configurable, @@ -100,8 +104,8 @@ protected function assertPrice( $price = $catalogCategoryView->getListProductBlock() ->getProductPriceBlock($configurable->getName()) ->getPrice(); - \PHPUnit_Framework_Assert::assertContains( - (string)$price, + \PHPUnit_Framework_Assert::assertEquals( + '$' . $price['price_regular_price'], $pricePresetData['category_price'], 'Product price on category page is not correct.' ); diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableInGrid.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableInGrid.php index 455e55dfb681c..a127b5bfe5fb2 100644 --- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableInGrid.php +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableInGrid.php @@ -25,12 +25,11 @@ namespace Magento\ConfigurableProduct\Test\Constraint; use Mtf\Constraint\AbstractConstraint; -use Magento\ConfigurableProduct\Test\Fixture\CatalogProductConfigurable; use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex; +use Magento\ConfigurableProduct\Test\Fixture\CatalogProductConfigurable; /** * Class AssertConfigurableInGrid - * */ class AssertConfigurableInGrid extends AbstractConstraint { @@ -42,24 +41,26 @@ class AssertConfigurableInGrid extends AbstractConstraint protected $severeness = 'high'; /** - * Assert product availability in Products Grid + * Assert product availability in products grid * - * @param CatalogProductConfigurable $configurable + * @param CatalogProductConfigurable $product * @param CatalogProductIndex $productPageGrid * @return void */ - public function processAssert(CatalogProductConfigurable $configurable, CatalogProductIndex $productPageGrid) + public function processAssert(CatalogProductConfigurable $product, CatalogProductIndex $productPageGrid) { - $filter = ['sku' => $configurable->getSku()]; + $filter = ['sku' => $product->getSku()]; $productPageGrid->open(); \PHPUnit_Framework_Assert::assertTrue( $productPageGrid->getProductGrid()->isRowVisible($filter), - 'Product with sku \'' . $configurable->getSku() . '\' is absent in Products grid.' + 'Product with sku \'' . $product->getSku() . '\' is absent in Products grid.' ); } /** - * @inheritdoc + * Returns a string representation of the object. + * + * @return string */ public function toString() { diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableView.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableView.php index ce11af86f4265..6a047a0f2ea08 100644 --- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableView.php +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableView.php @@ -24,10 +24,8 @@ namespace Magento\ConfigurableProduct\Test\Constraint; -use Magento\Catalog\Test\Page\Product\CatalogProductView; -use Magento\Checkout\Test\Page\CheckoutCart; use Mtf\Constraint\AbstractConstraint; -use Magento\Catalog\Test\Page\Category\CatalogCategoryView; +use Magento\Catalog\Test\Page\Product\CatalogProductView; use Magento\ConfigurableProduct\Test\Fixture\CatalogProductConfigurable; /** @@ -43,8 +41,11 @@ class AssertConfigurableView extends AbstractConstraint protected $severeness = 'low'; /** + * Assert configurable product, corresponds to the product page + * * @param CatalogProductView $catalogProductView * @param CatalogProductConfigurable $configurable + * @return void */ public function processAssert( CatalogProductView $catalogProductView, @@ -63,6 +64,7 @@ public function processAssert( * * @param CatalogProductConfigurable $configurable * @param CatalogProductView $catalogProductView + * @return void */ protected function assertOnProductView( CatalogProductConfigurable $configurable, @@ -87,11 +89,14 @@ protected function assertOnProductView( 'Product special price on product view page is not correct.' ); } else { - $price = $catalogProductView->getViewBlock()->getProductPriceBlock()->getPrice(); - \PHPUnit_Framework_Assert::assertContains( - (string)$price, + //Price verification + $price = $catalogProductView->getViewBlock() + ->getProductPriceBlock($configurable->getName()) + ->getPrice(); + \PHPUnit_Framework_Assert::assertEquals( + '$' . $price['price_regular_price'], $pricePresetData['product_price'], - 'Product price on product view page is not correct.' + 'Product price on category page is not correct.' ); } } 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 e97c27b63d50d..3edae23277f7c 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 @@ -96,7 +96,7 @@ public function __construct( 'is_required' => '0', 'default_value' => '', 'input' => 'text', - 'fixture' => 'Magento\Catalog\Test\Fixture\CategoryIds' + 'source' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\CategoryIds' ]; protected $color = [ @@ -194,7 +194,7 @@ public function __construct( 'default_value' => '', 'input' => 'text', 'group' => 'advanced-pricing', - 'fixture' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\GroupPriceOptions' + 'source' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\GroupPriceOptions' ]; protected $has_options = [ @@ -357,7 +357,7 @@ public function __construct( 'default_value' => '', 'input' => 'price', 'group' => 'product-details', - 'fixture' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\Price' + 'source' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\Price' ]; protected $quantity_and_stock_status = [ @@ -482,7 +482,7 @@ public function __construct( 'default_value' => '', 'input' => 'text', 'group' => 'advanced-pricing', - 'fixture' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\TierPriceOptions' + 'source' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\TierPriceOptions' ]; protected $updated_at = [ @@ -559,7 +559,7 @@ public function __construct( 'backend_type' => 'virtual', 'is_required' => '0', 'group' => 'customer-options', - 'fixture' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\CustomOptions', + 'source' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\CustomOptions', ]; protected $configurable_options = [ @@ -568,7 +568,7 @@ public function __construct( 'is_required' => '0', 'input' => 'variations', 'group' => 'product-details', - 'fixture' => 'Magento\ConfigurableProduct\Test\Fixture\CatalogProductConfigurable\ConfigurableOptions', + 'source' => 'Magento\ConfigurableProduct\Test\Fixture\CatalogProductConfigurable\ConfigurableOptions', ]; protected $attribute_options = [ @@ -577,7 +577,7 @@ public function __construct( 'is_required' => '0', 'input' => 'variations', 'group' => 'product-details', - 'fixture' => 'Magento\ConfigurableProduct\Test\Fixture\CatalogProductConfigurable\AttributeOptions', + 'source' => 'Magento\ConfigurableProduct\Test\Fixture\CatalogProductConfigurable\AttributeOptions', ]; public function getCategoryIds() 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 index 72f6331c95729..0562cf4341d63 100644 --- 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 @@ -26,9 +26,9 @@ use Mtf\TestCase\Injectable; use Magento\Catalog\Test\Fixture\Category; -use Magento\ConfigurableProduct\Test\Fixture\CatalogProductConfigurable; -use Magento\Catalog\Test\Page\Product\CatalogProductNew; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductNew; use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex; +use Magento\ConfigurableProduct\Test\Fixture\CatalogProductConfigurable; /** * Test Coverage for CreateConfigurableProductEntity @@ -46,16 +46,22 @@ class CreateConfigurableEntityTest extends Injectable { /** + * Category fixture + * * @var Category */ protected $category; /** + * Backend catalog page (product grid) + * * @var CatalogProductIndex */ protected $productPageGrid; /** + * Product page (product form) + * * @var CatalogProductNew */ protected $newProductPage; @@ -89,19 +95,21 @@ public function __inject( } /** + * Run create configurable product test + * * @param CatalogProductConfigurable $configurable * @param Category $category + * @return void */ public function testCreate(CatalogProductConfigurable $configurable, Category $category) { // Steps $this->productPageGrid->open(); $this->productPageGrid->getProductBlock()->addProduct('configurable'); - - $productBlockForm = $this->newProductPage->getConfigurableBlockForm(); - + // Fill form + $productBlockForm = $this->newProductPage->getConfigurableProductForm(); $productBlockForm->setCategory($category); $productBlockForm->fill($configurable); - $productBlockForm->save($configurable); + $this->newProductPage->getFormAction()->saveProduct($this->newProductPage, $configurable); } } diff --git a/dev/tests/functional/tests/app/Magento/Core/Test/Block/Messages.php b/dev/tests/functional/tests/app/Magento/Core/Test/Block/Messages.php index 51c9f99e6dc4c..b1319eceb45a6 100644 --- a/dev/tests/functional/tests/app/Magento/Core/Test/Block/Messages.php +++ b/dev/tests/functional/tests/app/Magento/Core/Test/Block/Messages.php @@ -40,6 +40,13 @@ class Messages extends Block */ protected $successMessage = '[data-ui-id$=message-success]'; + /** + * Message link + * + * @var string + */ + protected $messageLink = "//a[contains(.,'%s')]"; + /** * Error message selector. * @@ -87,6 +94,36 @@ public function getErrorMessages() ->getText(); } + /** + * Click on link in the messages which are present on the page + * + * @param string $messageType + * @param string $linkText + * @return void + */ + public function clickLinkInMessages($messageType, $linkText) + { + if ($this->isVisibleMessage($messageType)) { + $this->_rootElement + ->find($this->{$messageType . 'Message'}, Locator::SELECTOR_CSS) + ->find(sprintf($this->messageLink, $linkText), Locator::SELECTOR_XPATH) + ->click(); + } + } + + /** + * Check is visible messages + * + * @param string $messageType + * @return bool + */ + public function isVisibleMessage($messageType) + { + return $this->_rootElement + ->find($this->{$messageType . 'Message'}, Locator::SELECTOR_CSS) + ->isVisible(); + } + /** * Check for error message * diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Account/Menu.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Account/Links.php similarity index 71% rename from dev/tests/functional/tests/app/Magento/Customer/Test/Block/Account/Menu.php rename to dev/tests/functional/tests/app/Magento/Customer/Test/Block/Account/Links.php index 56bd1d430a451..b3163a3227b64 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Account/Menu.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Account/Links.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) */ @@ -29,23 +28,26 @@ use Mtf\Client\Element\Locator; /** - * Menu block - * + * Class Links + * Links block on customer account page */ -class Menu extends Block +class Links extends Block { /** - * Address book link selector + * XPath locator for account navigation on customer page * * @var string */ - protected $addressBook = '//li/a[text()[normalize-space()="Address Book"]]'; + protected $menuItem = '//*[contains(@class,"item")]/a[contains(.,"%s")]'; /** - * Click on address book menu item + * Select link in menu + * + * @param string $link + * @return void */ - public function goToAddressBook() + public function openMenuItem($link) { - $this->_rootElement->find($this->addressBook, Locator::SELECTOR_XPATH)->click(); + $this->_rootElement->find(sprintf($this->menuItem, $link), Locator::SELECTOR_XPATH)->click(); } } diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/Form.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/Form.php index 0d4c89a9b2bea..4b0170c6b5d22 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/Form.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/Form.php @@ -26,6 +26,7 @@ use Mtf\Fixture\FixtureInterface; use Magento\Backend\Test\Block\Widget\FormTabs; +use Mtf\Fixture\InjectableFixture; /** * Class Form @@ -43,8 +44,10 @@ class Form extends FormTabs */ public function fillCustomer(FixtureInterface $customer, $address = null) { - parent::fill($customer); - + $isHasData = ($customer instanceof InjectableFixture) ? $customer->hasData() : true; + if ($isHasData) { + parent::fill($customer); + } if (null !== $address) { $this->openTab('addresses'); $this->getTabElement('addresses')->fillAddresses($address); @@ -54,21 +57,42 @@ public function fillCustomer(FixtureInterface $customer, $address = null) } /** - * Verify Customer information, addresses on tabs. + * Update Customer forms on tabs by customer, addresses data + * + * @param FixtureInterface $customer + * @param FixtureInterface|FixtureInterface[]|null $address + * @return $this + */ + public function updateCustomer(FixtureInterface $customer, $address = null) + { + $isHasData = ($customer instanceof InjectableFixture) ? $customer->hasData() : true; + if ($isHasData) { + parent::fill($customer); + } + if (null !== $address) { + $this->openTab('addresses'); + $this->getTabElement('addresses')->updateAddresses($address); + } + + return $this; + } + + /** + * Get data of Customer information, addresses on tabs. * * @param FixtureInterface $customer * @param FixtureInterface|FixtureInterface[]|null $address - * @return bool + * @return array */ - public function verifyCustomer(FixtureInterface $customer, $address = null) + public function getDataCustomer(FixtureInterface $customer, $address = null) { - $isVerify = parent::verify($customer); + $data = ['customer' => $customer->hasData() ? parent::getData($customer) : parent::getData()]; if (null !== $address) { $this->openTab('addresses'); - $isVerify = $isVerify && $this->getTabElement('addresses')->verifyAddresses($address); + $data['addresses'] = $this->getTabElement('addresses')->getDataAddresses($address); } - return $isVerify; + return $data; } } diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/Form.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/Form.xml index 2ca9a0395044c..d2b2bf419058d 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/Form.xml +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/Form.xml @@ -36,6 +36,9 @@ <group_id> <input>select</input> </group_id> + <firstname/> + <lastname/> + <email/> <gender> <input>select</input> </gender> diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/Tab/Addresses.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/Tab/Addresses.php index 7293761596a61..9bee1e823f4d2 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/Tab/Addresses.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/Tab/Addresses.php @@ -27,6 +27,7 @@ use Mtf\Client\Element; use Mtf\Client\Element\Locator; use Mtf\Fixture\FixtureInterface; +use Magento\Customer\Test\Fixture\AddressInjectable; use Magento\Backend\Test\Block\Widget\Tab; /** @@ -50,48 +51,115 @@ class Addresses extends Tab */ protected $customerAddress = '//*[@id="address_list"]/li[%d]/a'; + /** + * Magento loader + * + * @var string + */ + protected $loader = '//ancestor::body/div[@data-role="loader"]'; + /** * Fill customer addresses * - * @param FixtureInterface|FixtureInterface[]|null $address + * @param FixtureInterface|FixtureInterface[] $address * @return $this */ public function fillAddresses($address) { - if (null !== $address) { - $addresses = is_array($address) ? $address : [$address]; - - foreach ($addresses as $address) { - if ($address->hasData()) { - $this->addNewAddress(); - $this->fillFormTab($address->getData(), $this->_rootElement); - } + $addresses = is_array($address) ? $address : [$address]; + foreach ($addresses as $address) { + $this->addNewAddress(); + + /* Fix switch between region_id and region */ + /** @var AddressInjectable $address */ + $countryId = $address->getCountryId(); + if ($countryId && $this->mapping['country_id']) { + $this->_fill($this->dataMapping(['country_id' => $countryId])); + $this->waitForElementNotVisible($this->loader, Locator::SELECTOR_XPATH); } + + $this->fillFormTab($address->getData(), $this->_rootElement); } return $this; } /** - * Verify customer addresses + * Update customer addresses + * + * @param FixtureInterface|FixtureInterface[] $address + * @return $this + * @throws \Exception + */ + public function updateAddresses($address) + { + $addresses = is_array($address) ? $address : [1 => $address]; + foreach ($addresses as $addressNumber => $address) { + /* Throw exception if isn't exist previous customer address. */ + if (1 < $addressNumber && !$this->isVisibleCustomerAddress($addressNumber - 1)) { + throw new \Exception("Invalid argument: can't update customer address #{$addressNumber}"); + } + + if (!$this->isVisibleCustomerAddress($addressNumber)) { + $this->addNewAddress(); + } + $this->openCustomerAddress($addressNumber); + + /* Fix switch between region_id and region */ + /** @var AddressInjectable $address */ + $countryId = $address->getCountryId(); + if ($countryId && $this->mapping['country_id']) { + $this->_fill($this->dataMapping(['country_id' => $countryId])); + $this->waitForElementNotVisible($this->loader, Locator::SELECTOR_XPATH); + } + $this->fillFormTab($address->getData(), $this->_rootElement); + } + + return $this; + } + + /** + * Get data of Customer addresses * * @param FixtureInterface|FixtureInterface[]|null $address - * @return bool + * @return array + * @throws \Exception */ - public function verifyAddresses($address) + public function getDataAddresses($address = null) { + $data = []; $addresses = is_array($address) ? $address : [1 => $address]; foreach ($addresses as $addressNumber => $address) { - if ($address->hasData()) { + $isHasData = (null === $address) || $address->hasData(); + $isVisibleCustomerAddress = $this->isVisibleCustomerAddress($addressNumber); + + if ($isHasData && !$isVisibleCustomerAddress) { + throw new \Exception("Invalid argument: can't get data from customer address #{$addressNumber}"); + } + + if (!$isHasData && !$isVisibleCustomerAddress) { + $data[$addressNumber] = []; + } else { $this->openCustomerAddress($addressNumber); - if (!$this->verifyFormTab($address->getData(), $this->_rootElement)) { - return false; - } + $data[$addressNumber] = $this->getData($address, $this->_rootElement); } } - return true; + return $data; + } + + /** + * Get data to fields on tab + * + * @param array|null $fields + * @param Element|null $element + * @return array + */ + public function getDataFormTab($fields = null, Element $element = null) + { + /* Skip get data for standard method. Use getDataAddresses. */ + return []; } /** @@ -120,4 +188,19 @@ protected function openCustomerAddress($addressNumber) } $addressTab->click(); } + + /** + * Check is visible customer address + * + * @param int $addressNumber + * @return bool + */ + protected function isVisibleCustomerAddress($addressNumber) + { + $addressTab = $this->_rootElement->find( + sprintf($this->customerAddress, $addressNumber), + Locator::SELECTOR_XPATH + ); + return $addressTab->isVisible(); + } } diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/Tab/Addresses.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/Tab/Addresses.xml index bc7fe100f89e2..0dad9cbefbe0d 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/Tab/Addresses.xml +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/Tab/Addresses.xml @@ -25,14 +25,30 @@ --> <mapping strict="0"> <fields> + <prefix> + <selector>#address_form_container [aria-hidden="false"] [name^="address"][name$="[prefix]"]</selector> + <strategy>css selector</strategy> + </prefix> <firstname> <selector>#address_form_container [aria-hidden="false"] [name^="address"][name$="[firstname]"]</selector> <strategy>css selector</strategy> </firstname> + <middlename> + <selector>#address_form_container [aria-hidden="false"] [name^="address"][name$="[middlename]"]</selector> + <strategy>css selector</strategy> + </middlename> <lastname> <selector>#address_form_container [aria-hidden="false"] [name^="address"][name$="[lastname]"]</selector> <strategy>css selector</strategy> </lastname> + <suffix> + <selector>#address_form_container [aria-hidden="false"] [name^="address"][name$="[suffix]"]</selector> + <strategy>css selector</strategy> + </suffix> + <company> + <selector>#address_form_container [aria-hidden="false"] [name^="address"][name$="[company]"]</selector> + <strategy>css selector</strategy> + </company> <street> <selector>#address_form_container [aria-hidden="false"] [name^="address"][name$="[street][0]"]</selector> <strategy>css selector</strategy> @@ -51,6 +67,10 @@ <selector>#address_form_container [aria-hidden="false"] [name^="address"][name$="[region_id]"]</selector> <strategy>css selector</strategy> </region_id> + <region> + <selector>#address_form_container [aria-hidden="false"] [name^="address"][name$="[region]"]</selector> + <strategy>css selector</strategy> + </region> <postcode> <selector>#address_form_container [aria-hidden="false"] [name^="address"][name$="[postcode]"]</selector> <strategy>css selector</strategy> @@ -59,5 +79,13 @@ <selector>#address_form_container [aria-hidden="false"] [name^="address"][name$="[telephone]"]</selector> <strategy>css selector</strategy> </telephone> + <fax> + <selector>#address_form_container [aria-hidden="false"] [name^="address"][name$="[fax]"]</selector> + <strategy>css selector</strategy> + </fax> + <vat_id> + <selector>#address_form_container [aria-hidden="false"] [name^="address"][name$="[vat_id]"]</selector> + <strategy>css selector</strategy> + </vat_id> </fields> </mapping> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab/SpecialOption.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Group/CustomerGroupGrid.php similarity index 68% rename from dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab/SpecialOption.php rename to dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Group/CustomerGroupGrid.php index 6a985b014869f..c34b09d69dc75 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab/SpecialOption.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Group/CustomerGroupGrid.php @@ -22,26 +22,26 @@ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ -namespace Magento\Catalog\Test\Block\Adminhtml\Product\Edit\AdvancedPricingTab; +namespace Magento\Customer\Test\Block\Adminhtml\Group; -use Mtf\Client\Element; -use Mtf\Client\Element\Locator; -use Mtf\Block\Block; +use Magento\Backend\Test\Block\Widget\Grid; /** - * Select Type + * Class CustomerGroupGrid + * Adminhtml customer group grid + * + * @package Magento\Customer\Test\Block\Adminhtml\Group */ -class SpecialOption extends Block +class CustomerGroupGrid extends Grid { /** - * Fill + * Initialize block elements * - * @param array $data + * @var array $filters */ - public function fill($data) - { - if (isset($data['value'])) { - $this->_rootElement->find('#special_price', Locator::SELECTOR_CSS)->setValue($data['value']); - } - } + protected $filters = [ + 'code' => [ + 'selector' => '#customerGroupGrid_filter_type' + ] + ]; } diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Group/Edit/Form.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Group/Edit/Form.php new file mode 100644 index 0000000000000..1e9fa7036e161 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Group/Edit/Form.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\Customer\Test\Block\Adminhtml\Group\Edit; + +use Magento\Backend\Test\Block\Widget\Form as AbstractForm; + +/** + * Class Form + * Customer group edit form + * + * @package Magento\Customer\Test\Block\Adminhtml\Group\Edit + */ +class Form extends AbstractForm +{ + // +} diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Group/Edit/Form.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Group/Edit/Form.xml new file mode 100644 index 0000000000000..98d30a134b2dc --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Group/Edit/Form.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> + <code /> + <tax_class_id> + <selector>#tax_class_id</selector> + <input>select</input> + </tax_class_id> + <customer_group_code> + <selector>#customer_group_code</selector> + </customer_group_code> + </fields> +</mapping> diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Form/Login.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Form/Login.php index 5b429bdcd7ef4..c9881283b0c01 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Form/Login.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Form/Login.php @@ -27,12 +27,11 @@ use Mtf\Block\Form; use Mtf\Client\Element; use Mtf\Client\Element\Locator; -use Magento\Customer\Test\Fixture\Customer; +use Mtf\Fixture\FixtureInterface; /** * Class Login * Form for frontend login - * */ class Login extends Form { @@ -53,11 +52,11 @@ class Login extends Form /** * Login customer in the Frontend * - * @param Customer $fixture + * @param FixtureInterface $customer */ - public function login(Customer $fixture) + public function login(FixtureInterface $customer) { - $this->fill($fixture); + $this->fill($customer); $this->submit(); $this->waitForElementNotVisible($this->loginButton, Locator::SELECTOR_CSS); } diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerForm.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerForm.php index 9fa15d1de4a8a..ddeb6b47b4aec 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerForm.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerForm.php @@ -31,7 +31,7 @@ use Magento\Customer\Test\Page\Adminhtml\CustomerIndexEdit; /** - * Class AssertCustomerInGrid + * Class AssertCustomerForm * */ class AssertCustomerForm extends AbstractConstraint @@ -43,6 +43,18 @@ class AssertCustomerForm extends AbstractConstraint */ protected $severeness = 'middle'; + /** + * Skipped fields for verify data + * + * @var array + */ + protected $customerSkippedFields = [ + 'id', + 'password', + 'password_confirmation', + 'is_subscribed', + ]; + /** * Assert that displayed customer data on edit page(backend) equals passed from fixture * @@ -50,24 +62,73 @@ class AssertCustomerForm extends AbstractConstraint * @param CustomerIndex $pageCustomerIndex * @param CustomerIndexEdit $pageCustomerIndexEdit * @param AddressInjectable $address [optional] + * @param CustomerInjectable $initialCustomer [optional] * @return void */ public function processAssert( CustomerInjectable $customer, CustomerIndex $pageCustomerIndex, CustomerIndexEdit $pageCustomerIndexEdit, - AddressInjectable $address = null + AddressInjectable $address = null, + CustomerInjectable $initialCustomer = null ) { - $filter = ['email' => $customer->getEmail()]; + $data = []; + $filter = []; + + if ($initialCustomer) { + $data['customer'] = $customer->hasData() + ? array_merge($initialCustomer->getData(), $customer->getData()) + : $initialCustomer->getData(); + } else { + $data['customer'] = $customer->getData(); + } + if ($address) { + $data['addresses'][1] = $address->hasData() ? $address->getData() : []; + } else { + $data['addresses'] = []; + } + $filter['email'] = $data['customer']['email']; $pageCustomerIndex->open(); $pageCustomerIndex->getCustomerGridBlock()->searchAndOpen($filter); + $dataForm = $pageCustomerIndexEdit->getCustomerForm()->getDataCustomer($customer, $address); + $dataDiff = $this->verify($data, $dataForm); \PHPUnit_Framework_Assert::assertTrue( - $pageCustomerIndexEdit->getCustomerForm()->verifyCustomer($customer, $address), + empty($dataDiff), 'Customer data on edit page(backend) not equals to passed from fixture.' + . "\nFailed values: " . implode(', ', $dataDiff) ); } + /** + * Verify data in form equals to passed from fixture + * + * @param array $dataFixture + * @param array $dataForm + * @return array + */ + protected function verify(array $dataFixture, array $dataForm) + { + $result = []; + + $customerDiff = array_diff_assoc($dataFixture['customer'], $dataForm['customer']); + foreach ($customerDiff as $name => $value) { + if (in_array($name, $this->customerSkippedFields)) { + continue; + } + $result[] = "\ncustomer {$name}: \"{$dataForm['customer'][$name]}\" instead of \"{$value}\""; + } + foreach ($dataFixture['addresses'] as $key => $address) { + $addressDiff = array_diff($address, $dataForm['addresses'][$key]); + foreach ($addressDiff as $name => $value) { + $result[] = "\naddress #{$key} {$name}: \"{$dataForm['addresses'][$key][$name]}" + . "\" instead of \"{$value}\""; + } + } + + return $result; + } + /** * Text success verify Customer form * diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerGroupAlreadyExists.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerGroupAlreadyExists.php new file mode 100644 index 0000000000000..469dda30552d1 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerGroupAlreadyExists.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\Adminhtml\CustomerGroupNew; +use Mtf\Constraint\AbstractConstraint; + +/** + * Class AssertCustomerGroupAlreadyExists + * + * @package Magento\Customer\Test\Constraint + */ +class AssertCustomerGroupAlreadyExists extends AbstractConstraint +{ + const SUCCESS_MESSAGE = 'Customer Group already exists.'; + + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Assert that customer group already exist + * + * @param CustomerGroupNew $customerGroupNew + * @return void + */ + public function processAssert(CustomerGroupNew $customerGroupNew) + { + $actualMessage = $customerGroupNew->getMessagesBlock()->getErrorMessages(); + \PHPUnit_Framework_Assert::assertEquals( + self::SUCCESS_MESSAGE, + $actualMessage, + 'Wrong error message is displayed.' + ); + } + + /** + * Success assert of customer group already exist + * + * @return string + */ + public function toString() + { + return 'Customer group already exist.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerGroupInGrid.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerGroupInGrid.php new file mode 100644 index 0000000000000..3cebe3e3c4565 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerGroupInGrid.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\Fixture\CustomerGroupInjectable; +use Magento\Customer\Test\Page\Adminhtml\CustomerGroupIndex; +use Mtf\Constraint\AbstractConstraint; + +/** + * Class AssertCustomerGroupInGrid + */ +class AssertCustomerGroupInGrid extends AbstractConstraint +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Assert that customer group in grid + * + * @param CustomerGroupInjectable $customerGroup + * @param CustomerGroupIndex $customerGroupIndex + * @return void + */ + public function processAssert( + CustomerGroupInjectable $customerGroup, + CustomerGroupIndex $customerGroupIndex + ) { + $customerGroupIndex->open(); + $filter = ['code' => $customerGroup->getCustomerGroupCode()]; + \PHPUnit_Framework_Assert::assertTrue( + $customerGroupIndex->getCustomerGroupGrid()->isRowVisible($filter), + 'Group with type \'' . $customerGroup->getCustomerGroupCode() . '\'is absent in customer groups grid.' + ); + } + + /** + * Success assert of customer group in grid + * + * @return string + */ + public function toString() + { + return 'Customer group in grid.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerGroupNotInGrid.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerGroupNotInGrid.php new file mode 100644 index 0000000000000..46cb28896ae75 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerGroupNotInGrid.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\Fixture\CustomerGroupInjectable; +use Magento\Customer\Test\Page\Adminhtml\CustomerGroupIndex; +use Mtf\Constraint\AbstractConstraint; + +/** + * Class AssertCustomerGroupNotInGrid + */ +class AssertCustomerGroupNotInGrid extends AbstractConstraint +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Assert that customer group not in grid + * + * @param CustomerGroupInjectable $customerGroup + * @param CustomerGroupIndex $customerGroupIndex + * @return void + */ + public function processAssert( + CustomerGroupInjectable $customerGroup, + CustomerGroupIndex $customerGroupIndex + ) { + $customerGroupIndex->open(); + $filter = ['code' => $customerGroup->getCustomerGroupCode()]; + \PHPUnit_Framework_Assert::assertFalse( + $customerGroupIndex->getCustomerGroupGrid()->isRowVisible($filter), + 'Group with name \'' . $customerGroup->getCustomerGroupCode() . '\' in customer groups grid.' + ); + } + + /** + * Success assert of customer group not in grid. + * + * @return string + */ + public function toString() + { + return 'Customer group not in grid.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerGroupOnCustomerForm.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerGroupOnCustomerForm.php new file mode 100644 index 0000000000000..2a61edc9c015f --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerGroupOnCustomerForm.php @@ -0,0 +1,94 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 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\CustomerInjectable; +use Magento\Customer\Test\Page\Adminhtml\CustomerIndex; +use Mtf\Constraint\AbstractConstraint; +use Magento\Customer\Test\Fixture\CustomerGroupInjectable; +use Magento\Customer\Test\Page\Adminhtml\CustomerIndexNew; +use Mtf\Fixture\FixtureFactory; + +/** + * Class AssertCustomerGroupOnCustomerForm + */ +class AssertCustomerGroupOnCustomerForm extends AbstractConstraint +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Assert that customer group find on account information page + * + * @param FixtureFactory $fixtureFactory + * @param CustomerGroupInjectable $customerGroup + * @param CustomerIndexNew $customerIndexNew + * @param CustomerIndex $customerIndex + * @return void + */ + public function processAssert( + FixtureFactory $fixtureFactory, + CustomerGroupInjectable $customerGroup, + CustomerIndexNew $customerIndexNew, + CustomerIndex $customerIndex + ) { + /** @var CustomerInjectable $customer */ + $customer = $fixtureFactory->createByCode( + 'customerInjectable', + [ + 'dataSet' => 'defaultBackend', + 'data' => ['group_id' => $customerGroup->getCustomerGroupCode()] + ] + ); + $filter = ['email' => $customer->getEmail()]; + + $customerIndexNew->open(); + $customerIndexNew->getCustomerForm()->fillCustomer($customer); + $customerIndexNew->getPageActionsBlock()->save(); + $customerIndex->getCustomerGridBlock()->searchAndOpen($filter); + $customerFormData = $customerIndexNew->getCustomerForm()->getData($customer); + $customerFixtureData = $customer->getData(); + $diff = array_diff($customerFixtureData, $customerFormData); + + \PHPUnit_Framework_Assert::assertTrue( + empty($diff), + "Customer group {$customerGroup->getCustomerGroupCode()} not in customer form." + ); + } + + /** + * Success assert of customer group find on account information page + * + * @return string + */ + public function toString() + { + return 'Customer group find on account information page.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerGroupSuccessCreateMessage.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerGroupSuccessCreateMessage.php new file mode 100644 index 0000000000000..dfe1501cb5804 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerGroupSuccessCreateMessage.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\Customer\Test\Constraint; + +use Mtf\Constraint\AbstractConstraint; +use Magento\Customer\Test\Page\Adminhtml\CustomerGroupIndex; + +/** + * Class AssertCustomerGroupSuccessCreateMessage + * + * @package Magento\Customer\Test\Constraint + */ +class AssertCustomerGroupSuccessCreateMessage extends AbstractConstraint +{ + const SUCCESS_MESSAGE = 'The customer group has been saved.'; + + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Assert that success message is displayed after customer group save + * + * @param CustomerGroupIndex $customerGroupIndex + * @return void + */ + public function processAssert(CustomerGroupIndex $customerGroupIndex) + { + $actualMessage = $customerGroupIndex->getMessagesBlock()->getSuccessMessages(); + \PHPUnit_Framework_Assert::assertEquals( + self::SUCCESS_MESSAGE, + $actualMessage, + 'Wrong success message is displayed.' + . "\nExpected: " . self::SUCCESS_MESSAGE + . "\nActual: " . $actualMessage + ); + } + + /** + * Success assert of created customer group success message. + * + * @return string + */ + public function toString() + { + return 'Customer group success save message is present.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerInGrid.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerInGrid.php index 1cf54322d872a..dc229c13a6101 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerInGrid.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerInGrid.php @@ -46,18 +46,29 @@ class AssertCustomerInGrid extends AbstractConstraint * * @param CustomerInjectable $customer * @param CustomerIndex $pageCustomerIndex + * @param CustomerInjectable $initialCustomer [optional] * @return void */ - public function processAssert(CustomerInjectable $customer, CustomerIndex $pageCustomerIndex) - { - $name = ($customer->hasData('prefix') ? $customer->getPrefix() . ' ' : '') - . $customer->getFirstname() - . ($customer->hasData('middlename') ? ' ' . $customer->getMiddlename() : '') - . ' ' . $customer->getLastname() - . ($customer->hasData('suffix') ? ' ' . $customer->getSuffix() : ''); + public function processAssert( + CustomerInjectable $customer, + CustomerIndex $pageCustomerIndex, + CustomerInjectable $initialCustomer = null + ) { + if ($initialCustomer) { + $customer = $customer->hasData() + ? array_merge($initialCustomer->getData(), $customer->getData()) + : $initialCustomer->getData(); + } else { + $customer = $customer->getData(); + } + $name = (isset($customer['prefix']) ? $customer['prefix'] . ' ' : '') + . $customer['firstname'] + . (isset($customer['middlename']) ? ' ' . $customer['middlename'] : '') + . ' ' . $customer['lastname'] + . (isset($customer['suffix']) ? ' ' . $customer['suffix'] : ''); $filter = [ 'name' => $name, - 'email' => $customer->getEmail(), + 'email' => $customer['email'], ]; $pageCustomerIndex->open(); diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerSuccessRegisterMessage.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerSuccessRegisterMessage.php index d7e8defda2d43..8d7a4ecd3ae43 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerSuccessRegisterMessage.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerSuccessRegisterMessage.php @@ -50,7 +50,7 @@ class AssertCustomerSuccessRegisterMessage extends AbstractConstraint */ public function processAssert(CustomerAccountCreate $registerPage) { - $actualMessage = $registerPage->getMessageBlock()->getSuccessMessages(); + $actualMessage = $registerPage->getMessagesBlock()->getSuccessMessages(); \PHPUnit_Framework_Assert::assertEquals( self::SUCCESS_MESSAGE, $actualMessage, diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/CustomerGroup/TaxClassIds.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/CustomerGroup/TaxClassIds.php new file mode 100644 index 0000000000000..838822246a202 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/CustomerGroup/TaxClassIds.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\Customer\Test\Fixture\CustomerGroup; + +use Mtf\Fixture\FixtureFactory; +use Mtf\Fixture\FixtureInterface; + +/** + * Class TaxClass + * @package Magento\Customer\Test\Fixture + */ +class TaxClassIds implements FixtureInterface +{ + /** @var string Data */ + protected $data; + + /** + * @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']) && $data['dataSet'] !== '-') { + $dataSet = $data['dataSet']; + /** @var \Magento\Tax\Test\Fixture\TaxClass $taxClass */ + $taxClass = $fixtureFactory->createByCode('taxClass', ['dataSet' => $dataSet]); + if (!$taxClass->hasData('id')) { + $taxClass->persist(); + } + $this->data = $taxClass->getClassName(); + } + } + + /** + * Persist custom selections products + * + * @return void + */ + public function persist() + { + // + } + + /** + * Return prepared data set + * + * @param $key [optional] + * @return mixed + */ + public function getData($key = null) + { + return $this->data; + } + + /** + * Return data set configuration settings + * + * @return string + */ + public function getDataConfig() + { + return $this->params; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/CustomerGroupInjectable.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/CustomerGroupInjectable.php new file mode 100644 index 0000000000000..07ba892a115e6 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/CustomerGroupInjectable.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\Customer\Test\Fixture; + +use Mtf\Fixture\InjectableFixture; + +/** + * Class CustomerGroupInjectable + */ +class CustomerGroupInjectable extends InjectableFixture +{ + protected $defaultDataSet = [ + 'customer_group_code' => 'customer_code_%isolation%', + 'tax_class_id' => 'Retail Customer', + ]; + + protected $customer_group_code = [ + 'attribute_code' => 'code', + 'backend_type' => 'varchar', + 'is_required' => '1', + 'default_value' => '', + 'input' => 'text', + ]; + + protected $tax_class_id = [ + 'attribute_code' => 'tax_class', + 'backend_type' => 'varchar', + 'is_required' => '1', + 'default_value' => '', + 'input' => 'select', + 'source' => 'Magento\Customer\Test\Fixture\CustomerGroup\TaxClassIds', + ]; + + public function getCustomerGroupCode() + { + return $this->getData('customer_group_code'); + } + + public function getTaxClassId() + { + return $this->getData('tax_class_id'); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/CustomerGroupInjectable.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/CustomerGroupInjectable.xml new file mode 100644 index 0000000000000..7a57153862b0a --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/CustomerGroupInjectable.xml @@ -0,0 +1,47 @@ +<?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\Customer\Test\Fixture\CustomerGroup"> + <module>Magento_Customer</module> + <type>flat</type> + <entity_type>customer_group</entity_type> + <collection>Magento\Customer\Model\Resource\Group\Collection</collection> + <fields> + <customer_group_code> + <attribute_code>code</attribute_code> + <backend_type>varchar</backend_type> + <is_required>1</is_required> + <default_value>customer_code_%isolation%</default_value> + <input>text</input> + </customer_group_code> + <tax_class_id> + <attribute_code>tax_class</attribute_code> + <backend_type>varchar</backend_type> + <is_required>1</is_required> + <default_value>Retail Customer</default_value> + <input>select</input> + </tax_class_id> + </fields> +</fixture> 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 81aad2818c74f..cbeb35f7767d5 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 @@ -28,7 +28,7 @@ /** * Class CustomerInjectable - * + * Customer fixture */ class CustomerInjectable extends InjectableFixture { @@ -46,6 +46,8 @@ class CustomerInjectable extends InjectableFixture 'firstname' => 'John', 'lastname' => 'Doe', 'email' => 'John.Doe%isolation%@example.com', + 'password' => '123123q', + 'password_confirmation' => '123123q', ]; protected $confirmation = [ @@ -200,6 +202,7 @@ class CustomerInjectable extends InjectableFixture 'is_required' => '1', 'default_value' => '', 'input' => 'select', + 'group' => 'account_information', ]; protected $suffix = [ 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 d644d70feca04..439a6cb0d5d27 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 @@ -165,6 +165,7 @@ <is_required>1</is_required> <default_value></default_value> <input>select</input> + <group>account_information</group> </store_id> <suffix> <attribute_code>suffix</attribute_code> @@ -203,6 +204,5 @@ <backend_type>virtual</backend_type> </password_confirmation> </fields> - <repository_class>Magento\Customer\Test\Repository\CustomerInjectable</repository_class> <handler_interface>Magento\Customer\Test\Handler\CustomerInjectable\CustomerInjectableInterface</handler_interface> </fixture> diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Handler/CustomerInjectable/Curl.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Handler/CustomerInjectable/Curl.php new file mode 100644 index 0000000000000..ee6b0900557dd --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Handler/CustomerInjectable/Curl.php @@ -0,0 +1,101 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 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\Handler\CustomerInjectable; + +use Mtf\System\Config; +use Mtf\Handler\Curl as AbstractCurl; +use Mtf\Util\Protocol\CurlInterface; +use Mtf\Util\Protocol\CurlTransport; +use Mtf\Util\Protocol\CurlTransport\BackendDecorator; +use Mtf\Fixture\FixtureInterface; +use Magento\Customer\Test\Fixture\CustomerInjectable; + +/** + * Class Curl + * Curl handler for creating customer through registration page. + */ +class Curl extends AbstractCurl implements CustomerInjectableInterface +{ + /** + * Post request for creating customer in frontend + * + * @param FixtureInterface|null $customer + * @return array + * @throws \Exception + */ + public function persist(FixtureInterface $customer = null) + { + /** @var CustomerInjectable $customer */ + $url = $_ENV['app_frontend_url'] . 'customer/account/createpost/?nocookie=true'; + $data = $customer->getData(); + $curl = new CurlTransport(); + + $curl->write(CurlInterface::POST, $url, '1.0', array(), $data); + $response = $curl->read(); + $curl->close(); + if (!strpos($response, 'data-ui-id="global-messages-message-success"')) { + throw new \Exception("Customer entity creating by curl handler was not successful! Response: $response"); + } + + return ['id' => $this->getCustomerId($customer->getEmail())]; + } + + /** + * Get customer id by email + * + * @param string $email + * @return int|null + */ + protected function getCustomerId($email) + { + $filter = ['email' => $email]; + $url = $_ENV['app_backend_url'] . 'customer/index/grid/filter/' . $this->encodeFilter($filter); + $curl = new BackendDecorator(new CurlTransport(), new Config()); + + $curl->write(CurlInterface::GET, $url, '1.0'); + $response = $curl->read(); + $curl->close(); + + preg_match('/data-column="entity_id"[^>]*>\s*([0-9]+)\s*</', $response, $match); + return empty($match[1]) ? null : $match[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/Customer/Test/Handler/CustomerInjectable/CustomerInjectableInterface.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Handler/CustomerInjectable/CustomerInjectableInterface.php new file mode 100644 index 0000000000000..e7218de7541d7 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Handler/CustomerInjectable/CustomerInjectableInterface.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\Customer\Test\Handler\CustomerInjectable; + +use Mtf\Handler\HandlerInterface; + +/** + * Interface CustomerInjectableInterface + * + * @package Magento\Customer\Test\Handler\CustomerInjectable + */ +interface CustomerInjectableInterface extends HandlerInterface +{ + // +} diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Page/Adminhtml/CustomerGroupIndex.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/Adminhtml/CustomerGroupIndex.php new file mode 100644 index 0000000000000..15ce7e19b5b68 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/Adminhtml/CustomerGroupIndex.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\Customer\Test\Page\Adminhtml; + +use Mtf\Page\BackendPage; + +/** + * Class CustomerGroupIndex + * + * @package Magento\Customer\Test\Page\Adminhtml + */ +class CustomerGroupIndex extends BackendPage +{ + const MCA = 'customer/group/index'; + + protected $_blocks = [ + 'messagesBlock' => [ + 'name' => 'messagesBlock', + 'class' => 'Magento\Core\Test\Block\Messages', + 'locator' => '#messages .messages', + 'strategy' => 'css selector', + ], + 'gridPageActions' => [ + 'name' => 'gridPageActions', + 'class' => 'Magento\Backend\Test\Block\GridPageActions', + 'locator' => '.page-main-actions', + 'strategy' => 'css selector', + ], + 'customerGroupGrid' => [ + 'name' => 'customerGroupGrid', + 'class' => 'Magento\Customer\Test\Block\Adminhtml\Group\CustomerGroupGrid', + 'locator' => '#customerGroupGrid', + 'strategy' => 'css selector', + ], + ]; + + /** + * @return \Magento\Core\Test\Block\Messages + */ + public function getMessagesBlock() + { + return $this->getBlockInstance('messagesBlock'); + } + + /** + * @return \Magento\Backend\Test\Block\GridPageActions + */ + public function getGridPageActions() + { + return $this->getBlockInstance('gridPageActions'); + } + + /** + * @return \Magento\Customer\Test\Block\Adminhtml\Group\CustomerGroupGrid + */ + public function getCustomerGroupGrid() + { + return $this->getBlockInstance('customerGroupGrid'); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Page/Adminhtml/CustomerGroupIndex.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/Adminhtml/CustomerGroupIndex.xml new file mode 100644 index 0000000000000..f3b4512fc8dac --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/Adminhtml/CustomerGroupIndex.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="customer/group/index"> + <block> + <name>messagesBlock</name> + <class>Magento\Core\Test\Block\Messages</class> + <locator>#messages .messages</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>customerGroupGrid</name> + <class>Magento\Customer\Test\Block\Adminhtml\Group\CustomerGroupGrid</class> + <locator>#customerGroupGrid</locator> + <strategy>css selector</strategy> + </block> +</page> diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Page/Adminhtml/CustomerGroupNew.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/Adminhtml/CustomerGroupNew.php new file mode 100644 index 0000000000000..4e69b6f77d5ee --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/Adminhtml/CustomerGroupNew.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\Customer\Test\Page\Adminhtml; + +use Mtf\Page\BackendPage; + +/** + * Class CustomerGroupNew + * + * @package Magento\Customer\Test\Page\Adminhtml + */ +class CustomerGroupNew extends BackendPage +{ + const MCA = 'customer/group/new'; + + protected $_blocks = [ + 'pageMainActions' => [ + 'name' => 'pageMainActions', + 'class' => 'Magento\Backend\Test\Block\FormPageActions', + 'locator' => '.page-main-actions', + 'strategy' => 'css selector', + ], + 'pageMainForm' => [ + 'name' => 'pageMainForm', + 'class' => 'Magento\Customer\Test\Block\Adminhtml\Group\Edit\Form', + '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\FormPageActions + */ + public function getPageMainActions() + { + return $this->getBlockInstance('pageMainActions'); + } + + /** + * @return \Magento\Customer\Test\Block\Adminhtml\Group\Edit\Form + */ + public function getPageMainForm() + { + return $this->getBlockInstance('pageMainForm'); + } + + /** + * @return \Magento\Core\Test\Block\Messages + */ + public function getMessagesBlock() + { + return $this->getBlockInstance('messagesBlock'); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Page/Adminhtml/CustomerGroupNew.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/Adminhtml/CustomerGroupNew.xml new file mode 100644 index 0000000000000..17794ef92a6d6 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/Adminhtml/CustomerGroupNew.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="customer/group/new" > + <block> + <name>pageMainActions</name> + <class>Magento\Backend\Test\Block\FormPageActions</class> + <locator>.page-main-actions</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>pageMainForm</name> + <class>Magento\Customer\Test\Block\Adminhtml\Group\Edit\Form</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/Customer/Test/Page/CustomerAccountCreate.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAccountCreate.php index 0f0ddda8ecba0..767b36ee76280 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAccountCreate.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAccountCreate.php @@ -41,8 +41,8 @@ class CustomerAccountCreate extends FrontendPage 'locator' => '#form-validate', 'strategy' => 'css selector', ], - 'messageBlock' => [ - 'name' => 'messageBlock', + 'messagesBlock' => [ + 'name' => 'messagesBlock', 'class' => 'Magento\Core\Test\Block\Messages', 'locator' => '.page.messages', 'strategy' => 'css selector', @@ -60,8 +60,8 @@ public function getRegisterForm() /** * @return \Magento\Core\Test\Block\Messages */ - public function getMessageBlock() + public function getMessagesBlock() { - return $this->getBlockInstance('messageBlock'); + return $this->getBlockInstance('messagesBlock'); } } diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAccountCreate.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAccountCreate.xml index 62e0f9fa87c0a..bfa92b466f367 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAccountCreate.xml +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAccountCreate.xml @@ -31,7 +31,7 @@ <strategy>css selector</strategy> </block> <block> - <name>messageBlock</name> + <name>messagesBlock</name> <class>Magento\Core\Test\Block\Messages</class> <locator>.page.messages</locator> <strategy>css selector</strategy> 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 214582417afda..ca68f19c111f3 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 @@ -25,99 +25,74 @@ namespace Magento\Customer\Test\Page; -use Mtf\Page\Page; -use Mtf\Factory\Factory; +use Mtf\Page\FrontendPage; /** - * Frontend Customer Dashboard page - * + * Class CustomerAccountIndex + * Page of customer account */ -class CustomerAccountIndex extends Page +class CustomerAccountIndex extends FrontendPage { - /** - * URL for customer Dashboard - */ const MCA = 'customer/account/index'; - /** - * Messages block - * - * @var string - */ - protected $messagesBlock = '.page.messages'; - - /** - * Address Book block - * - * @var string - */ - protected $dashboardAddressBlock = '.block.dashboard.addresses'; - - /** - * Dashboard title - * - * @var string - */ - protected $titleBlock = '.page.title'; - - /** - * Account menu selector - * - * @var string - */ - protected $accountMenuSelector = '.nav.items'; + protected $_blocks = [ + 'messages' => [ + 'name' => 'messages', + 'class' => 'Magento\Core\Test\Block\Messages', + 'locator' => '.page.messages', + 'strategy' => 'css selector', + ], + 'dashboardAddress' => [ + 'name' => 'dashboardAddress', + 'class' => 'Magento\Customer\Test\Block\Account\Dashboard\Address', + 'locator' => '.block.dashboard.addresses', + 'strategy' => 'css selector', + ], + 'titleBlock' => [ + 'name' => 'titleBlock', + 'class' => 'Magento\Theme\Test\Block\Html\Title', + 'locator' => '.page.title', + 'strategy' => 'css selector', + ], + 'accountMenuBlock' => [ + 'name' => 'accountMenuBlock', + 'class' => 'Magento\Customer\Test\Block\Account\Links', + 'locator' => '.nav.items', + 'strategy' => 'css selector', + ], + ]; /** - * Custom constructor - */ - protected function _init() - { - $this->_url = $_ENV['app_frontend_url'] . self::MCA; - } - - /** - * Get Messages block - * * @return \Magento\Core\Test\Block\Messages */ public function getMessages() { - return Factory::getBlockFactory()->getMagentoCoreMessages($this->_browser->find($this->messagesBlock)); + return $this->getBlockInstance('messages'); } /** - * Get Address Book block - * * @return \Magento\Customer\Test\Block\Account\Dashboard\Address */ public function getDashboardAddress() { - return Factory::getBlockFactory()->getMagentoCustomerAccountDashboardAddress( - $this->_browser->find($this->dashboardAddressBlock) - ); + return $this->getBlockInstance('dashboardAddress'); } /** - * Get title block - * * @return \Magento\Theme\Test\Block\Html\Title */ public function getTitleBlock() { - return $this->titleBlock = Factory::getBlockFactory()->getMagentoThemeHtmlTitle( - $this->_browser->find($this->titleBlock) - ); + return $this->getBlockInstance('titleBlock'); } /** * Get Account Menu Block * - * @return \Magento\Customer\Test\Block\Account\Menu + * @return \Magento\Customer\Test\Block\Account\Links */ public function getAccountMenuBlock() { - return Factory::getBlockFactory()->getMagentoCustomerAccountMenu( - $this->_browser->find($this->accountMenuSelector) - ); + return $this->getBlockInstance('accountMenuBlock'); } } 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 new file mode 100644 index 0000000000000..08a8c094a0f90 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAccountIndex.xml @@ -0,0 +1,51 @@ +<?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/index"> + <block> + <name>messages</name> + <class>Magento\Core\Test\Block\Messages</class> + <locator>.page.messages</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>dashboardAddress</name> + <class>Magento\Customer\Test\Block\Account\Dashboard\Address</class> + <locator>.block.dashboard.addresses</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>titleBlock</name> + <class>Magento\Theme\Test\Block\Html\Title</class> + <locator>.page.title</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>accountMenuBlock</name> + <class>Magento\Customer\Test\Block\Account\Links</class> + <locator>.nav.items</locator> + <strategy>css selector</strategy> + </block> +</page> 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 new file mode 100644 index 0000000000000..52c1ff5f2958c --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Repository/CustomerInjectable.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\Customer\Test\Repository; + +use Mtf\Repository\AbstractRepository; + +/** + * Class CustomerInjectable + * + * @package Magento\Customer\Test\Repository + */ +class CustomerInjectable extends AbstractRepository +{ + /** + * @param array $defaultConfig + * @param array $defaultData + */ + public function __construct(array $defaultConfig = [], array $defaultData = []) + { + $this->_data['default'] = [ + 'firstname' => 'John', + 'lastname' => 'Doe', + 'email' => 'JohnDoe_%isolation%@example.com', + 'password' => '123123q', + 'password_confirmation' => '123123q', + ]; + + $this->_data['defaultBackend'] = [ + 'firstname' => 'John', + 'lastname' => 'Doe', + 'email' => 'JohnDoe_%isolation%@example.com', + ]; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerBackendEntityTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerBackendEntityTest.php index 11e8172516647..f91e3aa20d3d7 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerBackendEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerBackendEntityTest.php @@ -78,6 +78,9 @@ public function __inject( */ public function testCreateCustomerBackendEntity(CustomerInjectable $customer, AddressInjectable $address) { + // Prepare data + $address = $address->hasData() ? $address : null; + // Steps $this->pageCustomerIndex->open(); $this->pageCustomerIndex->getPageActionsBlock()->addNew(); diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerGroupEntityTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerGroupEntityTest.php new file mode 100644 index 0000000000000..601698b4bf8f6 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerGroupEntityTest.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\Customer\Test\TestCase; + +use Magento\Customer\Test\Fixture\CustomerGroupInjectable; +use Magento\Customer\Test\Page\Adminhtml\CustomerGroupIndex; +use Magento\Customer\Test\Page\Adminhtml\CustomerGroupNew; +use Mtf\TestCase\Injectable; + +/** + * Test Creation for CreateCustomerGroupEntity + * + * Test Flow: + * 1.Log in to backend as admin user. + * 2.Navigate to Stores>Other Settings>Customer Groups. + * 3.Start to create new Customer Group. + * 4.Fill in all data according to data set. + * 5.Click "Save Customer Group" button. + * 6.Perform all assertions. + * + * @group Customer_Groups_(MX) + * @ZephyrId MAGETWO-23422 + */ +class CreateCustomerGroupEntityTest extends Injectable +{ + /** + * Customer group index + * + * @var CustomerGroupIndex + */ + protected $customerGroupIndex; + + /** + * New customer group + * + * @var CustomerGroupNew + */ + protected $customerGroupNew; + + /** + * @param CustomerGroupIndex $customerGroupIndex + * @param CustomerGroupNew $customerGroupNew + */ + public function __inject( + CustomerGroupIndex $customerGroupIndex, + CustomerGroupNew $customerGroupNew + ) { + $this->customerGroupIndex = $customerGroupIndex; + $this->customerGroupNew = $customerGroupNew; + } + + /** + * Create customer group + * + * @param CustomerGroupInjectable $customerGroup + */ + public function testCreateCustomerGroup( + CustomerGroupInjectable $customerGroup + ) { + //Steps + $this->customerGroupIndex->open(); + $this->customerGroupIndex->getGridPageActions()->addNew(); + $this->customerGroupNew->getPageMainForm()->fill($customerGroup); + $this->customerGroupNew->getPageMainActions()->save(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerGroupEntityTest/testCreateCustomerGroup.csv b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerGroupEntityTest/testCreateCustomerGroup.csv new file mode 100644 index 0000000000000..1bc43c1efba0d --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerGroupEntityTest/testCreateCustomerGroup.csv @@ -0,0 +1,4 @@ +"customerGroup/data/tax_class_id/dataSet";"customerGroup/data/customer_group_code";"constraint" +"Retail Customer";"GroupName%isolation%";"assertCustomerGroupSuccessCreateMessage, assertCustomerGroupInGrid, assertCustomerGroupOnCustomerForm" +"Retail Customer";"General ";"assertCustomerGroupAlreadyExists, assertCustomerGroupNotInGrid" +"customer_tax_class";"GroupName%isolation%";"assertCustomerGroupSuccessCreateMessage, assertCustomerGroupInGrid, assertCustomerGroupOnCustomerForm" diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateOnFrontendTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateOnFrontendTest.php index 7036103082bd9..7b02a957ed642 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateOnFrontendTest.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateOnFrontendTest.php @@ -26,6 +26,8 @@ use Mtf\Factory\Factory; use Mtf\TestCase\Functional; +use Magento\Customer\Test\Fixture\Address; +use Magento\Customer\Test\Block\Address\Edit as AddressEditForm; /** * Create Customer on frontend and set default billing address @@ -75,6 +77,29 @@ public function testCreateCustomer() $accountIndexPage->open(); $accountIndexPage->getDashboardAddress()->editBillingAddress(); $addressEditPage = Factory::getPageFactory()->getCustomerAddressEdit(); - $this->assertTrue($addressEditPage->getEditForm()->verify($customerAddress)); + $this->verifyCustomerAddress($customerAddress, $addressEditPage->getEditForm()); + } + + /** + * Verify that customer address is equals data on form + * + * @param Address $address + * @param AddressEditForm $form + * @return bool + */ + protected function verifyCustomerAddress(Address $address, AddressEditForm $form) + { + $dataAddress = $address->getData(); + $preparedDataAddress = []; + + foreach ($dataAddress['fields'] as $key => $field) { + $preparedDataAddress[$key] = $field['value']; + } + + $dataDiff = array_diff($preparedDataAddress, $form->getData($address)); + $this->assertTrue( + empty($dataDiff), + 'Customer addresses data on edit page(backend) not equals to passed from fixture.' + ); } } diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerBackendEntityTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerBackendEntityTest.php new file mode 100644 index 0000000000000..90f8fdcb51555 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerBackendEntityTest.php @@ -0,0 +1,93 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 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 Mtf\TestCase\Injectable; +use Magento\Customer\Test\Page\Adminhtml\CustomerIndex; +use Magento\Customer\Test\Page\Adminhtml\CustomerIndexEdit; +use Magento\Customer\Test\Fixture\AddressInjectable; +use Magento\Customer\Test\Fixture\CustomerInjectable; + +/** + * Test Creation for UpdateCustomerBackendEntity + * + * General Flow: + * 1. Login to backend as admin + * 2. Navigate to CUSTOMERS->All Customers + * 3. Open from grid test customer + * 4. Edit some values, if addresses fields are not presented click 'Add New Address' button + * 5. Click 'Save' button + * 6. Perform all assertions + * + * @ticketId MAGETWO-23881 + */ +class UpdateCustomerBackendEntityTest extends Injectable +{ + /** + * @var CustomerIndex + */ + protected $customerIndexPage; + + /** + * @var CustomerIndexEdit + */ + protected $customerIndexEditPage; + + /** + * @param CustomerIndex $customerIndexPage + * @param CustomerIndexEdit $customerIndexEditPage + */ + public function __inject( + CustomerIndex $customerIndexPage, + CustomerIndexEdit $customerIndexEditPage + ) { + $this->customerIndexPage = $customerIndexPage; + $this->customerIndexEditPage = $customerIndexEditPage; + } + + /** + * @param CustomerInjectable $initialCustomer + * @param CustomerInjectable $customer + * @param AddressInjectable $address + */ + public function testUpdateCustomerBackendEntity( + CustomerInjectable $initialCustomer, + CustomerInjectable $customer, + AddressInjectable $address + ) { + // Prepare data + $address = $address->hasData() ? $address : null; + + // Preconditions: + $initialCustomer->persist(); + + // Steps + $filter = ['email' => $initialCustomer->getEmail()]; + $this->customerIndexPage->open(); + $this->customerIndexPage->getCustomerGridBlock()->searchAndOpen($filter); + $this->customerIndexEditPage->getCustomerForm()->updateCustomer($customer, $address); + $this->customerIndexEditPage->getPageActionsBlock()->save(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerBackendEntityTest/testUpdateCustomerBackendEntity.csv b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerBackendEntityTest/testUpdateCustomerBackendEntity.csv new file mode 100644 index 0000000000000..6fd1ba7c220b3 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerBackendEntityTest/testUpdateCustomerBackendEntity.csv @@ -0,0 +1,4 @@ +"initialCustomer/dataSet";"customer/data/group_id";"customer/data/prefix";"customer/data/firstname";"customer/data/middlename";"customer/data/lastname";"customer/data/suffix";"customer/data/email";"customer/data/dob";"customer/data/taxvat";"customer/data/gender";"address/data/prefix";"address/data/firstname";"address/data/middlename";"address/data/lastname";"address/data/suffix";"address/data/company";"address/data/street";"address/data/city";"address/data/country_id";"address/data/region_id";"address/data/region";"address/data/postcode";"address/data/telephone";"address/data/fax";"address/data/vat_id";"constraint" +"default";"Wholesale";"%isolation%Prefix_";"John_%isolation%";"Middle Name %isolation%";"Doe%isolation%";"_Suffix%isolation%";"JohnDoe%isolation%@example.com";1/8/1986;123456789001;"Male";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"assertCustomerSuccessSaveMessage, assertCustomerForm, assertCustomerInGrid" +"default";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"Prefix%isolation%_";"Doe%isolation%";"Middle Name %isolation%";"Doe%isolation%";"_Suffix%isolation%";"Company%isolation%";"3962 Horner Street";"Dothan";"United States";"Alabama";"-";36303;"334-200-4060";"555-666-777-8910";"U1234567890";"assertCustomerSuccessSaveMessage, assertCustomerForm, assertCustomerInGrid" +"default";"Retailer";"%isolation%Prefix_";"Jane_%isolation%";"Jane Middle Name %isolation%";"Doe%isolation%";"_JaneSuffix%isolation%";"Jane%isolation%@example.com";1/12/2000;987654321;"Female";"Prefix%isolation%_";"Doe%isolation%";"Middle Name %isolation%";"Doe%isolation%";"_Suffix%isolation%";"Company%isolation%";"39 Northgate Street";"BICKTON";"United Kingdom";"-";"PINMINNOCH";"KA26 1PF ";"999-777-111-2345";"-";987654321;"assertCustomerSuccessSaveMessage, assertCustomerForm, assertCustomerInGrid" diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/etc/curl/di.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/etc/curl/di.xml new file mode 100644 index 0000000000000..00a17f9778b4a --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/etc/curl/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/Magento/Framework/ObjectManager/etc/config.xsd"> + <preference for="Magento\Customer\Test\Handler\CustomerInjectable\CustomerInjectableInterface" + type="\Magento\Customer\Test\Handler\CustomerInjectable\Curl"/> +</config> 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 cb41b4f3d0b70..68b0d80fe8be6 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 @@ -43,6 +43,14 @@ <pageCustomerIndex class="Magento\Customer\Test\Page\Adminhtml\CustomerIndex" /> </require> </assertCustomerInGrid> + <assertUpdateCustomerInGrid module="Magento_Customer"> + <severeness>middle</severeness> + <require> + <preconditionCustomer class="Magento\Customer\Test\Fixture\CustomerInjectable" /> + <customer class="Magento\Customer\Test\Fixture\CustomerInjectable" /> + <pageCustomerIndex class="Magento\Customer\Test\Page\Adminhtml\CustomerIndex" /> + </require> + </assertUpdateCustomerInGrid> <assertCustomerForm module="Magento_Customer"> <severeness>middle</severeness> <require> @@ -51,6 +59,15 @@ <pageCustomerIndexEdit class="Magento\Customer\Test\Page\Adminhtml\CustomerIndexEdit" /> </require> </assertCustomerForm> + <assertUpdateCustomerForm module="Magento_Customer"> + <severeness>middle</severeness> + <require> + <preconditionCustomer class="Magento\Customer\Test\Fixture\CustomerInjectable" /> + <customer class="Magento\Customer\Test\Fixture\CustomerInjectable" /> + <pageCustomerIndex class="Magento\Customer\Test\Page\Adminhtml\CustomerIndex" /> + <pageCustomerIndexEdit class="Magento\Customer\Test\Page\Adminhtml\CustomerIndexEdit" /> + </require> + </assertUpdateCustomerForm> <assertCustomerInvalidEmail module="Magento_Customer"> <severeness>middle</severeness> <require> @@ -59,4 +76,19 @@ <pageCustomerIndexNew class="Magento\Customer\Test\Page\Adminhtml\CustomerIndexNew" /> </require> </assertCustomerInvalidEmail> + <assertCustomerGroupSuccessCreateMessage module="Magento_Customer"> + <severeness>low</severeness> + </assertCustomerGroupSuccessCreateMessage> + <assertCustomerGroupInGrid module="Magento_Customer"> + <severeness>low</severeness> + </assertCustomerGroupInGrid> + <assertCustomerGroupOnCustomerForm module="Magento_Customer"> + <severeness>low</severeness> + </assertCustomerGroupOnCustomerForm> + <assertCustomerGroupAlreadyExists module="Magento_Customer"> + <severeness>low</severeness> + </assertCustomerGroupAlreadyExists> + <assertCustomerGroupNotInGrid module="Magento_Customer"> + <severeness>low</severeness> + </assertCustomerGroupNotInGrid> </constraint> diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/etc/global/fixture.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/etc/global/fixture.xml index a4576f12fb9ba..4038bc2143996 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/etc/global/fixture.xml +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/etc/global/fixture.xml @@ -49,4 +49,9 @@ <entity_type>customer_address</entity_type> <collection>Magento\Customer\Model\Resource\Address\Collection</collection> </addressInjectable> + <customerGroup module="Magento_Customer"> + <type>flat</type> + <entity_type>customer_group</entity_type> + <collection>Magento\Customer\Model\Resource\Group\Collection</collection> + </customerGroup> </fixture> 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 fb2c506e146a3..968424e9029fb 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 @@ -28,6 +28,10 @@ <mca>customer/account/create</mca> <class>Magento\Customer\Test\Page\CustomerAccountCreate</class> </customerAccountCreate> + <customerAccountIndex> + <mca>customer/account/index</mca> + <class>Magento\Customer\Test\Page\CustomerAccountIndex</class> + </customerAccountIndex> <customerIndex> <mca>customer/index</mca> <area>adminhtml</area> @@ -43,4 +47,14 @@ <area>adminhtml</area> <class>Magento\Customer\Test\Page\Adminhtml\CustomerIndexEdit</class> </customerIndexEdit> + <customerGroupIndex> + <mca>customer/group/index</mca> + <area>adminhtml</area> + <class>Magento\Customer\Test\Page\Adminhtml\CustomerGroupIndex</class> + </customerGroupIndex> + <customerGroupNew> + <mca>customer/group/new</mca> + <area>adminhtml</area> + <class>Magento\Customer\Test\Page\Adminhtml\CustomerGroupNew</class> + </customerGroupNew> </page> diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable.php index 2fa35ecf5c987..5272ddc9cb88f 100644 --- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable.php +++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable.php @@ -47,10 +47,10 @@ class Downloadable extends Tab * Fill downloadable information * * @param array $fields - * @param Element $element + * @param Element|null $element * @return $this */ - public function fillFormTab(array $fields, Element $element) + public function fillFormTab(array $fields, Element $element = null) { if (isset($fields['downloadable'])) { foreach ($fields['downloadable']['link'] as $index => $link) { 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 index 213953b494d5a..274e3a47850a2 100644 --- 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 @@ -21,12 +21,16 @@ * @copyright Copyright (c) 2014 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\TestCase\Create; use Mtf\Factory\Factory; use Mtf\TestCase\Functional; use Magento\Downloadable\Test\Fixture\DownloadableProduct; +/** + * Class LinksPurchasedSeparatelyTest + */ class LinksPurchasedSeparatelyTest extends Functional { /** @@ -49,16 +53,17 @@ protected function setUp() * Creating Downloadable product with required fields only and assign it to the category * * @ZephyrId MAGETWO-13595 + * @return void */ public function test() { $createProductPage = Factory::getPageFactory()->getCatalogProductNew(); $createProductPage->init($this->product); - $productBlockForm = $createProductPage->getProductBlockForm(); + $productForm = $createProductPage->getProductForm(); $createProductPage->open(); - $productBlockForm->fill($this->product); - $productBlockForm->save($this->product); + $productForm->fill($this->product); + $createProductPage->getFormAction()->save(); $createProductPage->getMessagesBlock()->assertSuccessMessage(); @@ -73,6 +78,8 @@ public function test() /** * Assert existing product on admin product grid + * + * @return void */ protected function assertOnBackend() { @@ -84,6 +91,8 @@ protected function assertOnBackend() /** * Assert product data on category and product pages + * + * @return void */ protected function assertOnFrontend() { @@ -101,13 +110,16 @@ protected function assertOnFrontend() $productViewBlock = $productPage->getViewBlock(); $this->assertEquals($product->getProductName(), $productViewBlock->getProductName()); - $this->assertEquals($product->getProductPrice(), $productViewBlock->getProductPrice()); + $price = $productViewBlock->getProductPrice(); + $this->assertEquals(number_format($product->getProductPrice(), 2), $price['price_regular_price']); $productPage->getDownloadableLinksBlock() ->check([['title' => $product->getData('fields/downloadable/link/0/title/value')]]); + + $price = $productViewBlock->getProductPrice(); $this->assertEquals( - (int)$product->getProductPrice() + $product->getData('fields/downloadable/link/0/price/value'), - $productViewBlock->getProductPrice() + number_format($product->getProductPrice() + $product->getData('fields/downloadable/link/0/price/value'), 2), + $price['price_regular_price'] ); } } diff --git a/dev/tests/functional/tests/app/Magento/Search/Test/Block/Catalog/Layer/View.php b/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/Block/Navigation.php similarity index 96% rename from dev/tests/functional/tests/app/Magento/Search/Test/Block/Catalog/Layer/View.php rename to dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/Block/Navigation.php index e2d8cbb7409c2..ad4d80cc3adcd 100644 --- a/dev/tests/functional/tests/app/Magento/Search/Test/Block/Catalog/Layer/View.php +++ b/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/Block/Navigation.php @@ -21,16 +21,15 @@ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ -namespace Magento\Search\Test\Block\Catalog\Layer; +namespace Magento\LayeredNavigation\Test\Block; use Mtf\Block\Block; use Mtf\Client\Element\Locator; /** * Catalog layered navigation view block - * */ -class View extends Block +class Navigation extends Block { /** * 'Clear All' link diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/Block/Adminhtml/Template/FormPageActions.php b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Block/Adminhtml/Template/FormPageActions.php new file mode 100644 index 0000000000000..b4ce7a70876d0 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Block/Adminhtml/Template/FormPageActions.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) + */ + +namespace Magento\Newsletter\Test\Block\Adminhtml\Template; + +use Magento\Backend\Test\Block\FormPageActions as AbstractFormPageActions; + +/** + * Class FormPageActions + * Form page actions block + * + * @package Magento\Newsletter\Test\Block\Adminhtml\Template + */ +class FormPageActions extends AbstractFormPageActions +{ + /** + * "Save" button + * + * @var string + */ + protected $saveButton = "[data-ui-id='page-actions-toolbar-save-button']"; +} diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/Block/Adminhtml/Template/Grid.php b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Block/Adminhtml/Template/Grid.php new file mode 100644 index 0000000000000..d25a5e0cb5b63 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Block/Adminhtml/Template/Grid.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) + */ + +namespace Magento\Newsletter\Test\Block\Adminhtml\Template; + +use Magento\Backend\Test\Block\Widget\Grid as AbstractGrid; + +/** + * Class Grid + * Newsletter templates grid block + * + * @package Magento\Newsletter\Test\Block\Aminhtml\Template + */ +class Grid extends AbstractGrid +{ + /** + * Filters array mapping + * + * @var array $filters + */ + protected $filters = [ + 'code' => [ + 'selector' => '[data-ui-id="widget-grid-column-filter-text-1-filter-code"]' + ] + ]; +} diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/Block/Adminhtml/Template/GridPageActions.php b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Block/Adminhtml/Template/GridPageActions.php new file mode 100644 index 0000000000000..496304b5cc168 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Block/Adminhtml/Template/GridPageActions.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) + */ + +namespace Magento\Newsletter\Test\Block\Adminhtml\Template; + +use Magento\Backend\Test\Block\GridPageActions as AbstractGridPageActions; + +/** + * Class GridPageActions + * Grid page actions block + * + * @package Magento\Newsletter\Test\Block\Adminhtml\Template + */ +class GridPageActions extends AbstractGridPageActions +{ + /** + * "Add New" button + * + * @var string + */ + protected $addNewButton = "[data-ui-id='page-actions-toolbar-add-button']"; +} diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/Constraint/AssertNewsletterInGrid.php b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Constraint/AssertNewsletterInGrid.php new file mode 100644 index 0000000000000..772ae2d0d89a9 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Constraint/AssertNewsletterInGrid.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\Newsletter\Test\Constraint; + +use Magento\Newsletter\Test\Fixture\Template; +use Magento\Newsletter\Test\Page\Adminhtml\TemplateIndex; +use Mtf\Constraint\AbstractConstraint; + +/** + * Class AssertNewsletterInGrid + * + * @package Magento\Newsletter\Test\Constraint + */ +class AssertNewsletterInGrid extends AbstractConstraint +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Assert that newsletter template is present in grid + * + * @param TemplateIndex $templateIndex + * @param Template $template + * @return void + */ + public function processAssert( + TemplateIndex $templateIndex, + Template $template + ) { + $templateIndex->open(); + $filter = ['code' => $template->getCode()]; + \PHPUnit_Framework_Assert::assertTrue( + $templateIndex->getNewsletterTemplateGrid()->isRowVisible($filter), + 'Newsletter \'' . $template->getCode() . '\'is absent in newsletter template grid.' + ); + } + + /** + * Success assert of newsletter template in grid. + * + * @return string + */ + public function toString() + { + return 'Newsletter template is present in grid.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/Constraint/AssertNewsletterSuccessCreateMessage.php b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Constraint/AssertNewsletterSuccessCreateMessage.php new file mode 100644 index 0000000000000..b0d43d9ea562a --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Constraint/AssertNewsletterSuccessCreateMessage.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\Newsletter\Test\Constraint; + +use Magento\Newsletter\Test\Page\Adminhtml\TemplateIndex; +use Mtf\Constraint\AbstractConstraint; + +/** + * Class AssertNewsletterSuccessCreateMessage + * + * @package Magento\Newsletter\Test\Constraint + */ +class AssertNewsletterSuccessCreateMessage extends AbstractConstraint +{ + const SUCCESS_MESSAGE = 'The newsletter template has been saved.'; + + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Assert that success message is displayed after newsletter template save + * + * @param TemplateIndex $templateIndex + */ + public function processAssert(TemplateIndex $templateIndex) + { + $actualMessage = $templateIndex->getMessagesBlock()->getSuccessMessages(); + \PHPUnit_Framework_Assert::assertEquals( + self::SUCCESS_MESSAGE, + $actualMessage, + 'Wrong success message is displayed.' + . "\nExpected: " . self::SUCCESS_MESSAGE + . "\nActual: " . $actualMessage + ); + } + + /** + * Success assert of created newsletter template success message + * + * @return string + */ + public function toString() + { + return 'Newsletter success save message is present.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/Fixture/Template.php b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Fixture/Template.php new file mode 100644 index 0000000000000..8d6b2e95eb654 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Fixture/Template.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\Newsletter\Test\Fixture; + +use Mtf\Fixture\InjectableFixture; + +/** + * Class Template + * + * @package Magento\Newsletter\Test\Fixture + */ +class Template extends InjectableFixture +{ + protected $defaultDataSet = [ + 'code' => 'TemplateName%isolation%', + 'subject' => 'TemplateSubject%isolation%', + 'sender_name' => 'SenderName%isolation%', + 'sender_email' => 'SenderName%isolation%@example.com', + 'text' => 'Some text %isolation%', + ]; + + protected $id = [ + 'attribute_code' => 'template_id', + 'backend_type' => 'int', + 'is_required' => '1', + 'default_value' => '', + 'input' => '', + ]; + + protected $code = [ + 'attribute_code' => 'template_code', + 'backend_type' => 'varchar', + 'is_required' => '', + 'default_value' => '', + 'input' => '', + ]; + + protected $text = [ + 'attribute_code' => 'template_text', + 'backend_type' => 'text', + 'is_required' => '', + 'default_value' => '', + 'input' => '', + ]; + + protected $text_preprocessed = [ + 'attribute_code' => 'template_text_preprocessed', + 'backend_type' => 'text', + 'is_required' => '', + 'default_value' => '', + 'input' => '', + ]; + + protected $styles = [ + 'attribute_code' => 'template_styles', + 'backend_type' => 'text', + 'is_required' => '', + 'default_value' => '', + 'input' => '', + ]; + + protected $type = [ + 'attribute_code' => 'template_type', + 'backend_type' => 'int', + 'is_required' => '', + 'default_value' => '', + 'input' => '', + ]; + + protected $subject = [ + 'attribute_code' => 'template_subject', + 'backend_type' => 'varchar', + 'is_required' => '', + 'default_value' => '', + 'input' => '', + ]; + + protected $sender_name = [ + 'attribute_code' => 'template_sender_name', + 'backend_type' => 'varchar', + 'is_required' => '', + 'default_value' => '', + 'input' => '', + ]; + + protected $sender_email = [ + 'attribute_code' => 'template_sender_email', + 'backend_type' => 'varchar', + 'is_required' => '', + 'default_value' => '', + 'input' => '', + ]; + + protected $actual = [ + 'attribute_code' => 'template_actual', + 'backend_type' => 'smallint', + 'is_required' => '', + 'default_value' => '1', + 'input' => '', + ]; + + protected $added_at = [ + 'attribute_code' => 'added_at', + 'backend_type' => 'timestamp', + 'is_required' => '', + 'default_value' => '', + 'input' => '', + ]; + + protected $modified_at = [ + 'attribute_code' => 'modified_at', + 'backend_type' => 'timestamp', + 'is_required' => '', + 'default_value' => '', + 'input' => '', + ]; + + public function getId() + { + return $this->getData('id'); + } + + public function getCode() + { + return $this->getData('code'); + } + + public function getText() + { + return $this->getData('text'); + } + + public function getTextPreprocessed() + { + return $this->getData('text_preprocessed'); + } + + public function getStyles() + { + return $this->getData('styles'); + } + + public function getType() + { + return $this->getData('type'); + } + + public function getSubject() + { + return $this->getData('subject'); + } + + public function getSenderName() + { + return $this->getData('sender_name'); + } + + public function getSenderEmail() + { + return $this->getData('sender_email'); + } + + public function getActual() + { + return $this->getData('actual'); + } + + public function getAddedAt() + { + return $this->getData('added_at'); + } + + public function getModifiedAt() + { + return $this->getData('modified_at'); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/Fixture/Template.xml b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Fixture/Template.xml new file mode 100644 index 0000000000000..8cbfa452add0d --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Fixture/Template.xml @@ -0,0 +1,118 @@ +<?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\Newsletter\Test\Fixture\Template"> + <module>Magento_Newsletter</module> + <type>flat</type> + <entity_type>newsletter_template</entity_type> + <collection>Magento\Newsletter\Model\Resource\Template\Collection</collection> + <identifier>template_id</identifier> + <fields> + <id> + <attribute_code>template_id</attribute_code> + <backend_type>int</backend_type> + <is_required>1</is_required> + <default_value/> + <input/> + </id> + <code> + <attribute_code>template_code</attribute_code> + <backend_type>varchar</backend_type> + <is_required/> + <default_value/> + <input/> + </code> + <text> + <attribute_code>template_text</attribute_code> + <backend_type>text</backend_type> + <is_required/> + <default_value/> + <input/> + </text> + <text_preprocessed> + <attribute_code>template_text_preprocessed</attribute_code> + <backend_type>text</backend_type> + <is_required/> + <default_value/> + <input/> + </text_preprocessed> + <styles> + <attribute_code>template_styles</attribute_code> + <backend_type>text</backend_type> + <is_required/> + <default_value/> + <input/> + </styles> + <type> + <attribute_code>template_type</attribute_code> + <backend_type>int</backend_type> + <is_required/> + <default_value/> + <input/> + </type> + <subject> + <attribute_code>template_subject</attribute_code> + <backend_type>varchar</backend_type> + <is_required/> + <default_value/> + <input/> + </subject> + <sender_name> + <attribute_code>template_sender_name</attribute_code> + <backend_type>varchar</backend_type> + <is_required/> + <default_value/> + <input/> + </sender_name> + <sender_email> + <attribute_code>template_sender_email</attribute_code> + <backend_type>varchar</backend_type> + <is_required/> + <default_value/> + <input/> + </sender_email> + <actual> + <attribute_code>template_actual</attribute_code> + <backend_type>smallint</backend_type> + <is_required/> + <default_value>1</default_value> + <input/> + </actual> + <added_at> + <attribute_code>added_at</attribute_code> + <backend_type>timestamp</backend_type> + <is_required/> + <default_value/> + <input/> + </added_at> + <modified_at> + <attribute_code>modified_at</attribute_code> + <backend_type>timestamp</backend_type> + <is_required/> + <default_value/> + <input/> + </modified_at> + </fields> +</fixture> diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/Page/Adminhtml/TemplateIndex.php b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Page/Adminhtml/TemplateIndex.php new file mode 100644 index 0000000000000..18a1317adc918 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Page/Adminhtml/TemplateIndex.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\Newsletter\Test\Page\Adminhtml; + +use Mtf\Page\BackendPage; + +/** + * Class TemplateIndex + * + * @package Magento\Newsletter\Test\Page\Adminhtml + */ +class TemplateIndex extends BackendPage +{ + const MCA = 'newsletter/template/index'; + + protected $_blocks = [ + 'messagesBlock' => [ + 'name' => 'messagesBlock', + 'class' => 'Magento\Core\Test\Block\Messages', + 'locator' => '#messages .messages', + 'strategy' => 'css selector', + ], + 'gridPageActions' => [ + 'name' => 'gridPageActions', + 'class' => 'Magento\Newsletter\Test\Block\Adminhtml\Template\GridPageActions', + 'locator' => '.page-main-actions', + 'strategy' => 'css selector', + ], + 'newsletterTemplateGrid' => [ + 'name' => 'newsletterTemplateGrid', + 'class' => 'Magento\Newsletter\Test\Block\Adminhtml\Template\Grid', + 'locator' => '[id="page:main-container"]', + 'strategy' => 'css selector', + ], + ]; + + /** + * @return \Magento\Core\Test\Block\Messages + */ + public function getMessagesBlock() + { + return $this->getBlockInstance('messagesBlock'); + } + + /** + * @return \Magento\Newsletter\Test\Block\Adminhtml\Template\GridPageActions + */ + public function getGridPageActions() + { + return $this->getBlockInstance('gridPageActions'); + } + + /** + * @return \Magento\Newsletter\Test\Block\Adminhtml\Template\Grid + */ + public function getNewsletterTemplateGrid() + { + return $this->getBlockInstance('newsletterTemplateGrid'); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/Page/Adminhtml/TemplateIndex.xml b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Page/Adminhtml/TemplateIndex.xml new file mode 100644 index 0000000000000..72fe1d07e81a4 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Page/Adminhtml/TemplateIndex.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="newsletter/template/index"> + <block> + <name>messagesBlock</name> + <class>Magento\Core\Test\Block\Messages</class> + <locator>#messages .messages</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>gridPageActions</name> + <class>Magento\Newsletter\Test\Block\Adminhtml\Template\GridPageActions</class> + <locator>.page-main-actions</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>newsletterTemplateGrid</name> + <class>Magento\Newsletter\Test\Block\Adminhtml\Template\Grid</class> + <locator>[id="page:main-container"]</locator> + <strategy>css selector</strategy> + </block> +</page> diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/Page/Adminhtml/TemplateNewIndex.php b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Page/Adminhtml/TemplateNewIndex.php new file mode 100644 index 0000000000000..0c266605c9219 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Page/Adminhtml/TemplateNewIndex.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\Newsletter\Test\Page\Adminhtml; + +use Mtf\Page\BackendPage; + +/** + * Class TemplateNewIndex + * + * @package Magento\Newsletter\Test\Page\Adminhtml + */ +class TemplateNewIndex extends BackendPage +{ + const MCA = 'newsletter/template/new/index'; + + protected $_blocks = [ + 'formPageActions' => [ + 'name' => 'formPageActions', + 'class' => 'Magento\Newsletter\Test\Block\Adminhtml\Template\FormPageActions', + 'locator' => '.page-main-actions', + 'strategy' => 'css selector', + ], + 'editForm' => [ + 'name' => 'editForm', + 'class' => 'Magento\Backend\Test\Block\Widget\Form', + 'locator' => '[id="page:main-container"]', + 'strategy' => 'css selector', + ], + 'messagesBlock' => [ + 'name' => 'messagesBlock', + 'class' => 'Magento\Core\Test\Block\Messages', + 'locator' => '#messages', + 'strategy' => 'css selector', + ], + ]; + + /** + * @return \Magento\Newsletter\Test\Block\Adminhtml\Template\FormPageActions + */ + public function getFormPageActions() + { + return $this->getBlockInstance('formPageActions'); + } + + /** + * @return \Magento\Backend\Test\Block\Widget\Form + */ + public function getEditForm() + { + return $this->getBlockInstance('editForm'); + } + + /** + * @return \Magento\Core\Test\Block\Messages + */ + public function getMessagesBlock() + { + return $this->getBlockInstance('messagesBlock'); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/Page/Adminhtml/TemplateNewIndex.xml b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Page/Adminhtml/TemplateNewIndex.xml new file mode 100644 index 0000000000000..0f7231a192d5a --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Page/Adminhtml/TemplateNewIndex.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="newsletter/template/new/index"> + <block> + <name>formPageActions</name> + <class>Magento\Newsletter\Test\Block\Adminhtml\Template\FormPageActions</class> + <locator>.page-main-actions</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>editForm</name> + <class>Magento\Backend\Test\Block\Widget\Form</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/Newsletter/Test/TestCase/CreateNewsletterTemplateEntityTest.php b/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/CreateNewsletterTemplateEntityTest.php new file mode 100644 index 0000000000000..fd132df9ef133 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/CreateNewsletterTemplateEntityTest.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\Newsletter\Test\TestCase; + +use Magento\Newsletter\Test\Fixture\Template; +use Magento\Newsletter\Test\Page\Adminhtml\TemplateIndex; +use Magento\Newsletter\Test\Page\Adminhtml\TemplateNewIndex; +use Mtf\TestCase\Injectable; + +/** + * Test Creation for Create Newsletter Template + * + * Test Flow: + * 1. Login to backend. + * 2. Navigate to MARKETING > Newsletter Template. + * 3. Add New Template. + * 4. Fill in all data according to data set. + * 5. Save. + * 6. Perform asserts. + * + * @group Newsletters_(MX) + * @ZephyrId MAGETWO-23302 + */ +class CreateNewsletterTemplateEntityTest extends Injectable +{ + /** + * Page for create newsletter template + * + * @var TemplateNewIndex + */ + protected $templateNewIndex; + + /** + * Page with newsletter template grid + * + * @var TemplateIndex + */ + protected $templateIndex; + + /** + * Inject newsletter page + * + * @param TemplateIndex $templateIndex + * @param TemplateNewIndex $templateNewIndex + */ + public function __inject( + TemplateIndex $templateIndex, + TemplateNewIndex $templateNewIndex + ) { + $this->templateIndex = $templateIndex; + $this->templateNewIndex = $templateNewIndex; + } + + /** + * Create newsletter template + * + * @param Template $template + */ + public function testCreateNewsletterTemplate(Template $template) + { + // Steps + $this->templateIndex->open(); + $this->templateIndex->getGridPageActions()->addNew(); + $this->templateNewIndex->getEditForm()->fill($template); + $this->templateNewIndex->getFormPageActions()->save(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/CreateNewsletterTemplateEntityTest/testCreateNewsletterTemplate.csv b/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/CreateNewsletterTemplateEntityTest/testCreateNewsletterTemplate.csv new file mode 100644 index 0000000000000..a87a9c80325b7 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/CreateNewsletterTemplateEntityTest/testCreateNewsletterTemplate.csv @@ -0,0 +1,2 @@ +"template/data/code";"template/data/subject";"template/data/sender_name";"template/data/sender_email";"template/data/text";"constraint" +"TemplateName%isolation%";"TemplateSubject%isolation%";"SenderName%isolation%";"SenderName%isolation%@example.com";"Some content %isolation%";"assertNewsletterSuccessCreateMessage, assertNewsletterInGrid" diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/etc/global/constraint.xml b/dev/tests/functional/tests/app/Magento/Newsletter/Test/etc/global/constraint.xml index 1dc7c77bc8d25..9321ac6084220 100644 --- a/dev/tests/functional/tests/app/Magento/Newsletter/Test/etc/global/constraint.xml +++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/etc/global/constraint.xml @@ -24,6 +24,12 @@ */ --> <constraint> + <assertNewsletterSuccessCreateMessage module="Magento_Newsletter"> + <severeness>low</severeness> + </assertNewsletterSuccessCreateMessage> + <assertNewsletterInGrid module="Magento_Newsletter"> + <severeness>low</severeness> + </assertNewsletterInGrid> <assertCustomerIsSubscribedToNewsletter module="Magento_Newsletter"> <severeness>low</severeness> <require> diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/etc/global/fixture.xml b/dev/tests/functional/tests/app/Magento/Newsletter/Test/etc/global/fixture.xml new file mode 100644 index 0000000000000..eefd75a556ba4 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/etc/global/fixture.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) + */ +--> +<fixture> + <template module="Magento_Newsletter"> + <type>flat</type> + <entity_type>newsletter_template</entity_type> + <collection>Magento\Newsletter\Model\Resource\Template\Collection</collection> + <identifier>template_id</identifier> + </template> +</fixture> diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/etc/global/page.xml b/dev/tests/functional/tests/app/Magento/Newsletter/Test/etc/global/page.xml index aeab517713159..a18cb41d5d14a 100644 --- a/dev/tests/functional/tests/app/Magento/Newsletter/Test/etc/global/page.xml +++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/etc/global/page.xml @@ -24,6 +24,16 @@ */ --> <page> + <templateIndex> + <mca>newsletter/template/index</mca> + <area>adminhtml</area> + <class>Magento\Newsletter\Test\Page\Adminhtml\templateIndex</class> + </templateIndex> + <templateNewIndex> + <mca>newsletter/template/new/index</mca> + <area>adminhtml</area> + <class>Magento\Newsletter\Test\Page\Adminhtml\templateNewIndex</class> + </templateNewIndex> <subscriberIndex> <mca>newsletter/subscriber/index</mca> <area>adminhtml</area> diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/ReviewTest.php b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/ReviewTest.php index b54c12f871574..fc05c321c3ddb 100644 --- a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/ReviewTest.php +++ b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/ReviewTest.php @@ -24,6 +24,7 @@ namespace Magento\Review\Test\TestCase; +use Mtf\Block\Form; use Magento\Review\Test\Block\Product\View\Summary; use Magento\Review\Test\Block\Product\View; use Magento\Review\Test\Fixture\Review; @@ -84,14 +85,14 @@ public function testAddReviewByGuest() $this->assertEquals('Guest', $reviewBackendForm->getPostedBy(), 'Review is not posted by Guest'); $this->assertEquals('Pending', $reviewBackendForm->getStatus(), 'Review is not in Pending status'); $this->assertTrue( - $reviewBackendForm->verify($reviewFixture), + $this->verifyReviewBackendForm($reviewFixture, $reviewBackendForm), 'Review data is not corresponds to submitted one' ); $reviewBackendForm->approveReview(); $this->assertContains( 'You saved the review.', - $backendReviewPage->getMessageBlock()->getSuccessMessages(), + $backendReviewPage->getMessagesBlock()->getSuccessMessages(), 'Review is not saved' ); @@ -161,4 +162,22 @@ protected function verifyReview(View $reviewBlock, Review $fixture) ); } } + + /** + * Verify that review is equals to data on form + * + * @param Review $review + * @param Form $form + * @return bool + */ + protected function verifyReviewBackendForm(Review $review, Form $form) + { + $reviewData = []; + foreach ($review->getData()['fields'] as $key => $field) { + $reviewData[$key] = $field['value']; + } + $dataDiff = array_diff($reviewData, $form->getData($review)); + + return empty($dataDiff); + } } diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Edit/Form.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Edit/Form.php index 5bdbcd0db1dd9..fcf5167241896 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Edit/Form.php +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Edit/Form.php @@ -24,88 +24,102 @@ namespace Magento\Tax\Test\Block\Adminhtml\Rule\Edit; +use Magento\Tax\Test\Fixture\TaxRule; +use Mtf\Block\BlockFactory; +use Mtf\Block\Form as FormInterface; +use Mtf\Block\Mapper; +use Mtf\Client\Browser; use Mtf\Client\Element; -use Mtf\Factory\Factory; use Mtf\Client\Element\Locator; use Mtf\Fixture\FixtureInterface; -use Mtf\Block\Form as FormInterface; -use Magento\Tax\Test\Fixture\TaxRule; /** * Class Form * Form for tax rule creation - * */ class Form extends FormInterface { /** - * Tax rule name + * The root element of the browser + * + * @var Browser + */ + protected $browser; + + /** + * 'Additional Settings' link * * @var string */ - protected $name = '#code'; + protected $additionalSettings = '#details-summarybase_fieldset'; /** - * Tax rule priority field + * Tax rate block * * @var string */ - protected $priority = '#priority'; + protected $taxRateBlock = '[class*=tax_rate]'; /** - * Tax rule sort order field + * Tax rate form * * @var string */ - protected $position = '#position'; + protected $taxRateForm = '//*[contains(@class, "tax-rate-popup")]'; /** - * 'Additional Settings' link + * Customer Tax Class block * * @var string */ - protected $additionalSettings = '#details-summarybase_fieldset'; + protected $taxCustomerBlock = '[class*=tax_customer_class]'; /** - * 'Save and Continue Edit' button + * Product Tax Class block * * @var string */ - protected $saveAndContinue = '#save_and_continue'; + protected $taxProductBlock = '[class*=tax_product_class]'; /** - * Tax rate block + * XPath selector for finding needed option by its value * * @var string */ - protected $taxRateBlock = '[class*=tax_rate]'; + protected $optionMaskElement = './/*[contains(@class, "mselect-list-item")]//label/span[text()="%s"]'; /** - * Get tax rate block + * Css selector for Add New button * - * @return \Magento\Tax\Test\Block\Adminhtml\Rule\Edit\TaxRate + * @var string */ - protected function getTaxRateBlock() - { - return Factory::getBlockFactory()->getMagentoTaxAdminhtmlRuleEditTaxRate( - $this->_rootElement->find($this->taxRateBlock, Locator::SELECTOR_CSS) - ); - } + protected $addNewButton = '.mselect-button-add'; /** - * Get Customer/Product Tax Classes bloc + * Css selector for Add New tax class input * - * @param string $taxClass (e.g. customer|product) + * @var string + */ + protected $addNewInput = '.mselect-input'; + + /** + * Css selector for Add New save button * - * @return \Magento\Tax\Test\Block\Adminhtml\Rule\Edit\TaxClass + * @var string */ - protected function getTaxClassBlock($taxClass) - { - $taxClassBlock = Factory::getBlockFactory()->getMagentoTaxAdminhtmlRuleEditTaxClass( - $this->_rootElement->find('[class*=tax_' . $taxClass . ']', Locator::SELECTOR_CSS) - ); + protected $saveButton = '.mselect-save'; - return $taxClassBlock; + /** + * @constructor + * @param Element $element + * @param BlockFactory $blockFactory + * @param Mapper $mapper + * @param Browser $browser + */ + public function __construct(Element $element, BlockFactory $blockFactory, Mapper $mapper, Browser $browser) + { + parent::__construct($element, $blockFactory, $mapper); + $this->browser = $browser; } /** @@ -113,30 +127,115 @@ protected function getTaxClassBlock($taxClass) * * @param FixtureInterface $fixture * @param Element $element - * @return $this + * @return $this|void */ public function fill(FixtureInterface $fixture, Element $element = null) { /** @var TaxRule $fixture */ - $data = $fixture->getData('fields'); - $this->_rootElement->find($this->name, Locator::SELECTOR_CSS)->setValue($fixture->getTaxRuleName()); - $this->getTaxRateBlock()->selectTaxRate($fixture->getTaxRate()); - $this->_rootElement->find($this->additionalSettings, Locator::SELECTOR_CSS)->click(); - $this->getTaxClassBlock('customer')->selectTaxClass($fixture->getTaxClass('customer')); - $this->getTaxClassBlock('product')->selectTaxClass($fixture->getTaxClass('product')); - if (!empty($data['priority'])) { - $this->_rootElement->find($this->priority, Locator::SELECTOR_CSS)->setValue($fixture->getTaxRulePriority()); + $this->addNewTaxRates($fixture); + $this->openAdditionalSettings(); + if ($fixture->hasData('tax_customer_class')) { + $taxCustomerBlock = $this->_rootElement->find( + $this->taxCustomerBlock, + Locator::SELECTOR_CSS, + 'multiselectlist' + ); + $this->addNewTaxClass($fixture->getTaxCustomerClass(), $taxCustomerBlock); + } + if ($fixture->hasData('tax_product_class')) { + $taxProductBlock = $this->_rootElement->find( + $this->taxProductBlock, + Locator::SELECTOR_CSS, + 'multiselectlist' + ); + $this->addNewTaxClass($fixture->getTaxProductClass(), $taxProductBlock); } - if (!empty($data['position'])) { - $this->_rootElement->find($this->position, Locator::SELECTOR_CSS)->setValue($fixture->getTaxRulePosition()); + + parent::fill($fixture); + } + + /** + * Method to add new tax rate + * + * @param TaxRule $taxRule + * @return void + */ + protected function addNewTaxRates($taxRule) + { + $taxRateBlock = $this->_rootElement->find($this->taxRateBlock, Locator::SELECTOR_CSS, 'multiselectlist'); + /** @var \Magento\Tax\Test\Block\Adminhtml\Rule\Edit\TaxRate $taxRateForm */ + $taxRateForm = $this->blockFactory->create( + 'Magento\Tax\Test\Block\Adminhtml\Rule\Edit\TaxRate', + ['element' => $this->browser->find($this->taxRateForm, Locator::SELECTOR_XPATH)] + ); + + /** @var \Magento\Tax\Test\Fixture\TaxRule\TaxRate $taxRatesFixture */ + $taxRatesFixture = $taxRule->getDataFieldConfig('tax_rate')['source']; + $taxRatesFixture = $taxRatesFixture->getFixture(); + $taxRatesData = $taxRule->getTaxRate(); + + foreach ($taxRatesData as $key => $taxRate) { + $option = $taxRateBlock->find(sprintf($this->optionMaskElement, $taxRate), Locator::SELECTOR_XPATH); + if (!$option->isVisible()) { + $taxRate = $taxRatesFixture[$key]; + + /** @var \Magento\Tax\Test\Fixture\TaxRate $taxRate */ + $taxRateBlock->find($this->addNewButton)->click(); + $taxRateForm->fill($taxRate); + $taxRateForm->saveTaxRate(); + $code = $taxRate->getCode(); + $this->waitUntilOptionIsVisible($taxRateBlock, $code); + } + } + } + + /** + * Method to add new tax classes + * + * @param array $taxClasses + * @param Element $element + * @return void + */ + protected function addNewTaxClass(array $taxClasses, Element $element) + { + foreach ($taxClasses as $taxClass) { + $option = $element->find(sprintf($this->optionMaskElement, $taxClass), Locator::SELECTOR_XPATH); + if (!$option->isVisible()) { + $element->find($this->addNewButton)->click(); + $element->find($this->addNewInput)->setValue($taxClass); + $element->find($this->saveButton)->click(); + $this->waitUntilOptionIsVisible($element, $taxClass); + } } } /** - * Click Save And Continue Button on Form + * Waiting until option in list is visible + * + * @param Element $element + * @param string $value + * @return void + */ + protected function waitUntilOptionIsVisible($element, $value) + { + $element->waitUntil( + function () use ($element, $value) { + $productSavedMessage = $element->find( + sprintf($this->optionMaskElement, $value), + Locator::SELECTOR_XPATH + ); + return $productSavedMessage->isVisible() ? true : null; + } + ); + } + + /** + * Open Additional Settings on Form + * + * @return void */ - public function clickSaveAndContinue() + public function openAdditionalSettings() { - $this->_rootElement->find($this->saveAndContinue, Locator::SELECTOR_CSS)->click(); + $this->_rootElement->find($this->additionalSettings)->click(); } } diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Edit/Form.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Edit/Form.xml new file mode 100644 index 0000000000000..d0df4db97b61a --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Edit/Form.xml @@ -0,0 +1,44 @@ +<?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> + <code /> + <priority /> + <position /> + <tax_rate> + <selector>[class*=tax_rate]</selector> + <input>multiselectlist</input> + </tax_rate> + <tax_customer_class> + <selector>[class*=tax_customer_class]</selector> + <input>multiselectlist</input> + </tax_customer_class> + <tax_product_class> + <selector>[class*=tax_product_class]</selector> + <input>multiselectlist</input> + </tax_product_class> + </fields> +</mapping> diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Edit/TaxClass.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Edit/TaxClass.php deleted file mode 100644 index 555d71cd8a3fa..0000000000000 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Edit/TaxClass.php +++ /dev/null @@ -1,103 +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\Tax\Test\Block\Adminhtml\Rule\Edit; - -use Mtf\Fixture\FixtureInterface; -use Mtf\Block\Block; -use Mtf\Client\Element\Locator; - -/** - * Class TaxClass - * Customer/Product Tax Classes block - * - */ -class TaxClass extends Block -{ - /** - * Tax class row item - * - * @var string - */ - protected $taxClassRow = './/label[input[contains(@class, "mselect-checked")]]'; - - /** - * Add new tax class button - * - * @var string - */ - protected $addNewTaxClass = '.action-add'; - - /** - * Tax class to select - * - * @var string - */ - protected $taxClassItem = './/*[contains(@class, "mselect-list-item")]//span'; - - /** - * New tax class input field - * - * @var string - */ - protected $newTaxClass = '.mselect-input'; - - /** - * Save new tax class - * - * @var string - */ - protected $saveTaxClass = '.mselect-save'; - - /** - * Select Tax Class in multiselect and create new one if required - * - * @param array $taxClasses - */ - public function selectTaxClass($taxClasses) - { - //Uncheck all marked classes - while ($this->_rootElement->find($this->taxClassRow, Locator::SELECTOR_XPATH)->isVisible()) { - $this->_rootElement->find($this->taxClassRow, Locator::SELECTOR_XPATH)->click(); - } - //Select tax classes - foreach ($taxClasses as $class) { - $taxOption = $this->_rootElement->find( - $this->taxClassItem . '[text()="' . $class . '"]', - Locator::SELECTOR_XPATH - ); - if (!$taxOption->isVisible()) { - $this->_rootElement->find($this->addNewTaxClass, Locator::SELECTOR_CSS)->click(); - $this->_rootElement->find($this->newTaxClass, Locator::SELECTOR_CSS)->setValue($class); - $this->_rootElement->find($this->saveTaxClass, Locator::SELECTOR_CSS)->click(); - $this->waitForElementVisible( - $this->taxClassRow . '/span[text()="' . $class . '"]', - Locator::SELECTOR_XPATH - ); - } else { - $this->_rootElement->find('//label/span[text()="' . $class . '"]', Locator::SELECTOR_XPATH)->click(); - } - } - } -} diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Edit/TaxRate.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Edit/TaxRate.php index e3b87b382a741..15c84e159bc45 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Edit/TaxRate.php +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Edit/TaxRate.php @@ -24,30 +24,14 @@ namespace Magento\Tax\Test\Block\Adminhtml\Rule\Edit; -use Mtf\Client\Element\Locator; use Mtf\Block\Form as FormInterface; /** * Class TaxRate * Tax rate block - * */ class TaxRate extends FormInterface { - /** - * 'Add New Tax Rate' button - * - * @var string - */ - protected $addNewTaxRate = '.action-add'; - - /** - * Dialog window for creating new tax rate - * - * @var string - */ - protected $taxRateUiDialog = '//*[contains(@class, ui-dialog)]//*[@id="tax-rate-form"]/..'; - /** * 'Save' button on dialog window for creating new tax rate * @@ -56,32 +40,12 @@ class TaxRate extends FormInterface protected $saveTaxRate = '#tax-rule-edit-apply-button'; /** - * Tax rate option - * - * @var string - */ - protected $taxRateOption = '//*[contains(@class, "mselect-list-item")]//label'; - - /** - * Select Tax Rate in multiselect and create new one if required + * Clicking 'Save' button on dialog window for creating new tax rate * - * @param array $rates + * @return void */ - public function selectTaxRate(array $rates) + public function saveTaxRate() { - foreach ($rates as $rate) { - if (isset($rate['rate'])) { - $this->_rootElement->find($this->addNewTaxRate, Locator::SELECTOR_CSS)->click(); - $taxRateDialog = $this->_rootElement->find($this->taxRateUiDialog, Locator::SELECTOR_XPATH); - $this->_fill($this->dataMapping($rate), $taxRateDialog); - $taxRateDialog->find($this->saveTaxRate, Locator::SELECTOR_CSS)->click(); - $this->waitForElementNotVisible($this->taxRateUiDialog, Locator::SELECTOR_XPATH); - } else { - $this->_rootElement->find( - $this->taxRateOption . '/span[text()="' . $rate['code']['value'] . '"]', - Locator::SELECTOR_XPATH - )->click(); - } - } + $this->_rootElement->find($this->saveTaxRate)->click(); } } diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Edit/TaxRate.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Edit/TaxRate.xml index 44708431b48bc..cb1e40217b961 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Edit/TaxRate.xml +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Edit/TaxRate.xml @@ -27,8 +27,17 @@ <fields> <code /> <rate /> + <tax_postcode /> + <zip_from /> + <zip_to /> <tax_region_id> <input>select</input> </tax_region_id> + <tax_country_id> + <input>select</input> + </tax_country_id> + <zip_is_range> + <input>checkbox</input> + </zip_is_range> </fields> </mapping> diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Grid.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Grid.php index e0c6237ec5cd1..75f800359e287 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Grid.php +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Grid.php @@ -24,43 +24,43 @@ namespace Magento\Tax\Test\Block\Adminhtml\Rule; -use Mtf\Client\Element\Locator; use Magento\Backend\Test\Block\Widget\Grid as GridInterface; /** * Class Grid - * Tax rules grid - * + * Adminhtml Tax Rules management grid */ class Grid extends GridInterface { /** - * 'Add New' rule button + * Locator value for opening needed row * * @var string */ - protected $addNewRule = "../*[@class='page-actions']//*[@id='add']"; + protected $editLink = 'td[class*=col-code]'; /** - * {@inheritdoc} + * Initialize block elements + * + * @var array */ - protected $filters = array( - 'name' => array( - 'selector' => '#taxRuleGrid_filter_code' - ), - 'customer_tax_class' => array( + protected $filters = [ + 'code' => [ + 'selector' => '#taxRuleGrid_filter_code', + ], + 'tax_customer_class' => [ 'selector' => '#taxRuleGrid_filter_customer_tax_classes', - 'input' => 'select' - ), - 'product_tax_class' => array( + 'input' => 'select', + ], + 'tax_product_class' => [ 'selector' => '#taxRuleGrid_filter_product_tax_classes', - 'input' => 'select' - ), - 'tax_rate' => array( + 'input' => 'select', + ], + 'tax_rate' => [ 'selector' => '#taxRuleGrid_filter_tax_rates', - 'input' => 'select' - ) - ); + 'input' => 'select', + ], + ]; /** * Check if specific row exists in grid @@ -71,15 +71,7 @@ class Grid extends GridInterface */ public function isRowVisible(array $filter, $isSearchable = false) { - $this->search(array('name' => $filter['name'])); + $this->search(array('code' => $filter['code'])); return parent::isRowVisible($filter, $isSearchable); } - - /** - * Add new rule - */ - public function addNewRule() - { - $this->_rootElement->find($this->addNewRule, Locator::SELECTOR_XPATH)->click(); - } } diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AssertTaxRuleForm.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AssertTaxRuleForm.php new file mode 100644 index 0000000000000..a1bd7eb7988ca --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AssertTaxRuleForm.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\Tax\Test\Constraint; + +use Magento\Tax\Test\Fixture\TaxRule; +use Magento\Tax\Test\Page\Adminhtml\TaxRuleIndex; +use Magento\Tax\Test\Page\Adminhtml\TaxRuleNew; +use Mtf\Constraint\AbstractConstraint; + +/** + * Class AssertTaxRuleForm + */ +class AssertTaxRuleForm extends AbstractConstraint +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'high'; + + /** + * Assert that tax rule form filled right + * + * @param TaxRuleNew $taxRuleNew + * @param TaxRuleIndex $taxRuleIndex + * @param TaxRule $taxRule + * @param TaxRule $initialTaxRule + */ + public function processAssert( + TaxRuleNew $taxRuleNew, + TaxRuleIndex $taxRuleIndex, + TaxRule $taxRule, + TaxRule $initialTaxRule = null + ) { + $data = $taxRule->getData(); + if ($initialTaxRule !== null) { + $taxRuleCode = ($taxRule->hasData('code')) ? $taxRule->getCode() : $initialTaxRule->getCode(); + } else { + $taxRuleCode = $taxRule->getCode(); + } + $filter = [ + 'code' => $taxRuleCode, + ]; + $taxRuleIndex->open(); + $taxRuleIndex->getTaxRuleGrid()->searchAndOpen($filter); + $taxRuleNew->getTaxRuleForm()->openAdditionalSettings(); + $formData = $taxRuleNew->getTaxRuleForm()->getData($taxRule); + $dataDiff = $this->verifyForm($formData, $data); + \PHPUnit_Framework_Assert::assertTrue( + empty($dataDiff), + 'Tax Rule form was filled not right.' + . "\nLog:\n" . implode(";\n", $dataDiff) + ); + } + + /** + * Verifying that form is filled right + * + * @param array $formData + * @param array $fixtureData + * @return array $errorMessage + */ + protected function verifyForm(array $formData, array $fixtureData) + { + $errorMessage = []; + + foreach ($fixtureData as $key => $value) { + if (is_array($value)) { + $diff = array_diff($value, $formData[$key]); + $diff = array_merge($diff, array_diff($formData[$key], $value)); + if (!empty($diff)) { + $errorMessage[] = "Data in " . $key . " field not equal." + . "\nExpected: " . implode(", ", $value) + . "\nActual: " . implode(", ", $formData[$key]); + } + } else { + if ($value !== $formData[$key]) { + $errorMessage[] = "Data in " . $key . " field not equal." + . "\nExpected: " . $value + . "\nActual: " . $formData[$key]; + } + } + } + + return $errorMessage; + } + + /** + * Text that form was filled right + * + * @return string + */ + public function toString() + { + return 'Tax Rule form has been filled right.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AssertTaxRuleInGrid.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AssertTaxRuleInGrid.php new file mode 100644 index 0000000000000..4decb13dc2a0c --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AssertTaxRuleInGrid.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\Tax\Test\Constraint; + +use Magento\Tax\Test\Fixture\TaxRule; +use Magento\Tax\Test\Page\Adminhtml\TaxRuleIndex; +use Mtf\Constraint\AbstractConstraint; + +/** + * Class AssertTaxRuleInGrid + */ +class AssertTaxRuleInGrid extends AbstractConstraint +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'high'; + + /** + * Assert tax rule availability in Tax Rule grid + * + * @param TaxRuleIndex $taxRuleIndex + * @param TaxRule $taxRule + * @param TaxRule $initialTaxRule + */ + public function processAssert( + TaxRuleIndex $taxRuleIndex, + TaxRule $taxRule, + TaxRule $initialTaxRule = null + ) { + if ($initialTaxRule !== null) { + $taxRuleCode = ($taxRule->hasData('code')) ? $taxRule->getCode() : $initialTaxRule->getCode(); + } else { + $taxRuleCode = $taxRule->getCode(); + } + $filter = [ + 'code' => $taxRuleCode, + ]; + + $taxRuleIndex->open(); + \PHPUnit_Framework_Assert::assertTrue( + $taxRuleIndex->getTaxRuleGrid()->isRowVisible($filter), + 'Tax Rule \'' . $filter['code'] . '\' is absent in Tax Rule grid.' + ); + } + + /** + * Text of Tax Rule in grid assert + * + * @return string + */ + public function toString() + { + return 'Tax rule is present in grid.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AssertTaxRuleSuccessSaveMessage.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AssertTaxRuleSuccessSaveMessage.php new file mode 100644 index 0000000000000..2d35eae41fc37 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AssertTaxRuleSuccessSaveMessage.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\Tax\Test\Constraint; + +use Magento\Tax\Test\Page\Adminhtml\TaxRuleIndex; +use Mtf\Constraint\AbstractConstraint; + +/** + * Class AssertSuccessSavedMessageTaxRule + */ +class AssertTaxRuleSuccessSaveMessage extends AbstractConstraint +{ + const SUCCESS_MESSAGE = 'The tax rule has been saved.'; + + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Assert that success message is displayed after tax rule saved + * + * @param TaxRuleIndex $taxRuleIndex + * @return void + */ + public function processAssert(TaxRuleIndex $taxRuleIndex) + { + $actualMessage = $taxRuleIndex->getMessagesBlock()->getSuccessMessages(); + \PHPUnit_Framework_Assert::assertEquals( + self::SUCCESS_MESSAGE, + $actualMessage, + 'Wrong success message is displayed.' + . "\nExpected: " . self::SUCCESS_MESSAGE + . "\nActual: " . $actualMessage + ); + } + + /** + * Text of Created Tax Rule Success Message assert + * + * @return string + */ + public function toString() + { + return 'Tax rule success create message is present.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxClass.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxClass.php index 83e70d29d1880..246e8e1da3a77 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxClass.php +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxClass.php @@ -24,64 +24,73 @@ namespace Magento\Tax\Test\Fixture; -use Mtf\Factory\Factory; -use Mtf\Fixture\DataFixture; +use Mtf\Fixture\InjectableFixture; /** * Class TaxClass - * */ -class TaxClass extends DataFixture +class TaxClass extends InjectableFixture { /** - * Get tax class name - * - * @return string + * @var string */ - public function getTaxClassName() - { - return $this->getData('fields/data/class_name/value'); - } + protected $repositoryClass = 'Magento\Tax\Test\Repository\TaxClass'; /** - * Return saved class id - * - * @return mixed + * @var string */ - public function getTaxClassId() + protected $handlerInterface = 'Magento\Tax\Test\Handler\TaxClass\TaxClassInterface'; + + protected $defaultDataSet = [ + 'class_name' => 'Tax Class %isolation%', + ]; + + protected $class_id = [ + 'attribute_code' => 'class_id', + 'backend_type' => 'smallint', + 'is_required' => '1', + 'default_value' => '', + 'input' => '', + ]; + + protected $class_name = [ + 'attribute_code' => 'class_name', + 'backend_type' => 'varchar', + 'is_required' => '', + 'default_value' => '', + 'input' => '', + ]; + + protected $class_type = [ + 'attribute_code' => 'class_type', + 'backend_type' => 'varchar', + 'is_required' => '', + 'default_value' => 'CUSTOMER', + 'input' => '', + ]; + + protected $id = [ + 'attribute_code' => 'id', + 'backend_type' => 'virtual', + ]; + + public function getClassId() { - return $this->getData('fields/id'); + return $this->getData('class_id'); } - /** - * Create tax class - * - * @return TaxClass - */ - public function persist() + public function getClassName() { - $id = Factory::getApp()->magentoTaxCreateTaxClass($this); - $this->_data['fields']['id'] = $id; - return $this; + return $this->getData('class_name'); } - /** - * Init data - */ - protected function _initData() + public function getClassType() { - $this->_data = array( - 'fields' => array( - 'class_name' => array( - 'value' => 'Customer Tax Class %isolation%' - ), - 'class_type' => array( - 'value' => 'CUSTOMER' - ) - ) - ); + return $this->getData('class_type'); + } - $this->_repository = Factory::getRepositoryFactory() - ->getMagentoTaxTaxClass($this->_dataConfig, $this->_data); + public function getId() + { + return $this->getData('id'); } } diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxClass.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxClass.xml new file mode 100644 index 0000000000000..ad14daa4f633b --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxClass.xml @@ -0,0 +1,63 @@ +<?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\Tax\Test\Fixture\TaxClass"> + <module>Magento_Tax</module> + <type>flat</type> + <entity_type>tax_class</entity_type> + <collection>Magento\Tax\Model\Resource\TaxClass\Collection</collection> + <identifier /> + <fields> + <class_id> + <attribute_code>class_id</attribute_code> + <backend_type>smallint</backend_type> + <is_required>1</is_required> + <default_value /> + <input /> + </class_id> + <class_name> + <attribute_code>class_name</attribute_code> + <backend_type>varchar</backend_type> + <is_required /> + <default_value /> + <input /> + </class_name> + <class_type> + <attribute_code>class_type</attribute_code> + <backend_type>varchar</backend_type> + <is_required /> + <default_value>CUSTOMER</default_value> + <input /> + </class_type> + <id> + <attribute_code>id</attribute_code> + <backend_type>virtual</backend_type> + </id> + </fields> + <data_set /> + <data_config /> + <repository_class>Magento\Tax\Test\Repository\TaxClass</repository_class> + <handler_interface>Magento\Tax\Test\Handler\TaxClass\TaxClassInterface</handler_interface> +</fixture> diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRate.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRate.php index ccdc77fe29666..a71e5f2953b55 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRate.php +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRate.php @@ -24,73 +24,155 @@ namespace Magento\Tax\Test\Fixture; -use Mtf\Factory\Factory; -use Mtf\Fixture\DataFixture; +use Mtf\Fixture\InjectableFixture; /** * Class TaxRate - * */ -class TaxRate extends DataFixture +class TaxRate extends InjectableFixture { /** - * Get tax rate name - * - * @return string + * @var string */ - public function getTaxRateName() - { - return $this->getData('code/value'); - } + protected $repositoryClass = 'Magento\Tax\Test\Repository\TaxRate'; /** - * Get tax rate id - * - * @return string + * @var string */ - public function getTaxRateId() + protected $handlerInterface = 'Magento\Tax\Test\Handler\TaxRate\TaxRateInterface'; + + protected $defaultDataSet = [ + 'code' => 'Tax Rate %isolation%', + 'rate' => '10', + 'tax_country_id' => 'United States', + 'tax_postcode' => '*', + 'tax_region_id' => '0', + ]; + + protected $tax_calculation_rate_id = [ + 'attribute_code' => 'tax_calculation_rate_id', + 'backend_type' => 'int', + 'is_required' => '1', + 'default_value' => '', + 'input' => '', + ]; + + protected $tax_country_id = [ + 'attribute_code' => 'tax_country_id', + 'backend_type' => 'varchar', + 'is_required' => '', + 'default_value' => '', + 'input' => '', + ]; + + protected $tax_region_id = [ + 'attribute_code' => 'tax_region_id', + 'backend_type' => 'int', + 'is_required' => '', + 'default_value' => '', + 'input' => '', + ]; + + protected $tax_postcode = [ + 'attribute_code' => 'tax_postcode', + 'backend_type' => 'varchar', + 'is_required' => '', + 'default_value' => '', + 'input' => '', + ]; + + protected $code = [ + 'attribute_code' => 'code', + 'backend_type' => 'varchar', + 'is_required' => '', + 'default_value' => '', + 'input' => '', + ]; + + protected $rate = [ + 'attribute_code' => 'rate', + 'backend_type' => 'decimal', + 'is_required' => '', + 'default_value' => '', + 'input' => '', + ]; + + protected $zip_is_range = [ + 'attribute_code' => 'zip_is_range', + 'backend_type' => 'smallint', + 'is_required' => '', + 'default_value' => '', + 'input' => '', + ]; + + protected $zip_from = [ + 'attribute_code' => 'zip_from', + 'backend_type' => 'int', + 'is_required' => '', + 'default_value' => '', + 'input' => '', + ]; + + protected $zip_to = [ + 'attribute_code' => 'zip_to', + 'backend_type' => 'int', + 'is_required' => '', + 'default_value' => '', + 'input' => '', + ]; + + protected $id = [ + 'attribute_code' => 'id', + 'backend_type' => 'virtual', + ]; + + public function getTaxCalculationRateId() { - return $this->getData('fields/id'); + return $this->getData('tax_calculation_rate_id'); } - /** - * Create tax rate - * - * @return TaxRate - */ - public function persist() + public function getTaxCountryId() { - $id = Factory::getApp()->magentoTaxCreateTaxRate($this); - $this->_data['fields']['id'] = $id; - return $this; + return $this->getData('tax_country_id'); } - /** - * Init data - */ - protected function _initData() + public function getTaxRegionId() + { + return $this->getData('tax_region_id'); + } + + public function getTaxPostcode() + { + return $this->getData('tax_postcode'); + } + + public function getCode() + { + return $this->getData('code'); + } + + public function getRate() + { + return $this->getData('rate'); + } + + public function getZipIsRange() + { + return $this->getData('zip_is_range'); + } + + public function getZipFrom() + { + return $this->getData('zip_from'); + } + + public function getZipTo() + { + return $this->getData('zip_to'); + } + + public function getId() { - $this->_data = array( - 'fields' => array( - 'code' => array( - 'value' => 'Tax Rate %isolation%' - ), - 'rate' => array( - 'value' => '10' - ), - 'tax_country_id' => array( - 'value' => 'US', - ), - 'tax_postcode' => array( - 'value' => '*' - ), - 'tax_region_id' => array( - 'value' => '0' - ) - ) - ); - - $this->_repository = Factory::getRepositoryFactory() - ->getMagentoTaxTaxRate($this->_dataConfig, $this->_data); + return $this->getData('id'); } } diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRate.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRate.xml new file mode 100644 index 0000000000000..0ed8efa85c83c --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRate.xml @@ -0,0 +1,105 @@ +<?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\Tax\Test\Fixture\TaxRate"> + <module>Magento_Tax</module> + <type>flat</type> + <entity_type>tax_calculation_rate</entity_type> + <collection>Magento\Tax\Model\Resource\Calculation\Rate\Collection</collection> + <identifier>code</identifier> + <fields> + <tax_calculation_rate_id> + <attribute_code>tax_calculation_rate_id</attribute_code> + <backend_type>int</backend_type> + <is_required>1</is_required> + <default_value /> + <input /> + </tax_calculation_rate_id> + <tax_country_id> + <attribute_code>tax_country_id</attribute_code> + <backend_type>varchar</backend_type> + <is_required /> + <default_value /> + <input /> + </tax_country_id> + <tax_region_id> + <attribute_code>tax_region_id</attribute_code> + <backend_type>int</backend_type> + <is_required /> + <default_value /> + <input /> + </tax_region_id> + <tax_postcode> + <attribute_code>tax_postcode</attribute_code> + <backend_type>varchar</backend_type> + <is_required /> + <default_value /> + <input /> + </tax_postcode> + <code> + <attribute_code>code</attribute_code> + <backend_type>varchar</backend_type> + <is_required /> + <default_value /> + <input /> + </code> + <rate> + <attribute_code>rate</attribute_code> + <backend_type>decimal</backend_type> + <is_required /> + <default_value /> + <input /> + </rate> + <zip_is_range> + <attribute_code>zip_is_range</attribute_code> + <backend_type>smallint</backend_type> + <is_required /> + <default_value /> + <input /> + </zip_is_range> + <zip_from> + <attribute_code>zip_from</attribute_code> + <backend_type>int</backend_type> + <is_required /> + <default_value /> + <input /> + </zip_from> + <zip_to> + <attribute_code>zip_to</attribute_code> + <backend_type>int</backend_type> + <is_required /> + <default_value /> + <input /> + </zip_to> + <id> + <attribute_code>id</attribute_code> + <backend_type>virtual</backend_type> + </id> + </fields> + <data_set /> + <data_config /> + <repository_class>Magento\Tax\Test\Repository\TaxRate</repository_class> + <handler_interface>Magento\Tax\Test\Handler\TaxRate\TaxRateInterface</handler_interface> +</fixture> diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRule.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRule.php index e115104b9146f..3a89dba95ff8b 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRule.php +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRule.php @@ -24,160 +24,114 @@ namespace Magento\Tax\Test\Fixture; -use Mtf\Factory\Factory; -use Mtf\Fixture\DataFixture; -use Mtf\System\Config; +use Mtf\Fixture\InjectableFixture; /** * Class TaxRule - * */ -class TaxRule extends DataFixture +class TaxRule extends InjectableFixture { /** - * Initialize data and apply placeholders - * - * @param Config $configuration - * @param array $placeholders + * @var string */ - public function __construct(Config $configuration, array $placeholders = array()) - { - parent::__construct($configuration, $placeholders); - - $this->_placeholders['us_ca_rate_8_25'] = array($this, '_getTaxRateId'); - $this->_placeholders['uk_full_tax_rate'] = array($this, '_getTaxRateId'); - $this->_placeholders['us_ny_rate_8_1'] = array($this, '_getTaxRateData'); - $this->_placeholders['us_ny_rate_8_375'] = array($this, '_getTaxRateId'); - $this->_placeholders['product_tax_class'] = array($this, '_getTaxClassId'); - $this->_placeholders['customer_tax_class'] = array($this, '_getTaxClassId'); - } + protected $repositoryClass = 'Magento\Tax\Test\Repository\TaxRule'; /** - * Callback function returns created rate id - * - * @param string $dataSetName - * @return int + * @var string */ - protected function _getTaxRateId($dataSetName) - { - $taxRate = Factory::getFixtureFactory()->getMagentoTaxTaxRate(); - $taxRate->switchData($dataSetName); - return $taxRate->persist()->getTaxRateId(); - } + protected $handlerInterface = 'Magento\Tax\Test\Handler\TaxRule\TaxRuleInterface'; - /** - * Callback function returns class id - * - * @param string $dataSetName - * @return mixed - */ - protected function _getTaxClassId($dataSetName) - { - $taxClass = Factory::getFixtureFactory()->getMagentoTaxTaxClass(); - $taxClass->switchData($dataSetName); - return $taxClass->persist()->getTaxClassId(); - } + protected $defaultDataSet = [ + 'code' => 'TaxIdentifier%isolation%', + 'tax_rate' => [ + 'dataSet' => [ + 'US-CA-*-Rate 1' + ], + ], + ]; - protected function _getTaxRateData($dataSetName) - { - $taxClass = Factory::getFixtureFactory()->getMagentoTaxTaxRate(); - $taxClass->switchData($dataSetName); - return $taxClass->getData('fields'); - } + protected $tax_calculation_rule_id = [ + 'attribute_code' => 'tax_calculation_rule_id', + 'backend_type' => 'int', + 'is_required' => '1', + 'default_value' => '', + 'input' => '', + ]; - /** - * Get tax rule name - * - * @return string - */ - public function getTaxRuleName() + protected $code = [ + 'attribute_code' => 'code', + 'backend_type' => 'varchar', + 'is_required' => '', + 'default_value' => '', + 'input' => '', + ]; + + protected $priority = [ + 'attribute_code' => 'priority', + 'backend_type' => 'int', + 'is_required' => '', + 'default_value' => '', + 'input' => '', + ]; + + protected $position = [ + 'attribute_code' => 'position', + 'backend_type' => 'int', + 'is_required' => '', + 'default_value' => '', + 'input' => '', + ]; + + protected $tax_rate = [ + 'attribute_code' => 'tax_rate', + 'backend_type' => 'virtual', + 'source' => 'Magento\Tax\Test\Fixture\TaxRule\TaxRate', + ]; + + protected $tax_customer_class = [ + 'attribute_code' => 'tax_customer_class', + 'backend_type' => 'virtual', + 'source' => 'Magento\Tax\Test\Fixture\TaxRule\TaxClass', + ]; + + protected $tax_product_class = [ + 'attribute_code' => 'tax_product_class', + 'backend_type' => 'virtual', + 'source' => 'Magento\Tax\Test\Fixture\TaxRule\TaxClass', + ]; + + public function getTaxCalculationRuleId() { - return $this->getData('fields/code/value'); + return $this->getData('tax_calculation_rule_id'); } - /** - * Get tax rule priority - * - * @return string - */ - public function getTaxRulePriority() + public function getCode() { - return $this->getData('fields/priority/value'); + return $this->getData('code'); } - /** - * Get tax rule position - * - * @return string - */ - public function getTaxRulePosition() + public function getPriority() { - return $this->getData('fields/position/value'); + return $this->getData('priority'); } - /** - * Get product/customer tax class - * - * @return string|array - */ - public function getTaxRate() + public function getPosition() { - return $this->getData('fields/tax_rate'); + return $this->getData('position'); } - /** - * Get product/customer tax class - * - * @param string $taxClass (e.g. product|customer) - * @return string|array - */ - public function getTaxClass($taxClass) + public function getTaxRate() { - return $this->getData('fields/tax_' . $taxClass . '_class/value'); + return $this->getData('tax_rate'); } - /** - * Create tax rule - * - * @return TaxRule - */ - public function persist() + public function getTaxCustomerClass() { - Factory::getApp()->magentoTaxCreateTaxRule($this); - return $this; + return $this->getData('tax_customer_class'); } - /** - * Init data - */ - protected function _initData() + public function getTaxProductClass() { - $this->_data = array( - 'fields' => array( - 'code' => array( - 'value' => 'Tax Rule %isolation%' - ), - 'tax_rate' => array( - 'value' => '1', - 'input_name' => 'tax_rate[]' - ), - 'tax_product_class' => array( - 'value' => '2', - 'input_name' => 'tax_product_class[]' - ), - 'tax_customer_class' => array( - 'value' => '3', - 'input_name' => 'tax_customer_class[]' - ), - 'priority' => array( - 'value' => '0' - ), - 'position' => array( - 'value' => '0' - ) - ) - ); - - $this->_repository = Factory::getRepositoryFactory()->getMagentoTaxTaxRule($this->_dataConfig, $this->_data); + return $this->getData('tax_product_class'); } } diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRule.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRule.xml new file mode 100644 index 0000000000000..70977f3adb97b --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRule.xml @@ -0,0 +1,78 @@ +<?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\Tax\Test\Fixture\TaxRule"> + <module>Magento_Tax</module> + <type>flat</type> + <entity_type>tax_calculation_rule</entity_type> + <collection>Magento\Tax\Model\Resource\Calculation\Rule\Collection</collection> + <identifier>code</identifier> + <fields> + <tax_calculation_rule_id> + <attribute_code>tax_calculation_rule_id</attribute_code> + <backend_type>int</backend_type> + <is_required>1</is_required> + <default_value /> + <input /> + </tax_calculation_rule_id> + <code> + <attribute_code>code</attribute_code> + <backend_type>varchar</backend_type> + <is_required /> + <default_value /> + <input /> + </code> + <priority> + <attribute_code>priority</attribute_code> + <backend_type>int</backend_type> + <is_required /> + <default_value /> + <input /> + </priority> + <position> + <attribute_code>position</attribute_code> + <backend_type>int</backend_type> + <is_required /> + <default_value /> + <input /> + </position> + <tax_rate> + <attribute_code>tax_rate</attribute_code> + <backend_type>virtual</backend_type> + </tax_rate> + <tax_customer_class> + <attribute_code>tax_customer_class</attribute_code> + <backend_type>virtual</backend_type> + </tax_customer_class> + <tax_product_class> + <attribute_code>tax_product_class</attribute_code> + <backend_type>virtual</backend_type> + </tax_product_class> + </fields> + <data_set /> + <data_config /> + <repository_class>Magento\Tax\Test\Repository\TaxRule</repository_class> + <handler_interface>Magento\Tax\Test\Handler\TaxRule\TaxRuleInterface</handler_interface> +</fixture> diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRule/TaxClass.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRule/TaxClass.php new file mode 100644 index 0000000000000..4c52c1b111dd2 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRule/TaxClass.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\Tax\Test\Fixture\TaxRule; + +use Mtf\Fixture\FixtureFactory; +use Mtf\Fixture\FixtureInterface; + +/** + * Class TaxClass + * + * Data keys: + * - dataSet + */ +class TaxClass implements FixtureInterface +{ + /** + * Array with tax class names + * + * @var array + */ + protected $data; + + /** + * Array with tax class fixtures + * + * @var array + */ + protected $fixture; + + /** + * @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'])) { + $dataSets = $data['dataSet']; + foreach ($dataSets as $dataSet) { + if ($dataSet !== '-') { + /** @var \Magento\Tax\Test\Fixture\TaxClass $taxClass */ + $taxClass = $fixtureFactory->createByCode('taxClass', ['dataSet' => $dataSet]); + $this->fixture[] = $taxClass; + $this->data[] = $taxClass->getClassName(); + } + } + } + } + + /** + * Persist custom selections tax classes + * + * @return void + */ + public function persist() + { + // + } + + /** + * Return prepared data set + * + * @param $key [optional] + * @return mixed + */ + public function getData($key = null) + { + return $this->data; + } + + /** + * Return data set configuration settings + * + * @return string + */ + public function getDataConfig() + { + return $this->params; + } + + /** + * Return tax class fixture + * + * @return array + */ + public function getFixture() + { + return $this->fixture; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRule/TaxRate.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRule/TaxRate.php new file mode 100644 index 0000000000000..fbbbb82f91725 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRule/TaxRate.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\Tax\Test\Fixture\TaxRule; + +use Mtf\Fixture\FixtureFactory; +use Mtf\Fixture\FixtureInterface; + +/** + * Class TaxRate + * + * Data keys: + * - dataSet + */ +class TaxRate implements FixtureInterface +{ + /** + * Array with tax rates codes + * + * @var array + */ + protected $data; + + /** + * Array with tax rate fixtures + * + * @var array + */ + protected $fixture; + + /** + * @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'])) { + $dataSets = $data['dataSet']; + foreach ($dataSets as $dataSet) { + if ($dataSet !== '-') { + /** @var \Magento\Tax\Test\Fixture\TaxRate $taxRate */ + $taxRate = $fixtureFactory->createByCode('taxRate', ['dataSet' => $dataSet]); + $this->fixture[] = $taxRate; + $this->data[] = $taxRate->getCode(); + } + } + } + } + + /** + * Persist custom selections tax rates + * + * @return void + */ + public function persist() + { + // + } + + /** + * Return prepared data set + * + * @param $key [optional] + * @return mixed + */ + public function getData($key = null) + { + return $this->data; + } + + /** + * Return data set configuration settings + * + * @return string + */ + public function getDataConfig() + { + return $this->params; + } + + /** + * Return tax rate fixtures + * + * @return array + */ + public function getFixture() + { + return $this->fixture; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/Curl/CreateTaxClass.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxClass/Curl.php similarity index 74% rename from dev/tests/functional/tests/app/Magento/Tax/Test/Handler/Curl/CreateTaxClass.php rename to dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxClass/Curl.php index 80f87b66f1d3e..b3d25e63fdebf 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/Curl/CreateTaxClass.php +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxClass/Curl.php @@ -18,25 +18,24 @@ * 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\Tax\Test\Handler\Curl; +namespace Magento\Tax\Test\Handler\TaxClass; use Mtf\Fixture\FixtureInterface; -use Mtf\Handler\Curl; +use Mtf\Handler\Curl as AbstractCurl; use Mtf\Util\Protocol\CurlInterface; use Mtf\Util\Protocol\CurlTransport; use Mtf\Util\Protocol\CurlTransport\BackendDecorator; use Mtf\System\Config; /** - * Curl handler for creating customer and product tax class. - * + * Class Curl + * Curl handler for creating customer and product tax class */ -class CreateTaxClass extends Curl +class Curl extends AbstractCurl implements TaxClassInterface { /** * Post request for creating tax class @@ -46,28 +45,31 @@ class CreateTaxClass extends Curl */ public function persist(FixtureInterface $fixture = null) { - $data = $fixture->getData('fields'); - $fields = array(); - foreach ($data as $key => $field) { - $fields[$key] = $field['value']; - } + $data = $fixture->getData(); + $url = $_ENV['app_backend_url'] . 'tax/tax/ajaxSAve/?isAjax=true'; $curl = new BackendDecorator(new CurlTransport(), new Config()); - $curl->write(CurlInterface::POST, $url, '1.0', array(), $fields); + $curl->write(CurlInterface::POST, $url, '1.0', array(), $data); $response = $curl->read(); $curl->close(); - return $this->_getClassId($response); + + $id = $this->getClassId($response); + return ['id' => $id]; } /** * Return saved class id if saved * - * @param string $data + * @param $response * @return int|null + * @throws \Exception */ - protected function _getClassId($data) + protected function getClassId($response) { - $data = json_decode($data); + $data = json_decode($response); + if ($data->success !== true) { + throw new \Exception("Tax class creation by curl handler was not successful! Response: $response"); + } return isset($data->class_id) ? (int)$data->class_id : null; } } diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxClass/TaxClassInterface.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxClass/TaxClassInterface.php new file mode 100644 index 0000000000000..cd8c1ae059266 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxClass/TaxClassInterface.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\Tax\Test\Handler\TaxClass; + +use Mtf\Handler\HandlerInterface; + +/** + * Interface TaxClassInterface + */ +interface TaxClassInterface extends HandlerInterface +{ + // +} diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/Curl/CreateTaxRate.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxRate/Curl.php similarity index 58% rename from dev/tests/functional/tests/app/Magento/Tax/Test/Handler/Curl/CreateTaxRate.php rename to dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxRate/Curl.php index bd59f767df402..d76a231d2946b 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/Curl/CreateTaxRate.php +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxRate/Curl.php @@ -18,26 +18,47 @@ * 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\Tax\Test\Handler\Curl; +namespace Magento\Tax\Test\Handler\TaxRate; use Mtf\Fixture\FixtureInterface; -use Mtf\Handler\Curl; +use Mtf\Handler\Curl as AbstractCurl; use Mtf\Util\Protocol\CurlInterface; use Mtf\Util\Protocol\CurlTransport; use Mtf\Util\Protocol\CurlTransport\BackendDecorator; use Mtf\System\Config; /** + * Class Curl * Curl handler for creating Tax Rate - * */ -class CreateTaxRate extends Curl +class Curl extends AbstractCurl implements TaxRateInterface { + /** + * Mapping for countries + * + * @var array + */ + protected $countryId = [ + 'AU' => 'Australia', + 'US' => 'United States', + 'GB' => 'United Kingdom', + ]; + + /** + * Mapping for regions + * + * @var array + */ + protected $regionId = [ + '0' => '*', + '12' => 'California', + '43' => 'New York', + ]; + /** * Post request for creating tax rate * @@ -46,28 +67,37 @@ class CreateTaxRate extends Curl */ public function persist(FixtureInterface $fixture = null) { - $data = $fixture->getData('fields'); - $fields = array(); - foreach ($data as $key => $field) { - $fields[$key] = $field['value']; + $data = $fixture->getData(); + $data['tax_country_id'] = array_search($data['tax_country_id'], $this->countryId); + if (isset($data['tax_region_id'])) { + $data['tax_region_id'] = array_search($data['tax_region_id'], $this->regionId); + } else { + $data['tax_region_id'] = 0; } + $url = $_ENV['app_backend_url'] . 'tax/rate/ajaxSave/?isAjax=true'; $curl = new BackendDecorator(new CurlTransport(), new Config()); - $curl->write(CurlInterface::POST, $url, '1.0', array(), $fields); + $curl->write(CurlInterface::POST, $url, '1.0', array(), $data); $response = $curl->read(); $curl->close(); - return $this->_getTaxRateId($response); + + $id = $this->getTaxRateId($response); + return ['id' => $id]; } /** - * Return saved rate id + * Return saved tax rate id * - * @param string $data + * @param $response * @return int|null + * @throws \Exception */ - protected function _getTaxRateId($data) + protected function getTaxRateId($response) { - $data = json_decode($data); + $data = json_decode($response); + if ($data->success !== true) { + throw new \Exception("Tax rate creation by curl handler was not successful! Response: $response"); + } return isset($data->tax_calculation_rate_id) ? (int)$data->tax_calculation_rate_id : null; } } diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxRate/TaxRateInterface.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxRate/TaxRateInterface.php new file mode 100644 index 0000000000000..3468e23b7a22f --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxRate/TaxRateInterface.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\Tax\Test\Handler\TaxRate; + +use Mtf\Handler\HandlerInterface; + +/** + * Interface TaxRateInterface + */ +interface TaxRateInterface extends HandlerInterface +{ + // +} diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/Curl/CreateTaxRule.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxRule/Curl.php similarity index 53% rename from dev/tests/functional/tests/app/Magento/Tax/Test/Handler/Curl/CreateTaxRule.php rename to dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxRule/Curl.php index 66a4cb5413f60..0779ad699ec9f 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/Curl/CreateTaxRule.php +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxRule/Curl.php @@ -18,96 +18,89 @@ * 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\Tax\Test\Handler\Curl; +namespace Magento\Tax\Test\Handler\TaxRule; use Mtf\Fixture\FixtureInterface; -use Mtf\Handler\Curl; +use Mtf\Handler\Curl as AbstractCurl; use Mtf\Util\Protocol\CurlInterface; use Mtf\Util\Protocol\CurlTransport; use Mtf\Util\Protocol\CurlTransport\BackendDecorator; use Mtf\System\Config; /** - * Curl handler for creating Tax Rule. - * + * Class Curl + * Curl handler for creating Tax Rule */ -class CreateTaxRule extends Curl +class Curl extends AbstractCurl implements TaxRuleInterface { /** - * Returns data for curl POST params + * Default Tax Class values * - * @param $fixture - * @return array + * @var array */ - public function _getPostParams($fixture) - { - $data = $fixture->getData('fields'); - $fields = array(); - foreach ($data as $key => $field) { - $value = $this->_getParamValue($field); - - if (null === $value) { - continue; - } - - $_key = $this->_getParamKey($field); - if (null === $_key) { - $_key = $key; - } - $fields[$_key] = $value; - } - return $fields; - } + protected $defaultTaxClasses = [ + 'tax_customer_class' => 3, // Retail Customer + 'tax_product_class' => 2, // Taxable Goods + ]; /** - * Return key for request + * Post request for creating tax rule * - * @param array $data - * @return null|string + * @param FixtureInterface $fixture + * @return mixed|null */ - protected function _getParamKey(array $data) + public function persist(FixtureInterface $fixture = null) { - return isset($data['input_name']) ? $data['input_name'] : null; + $data = $this->prepareData($fixture); + + $url = $_ENV['app_backend_url'] . 'tax/rule/save/?back=1'; + $curl = new BackendDecorator(new CurlTransport(), new Config()); + $curl->addOption(CURLOPT_HEADER, 1); + $curl->write(CurlInterface::POST, $url, '1.0', array(), $data); + $response = $curl->read(); + $curl->close(); + + preg_match("~Location: [^\s]*\/rule\/(\d+)~", $response, $matches); + $id = isset($matches[1]) ? $matches[1] : null; + return ['id' => $id]; } /** - * Return value for request + * Returns data for curl POST params * - * @param array $data - * @return null|string + * @param FixtureInterface $fixture + * @return mixed */ - protected function _getParamValue(array $data) + protected function prepareData($fixture) { - if (array_key_exists('input_value', $data)) { - return $data['input_value']; - } + $data = $fixture->getData(); + $fields = [ + 'tax_rate', + 'tax_customer_class', + 'tax_product_class', + ]; - if (array_key_exists('value', $data)) { - return $data['value']; + foreach ($fields as $field) { + if (!array_key_exists($field, $data)) { + $data[$field][] = $this->defaultTaxClasses[$field]; + continue; + } + $fieldFixture = $fixture->getDataFieldConfig($field); + $fieldFixture = $fieldFixture['source']->getFixture(); + foreach ($data[$field] as $key => $value) { + $id = $fieldFixture[$key]->getId(); + if ($id === null) { + $fieldFixture[$key]->persist(); + $id = $fieldFixture[$key]->getId(); + } + $data[$field][$key] = $id; + } } - return null; - } - /** - * Post request for creating tax rate - * - * @param FixtureInterface $fixture [optional] - * @return mixed|string - */ - public function persist(FixtureInterface $fixture = null) - { - $url = $_ENV['app_backend_url'] . 'tax/rule/save/?back=1'; - $curl = new BackendDecorator(new CurlTransport(), new Config()); - $curl->addOption(CURLOPT_HEADER, 1); - $curl->write(CurlInterface::POST, $url, '1.0', array(), $this->_getPostParams($fixture)); - $response = $curl->read(); - $curl->close(); - preg_match("~Location: [^\s]*\/rule\/(\d+)~", $response, $matches); - return isset($matches[1]) ? $matches[1] : null; + return $data; } } diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxRule/TaxRuleInterface.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxRule/TaxRuleInterface.php new file mode 100644 index 0000000000000..560adf970ccc4 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxRule/TaxRuleInterface.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\Tax\Test\Handler\TaxRule; + +use Mtf\Handler\HandlerInterface; + +/** + * Interface TaxRuleInterface + */ +interface TaxRuleInterface extends HandlerInterface +{ + // +} diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Page/Adminhtml/TaxRuleIndex.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Page/Adminhtml/TaxRuleIndex.php new file mode 100644 index 0000000000000..db54d44e9d6c4 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Page/Adminhtml/TaxRuleIndex.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\Tax\Test\Page\Adminhtml; + +use Mtf\Page\BackendPage; + +/** + * Class TaxRuleIndex + */ +class TaxRuleIndex extends BackendPage +{ + const MCA = 'tax/rule/index'; + + protected $_blocks = [ + 'gridPageActions' => [ + 'name' => 'gridPageActions', + 'class' => 'Magento\Backend\Test\Block\GridPageActions', + 'locator' => '.page-main-actions', + 'strategy' => 'css selector', + ], + 'taxRuleGrid' => [ + 'name' => 'taxRuleGrid', + 'class' => 'Magento\Tax\Test\Block\Adminhtml\Rule\Grid', + 'locator' => '#taxRuleGrid', + 'strategy' => 'css selector', + ], + 'messagesBlock' => [ + 'name' => 'messagesBlock', + 'class' => 'Magento\Core\Test\Block\Messages', + 'locator' => '#messages', + 'strategy' => 'css selector', + ], + ]; + + /** + * @return \Magento\Backend\Test\Block\GridPageActions + */ + public function getGridPageActions() + { + return $this->getBlockInstance('gridPageActions'); + } + + /** + * @return \Magento\Tax\Test\Block\Adminhtml\Rule\Grid + */ + public function getTaxRuleGrid() + { + return $this->getBlockInstance('taxRuleGrid'); + } + + /** + * @return \Magento\Core\Test\Block\Messages + */ + public function getMessagesBlock() + { + return $this->getBlockInstance('messagesBlock'); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Page/Adminhtml/TaxRuleIndex.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/Page/Adminhtml/TaxRuleIndex.xml new file mode 100644 index 0000000000000..af69bc3bf86e1 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Page/Adminhtml/TaxRuleIndex.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="tax/rule/index"> + <block> + <name>gridPageActions</name> + <class>Magento\Backend\Test\Block\GridPageActions</class> + <locator>.page-main-actions</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>taxRuleGrid</name> + <class>Magento\Tax\Test\Block\Adminhtml\Rule\Grid</class> + <locator>#taxRuleGrid</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/Tax/Test/Page/Adminhtml/TaxRuleNew.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Page/Adminhtml/TaxRuleNew.php new file mode 100644 index 0000000000000..e1fe5b94aac98 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Page/Adminhtml/TaxRuleNew.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\Tax\Test\Page\Adminhtml; + +use Mtf\Page\BackendPage; + +/** + * Class TaxRuleNew + */ +class TaxRuleNew extends BackendPage +{ + const MCA = 'tax/rule/new'; + + protected $_blocks = [ + 'formPageActions' => [ + 'name' => 'formPageActions', + 'class' => 'Magento\Backend\Test\Block\FormPageActions', + 'locator' => '.page-main-actions', + 'strategy' => 'css selector', + ], + 'taxRuleForm' => [ + 'name' => 'taxRuleForm', + 'class' => 'Magento\Tax\Test\Block\Adminhtml\Rule\Edit\Form', + 'locator' => '#edit_form', + 'strategy' => 'css selector', + ], + 'messagesBlock' => [ + 'name' => 'messagesBlock', + 'class' => 'Magento\Core\Test\Block\Messages', + 'locator' => '#messages', + 'strategy' => 'css selector', + ], + ]; + + /** + * @return \Magento\Backend\Test\Block\FormPageActions + */ + public function getFormPageActions() + { + return $this->getBlockInstance('formPageActions'); + } + + /** + * @return \Magento\Tax\Test\Block\Adminhtml\Rule\Edit\Form + */ + public function getTaxRuleForm() + { + return $this->getBlockInstance('taxRuleForm'); + } + + /** + * @return \Magento\Core\Test\Block\Messages + */ + public function getMessagesBlock() + { + return $this->getBlockInstance('messagesBlock'); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Page/Adminhtml/TaxRuleNew.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/Page/Adminhtml/TaxRuleNew.xml new file mode 100644 index 0000000000000..efc8f5c65069b --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Page/Adminhtml/TaxRuleNew.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="tax/rule/new"> + <block> + <name>formPageActions</name> + <class>Magento\Backend\Test\Block\FormPageActions</class> + <locator>.page-main-actions</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>taxRuleForm</name> + <class>Magento\Tax\Test\Block\Adminhtml\Rule\Edit\Form</class> + <locator>#edit_form</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/Tax/Test/Page/TaxRule.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Page/TaxRule.php deleted file mode 100644 index 56a065f7394b0..0000000000000 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/Page/TaxRule.php +++ /dev/null @@ -1,90 +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\Tax\Test\Page; - -use Mtf\Page\Page; -use Mtf\Factory\Factory; -use Mtf\Client\Element\Locator; -use Magento\Backend\Test\Block\GridPageActions; - -/** - * Class TaxRule. - * Tax rule manage grid. - * - */ -class TaxRule extends Page -{ - /** - * URL for customer login - */ - const MCA = 'tax/rule/'; - - /** - * Tax rules grid - * - * @var string - */ - protected $taxRuleGrid = '#taxRuleGrid'; - - /** - * Grid page actions block - * - * @var string - */ - protected $pageActionsBlock = '.page-main-actions'; - - /** - * Custom constructor - */ - protected function _init() - { - $this->_url = $_ENV['app_backend_url'] . self::MCA; - } - - /** - * Get tax rules grid - * - * @return \Magento\Tax\Test\Block\Adminhtml\Rule\Grid - */ - public function getRuleGrid() - { - return Factory::getBlockFactory()->getMagentoTaxAdminhtmlRuleGrid( - $this->_browser->find($this->taxRuleGrid, Locator::SELECTOR_CSS) - ); - } - - /** - * Get Grid page actions block - * - * @return GridPageActions - */ - public function getActionsBlock() - { - return Factory::getBlockFactory()->getMagentoBackendGridPageActions( - $this->_browser->find($this->pageActionsBlock) - ); - } -} diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Page/TaxRuleNew.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Page/TaxRuleNew.php deleted file mode 100644 index a61abcab33508..0000000000000 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/Page/TaxRuleNew.php +++ /dev/null @@ -1,109 +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\Tax\Test\Page; - -use Mtf\Page\Page; -use Mtf\Factory\Factory; -use Mtf\Client\Element\Locator; -use Magento\Backend\Test\Block\FormPageActions; - -/** - * Class TaxRuleNew - * Class for new tax rule page - * - */ -class TaxRuleNew extends Page -{ - /** - * URL for new tax rule - */ - const MCA = 'tax/rule/new/'; - - /** - * Form for tax rule creation - * - * @var string - */ - protected $editBlock = '[id="page:main-container"]'; - - /** - * Global messages block - * - * @var string - */ - protected $messagesBlock = '#messages .messages'; - - /** - * Form page actions block - * - * @var string - */ - protected $pageActionsBlock = '.page-main-actions'; - - /** - * Custom constructor - */ - protected function _init() - { - $this->_url = $_ENV['app_backend_url'] . self::MCA; - } - - /** - * Get form for tax rule creation - * - * @return \Magento\Tax\Test\Block\Adminhtml\Rule\Edit\Form - */ - public function getEditBlock() - { - return Factory::getBlockFactory()->getMagentoTaxAdminhtmlRuleEditForm( - $this->_browser->find($this->editBlock, Locator::SELECTOR_CSS) - ); - } - - /** - * Get global messages block - * - * @return \Magento\Core\Test\Block\Messages - */ - public function getMessagesBlock() - { - return Factory::getBlockFactory()->getMagentoCoreMessages( - $this->_browser->find($this->messagesBlock, Locator::SELECTOR_CSS) - ); - } - - /** - * Get Form page actions block - * - * @return FormPageActions - */ - public function getPageActionsBlock() - { - return Factory::getBlockFactory()->getMagentoBackendFormPageActions( - $this->_browser->find($this->pageActionsBlock) - ); - } -} diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Repository/TaxClass.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Repository/TaxClass.php index 230e5a3447b30..bfbc4b50cb0f2 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/Repository/TaxClass.php +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Repository/TaxClass.php @@ -27,25 +27,36 @@ use Mtf\Repository\AbstractRepository; /** - * Class Tax Class Repository - * + * Class TaxClass Repository */ class TaxClass extends AbstractRepository { - 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['Taxable Goods'] = [ + 'class_id' => '2', + 'class_name' => 'Taxable Goods', + 'class_type' => 'PRODUCT', + 'id' => '2', + 'mtf_dataset_name' => 'Taxable Goods', + ]; + + $this->_data['Retail Customer'] = [ + 'class_id' => '3', + 'class_name' => 'Retail Customer', + 'class_type' => 'CUSTOMER', + 'id' => '3', + 'mtf_dataset_name' => 'Retail Customer', + ]; - $this->_data['customer_tax_class'] = array( - 'config' => $defaultConfig, - 'data' => $defaultData - ); + $this->_data['customer_tax_class'] = [ + 'class_name' => 'Customer Tax Class %isolation%', + 'class_type' => 'CUSTOMER', + ]; - $this->_data['product_tax_class'] = $this->_data['customer_tax_class']; - $this->_data['product_tax_class']['data']['fields']['class_name']['value'] = 'Product Tax Class %isolation%'; - $this->_data['product_tax_class']['data']['fields']['class_type']['value'] = 'PRODUCT'; + $this->_data['product_tax_class'] = [ + 'class_name' => 'Product Tax Class %isolation%', + 'class_type' => 'PRODUCT', + ]; } } diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Repository/TaxClass.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/Repository/TaxClass.xml new file mode 100644 index 0000000000000..3b8a8e20aa1b1 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Repository/TaxClass.xml @@ -0,0 +1,41 @@ +<?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) + */ +--> +<repository class="Magento\Tax\Test\Repository\TaxClass"> + <item> + <class_id>2</class_id> + <class_name><![CDATA[Taxable Goods]]></class_name> + <class_type><![CDATA[PRODUCT]]></class_type> + <id>2</id> + <mtf_dataset_name><![CDATA[taxable_goods]]></mtf_dataset_name> + </item> + <item> + <class_id>3</class_id> + <class_name><![CDATA[Retail Customer]]></class_name> + <class_type><![CDATA[CUSTOMER]]></class_type> + <id>3</id> + <mtf_dataset_name><![CDATA[retail_customer]]></mtf_dataset_name> + </item> +</repository> 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 f0d0388a7dbc7..958373b4dc044 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 @@ -27,147 +27,92 @@ use Mtf\Repository\AbstractRepository; /** - * Class Tax Rate Repository - * + * Class TaxRate Repository */ class TaxRate extends AbstractRepository { - /** - * Initialize default parameters - * - * @param array $defaultConfig - * @param array $defaultData - */ - 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['US-CA-*-Rate 1'] = [ + 'tax_calculation_rate_id' => '1', + 'tax_country_id' => 'US', + 'tax_region_id' => '12', + 'tax_postcode' => '*', + 'code' => 'US-CA-*-Rate 1', + 'rate' => '8.2500', + 'zip_is_range' => '', + 'zip_from' => '', + 'zip_to' => '', + 'id' => '1', + 'mtf_dataset_name' => 'US-CA-*-Rate 1', + ]; - $this->_data['us_ca_rate_8_25'] = array_replace_recursive($this->_data['default'], $this->_getRateUSCA()); - $this->_data['us_ny_rate_8_375'] = array_replace_recursive($this->_data['default'], $this->_getRateUSNY()); - $this->_data['us_ny_rate_8_1'] = array_replace_recursive($this->_data['default'], $this->_getRateUSNYCustom()); - $this->_data['paypal_rate_8_25'] = array_replace_recursive($this->_data['default'], $this->_getRatePayPal()); - $this->_data['uk_full_tax_rate'] = $this->getUKFullTaxRate($this->_data['default']); - } + $this->_data['US-NY-*-Rate 1'] = [ + 'tax_calculation_rate_id' => '2', + 'tax_country_id' => 'US', + 'tax_region_id' => '43', + 'tax_postcode' => '*', + 'code' => 'US-NY-*-Rate 1', + 'rate' => '8.3750', + 'zip_is_range' => '', + 'zip_from' => '', + 'zip_to' => '', + 'id' => '2', + 'mtf_dataset_name' => 'US-NY-*-Rate 1', + ]; - /** - * Rate US CA with 8.25% - * - * @return array - */ - protected function _getRateUSCA() - { - return array( - 'data' => array( - 'fields' => array( - 'rate' => array( - 'value' => '8.25' - ), - 'tax_postcode' => array( - 'value' => '90230' - ), - 'tax_region_id' => array( - 'value' => '12' // California - ) - ) - ) - ); - } + $this->_data['us_ca_rate_8_25'] = [ + 'code' => 'Tax Rate %isolation%', + 'rate' => '8.25', + 'tax_country_id' => 'United States', + 'tax_postcode' => '90230', + 'tax_region_id' => 'California', + ]; - /** - * Rate US CA with 8.25% - * - * @return array - */ - protected function _getRatePayPal() - { - return array( - 'data' => array( - 'fields' => array( - 'rate' => array( - 'value' => '8.25' - ), - 'tax_postcode' => array( - 'value' => '95131' - ), - 'tax_region_id' => array( - 'value' => '12' // California - ) - ) - ) - ); - } + $this->_data['us_ny_rate_8_375'] = [ + 'code' => 'Tax Rate %isolation%', + 'rate' => '8.375', + 'tax_country_id' => 'United States', + 'tax_region_id' => 'New York', + ]; - /** - * Rate US NY with 8.375% - * - * @return array - */ - protected function _getRateUSNY() - { - return array( - 'data' => array( - 'fields' => array( - 'rate' => array( - 'value' => '8.375' - ), - 'tax_region_id' => array( - 'value' => '43' // New York - ) - ) - ) - ); - } + $this->_data['us_ny_rate_8_1'] = [ + 'code' => 'US-NY-*-%isolation%', + 'rate' => '8.1', + 'tax_country_id' => 'United States', + 'tax_region_id' => 'New York', + ]; - /** - * Rate US NY with 8.1% - * - * @return array - */ - protected function _getRateUSNYCustom() - { - return array( - 'data' => array( - 'fields' => array( - 'code' => array( - 'value' => 'US-NY-*-%isolation%' - ), - 'rate' => array( - 'value' => '8.1' - ), - 'tax_region_id' => array( - 'value' => 'New York', - 'input' => 'select' - ) - ) - ) - ); - } + $this->_data['paypal_rate_8_25'] = [ + 'code' => 'Tax Rate %isolation%', + 'rate' => '8.25', + 'tax_country_id' => 'United States', + 'tax_postcode' => '95131', + 'tax_region_id' => 'California', + ]; - /** - * Get UK full tax rate - * - * @param array $defaultData - * @return array - */ - protected function getUKFullTaxRate($defaultData) - { - return array_replace_recursive( - $defaultData, - array( - 'data' => array( - 'fields' => array( - 'rate' => array( - 'value' => 20 - ), - 'tax_country_id' => array( - 'value' => 'GB', - ), - ), - ), - ) - ); + $this->_data['uk_full_tax_rate'] = [ + 'code' => 'Tax Rate %isolation%', + 'rate' => '10', + 'tax_country_id' => 'United Kingdom', + 'tax_postcode' => '*', + ]; + + $this->_data['default'] = [ + 'code' => 'TaxIdentifier%isolation%', + 'tax_postcode' => '*', + 'tax_country_id' => 'Australia', + 'rate' => '20' + ]; + + $this->_data['withZipRange'] = [ + 'code' => 'TaxIdentifier%isolation%', + 'zip_is_range' => 'Yes', + 'zip_from' => '90001', + 'zip_to' => '96162', + 'tax_country_id' => 'United States', + 'tax_region_id' => 'California', + 'rate' => '15.5' + ]; } } diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Repository/TaxRate.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/Repository/TaxRate.xml new file mode 100644 index 0000000000000..c50d07947fdf8 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Repository/TaxRate.xml @@ -0,0 +1,53 @@ +<?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) + */ +--> +<repository class="Magento\Tax\Test\Repository\TaxRate"> + <item> + <tax_calculation_rate_id>1</tax_calculation_rate_id> + <tax_country_id><![CDATA[US]]></tax_country_id> + <tax_region_id>12</tax_region_id> + <tax_postcode><![CDATA[*]]></tax_postcode> + <code><![CDATA[US-CA-*-Rate 1]]></code> + <rate>8.2500</rate> + <zip_is_range><![CDATA[]]></zip_is_range> + <zip_from><![CDATA[]]></zip_from> + <zip_to><![CDATA[]]></zip_to> + <id>1</id> + <mtf_dataset_name><![CDATA[US-CA-*-Rate 1]]></mtf_dataset_name> + </item> + <item> + <tax_calculation_rate_id>2</tax_calculation_rate_id> + <tax_country_id><![CDATA[US]]></tax_country_id> + <tax_region_id>43</tax_region_id> + <tax_postcode><![CDATA[*]]></tax_postcode> + <code><![CDATA[US-NY-*-Rate 1]]></code> + <rate>8.3750</rate> + <zip_is_range><![CDATA[]]></zip_is_range> + <zip_from><![CDATA[]]></zip_from> + <zip_to><![CDATA[]]></zip_to> + <id>2</id> + <mtf_dataset_name><![CDATA[US-NY-*-Rate 1]]></mtf_dataset_name> + </item> +</repository> 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 f72717da87010..2b57af9581d92 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 @@ -27,124 +27,98 @@ use Mtf\Repository\AbstractRepository; /** - * Class Tax Rule Repository - * + * Class TaxRule Repository */ class TaxRule extends AbstractRepository { - /** - * Initialize repository data - * - * @param array $defaultConfig - * @param array $defaultData - */ - 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['custom_rule'] = [ + 'code' => 'TaxIdentifier%isolation%', + 'tax_rate' => [ + 'dataSet' => [ + 0 => 'us_ca_rate_8_25', + 1 => 'us_ny_rate_8_375', + ] + ], + ]; - $this->_data['custom_rule'] = array_replace_recursive($this->_data['default'], $this->_getCustomTaxRule()); - $this->_data['us_ca_ny_rule'] = $this->_getUscanyTaxRule(); - $this->_data['uk_full_tax_rule'] = $this->getUKFullTaxRule($this->_data['default']); - } + $this->_data['us_ca_ny_rule'] = [ + 'code' => 'Tax Rule %isolation%', + 'tax_rate' => [ + 'dataSet' => [ + 0 => 'US-CA-*-Rate 1', + 1 => 'us_ny_rate_8_1', + ], + ], + 'tax_customer_class' => [ + 'dataSet' => [ + 0 => 'Retail Customer', + 1 => 'customer_tax_class', + ], + ], + 'tax_product_class' => [ + 'dataSet' => [ + 0 => 'Taxable Goods', + 1 => 'product_tax_class', + ], + ], + 'priority' => '0', + 'position' => '0', + ]; - /** - * Return data structure for Tax Rule with custom Rates, Tax class - * - * @return array - */ - protected function _getCustomTaxRule() - { - return array( - 'data' => array( - 'fields' => array( - 'tax_rate[0]' => array( - 'value' => '%us_ca_rate_8_25%' - ), - 'tax_rate[1]' => array( - 'value' => '%us_ny_rate_8_375%' - ), - ) - ) - ); - } + $this->_data['uk_full_tax_rule'] = [ + 'code' => 'TaxIdentifier%isolation%', + 'tax_rate' => [ + 'dataSet' => [ + 0 => 'uk_full_tax_rate', + ], + ], + ]; - /** - * Return data structure for Tax Rule with custom Rates, Tax classes - * - * @return array - */ - protected function _getUscanyTaxRule() - { - return array( - 'data' => array( - 'fields' => array( - 'code' => array( - 'value' => 'Tax Rule %isolation%' - ), - 'tax_rate' => array( - array( - 'code' => array( - 'value' => 'US-CA-*-Rate 1' - ) - ), - array( - 'code' => array( - 'value' => 'US-NY-*-%isolation%' - ), - 'rate' => array( - 'value' => '8.1' - ), - 'tax_region_id' => array( - 'value' => 'New York', - 'input' => 'select' - ) - ) - ), - 'tax_customer_class' => array( - 'value' => array( - 'Retail Customer', - 'Customer Tax Class %isolation%' - ) - ), - 'tax_product_class' => array( - 'value' => array( - 'Taxable Goods', - 'Product Tax Class %isolation%' - ) - ), - 'priority' => array( - 'value' => '0' - ), - 'position' => array( - 'value' => '0' - ) - ) - ) - ); - } + $this->_data['tax_rule_default'] = [ + 'code' => 'TaxIdentifier%isolation%', + 'tax_rate' => [ + 'dataSet' => [ + 0 => 'US-CA-*-Rate 1' + ], + ], + 'tax_customer_class' => [ + 'dataSet' => [ + 0 => 'Retail Customer', + ], + ], + 'tax_product_class' => [ + 'dataSet' => [ + 0 => 'Taxable Goods', + ], + ], + 'priority' => '1', + 'position' => '1', + ]; - /** - * Get UK full tax rule - * - * @param array $defaultData - * @return array - */ - protected function getUKFullTaxRule($defaultData) - { - return array_replace_recursive( - $defaultData, - array( - 'data' => array( - 'fields' => array( - 'tax_rate' => array( - 'value' => '%uk_full_tax_rate%' - ), - ), - ), - ) - ); + $this->_data['tax_rule_with_custom_tax_classes'] = [ + 'code' => 'TaxIdentifier%isolation%', + 'tax_rate' => [ + 'dataSet' => [ + 0 => 'US-CA-*-Rate 1', + 1 => 'US-NY-*-Rate 1', + ], + ], + 'tax_customer_class' => [ + 'dataSet' => [ + 0 => 'Retail Customer', + 1 => 'customer_tax_class', + ], + ], + 'tax_product_class' => [ + 'dataSet' => [ + 0 => 'Taxable Goods', + 1 => 'product_tax_class', + ], + ], + 'priority' => '1', + 'position' => '1', + ]; } } diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRuleEntityTest.php b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRuleEntityTest.php new file mode 100644 index 0000000000000..86180d2db3865 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRuleEntityTest.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\Tax\Test\TestCase; + +use Magento\Tax\Test\Fixture\TaxRule; +use Magento\Tax\Test\Page\Adminhtml\TaxRuleIndex; +use Magento\Tax\Test\Page\Adminhtml\TaxRuleNew; +use Mtf\TestCase\Injectable; + +/** + * Test Creation for CreateTaxRuleEntity + * + * Test Flow: + * 1. Log in as default admin user. + * 2. Go to Stores > Tax Rules. + * 3. Click 'Add New Tax Rule' button. + * 4. Fill in data according to dataSet + * 5. Save Tax Rule. + * 6. Perform all assertions. + * + * @group Tax_(CS) + * @ZephyrId MAGETWO-20913 + */ +class CreateTaxRuleEntityTest extends Injectable +{ + /** + * @var TaxRuleIndex + */ + protected $taxRuleIndexPage; + + /** + * @var TaxRuleNew + */ + protected $taxRuleNewPage; + + /** + * @param TaxRuleIndex $taxRuleIndexPage + * @param TaxRuleNew $taxRuleNewPage + */ + public function __inject( + TaxRuleIndex $taxRuleIndexPage, + TaxRuleNew $taxRuleNewPage + ) { + $this->taxRuleIndexPage = $taxRuleIndexPage; + $this->taxRuleNewPage = $taxRuleNewPage; + } + + /** + * @param TaxRule $taxRule + */ + public function testCreateTaxRule(TaxRule $taxRule) + { + // Steps + $this->taxRuleIndexPage->open(); + $this->taxRuleIndexPage->getGridPageActions()->addNew(); + $this->taxRuleNewPage->getTaxRuleForm()->fill($taxRule); + $this->taxRuleNewPage->getFormPageActions()->save(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRuleEntityTest/testCreateTaxRule.csv b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRuleEntityTest/testCreateTaxRule.csv new file mode 100644 index 0000000000000..3b880e7f96e98 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRuleEntityTest/testCreateTaxRule.csv @@ -0,0 +1,5 @@ +"taxRule/data/code";"taxRule/data/tax_rate/dataSet/rate_0";"taxRule/data/tax_rate/dataSet/rate_1";"taxRule/data/tax_rate/dataSet/rate_2";"taxRule/data/tax_customer_class/dataSet/class_0";"taxRule/data/tax_customer_class/dataSet/class_1";"taxRule/data/tax_product_class/dataSet/class_0";"taxRule/data/tax_product_class/dataSet/class_1";"taxRule/data/priority";"taxRule/data/position";"constraint" +"TaxIdentifier%isolation%";"US-CA-*-Rate 1";"-";"-";"-";"-";"-";"-";"-";"-";"assertTaxRuleSuccessSaveMessage, assertTaxRuleInGrid, assertTaxRuleForm" +"TaxIdentifier%isolation%";"US-CA-*-Rate 1";"US-NY-*-Rate 1";"-";"customer_tax_class";"-";"product_tax_class";"-";1;1;"assertTaxRuleSuccessSaveMessage, assertTaxRuleInGrid, assertTaxRuleForm" +"TaxIdentifier%isolation%";"default";"US-NY-*-Rate 1";"US-CA-*-Rate 1";"Retail Customer";"customer_tax_class";"Taxable Goods";"-";"-";1;"assertTaxRuleSuccessSaveMessage, assertTaxRuleInGrid, assertTaxRuleForm" +"TaxIdentifier%isolation%";"withZipRange";"US-CA-*-Rate 1";"-";"Retail Customer";"customer_tax_class";"Taxable Goods";"product_tax_class";1;"-";"assertTaxRuleSuccessSaveMessage, assertTaxRuleInGrid, assertTaxRuleForm" diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxRuleTest.php b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxRuleTest.php index 16e48a448dfec..c1d1dfd028e10 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxRuleTest.php +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxRuleTest.php @@ -18,6 +18,9 @@ * 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) */ @@ -31,7 +34,6 @@ /** * Class TaxRuleTest * Functional test for Tax Rule configuration - * */ class TaxRuleTest extends Functional { @@ -43,17 +45,17 @@ class TaxRuleTest extends Functional public function testCreateTaxRule() { //Data - $fixture = Factory::getFixtureFactory()->getMagentoTaxTaxRule(); - $fixture->switchData('us_ca_ny_rule'); + $objectManager = Factory::getObjectManager(); + $fixture = $objectManager->create('\Magento\Tax\Test\Fixture\TaxRule', ['dataSet' => 'us_ca_ny_rule']); //Pages - $taxGridPage = Factory::getPageFactory()->getTaxRule(); + $taxGridPage = Factory::getPageFactory()->getTaxRuleIndex(); $newTaxRulePage = Factory::getPageFactory()->getTaxRuleNew(); //Steps Factory::getApp()->magentoBackendLoginUser(); $taxGridPage->open(); - $taxGridPage->getActionsBlock()->addNew(); - $newTaxRulePage->getEditBlock()->fill($fixture); - $newTaxRulePage->getPageActionsBlock()->saveAndContinue(); + $taxGridPage->getGridPageActions()->addNew(); + $newTaxRulePage->getTaxRuleForm()->fill($fixture); + $newTaxRulePage->getFormPageActions()->saveAndContinue(); //Verifying $newTaxRulePage->getMessagesBlock()->assertSuccessMessage(); $this->_assertOnGrid($fixture); @@ -67,19 +69,19 @@ public function testCreateTaxRule() protected function _assertOnGrid(TaxRule $fixture) { //Data - $taxRates = array(); - foreach ($fixture->getTaxRate() as $rate) { - $taxRates[] = $rate['code']['value']; + $filter = [ + 'code' => $fixture->getCode(), + 'tax_rate' => implode(', ', $fixture->getTaxRate()), + ]; + if ($fixture->getTaxCustomerClass() !== null) { + $filter['tax_customer_class'] = implode(', ', $fixture->getTaxCustomerClass()); + } + if ($fixture->getTaxProductClass() !== null) { + $filter['tax_product_class'] = implode(', ', $fixture->getTaxProductClass()); } - $filter = array( - 'name' => $fixture->getTaxRuleName(), - 'customer_tax_class' => implode(', ', $fixture->getTaxClass('customer')), - 'product_tax_class' => implode(', ', $fixture->getTaxClass('product')), - 'tax_rate' => implode(', ', $taxRates) - ); //Verification - $taxGridPage = Factory::getPageFactory()->getTaxRule(); + $taxGridPage = Factory::getPageFactory()->getTaxRuleIndex(); $taxGridPage->open(); - $this->assertTrue($taxGridPage->getRuleGrid()->isRowVisible($filter), 'New tax rule was not found.'); + $this->assertTrue($taxGridPage->getTaxRuleGrid()->isRowVisible($filter), 'New tax rule was not found.'); } } diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/etc/curl/di.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/etc/curl/di.xml new file mode 100644 index 0000000000000..a27f5a1e18d03 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/etc/curl/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/Magento/Framework/ObjectManager/etc/config.xsd"> + <preference for="\Magento\Tax\Test\Handler\TaxRule\TaxRuleInterface" type="\Magento\Tax\Test\Handler\TaxRule\Curl" /> + <preference for="\Magento\Tax\Test\Handler\TaxRate\TaxRateInterface" type="\Magento\Tax\Test\Handler\TaxRate\Curl" /> + <preference for="\Magento\Tax\Test\Handler\TaxClass\TaxClassInterface" type="\Magento\Tax\Test\Handler\TaxClass\Curl" /> +</config> diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/etc/global/constraint.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/etc/global/constraint.xml new file mode 100644 index 0000000000000..54e405d8c0a07 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/etc/global/constraint.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) + */ +--> +<constraint> + <assertTaxRuleSuccessSaveMessage module="Magento_Tax"> + <severeness>low</severeness> + <require> + <taxRuleIndex class="Magento\Tax\Test\Page\Adminhtml\TaxRuleIndex" /> + </require> + </assertTaxRuleSuccessSaveMessage> + <assertTaxRuleInGrid module="Magento_Tax"> + <severeness>high</severeness> + <require> + <taxRuleIndex class="Magento\Tax\Test\Page\Adminhtml\TaxRuleIndex" /> + <taxRule class="Magento\Tax\Test\Fixture\TaxRule" /> + </require> + </assertTaxRuleInGrid> + <assertTaxRuleForm module="Magento_Tax"> + <severeness>high</severeness> + <require> + <taxRuleIndex class="Magento\Tax\Test\Page\Adminhtml\TaxRuleIndex" /> + <taxRuleNew class="Magento\Tax\Test\Page\Adminhtml\TaxRuleNew" /> + <taxRule class="Magento\Tax\Test\Fixture\TaxRule" /> + </require> + </assertTaxRuleForm> +</constraint> diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/etc/global/fixture.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/etc/global/fixture.xml index 0b810461a6838..7632665296fd7 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/etc/global/fixture.xml +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/etc/global/fixture.xml @@ -26,19 +26,29 @@ <fixture> <taxClass module="Magento_Tax"> <type>flat</type> - <entity_type>tax_calculation_rate</entity_type> + <entity_type>tax_class</entity_type> <collection>Magento\Tax\Model\Resource\TaxClass\Collection</collection> <identifier /> - <fields /> + <fields> + <id> + <attribute_code>id</attribute_code> + <backend_type>virtual</backend_type> + </id> + </fields> <data_set /> <data_config /> </taxClass> <taxRate module="Magento_Tax"> <type>flat</type> - <entity_type>tax_class</entity_type> + <entity_type>tax_calculation_rate</entity_type> <collection>Magento\Tax\Model\Resource\Calculation\Rate\Collection</collection> <identifier>code</identifier> - <fields /> + <fields> + <id> + <attribute_code>id</attribute_code> + <backend_type>virtual</backend_type> + </id> + </fields> <data_set /> <data_config /> </taxRate> @@ -47,7 +57,20 @@ <entity_type>tax_calculation_rule</entity_type> <collection>Magento\Tax\Model\Resource\Calculation\Rule\Collection</collection> <identifier>code</identifier> - <fields /> + <fields> + <tax_rate> + <attribute_code>tax_rate</attribute_code> + <backend_type>virtual</backend_type> + </tax_rate> + <tax_customer_class> + <attribute_code>tax_customer_class</attribute_code> + <backend_type>virtual</backend_type> + </tax_customer_class> + <tax_product_class> + <attribute_code>tax_product_class</attribute_code> + <backend_type>virtual</backend_type> + </tax_product_class> + </fields> <data_set /> <data_config /> </taxRule> diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/etc/global/page.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/etc/global/page.xml new file mode 100644 index 0000000000000..ddde8e9355ca7 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Tax/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> + <taxRuleIndex> + <mca>tax/rule/index</mca> + <area>adminhtml</area> + <class>Magento\Tax\Test\Page\Adminhtml\TaxRuleIndex</class> + </taxRuleIndex> + <taxRuleNew> + <mca>tax/rule/new</mca> + <area>adminhtml</area> + <class>Magento\Tax\Test\Page\Adminhtml\TaxRuleNew</class> + </taxRuleNew> +</page> 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 254d85d35574f..41120ea798992 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 @@ -47,4 +47,17 @@ public function openLink($linkTitle) ->find('//a[contains(text(), "' . $linkTitle . '")]', Locator::SELECTOR_XPATH) ->click(); } + + /** + * Is visible Link by title + * + * @param string $linkTitle + * @return bool + */ + public function isLinkVisible($linkTitle) + { + return $this->_rootElement + ->find('//a[contains(text(), "' . $linkTitle . '")]', Locator::SELECTOR_XPATH) + ->isVisible(); + } } diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/Role/Edit.php b/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/Role/Edit.php new file mode 100644 index 0000000000000..bd33825f2dced --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/Role/Edit.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\User\Test\Block\Adminhtml\Role; + +use Magento\Backend\Test\Block\Widget\FormTabs; + +/** + * Class Edit + * Role edit form page + * + * @package Magento\User\Test\Block\Adminhtml\Role + */ +class Edit extends FormTabs +{ + // +} diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/Role/Edit.xml b/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/Role/Edit.xml new file mode 100644 index 0000000000000..5a9858f60d558 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/Role/Edit.xml @@ -0,0 +1,55 @@ +<?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> + <role-info> + <class>\Magento\Backend\Test\Block\Widget\Tab</class> + <selector>#role_info_tabs_info</selector> + <strategy>css selector</strategy> + <fields> + <role_name> + <selector>[name='rolename']</selector> + <strategy>css selector</strategy> + </role_name> + </fields> + </role-info> + <role-resources-tab> + <class>\Magento\Backend\Test\Block\Widget\Tab</class> + <selector>#role_info_tabs_account</selector> + <strategy>css selector</strategy> + <fields> + <resource_access> + <input>select</input> + <selector>#all</selector> + <strategy>css selector</strategy> + </resource_access> + <roles_resources> + <input>jquerytree</input> + <selector>[data-role="resource-tree"]</selector> + <strategy>css selector</strategy> + </roles_resources> + </fields> + </role-resources-tab> +</tabs> diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/Role/PageActions.php b/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/Role/PageActions.php new file mode 100644 index 0000000000000..40fea7be4f42f --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/Role/PageActions.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) + */ + +namespace Magento\User\Test\Block\Adminhtml\Role; + +use Magento\Backend\Test\Block\FormPageActions; + +/** + * Class PageActions + * PageActions for the role edit page + * + * @package Magento\User\Test\Block\Adminhtml\Role + */ +class PageActions extends FormPageActions +{ + /** + * "Save Role" button + * + * @var string + */ + protected $saveButton = '.save-role'; +} diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/RoleGrid.php b/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/RoleGrid.php new file mode 100644 index 0000000000000..62e9fb9d2be0b --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/RoleGrid.php @@ -0,0 +1,50 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\User\Test\Block\Adminhtml; + +use Magento\Backend\Test\Block\Widget\Grid; + +/** + * Class RoleGrid + * Role grid on role index page + * + * @package Magento\User\Test\Block\Adminhtml + */ +class RoleGrid extends Grid +{ + /** + * Grid filters' selectors + * + * @var array + */ + protected $filters = [ + 'id' => [ + 'selector' => '#roleGrid_filter_role_id' + ], + 'role_name' => [ + 'selector' => '#roleGrid_filter_role_name' + ] + ]; +} diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertRoleInGrid.php b/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertRoleInGrid.php new file mode 100644 index 0000000000000..ec96db7014d59 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertRoleInGrid.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\User\Test\Constraint; + +use Mtf\Constraint\AbstractConstraint; +use Magento\User\Test\Page\Adminhtml\UserRoleIndex; +use Magento\User\Test\Fixture\AdminUserRole; + +/** + * Class AssertRoleInGrid + * + * @package Magento\User\Test\Constraint + */ +class AssertRoleInGrid extends AbstractConstraint +{ + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Asserts that saved role is present in Role Grid. + * + * @return void + */ + public function processAssert( + UserRoleIndex $rolePage, + AdminUserRole $role + ) { + $filter = ['role_name' => $role->getRoleName()]; + $rolePage->open(); + \PHPUnit_Framework_Assert::assertTrue( + $rolePage->getRoleGrid()->isRowVisible($filter), + 'Role with name \'' . $role->getRoleName() . '\' is absent in Roles grid.' + ); + } + + /** + * Returns success message if assert true. + * + * @return string + */ + public function toString() + { + return 'Role is present in Roles grid.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertRoleSuccessSaveMessage.php b/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertRoleSuccessSaveMessage.php new file mode 100644 index 0000000000000..ff1a4a3042f12 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertRoleSuccessSaveMessage.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\User\Test\Constraint; + +use Mtf\Constraint\AbstractConstraint; +use Magento\User\Test\Page\Adminhtml\UserRoleIndex; + +/** + * Class AssertRoleSuccessSaveMessage + * + * @package Magento\User\Test\Constraint + */ +class AssertRoleSuccessSaveMessage extends AbstractConstraint +{ + + const SUCCESS_MESSAGE = 'You saved the role.'; + + /** + * Constraint severeness + * + * @var string + */ + protected $severeness = 'low'; + + /** + * Asserts that success message equals to expected message. + * + * @return void + */ + public function processAssert(UserRoleIndex $rolePage) + { + $successMessage = $rolePage->getMessagesBlock()->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 message on roles page is correct.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Fixture/AdminUserRole.php b/dev/tests/functional/tests/app/Magento/User/Test/Fixture/AdminUserRole.php new file mode 100644 index 0000000000000..e19d3c80dd79d --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/User/Test/Fixture/AdminUserRole.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\User\Test\Fixture; + +use Mtf\Fixture\InjectableFixture; + +/** + * Class AdminUserRole + * + * @package Magento\User\Test\Fixture + */ +class AdminUserRole extends InjectableFixture +{ + /** + * @var string + */ + protected $repositoryClass = 'Magento\User\Test\Repository\AdminUserRole'; + + /** + * @var string + */ + protected $handlerInterface = 'Magento\User\Test\Handler\AdminUserRole\AdminUserRoleInterface'; + + protected $defaultDataSet = [ + 'rolename' => 'AdminRole%isolation%', + 'resource_access' => 'All', + ]; + + protected $role_id = [ + 'attribute_code' => 'role_id', + 'backend_type' => 'int', + 'is_required' => '1', + 'default_value' => '', + 'input' => '', + ]; + + protected $parent_id = [ + 'attribute_code' => 'parent_id', + 'backend_type' => 'int', + 'is_required' => '', + 'default_value' => '0', + 'input' => '', + ]; + + protected $tree_level = [ + 'attribute_code' => 'tree_level', + 'backend_type' => 'smallint', + 'is_required' => '', + 'default_value' => '0', + 'input' => '', + ]; + + protected $sort_order = [ + 'attribute_code' => 'sort_order', + 'backend_type' => 'smallint', + 'is_required' => '', + 'default_value' => '0', + 'input' => '', + ]; + + protected $role_type = [ + 'attribute_code' => 'role_type', + 'backend_type' => 'varchar', + 'is_required' => '', + 'default_value' => '0', + 'input' => '', + ]; + + protected $user_id = [ + 'attribute_code' => 'user_id', + 'backend_type' => 'int', + 'is_required' => '', + 'default_value' => '0', + 'input' => '', + ]; + + protected $role_name = [ + 'attribute_code' => 'role_name', + 'backend_type' => 'varchar', + 'is_required' => '', + 'default_value' => '', + 'input' => '', + ]; + + protected $user_type = [ + 'attribute_code' => 'user_type', + 'backend_type' => 'varchar', + 'is_required' => '', + 'default_value' => '', + 'input' => '', + ]; + + protected $resource_access = [ + 'attribute_code' => 'resource_access', + 'backend_type' => 'virtual', + ]; + + protected $roles_resources = [ + 'attribute_code' => 'roles_resources', + 'backend_type' => 'virtual', + ]; + + public function getRoleId() + { + return $this->getData('role_id'); + } + + public function getParentId() + { + return $this->getData('parent_id'); + } + + public function getTreeLevel() + { + return $this->getData('tree_level'); + } + + public function getSortOrder() + { + return $this->getData('sort_order'); + } + + public function getRoleType() + { + return $this->getData('role_type'); + } + + public function getUserId() + { + return $this->getData('user_id'); + } + + public function getRoleName() + { + return $this->getData('role_name'); + } + + public function getUserType() + { + return $this->getData('user_type'); + } + + public function getGwsIsAll() + { + return $this->getData('gws_is_all'); + } + + public function getGwsWebsites() + { + return $this->getData('gws_websites'); + } + + public function getGwsStoreGroups() + { + return $this->getData('gws_store_groups'); + } + + public function getResourceAccess() + { + return $this->getData('resource_access'); + } + + public function getRolesResources() + { + return $this->getData('roles_resources'); + } +} diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Fixture/AdminUserRole.xml b/dev/tests/functional/tests/app/Magento/User/Test/Fixture/AdminUserRole.xml new file mode 100644 index 0000000000000..9d091e47fae32 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/User/Test/Fixture/AdminUserRole.xml @@ -0,0 +1,99 @@ +<?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\User\Test\Fixture\AdminUserRole"> + <module>Magento_User</module> + <type>flat</type> + <entity_type>admin_role</entity_type> + <collection>Magento\User\Model\Resource\Role\User\Collection</collection> + <fields> + <role_id> + <attribute_code>role_id</attribute_code> + <backend_type>int</backend_type> + <is_required>1</is_required> + <default_value></default_value> + <input></input> + </role_id> + <parent_id> + <attribute_code>parent_id</attribute_code> + <backend_type>int</backend_type> + <is_required></is_required> + <default_value>0</default_value> + <input></input> + </parent_id> + <tree_level> + <attribute_code>tree_level</attribute_code> + <backend_type>smallint</backend_type> + <is_required></is_required> + <default_value>0</default_value> + <input></input> + </tree_level> + <sort_order> + <attribute_code>sort_order</attribute_code> + <backend_type>smallint</backend_type> + <is_required></is_required> + <default_value>0</default_value> + <input></input> + </sort_order> + <role_type> + <attribute_code>role_type</attribute_code> + <backend_type>varchar</backend_type> + <is_required></is_required> + <default_value>0</default_value> + <input></input> + </role_type> + <user_id> + <attribute_code>user_id</attribute_code> + <backend_type>int</backend_type> + <is_required></is_required> + <default_value>0</default_value> + <input></input> + </user_id> + <role_name> + <attribute_code>role_name</attribute_code> + <backend_type>varchar</backend_type> + <is_required></is_required> + <default_value></default_value> + <input></input> + </role_name> + <user_type> + <attribute_code>user_type</attribute_code> + <backend_type>varchar</backend_type> + <is_required></is_required> + <default_value></default_value> + <input></input> + </user_type> + <resource_access> + <attribute_code>resource_access</attribute_code> + <backend_type>virtual</backend_type> + </resource_access> + <roles_resources> + <attribute_code>roles_resources</attribute_code> + <backend_type>virtual</backend_type> + </roles_resources> + </fields> + <repository_class>Magento\User\Test\Repository\AdminUserRole</repository_class> + <handler_interface>Magento\User\Test\Handler\AdminUserRole\AdminUserRoleInterface</handler_interface> +</fixture> diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Page/Adminhtml/UserRoleEditRole.php b/dev/tests/functional/tests/app/Magento/User/Test/Page/Adminhtml/UserRoleEditRole.php new file mode 100644 index 0000000000000..f0700c395e8ae --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/User/Test/Page/Adminhtml/UserRoleEditRole.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\User\Test\Page\Adminhtml; + +use Mtf\Page\BackendPage; + +/** + * Class UserRoleEditRole + * + * @package Magento\User\Test\Page\Adminhtml + */ +class UserRoleEditRole extends BackendPage +{ + const MCA = 'admin/user_role/editrole'; + + protected $_blocks = [ + 'pageActions' => [ + 'name' => 'pageActions', + 'class' => 'Magento\User\Test\Block\Adminhtml\Role\PageActions', + 'locator' => '.page-main-actions', + 'strategy' => 'css selector', + ], + 'roleFormTabs' => [ + 'name' => 'roleFormTabs', + 'class' => 'Magento\User\Test\Block\Adminhtml\Role\Edit', + 'locator' => '[id="page:main-container"]', + 'strategy' => 'css selector', + ], + ]; + + /** + * @return \Magento\User\Test\Block\Adminhtml\Role\PageActions + */ + public function getPageActions() + { + return $this->getBlockInstance('pageActions'); + } + + /** + * @return \Magento\User\Test\Block\Adminhtml\Role\Edit + */ + public function getRoleFormTabs() + { + return $this->getBlockInstance('roleFormTabs'); + } +} diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Page/Adminhtml/UserRoleEditRole.xml b/dev/tests/functional/tests/app/Magento/User/Test/Page/Adminhtml/UserRoleEditRole.xml new file mode 100644 index 0000000000000..0f9ff486f6d61 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/User/Test/Page/Adminhtml/UserRoleEditRole.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/user_role/editrole" > + <block> + <name>pageActions</name> + <class>Magento\User\Test\Block\Adminhtml\Role\PageActions</class> + <locator>.page-main-actions</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>roleFormTabs</name> + <class>Magento\User\Test\Block\Adminhtml\Role\Edit</class> + <locator>[id="page:main-container"]</locator> + <strategy>css selector</strategy> + </block> +</page> diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Page/Adminhtml/UserRoleIndex.php b/dev/tests/functional/tests/app/Magento/User/Test/Page/Adminhtml/UserRoleIndex.php new file mode 100644 index 0000000000000..b4a81e25238cf --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/User/Test/Page/Adminhtml/UserRoleIndex.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\User\Test\Page\Adminhtml; + +use Mtf\Page\BackendPage; + +/** + * Class UserRoleIndex + * + * @package Magento\User\Test\Page\Adminhtml + */ +class UserRoleIndex extends BackendPage +{ + const MCA = 'admin/user_role/index'; + + protected $_blocks = [ + 'roleActions' => [ + 'name' => 'roleActions', + 'class' => 'Magento\Backend\Test\Block\GridPageActions', + 'locator' => '.page-main-actions', + 'strategy' => 'css selector', + ], + 'roleGrid' => [ + 'name' => 'roleGrid', + 'class' => 'Magento\User\Test\Block\Adminhtml\RoleGrid', + 'locator' => '#roleGrid', + 'strategy' => 'css selector', + ], + 'messagesBlock' => [ + 'name' => 'messagesBlock', + 'class' => 'Magento\Core\Test\Block\Messages', + 'locator' => '.messages', + 'strategy' => 'css selector', + ], + ]; + + /** + * @return \Magento\Backend\Test\Block\GridPageActions + */ + public function getRoleActions() + { + return $this->getBlockInstance('roleActions'); + } + + /** + * @return \Magento\User\Test\Block\Adminhtml\RoleGrid + */ + public function getRoleGrid() + { + return $this->getBlockInstance('roleGrid'); + } + + /** + * @return \Magento\Core\Test\Block\Messages + */ + public function getMessagesBlock() + { + return $this->getBlockInstance('messagesBlock'); + } +} diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Page/Adminhtml/UserRoleIndex.xml b/dev/tests/functional/tests/app/Magento/User/Test/Page/Adminhtml/UserRoleIndex.xml new file mode 100644 index 0000000000000..bc7e240e0f2b6 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/User/Test/Page/Adminhtml/UserRoleIndex.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/user_role/index" > + <block> + <name>roleActions</name> + <class>Magento\Backend\Test\Block\GridPageActions</class> + <locator>.page-main-actions</locator> + <strategy>css selector</strategy> + </block> + <block> + <name>roleGrid</name> + <class>Magento\User\Test\Block\Adminhtml\RoleGrid</class> + <locator>#roleGrid</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/User/Test/TestCase/CreateAdminUserRoleEntityTest.php b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserRoleEntityTest.php new file mode 100644 index 0000000000000..796adf8faf3ec --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserRoleEntityTest.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\User\Test\TestCase; + +use Magento\User\Test\Fixture\AdminUserRole; +use Magento\User\Test\Page\Adminhtml\UserRoleIndex; +use Magento\User\Test\Page\Adminhtml\UserRoleEditRole; +use Mtf\TestCase\Injectable; + +/** + * Test Creation for CreateAdminUserRolesEntity + * + * Test Flow: + * 1. Log in as default admin user + * 2. Go to System>Permissions>User Roles + * 3. Press "+" button to start create New Role + * 4. Fill in all data according to data set + * 5. Save role + * 6. Perform assertions + * + * @group ACL_(MX) + * @ZephyrId MAGETWO-23413 + */ +class CreateAdminUserRoleEntityTest extends Injectable +{ + /** + * @var UserRoleIndex + */ + protected $userRoleIndex; + + /** + * @var UserRoleEditRole + */ + protected $userRoleEditRole; + + /** + * @param UserRoleIndex $userRoleIndex + * @param UserRoleEditRole $userRoleEditRole + */ + public function __inject( + UserRoleIndex $userRoleIndex, + UserRoleEditRole $userRoleEditRole + ) { + $this->userRoleIndex = $userRoleIndex; + $this->userRoleEditRole = $userRoleEditRole; + } + + /** + * Runs Create Admin User Role Entity test. + * + * @param AdminUserRole $role + */ + public function testCreateUserRole(AdminUserRole $role) + { + //Steps + $this->userRoleIndex->open(); + $this->userRoleIndex->getRoleActions()->addNew(); + $this->userRoleEditRole->getRoleFormTabs()->fill($role); + $this->userRoleEditRole->getPageActions()->save(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserRoleEntityTest/testCreateUserRole.csv b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserRoleEntityTest/testCreateUserRole.csv new file mode 100644 index 0000000000000..b8c7ec03d178b --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserRoleEntityTest/testCreateUserRole.csv @@ -0,0 +1,3 @@ +"role/data/role_name";"role/data/resource_access";"role/data/roles_resources";"constraint" +AdminRole%isolation%;Custom;Sales;"assertRoleSuccessSaveMessage, assertRoleInGrid" +AdminRole%isolation%;All;-;"assertRoleSuccessSaveMessage, assertRoleInGrid" \ No newline at end of file diff --git a/dev/tests/functional/tests/app/Magento/User/Test/etc/global/constraint.xml b/dev/tests/functional/tests/app/Magento/User/Test/etc/global/constraint.xml index e2906f2b20306..f11707ddacb4c 100644 --- a/dev/tests/functional/tests/app/Magento/User/Test/etc/global/constraint.xml +++ b/dev/tests/functional/tests/app/Magento/User/Test/etc/global/constraint.xml @@ -36,4 +36,16 @@ <loginPage class="Magento\Backend\Test\Page\AdminAuthLogin" /> </require> </invalidCredentials> + <assertRoleSuccessSaveMessage module="Magento_User"> + <severeness>low</severeness> + <require> + <rolePage class="Magento\User\Test\Page\Adminhtml\UserRoleIndex" /> + </require> + </assertRoleSuccessSaveMessage> + <assertRoleInGrid module="Magento_User"> + <severeness>low</severeness> + <require> + <rolePage class="Magento\User\Test\Page\Adminhtml\UserRoleIndex" /> + </require> + </assertRoleInGrid> </constraint> diff --git a/dev/tests/functional/tests/app/Magento/User/Test/etc/global/fixture.xml b/dev/tests/functional/tests/app/Magento/User/Test/etc/global/fixture.xml index f9a8a2587598e..7358eadc454d1 100644 --- a/dev/tests/functional/tests/app/Magento/User/Test/etc/global/fixture.xml +++ b/dev/tests/functional/tests/app/Magento/User/Test/etc/global/fixture.xml @@ -29,4 +29,19 @@ <entity_type>admin_user</entity_type> <collection>Magento\User\Model\Resource\User\Collection</collection> </adminUser> + <adminUserRole module="Magento_User"> + <type>flat</type> + <entity_type>admin_role</entity_type> + <collection>Magento\User\Model\Resource\Role\User\Collection</collection> + <fields> + <resource_access> + <attribute_code>all</attribute_code> + <backend_type>virtual</backend_type> + </resource_access> + <roles_resources> + <attribute_code>roles_resources</attribute_code> + <backend_type>virtual</backend_type> + </roles_resources> + </fields> + </adminUserRole> </fixture> diff --git a/dev/tests/functional/tests/app/Magento/User/Test/etc/global/page.xml b/dev/tests/functional/tests/app/Magento/User/Test/etc/global/page.xml new file mode 100644 index 0000000000000..6a38cc6d0b0f7 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/User/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> + <adminUserRoleIndex> + <mca>admin/user_role/index</mca> + <area>adminhtml</area> + <class>Magento\User\Test\Page\Adminhtml\UserRoleIndex</class> + </adminUserRoleIndex> + <adminUserRoleNew> + <mca>admin/user_role/editrole</mca> + <area>adminhtml</area> + <class>Magento\User\Test\Page\Adminhtml\UserRoleEditRole</class> + </adminUserRoleNew> +</page> \ No newline at end of file diff --git a/dev/tests/integration/framework/Magento/TestFramework/Application.php b/dev/tests/integration/framework/Magento/TestFramework/Application.php index edcbf543fca0c..e1fa69567bb53 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Application.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Application.php @@ -149,7 +149,8 @@ public function __construct( Filesystem::STATIC_VIEW_DIR => array('path' => "{$installDir}/pub_static"), Filesystem::PUB_VIEW_CACHE_DIR => array('path' => "{$installDir}/pub_cache"), Filesystem::GENERATION_DIR => array('path' => $generationDir), - Filesystem::CACHE_DIR => array('path' => $installDir . '/cache') + Filesystem::CACHE_DIR => array('path' => $installDir . '/cache'), + Filesystem::LOG_DIR => array('path' => $installDir . '/log'), ), \Magento\Framework\App\State::PARAM_MODE => $appMode ); diff --git a/dev/tests/integration/testsuite/Magento/Email/Model/Template/FilterTest.php b/dev/tests/integration/testsuite/Magento/Email/Model/Template/FilterTest.php index 6599eb9b1cd64..97ef0078169de 100644 --- a/dev/tests/integration/testsuite/Magento/Email/Model/Template/FilterTest.php +++ b/dev/tests/integration/testsuite/Magento/Email/Model/Template/FilterTest.php @@ -50,6 +50,23 @@ public function testViewDirective() $this->assertStringEndsWith('favicon.ico', $url); } + /** + * Isolation level has been raised in order to flush themes configuration in-memory cache + * + * @magentoAppArea frontend + */ + public function testBlockDirective() + { + $class = 'Magento\\\\Theme\\\\Block\\\\Html\\\\Footer'; + $data = array("{{block class='$class' name='test.block' template='Magento_Theme::html/footer.phtml'}}", + 'block', + " class='$class' name='test.block' template='Magento_Theme::html/footer.phtml'" + + ); + $html = $this->_model->blockDirective($data); + $this->assertContains('<div class="footer-container">', $html); + } + /** * @magentoConfigFixture current_store web/unsecure/base_link_url http://example.com/ * @magentoConfigFixture admin_store web/unsecure/base_link_url http://example.com/ diff --git a/dev/tests/integration/testsuite/Magento/Tax/Model/Rate/CsvImportHandlerTest.php b/dev/tests/integration/testsuite/Magento/Tax/Model/Rate/CsvImportHandlerTest.php index 3d3cfca5bf77c..4fe351867310d 100644 --- a/dev/tests/integration/testsuite/Magento/Tax/Model/Rate/CsvImportHandlerTest.php +++ b/dev/tests/integration/testsuite/Magento/Tax/Model/Rate/CsvImportHandlerTest.php @@ -59,6 +59,7 @@ public function testImportFromCsvFileWithCorrectData() $this->assertNotEmpty($importedRuleCA->getId()); $this->assertEquals(8.25, (double)$importedRuleCA->getRate()); $this->assertEquals('US', $importedRuleCA->getTaxCountryId()); + $this->assertEquals('*', $importedRuleCA->getTaxPostcode()); $importedRuleFL = $objectManager->create( 'Magento\Tax\Model\Calculation\Rate' @@ -68,6 +69,7 @@ public function testImportFromCsvFileWithCorrectData() $this->assertNotEmpty($importedRuleFL->getId()); $this->assertEquals(15, (double)$importedRuleFL->getRate()); $this->assertEquals('US', $importedRuleFL->getTaxCountryId()); + $this->assertNull($importedRuleFL->getTaxPostcode()); } /** diff --git a/dev/tests/integration/testsuite/Magento/Tax/Model/Rate/_files/correct_rates_import_file.csv b/dev/tests/integration/testsuite/Magento/Tax/Model/Rate/_files/correct_rates_import_file.csv index 2c63dc259d96d..2c5dc1d6905cf 100644 --- a/dev/tests/integration/testsuite/Magento/Tax/Model/Rate/_files/correct_rates_import_file.csv +++ b/dev/tests/integration/testsuite/Magento/Tax/Model/Rate/_files/correct_rates_import_file.csv @@ -1,3 +1,3 @@ "Code","Country","State","Zip/Post Code","Rate","Zip/Post is Range","Range From","Range To","default" -"US-CA-*-Rate Import Test","US","CA","","8.2500","","","","" +"US-CA-*-Rate Import Test","US","CA","*","8.2500","","","","" "US-FL-*-Rate Import Test","US","FL","","15.0000","","","","" diff --git a/dev/tests/integration/testsuite/Magento/Tax/Model/Sales/Total/Quote/SetupUtil.php b/dev/tests/integration/testsuite/Magento/Tax/Model/Sales/Total/Quote/SetupUtil.php new file mode 100644 index 0000000000000..be9f738483c99 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Tax/Model/Sales/Total/Quote/SetupUtil.php @@ -0,0 +1,669 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 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\Tax\Model\Config; +use Magento\Tax\Model\Calculation; + +class SetupUtil +{ + /** + * Default tax related configurations + * + * @var array + */ + protected $defaultConfig = [ + Config::CONFIG_XML_PATH_SHIPPING_TAX_CLASS => '0', + Config::CONFIG_XML_PATH_PRICE_INCLUDES_TAX => 0, //Excluding tax + Config::CONFIG_XML_PATH_SHIPPING_INCLUDES_TAX => 0, //Excluding tax + Config::CONFIG_XML_PATH_BASED_ON => 'shipping', // or 'billing' + Config::CONFIG_XML_PATH_APPLY_ON => '0', + Config::CONFIG_XML_PATH_APPLY_AFTER_DISCOUNT => '0', + Config::CONFIG_XML_PATH_DISCOUNT_TAX => '0', + Config::XML_PATH_ALGORITHM => Calculation::CALC_TOTAL_BASE, + //@TODO: add config for cross border trade + ]; + + const TAX_RATE_TX = 'tax_rate_tx'; + const TAX_RATE_SHIPPING = 'tax_rate_shipping'; + const TAX_STORE_RATE = 'tax_store_rate'; + const REGION_TX = '57'; + const REGION_CA = '12'; + const COUNTRY_US = 'US'; + const AUSTIN_POST_CODE = '79729'; + + /** + * Tax rates + * + * @var array + */ + protected $taxRates = [ + self::TAX_RATE_TX => [ + 'data' => [ + 'tax_country_id' => self::COUNTRY_US, + 'tax_region_id' => self::REGION_TX, + 'tax_postcode' => '*', + 'code' => self::TAX_RATE_TX, + 'rate' => '20', + ], + 'id' => null, + ], + self::TAX_RATE_SHIPPING => [ + 'data' => [ + 'tax_country_id' => self::COUNTRY_US, + 'tax_region_id' => '*', + 'tax_postcode' => '*', + 'code' => self::TAX_RATE_SHIPPING, + 'rate' => '7.5', + ], + 'id' => null, + ], + self::TAX_STORE_RATE => [ + 'data' => [ + 'tax_country_id' => self::COUNTRY_US, + 'tax_region_id' => self::REGION_CA, + 'tax_postcode' => '*', + 'code' => self::TAX_STORE_RATE, + 'rate' => '8.25', + ], + 'id' => null, + ], + ]; + + const PRODUCT_TAX_CLASS_1 = 'product_tax_class_1'; + const PRODUCT_TAX_CLASS_2 = 'product_tax_class_2'; + const SHIPPING_TAX_CLASS = 'shipping_tax_class'; + + /** + * List of product tax class that will be created + * + * @var array + */ + protected $productTaxClasses = [ + self::PRODUCT_TAX_CLASS_1 => null, + self::PRODUCT_TAX_CLASS_2 => null, + self::SHIPPING_TAX_CLASS => null, + ]; + + const CUSTOMER_TAX_CLASS_1 = 'customer_tax_class_1'; + + /** + * List of customer tax class to be created + * + * @var array + */ + protected $customerTaxClasses = [ + self::CUSTOMER_TAX_CLASS_1 => null, + ]; + + /** + * List of tax rules + * + * @var array + */ + protected $taxRules = []; + + const CONFIG_OVERRIDES = 'config_overrides'; + const TAX_RATE_OVERRIDES = 'tax_rate_overrides'; + const TAX_RULE_OVERRIDES = 'tax_rule_overrides'; + + /** + * Default data for shopping cart rule + * + * @var array + */ + protected $defaultShoppingCartPriceRule = [ + 'name' => 'Shopping Cart Rule', + 'is_active' => 1, + 'customer_group_ids' => array(\Magento\Customer\Service\V1\CustomerGroupServiceInterface::CUST_GROUP_ALL), + 'coupon_type' => \Magento\SalesRule\Model\Rule::COUPON_TYPE_NO_COUPON, + 'simple_action' => 'by_percent', + 'discount_amount' => 40, + 'stop_rules_processing' => 1, + 'website_ids' => [1], + ]; + + /** + * Object manager + * + * @var \Magento\Framework\ObjectManager + */ + var $objectManager; + + /** + * @param \Magento\Framework\ObjectManager $objectManager + */ + public function __construct($objectManager) + { + $this->objectManager = $objectManager; + } + + /** + * Create customer tax classes + * + * @return $this + */ + protected function createCustomerTaxClass() + { + foreach (array_keys($this->customerTaxClasses) as $className) { + $this->customerTaxClasses[$className] = $this->objectManager->create('Magento\Tax\Model\ClassModel') + ->setClassName($className) + ->setClassType(\Magento\Tax\Model\ClassModel::TAX_CLASS_TYPE_CUSTOMER) + ->save() + ->getId(); + } + + return $this; + } + + /** + * Create product tax classes + * + * @return $this + */ + protected function createProductTaxClass() + { + foreach (array_keys($this->productTaxClasses) as $className) { + $this->productTaxClasses[$className] = $this->objectManager->create('Magento\Tax\Model\ClassModel') + ->setClassName($className) + ->setClassType(\Magento\Tax\Model\ClassModel::TAX_CLASS_TYPE_PRODUCT) + ->save() + ->getId(); + } + + return $this; + } + + /** + * Set the configuration. + * + * @param array $configData + * @return $this + */ + protected function setConfig($configData) + { + /** @var \Magento\Core\Model\Resource\Config $config */ + $config = $this->objectManager->get('Magento\Core\Model\Resource\Config'); + foreach ($configData as $path => $value) { + if ($path == Config::CONFIG_XML_PATH_SHIPPING_TAX_CLASS) { + $value = $this->productTaxClasses[$value]; + } + $config->saveConfig( + $path, + $value, + \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT, + 0 + ); + } + + /** @var \Magento\Framework\App\Config\ReinitableConfigInterface $config */ + $config = $this->objectManager->get('Magento\Framework\App\Config\ReinitableConfigInterface'); + $config->reinit(); + + return $this; + } + + /** + * Create tax rates + * + * @param array $overrides + * @return $this + */ + protected function createTaxRates($overrides) + { + $taxRateOverrides = empty($overrides[self::TAX_RATE_OVERRIDES]) ? [] : $overrides[self::TAX_RATE_OVERRIDES]; + foreach (array_keys($this->taxRates) as $taxRateCode) { + if (isset($taxRateOverrides[$taxRateCode])) { + $this->taxRates[$taxRateCode]['data']['rate'] = $taxRateOverrides[$taxRateCode]; + } + $this->taxRates[$taxRateCode]['id'] = $this->objectManager->create('Magento\Tax\Model\Calculation\Rate') + ->setData($this->taxRates[$taxRateCode]['data']) + ->save() + ->getId(); + } + return $this; + } + + /** + * Convert the code to id for productTaxClass, customerTaxClass and taxRate in taxRuleOverrideData + * + * @param array $taxRuleOverrideData + * @param array $taxRateIds + * @return array + */ + protected function processTaxRuleOverrides($taxRuleOverrideData, $taxRateIds) + { + if (!empty($taxRuleOverrideData['tax_customer_class'])) { + $customerTaxClassIds = []; + foreach ($taxRuleOverrideData['tax_customer_class'] as $customerClassCode) { + $customerTaxClassIds[] = $this->customerTaxClasses[$customerClassCode]; + } + $taxRuleOverrideData['tax_customer_class'] = $customerTaxClassIds; + } + if (!empty($taxRuleOverrideData['tax_product_class'])) { + $productTaxClassIds = []; + foreach ($taxRuleOverrideData['tax_product_class'] as $productClassCode) { + $productTaxClassIds[] = $this->productTaxClasses[$productClassCode]; + } + $taxRuleOverrideData['tax_product_class'] = $productTaxClassIds; + } + if (!empty($taxRuleOverrideData['tax_rate'])) { + $taxRateIdsForRule = []; + foreach ($taxRuleOverrideData['tax_rate'] as $taxRateCode) { + $taxRateIdsForRule[] = $taxRateIds[$taxRateCode]; + } + $taxRuleOverrideData['tax_rate'] = $taxRateIdsForRule; + } + + return $taxRuleOverrideData; + } + + /** + * Return a list of product tax class ids NOT including shipping product tax class + * + * @return array + */ + protected function getProductTaxClassIds() + { + $productTaxClassIds = []; + foreach ($this->productTaxClasses as $productTaxClassName => $productTaxClassId) { + if ($productTaxClassName != self::SHIPPING_TAX_CLASS) { + $productTaxClassIds[] = $productTaxClassId; + } + } + + return $productTaxClassIds; + } + + /** + * Return a list of tax rate ids NOT including shipping tax rate + * + * @return array + */ + protected function getTaxRateIds() + { + $taxRateIds = []; + foreach ($this->taxRates as $taxRateName => $taxRate) { + if ($taxRateName != self::TAX_RATE_SHIPPING) { + $taxRateIds[] = $taxRate['id']; + } + } + + return $taxRateIds; + } + + /** + * Return the default customer group tax class id + * + * @return int + */ + public function getDefaultCustomerTaxClassId() + { + /** @var \Magento\Customer\Service\V1\CustomerGroupServiceInterface $groupService */ + $groupService = $this->objectManager->get('Magento\Customer\Service\V1\CustomerGroupServiceInterface'); + $defaultGroup = $groupService->getDefaultGroup(); + return $defaultGroup->getTaxClassId(); + } + + /** + * Create tax rules + * + * @param array $overrides + * @return $this + */ + protected function createTaxRules($overrides) + { + $taxRateIds = []; + foreach ($this->taxRates as $taxRateCode => $taxRate) { + $taxRateIds[$taxRateCode] = $taxRate['id']; + } + + //The default customer tax class id is used to calculate store tax rate + $customerClassIds = [ + $this->customerTaxClasses[self::CUSTOMER_TAX_CLASS_1], + $this->getDefaultCustomerTaxClassId() + ]; + + //By default create tax rule that covers all product tax classes except SHIPPING_TAX_CLASS + //The tax rule will cover all tax rates except TAX_RATE_SHIPPING + $taxRuleDefaultData = [ + 'code' => 'Test Rule', + 'priority' => '0', + 'position' => '0', + 'tax_customer_class' => $customerClassIds, + 'tax_product_class' => $this->getProductTaxClassIds(), + 'tax_rate' => $this->getTaxRateIds(), + ]; + + //Create tax rules + if (empty($overrides[self::TAX_RULE_OVERRIDES])) { + //Create separate shipping tax rule + $shippingTaxRuleData = [ + 'code' => 'Shipping Tax Rule', + 'priority' => '0', + 'position' => '0', + 'tax_customer_class' => $customerClassIds, + 'tax_product_class' => [$this->productTaxClasses[self::SHIPPING_TAX_CLASS]], + 'tax_rate' => [$this->taxRates[self::TAX_RATE_SHIPPING]['id']], + ]; + $this->taxRules[$shippingTaxRuleData['code']] = $this->objectManager + ->create('Magento\Tax\Model\Calculation\Rule') + ->setData($shippingTaxRuleData) + ->save() + ->getId(); + + //Create a default tax rule + $this->taxRules[$taxRuleDefaultData['code']] = $this->objectManager + ->create('Magento\Tax\Model\Calculation\Rule') + ->setData($taxRuleDefaultData) + ->save() + ->getId(); + } else { + foreach ($overrides[self::TAX_RULE_OVERRIDES] as $taxRuleOverrideData ) { + //convert code to id for productTaxClass, customerTaxClass and taxRate + $taxRuleOverrideData = $this->processTaxRuleOverrides($taxRuleOverrideData, $taxRateIds); + $mergedTaxRuleData = array_merge($taxRuleDefaultData, $taxRuleOverrideData); + $this->taxRules[$mergedTaxRuleData['code']] = $this->objectManager + ->create('Magento\Tax\Model\Calculation\Rule') + ->setData($mergedTaxRuleData) + ->save() + ->getId(); + } + } + + return $this; + } + + /** + * Set up tax classes, tax rates and tax rules + * The override structure: + * override['self::CONFIG_OVERRIDES'] + * [ + * [config_path => config_value] + * ] + * override['self::TAX_RATE_OVERRIDES'] + * [ + * ['tax_rate_code' => tax_rate] + * ] + * override['self::TAX_RULE_OVERRIDES'] + * [ + * [ + * 'code' => code //Required, has to be unique + * 'priority' => 0 + * 'position' => 0 + * 'tax_customer_class' => array of customer tax class names as defined in this class + * 'tax_product_class' => array of product tax class names as defined in this class + * 'tax_rate' => array of tax rate codes as defined in this class + * ] + * ] + * + * @param array $overrides + * @return void + */ + public function setupTax($overrides) + { + //Create product tax classes + $this->createProductTaxClass(); + + //Create customer tax classes + $this->createCustomerTaxClass(); + + //Create tax rates + $this->createTaxRates($overrides); + + //Create tax rules + $this->createTaxRules($overrides); + + //Tax calculation configuration + if (!empty($overrides[self::CONFIG_OVERRIDES])) { + $this->setConfig($overrides[self::CONFIG_OVERRIDES]); + } + } + + /** + * Create a simple product with given sku, price and tax class + * + * @param string $sku + * @param float $price + * @param int $taxClassId + * @return \Magento\Catalog\Model\Product + */ + public function createSimpleProduct($sku, $price, $taxClassId) + { + /** @var \Magento\Catalog\Model\Product $product */ + $product = $this->objectManager->create('Magento\Catalog\Model\Product'); + $product->isObjectNew(true); + $product->setTypeId('simple') + ->setAttributeSetId(4) + ->setName('Simple Product') + ->setSku($sku) + ->setPrice($price) + ->setTaxClassId($taxClassId) + ->setStockData( + [ + 'use_config_manage_stock' => 1, + 'qty' => 100, + 'is_qty_decimal' => 0, + 'is_in_stock' => 1 + ] + )->setMetaTitle('meta title') + ->setMetaKeyword('meta keyword') + ->setMetaDescription('meta description') + ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH) + ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) + ->save(); + + $product = $product->load($product->getId()); + return $product; + } + + /** + * Create a customer group and associated it with given customer tax class + * + * @param int $customerTaxClassId + * @return int + */ + protected function createCustomerGroup($customerTaxClassId) + { + /** @var \Magento\Customer\Service\V1\CustomerGroupService $customerGroupService */ + $customerGroupService = $this->objectManager->create('Magento\Customer\Service\V1\CustomerGroupService'); + $customerGroupBuilder = (new \Magento\Customer\Service\V1\Data\CustomerGroupBuilder()) + ->setCode('custom_group') + ->setTaxClassId($customerTaxClassId); + $customerGroup = new \Magento\Customer\Service\V1\Data\CustomerGroup($customerGroupBuilder); + $customerGroupId = $customerGroupService->saveGroup($customerGroup); + return $customerGroupId; + } + + /** + * Create a customer + * + * @return \Magento\Customer\Model\Customer + */ + protected function createCustomer() + { + $customerGroupId = $this->createCustomerGroup($this->customerTaxClasses[self::CUSTOMER_TAX_CLASS_1]); + /** @var \Magento\Customer\Model\Customer $customer */ + $customer = $this->objectManager->create('Magento\Customer\Model\Customer'); + $customer->isObjectNew(true); + $customer->setWebsiteId(1) + ->setEntityTypeId(1) + ->setAttributeSetId(1) + ->setEmail('customer@example.com') + ->setPassword('password') + ->setGroupId($customerGroupId) + ->setStoreId(1) + ->setIsActive(1) + ->setFirstname('Firstname') + ->setLastname('Lastname') + ->save(); + + return $customer; + } + + /** + * Create customer address + * + * @param array $addressOverride + * @param int $customerId + * @return \Magento\Customer\Model\Address + */ + protected function createCustomerAddress($addressOverride, $customerId) + { + $defaultAddressData = [ + 'attribute_set_id' => 2, + 'telephone' => 3468676, + 'postcode' => self::AUSTIN_POST_CODE, + 'country_id' => self::COUNTRY_US, + 'city' => 'CityM', + 'company' => 'CompanyName', + 'street' => ['Green str, 67'], + 'lastname' => 'Smith', + 'firstname' => 'John', + 'parent_id' => 1, + 'region_id' => self::REGION_TX, + ]; + $addressData = array_merge($defaultAddressData, $addressOverride); + + /** @var \Magento\Customer\Model\Address $customerAddress */ + $customerAddress = $this->objectManager->create('Magento\Customer\Model\Address'); + $customerAddress->setData($addressData) + ->setCustomerId($customerId) + ->save(); + + return $customerAddress; + } + + /** + * Create shopping cart rule + * + * @param array $ruleDataOverride + * @return $this + */ + protected function createCartRule($ruleDataOverride) + { + /** @var \Magento\SalesRule\Model\Rule $salesRule */ + $salesRule = $this->objectManager->create('Magento\SalesRule\Model\Rule'); + $ruleData = array_merge($this->defaultShoppingCartPriceRule, $ruleDataOverride); + $salesRule->setData($ruleData); + $salesRule->save(); + + return $this; + } + + /** + * Create a quote object with customer + * + * @param array $quoteData + * @param \Magento\Customer\Model\Customer $customer + * @return \Magento\Sales\Model\Quote + */ + protected function createQuote($quoteData, $customer) + { + /** @var \Magento\Customer\Service\V1\CustomerAddressServiceInterface $addressService */ + $addressService = $this->objectManager->create('Magento\Customer\Service\V1\CustomerAddressServiceInterface'); + + /** @var array $shippingAddressOverride */ + $shippingAddressOverride = empty($quoteData['shipping_address']) ? [] : $quoteData['shipping_address']; + /** @var \Magento\Customer\Model\Address $shippingAddress */ + $shippingAddress = $this->createCustomerAddress($shippingAddressOverride, $customer->getId()); + + /** @var \Magento\Sales\Model\Quote\Address $quoteShippingAddress */ + $quoteShippingAddress = $this->objectManager->create('Magento\Sales\Model\Quote\Address'); + $quoteShippingAddress->importCustomerAddressData($addressService->getAddress($shippingAddress->getId())); + + /** @var array $billingAddressOverride */ + $billingAddressOverride = empty($quoteData['billing_address']) ? [] : $quoteData['billing_address']; + /** @var \Magento\Customer\Model\Address $billingAddress */ + $billingAddress = $this->createCustomerAddress($billingAddressOverride, $customer->getId()); + + /** @var \Magento\Sales\Model\Quote\Address $quoteBillingAddress */ + $quoteBillingAddress = $this->objectManager->create('Magento\Sales\Model\Quote\Address'); + $quoteBillingAddress->importCustomerAddressData($addressService->getAddress($billingAddress->getId())); + + /** @var \Magento\Sales\Model\Quote $quote */ + $quote = $this->objectManager->create('Magento\Sales\Model\Quote'); + $quote->setStoreId(1) + ->setIsActive(true) + ->setIsMultiShipping(false) + ->assignCustomerWithAddressChange($customer, $quoteBillingAddress, $quoteShippingAddress) + ->setCheckoutMethod($customer->getMode()) + ->setPasswordHash($customer->encryptPassword($customer->getPassword())); + + return $quote; + } + + /** + * Add products to quote + * + * @param \Magento\Sales\Model\Quote $quote + * @param array $itemsData + * @return $this + */ + protected function addProductToQuote($quote, $itemsData) + { + foreach ($itemsData as $itemData) { + $sku = $itemData['sku']; + $price = $itemData['price']; + $qty = isset($itemData['qty']) ? $itemData['qty'] : 1; + $taxClassName = + isset($itemData['tax_class_name']) ? $itemData['tax_class_name'] : self::PRODUCT_TAX_CLASS_1; + $taxClassId = $this->productTaxClasses[$taxClassName]; + $product = $this->createSimpleProduct($sku, $price, $taxClassId); + $quote->addProduct($product, $qty); + } + return $this; + } + + /** + * Create a quote based on given data + * + * @param array $quoteData + * @return \Magento\Sales\Model\Quote + */ + public function setupQuote($quoteData) + { + $customer = $this->createCustomer(); + + $quote = $this->createQuote($quoteData, $customer); + + $this->addProductToQuote($quote, $quoteData['items']); + + //Set shipping amount + if (isset($quoteData['shipping_method'])) { + $quote->getShippingAddress()->setShippingMethod($quoteData['shipping_method']); + $quote->getShippingAddress()->setCollectShippingRates(true); + } + + //create shopping cart rules if necessary + if (!empty($quoteData['shopping_cart_rules'])) { + foreach ($quoteData['shopping_cart_rules'] as $ruleData) { + $ruleData['customer_group_ids'] = array($customer->getGroupId()); + $this->createCartRule($ruleData); + } + } + + return $quote; + } +} diff --git a/dev/tests/integration/testsuite/Magento/Tax/Model/Sales/Total/Quote/TaxTest.php b/dev/tests/integration/testsuite/Magento/Tax/Model/Sales/Total/Quote/TaxTest.php index 6aba699d1fdb0..301e0d8d8190a 100644 --- a/dev/tests/integration/testsuite/Magento/Tax/Model/Sales/Total/Quote/TaxTest.php +++ b/dev/tests/integration/testsuite/Magento/Tax/Model/Sales/Total/Quote/TaxTest.php @@ -24,9 +24,21 @@ namespace Magento\Tax\Model\Sales\Total\Quote; use Magento\TestFramework\Helper\Bootstrap; +use Magento\Tax\Model\Config; +use Magento\Tax\Model\Calculation; + +require_once __DIR__ . '/SetupUtil.php'; +require_once __DIR__ . '/../../../../_files/tax_calculation_data_aggregated.php'; class TaxTest extends \PHPUnit_Framework_TestCase { + /** + * Utility object for setting up tax rates, tax classes and tax rules + * + * @var SetupUtil + */ + protected $setupUtil = null; + /** * Test taxes collection for quote. * @@ -123,4 +135,157 @@ public function testCollect() 'Customer tax was collected by \Magento\Tax\Model\Sales\Total\Quote\Tax::collect incorrectly.' ); } + + /** + * Verify fields in quote item + * + * @param \Magento\Sales\Model\Quote\Address\Item $item + * @param array $expectedItemData + * @return $this + */ + protected function verifyItem($item, $expectedItemData) + { + foreach ($expectedItemData as $key => $value) { + $this->assertEquals($value, $item->getData($key), 'item ' . $key . ' is incorrect'); + } + + return $this; + } + + /** + * Verify one tax rate in a tax row + * + * @param array $appliedTaxRate + * @param array $expectedAppliedTaxRate + * @return $this + */ + protected function verifyAppliedTaxRate($appliedTaxRate, $expectedAppliedTaxRate) + { + foreach ($expectedAppliedTaxRate as $key => $value) { + $this->assertEquals($value, $appliedTaxRate[$key], 'Applied tax rate ' . $key . ' is incorrect'); + } + return $this; + } + + /** + * Verify one row in the applied taxes + * + * @param array $appliedTax + * @param array $expectedAppliedTax + * @return $this + */ + protected function verifyAppliedTax($appliedTax, $expectedAppliedTax) + { + foreach ($expectedAppliedTax as $key => $value) { + if ($key == 'rates') { + foreach ($value as $index => $taxRate) { + $this->verifyAppliedTaxRate($appliedTax['rates'][$index], $taxRate); + } + } else { + $this->assertEquals($value, $appliedTax[$key], 'Applied tax ' . $key . ' is incorrect'); + } + } + return $this; + } + + /** + * Verify that applied taxes are correct + * + * @param array $appliedTaxes + * @param array $expectedAppliedTaxes + * @return $this + */ + protected function verifyAppliedTaxes($appliedTaxes, $expectedAppliedTaxes) + { + foreach ($expectedAppliedTaxes as $taxRateKey => $expectedTaxRate) { + $this->assertTrue(isset($appliedTaxes[$taxRateKey]), 'Missing tax rate ' . $taxRateKey ); + $this->verifyAppliedTax($appliedTaxes[$taxRateKey], $expectedTaxRate); + } + return $this; + } + + /** + * Verify fields in quote address + * + * @param \Magento\Sales\Model\Quote\Address $quoteAddress + * @param array $expectedAddressData + * @return $this + */ + protected function verifyQuoteAddress($quoteAddress, $expectedAddressData) + { + + foreach ($expectedAddressData as $key => $value) { + if ($key == 'applied_taxes') { + $this->verifyAppliedTaxes($quoteAddress->getAppliedTaxes(), $value); + } else { + $this->assertEquals($value, $quoteAddress->getData($key), 'Quote address ' . $key . ' is incorrect'); + } + } + + return $this; + } + + /** + * Verify fields in quote address and quote item are correct + * + * @param \Magento\Sales\Model\Quote\Address $quoteAddress + * @param array $expectedResults + * @return $this + */ + protected function verifyResult($quoteAddress, $expectedResults) + { + $addressData = $expectedResults['address_data']; + + $this->verifyQuoteAddress($quoteAddress, $addressData); + + $quoteItems = $quoteAddress->getAllItems(); + foreach ($quoteItems as $item) { + /** @var \Magento\Sales\Model\Quote\Address\Item $item */ + $sku = $item->getProduct()->getSku(); + $expectedItemData = $expectedResults['items_data'][$sku]; + $this->verifyItem($item, $expectedItemData); + } + + return $this; + } + + /** + * Test tax calculation with various configuration and combination of items + * This method will test various collectors through $quoteAddress->collectTotals() method + * + * @param array $configData + * @param array $quoteData + * @param array $expectedResults + * @magentoDbIsolation enabled + * @dataProvider taxDataProvider + * @return void + */ + public function testTaxCalculation($configData, $quoteData, $expectedResults) + { + Bootstrap::getInstance()->reinitialize(); + /** @var \Magento\Framework\ObjectManager $objectManager */ + $objectManager = Bootstrap::getObjectManager(); + + //Setup tax configurations + $this->setupUtil = new SetupUtil($objectManager); + $this->setupUtil->setupTax($configData); + + $quote = $this->setupUtil->setupQuote($quoteData); + $quoteAddress = $quote->getShippingAddress(); + + $quoteAddress->collectTotals(); + $this->verifyResult($quoteAddress, $expectedResults); + } + + /** + * Read the array defined in ../../../../_files/tax_calculation_data_aggregated.php + * and feed it to testTaxCalculation + * + * @return array + */ + public function taxDataProvider() + { + global $taxCalculationData; + return $taxCalculationData; + } } diff --git a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_apply_tax_after_discount.php b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_apply_tax_after_discount.php new file mode 100644 index 0000000000000..5a25277044d95 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_apply_tax_after_discount.php @@ -0,0 +1,146 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (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'] = [ + 'config_data' => [ + SetupUtil::CONFIG_OVERRIDES => [ + Config::CONFIG_XML_PATH_APPLY_AFTER_DISCOUNT => 1, + Config::CONFIG_XML_PATH_SHIPPING_TAX_CLASS => SetupUtil::SHIPPING_TAX_CLASS, + ], + 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.75, + 'base_tax_amount' => 2.75, + 'shipping_amount' => 10, + 'base_shipping_amount' => 10, + 'shipping_incl_tax' => 10.75, + 'base_shipping_incl_tax' => 10.75, + 'shipping_taxable' => 10, + 'base_shipping_taxable' => 10, + 'shipping_tax_amount' => 0.75, + 'base_shipping_tax_amount' => 0.75, + 'discount_amount' => -10, + 'base_discount_amount' => -10, + 'hidden_tax_amount' => 0, + 'base_hidden_tax_amount' => 0, + 'shipping_hidden_tax_amount' => 0, + 'base_shipping_hidden_tax_amount' => 0, + 'grand_total' => 22.75, + 'base_grand_total' => 22.75, + 'applied_taxes' => [ + SetupUtil::TAX_RATE_TX => [ + 'percent' => 20, + 'amount' => 2, + 'base_amount' => 2, + '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, + 'taxable_amount' => 20, + 'base_taxable_amount' => 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' => 2, + 'base_tax_amount' => 2, + 'discount_amount' => 10, + 'base_discount_amount' => 10, + '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/excluding_tax_apply_tax_before_discount.php b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_apply_tax_before_discount.php new file mode 100644 index 0000000000000..9eaffb5eb7526 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_apply_tax_before_discount.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) + */ + +use Magento\Tax\Model\Config; +use Magento\Tax\Model\Sales\Total\Quote\SetupUtil; + +$taxCalculationData['excluding_tax_apply_tax_before_discount'] = [ + 'config_data' => [ + SetupUtil::CONFIG_OVERRIDES => [ + Config::CONFIG_XML_PATH_SHIPPING_TAX_CLASS => SetupUtil::PRODUCT_TAX_CLASS_1, + ], + SetupUtil::TAX_RATE_OVERRIDES => [ + SetupUtil::TAX_RATE_TX => 20, + ], + SetupUtil::TAX_RULE_OVERRIDES => [ + ], + ], + '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' => 6, + 'base_tax_amount' => 6, + 'shipping_amount' => 10, + 'base_shipping_amount' => 10, + 'shipping_incl_tax' => 12, + 'base_shipping_incl_tax' => 12, + 'shipping_taxable' => 10, + 'base_shipping_taxable' => 10, + 'shipping_tax_amount' => 2, + 'base_shipping_tax_amount' => 2, + 'discount_amount' => -10, + 'base_discount_amount' => -10, + 'hidden_tax_amount' => 0, + 'base_hidden_tax_amount' => 0, + 'shipping_hidden_tax_amount' => 0, + 'base_shipping_hidden_tax_amount' => 0, + 'grand_total' => 26, + 'base_grand_total' => 26, + ], + 'items_data' => [ + 'simple1' => [ + 'row_total' => 20, + 'base_row_total' => 20, + 'taxable_amount' => 20, + 'base_taxable_amount' => 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' => 4, + 'base_tax_amount' => 4, + 'discount_amount' => 10, + 'base_discount_amount' => 10, + '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/excluding_tax_multi_item_row.php b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_multi_item_row.php new file mode 100644 index 0000000000000..07c050f2ecf20 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_multi_item_row.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) + */ + +use Magento\Tax\Model\Config; +use Magento\Tax\Model\Sales\Total\Quote\SetupUtil; +use Magento\Tax\Model\Calculation; + +$taxCalculationData['excluding_tax__multi_item_row'] = [ + 'config_data' => [ + SetupUtil::CONFIG_OVERRIDES => [ + Config::CONFIG_XML_PATH_APPLY_AFTER_DISCOUNT => 1, + Config::CONFIG_XML_PATH_PRICE_INCLUDES_TAX => 0, + Config::XML_PATH_ALGORITHM => Calculation::CALC_ROW_BASE, + ], + SetupUtil::TAX_RATE_OVERRIDES => [ + SetupUtil::TAX_RATE_TX => 8.25, + SetupUtil::TAX_STORE_RATE => 8.25, + ], + SetupUtil::TAX_RULE_OVERRIDES => [ + ], + ], + 'quote_data' => [ + 'billing_address' => [ + 'region_id' => SetupUtil::REGION_TX, + ], + 'shipping_address' => [ + 'region_id' => SetupUtil::REGION_TX, + ], + 'items' => [ + [ + 'sku' => 'simple1', + 'price' => 10.00, + 'qty' => 1, + ], + [ + 'sku' => 'simple2', + 'price' => 11.00, + 'qty' => 1, + ], + ], + ], + 'expected_results' => [ + 'address_data' => [ + 'subtotal' => 21, + 'base_subtotal' => 21, + 'subtotal_incl_tax' => 22.74, + 'base_subtotal_incl_tax' => 22.74, + 'tax_amount' => 1.74, + 'base_tax_amount' => 1.74, + 'shipping_amount' => 0, + 'base_shipping_amount' => 0, + 'shipping_incl_tax' => 0, + 'base_shipping_incl_tax' => 0, + 'shipping_taxable' => 0, + 'base_shipping_taxable' => 0, + 'shipping_tax_amount' => 0, + 'base_shipping_tax_amount' => 0, + 'discount_amount' => 0, + 'base_discount_amount' => 0, + 'hidden_tax_amount' => 0, + 'base_hidden_tax_amount' => 0, + 'shipping_hidden_tax_amount' => 0, + 'base_shipping_hidden_tax_amount' => 0, + 'grand_total' => 22.74, + 'base_grand_total' => 22.74, + ], + 'items_data' => [ + 'simple1' => [ + 'row_total' => 10, + 'base_row_total' => 10, + 'taxable_amount' => 10, + 'base_taxable_amount' => 10, + 'tax_percent' => 8.25, + 'price' => 10, + 'base_price' => 10, + 'price_incl_tax' => 10.83, + 'base_price_incl_tax' => 10.83, + 'row_total_incl_tax' => 10.83, + 'base_row_total_incl_tax' => 10.83, + 'tax_amount' => 0.83, + 'base_tax_amount' => 0.83, + 'discount_amount' => 0, + 'base_discount_amount' => 0, + 'discount_percent' => 0, + 'hidden_tax_amount' => 0, + 'base_hidden_tax_amount' => 0, + ], + 'simple2' => [ + 'row_total' => 11, + 'base_row_total' => 11, + 'taxable_amount' => 11, + 'base_taxable_amount' => 11, + 'tax_percent' => 8.25, + 'price' => 11, + 'base_price' => 11, + 'price_incl_tax' => 11.91, + 'base_price_incl_tax' => 11.91, + 'row_total_incl_tax' => 11.91, + 'base_row_total_incl_tax' => 11.91, + 'tax_amount' => 0.91, + 'base_tax_amount' => 0.91, + 'discount_amount' => 0, + 'base_discount_amount' => 0, + 'discount_percent' => 0, + '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/excluding_tax_multi_item_total.php b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_multi_item_total.php new file mode 100644 index 0000000000000..cacf6059a5d33 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_multi_item_total.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) + */ + +use Magento\Tax\Model\Config; +use Magento\Tax\Model\Sales\Total\Quote\SetupUtil; +use Magento\Tax\Model\Calculation; + +$taxCalculationData['excluding_tax__multi_item_total'] = [ + 'config_data' => [ + SetupUtil::CONFIG_OVERRIDES => [ + Config::CONFIG_XML_PATH_APPLY_AFTER_DISCOUNT => 1, + Config::CONFIG_XML_PATH_PRICE_INCLUDES_TAX => 0, + Config::XML_PATH_ALGORITHM => Calculation::CALC_TOTAL_BASE, + ], + SetupUtil::TAX_RATE_OVERRIDES => [ + SetupUtil::TAX_RATE_TX => 8.25, + SetupUtil::TAX_STORE_RATE => 8.25, + ], + SetupUtil::TAX_RULE_OVERRIDES => [ + ], + ], + 'quote_data' => [ + 'billing_address' => [ + 'region_id' => SetupUtil::REGION_TX, + ], + 'shipping_address' => [ + 'region_id' => SetupUtil::REGION_TX, + ], + 'items' => [ + [ + 'sku' => 'simple1', + 'price' => 10.00, + 'qty' => 1, + ], + [ + 'sku' => 'simple2', + 'price' => 11.00, + 'qty' => 1, + ], + ], + ], + 'expected_results' => [ + 'address_data' => [ + 'subtotal' => 21, + 'base_subtotal' => 21, + 'subtotal_incl_tax' => 22.73, + 'base_subtotal_incl_tax' => 22.73, + 'tax_amount' => 1.73, + 'base_tax_amount' => 1.73, + 'shipping_amount' => 0, + 'base_shipping_amount' => 0, + 'shipping_incl_tax' => 0, + 'base_shipping_incl_tax' => 0, + 'shipping_taxable' => 0, + 'base_shipping_taxable' => 0, + 'shipping_tax_amount' => 0, + 'base_shipping_tax_amount' => 0, + 'discount_amount' => 0, + 'base_discount_amount' => 0, + 'hidden_tax_amount' => 0, + 'base_hidden_tax_amount' => 0, + 'shipping_hidden_tax_amount' => 0, + 'base_shipping_hidden_tax_amount' => 0, + 'grand_total' => 22.73, + 'base_grand_total' => 22.73, + ], + 'items_data' => [ + 'simple1' => [ + 'row_total' => 10, + 'base_row_total' => 10, + 'taxable_amount' => 10, + 'base_taxable_amount' => 10, + 'tax_percent' => 8.25, + 'price' => 10, + 'base_price' => 10, + 'price_incl_tax' => 10.83, + 'base_price_incl_tax' => 10.83, + 'row_total_incl_tax' => 10.83, + 'base_row_total_incl_tax' => 10.83, + 'tax_amount' => 0.83, + 'base_tax_amount' => 0.83, + 'discount_amount' => 0, + 'base_discount_amount' => 0, + 'discount_percent' => 0, + 'hidden_tax_amount' => 0, + 'base_hidden_tax_amount' => 0, + ], + 'simple2' => [ + 'row_total' => 11, + 'base_row_total' => 11, + 'taxable_amount' => 11, + 'base_taxable_amount' => 11, + 'tax_percent' => 8.25, + 'price' => 11, + 'base_price' => 11, + 'price_incl_tax' => 11.90, + 'base_price_incl_tax' => 11.90, + 'row_total_incl_tax' => 11.90, + 'base_row_total_incl_tax' => 11.90, + 'tax_amount' => 0.90, + 'base_tax_amount' => 0.90, + 'discount_amount' => 0, + 'base_discount_amount' => 0, + 'discount_percent' => 0, + '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/excluding_tax_multi_item_unit.php b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_multi_item_unit.php new file mode 100644 index 0000000000000..9f0a90aed5c3c --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_multi_item_unit.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) + */ + +use Magento\Tax\Model\Config; +use Magento\Tax\Model\Sales\Total\Quote\SetupUtil; +use Magento\Tax\Model\Calculation; + +$taxCalculationData['excluding_tax__multi_item_unit'] = [ + 'config_data' => [ + SetupUtil::CONFIG_OVERRIDES => [ + Config::CONFIG_XML_PATH_APPLY_AFTER_DISCOUNT => 1, + Config::CONFIG_XML_PATH_PRICE_INCLUDES_TAX => 0, + Config::XML_PATH_ALGORITHM => Calculation::CALC_UNIT_BASE, + ], + SetupUtil::TAX_RATE_OVERRIDES => [ + SetupUtil::TAX_RATE_TX => 8.25, + SetupUtil::TAX_STORE_RATE => 8.25, + ], + SetupUtil::TAX_RULE_OVERRIDES => [ + ], + ], + 'quote_data' => [ + 'billing_address' => [ + 'region_id' => SetupUtil::REGION_TX, + ], + 'shipping_address' => [ + 'region_id' => SetupUtil::REGION_TX, + ], + 'items' => [ + [ + 'sku' => 'simple1', + 'price' => 10.00, + 'qty' => 1, + ], + [ + 'sku' => 'simple2', + 'price' => 11.00, + 'qty' => 1, + ], + ], + ], + 'expected_results' => [ + 'address_data' => [ + 'subtotal' => 21, + 'base_subtotal' => 21, + 'subtotal_incl_tax' => 22.74, + 'base_subtotal_incl_tax' => 22.74, + 'tax_amount' => 1.74, + 'base_tax_amount' => 1.74, + 'shipping_amount' => 0, + 'base_shipping_amount' => 0, + 'shipping_incl_tax' => 0, + 'base_shipping_incl_tax' => 0, + 'shipping_taxable' => 0, + 'base_shipping_taxable' => 0, + 'shipping_tax_amount' => 0, + 'base_shipping_tax_amount' => 0, + 'discount_amount' => 0, + 'base_discount_amount' => 0, + 'hidden_tax_amount' => 0, + 'base_hidden_tax_amount' => 0, + 'shipping_hidden_tax_amount' => 0, + 'base_shipping_hidden_tax_amount' => 0, + 'grand_total' => 22.74, + 'base_grand_total' => 22.74, + ], + 'items_data' => [ + 'simple1' => [ + 'row_total' => 10, + 'base_row_total' => 10, + 'taxable_amount' => 10, + 'base_taxable_amount' => 10, + 'tax_percent' => 8.25, + 'price' => 10, + 'base_price' => 10, + 'price_incl_tax' => 10.83, + 'base_price_incl_tax' => 10.83, + 'row_total_incl_tax' => 10.83, + 'base_row_total_incl_tax' => 10.83, + 'tax_amount' => 0.83, + 'base_tax_amount' => 0.83, + 'discount_amount' => 0, + 'base_discount_amount' => 0, + 'discount_percent' => 0, + 'hidden_tax_amount' => 0, + 'base_hidden_tax_amount' => 0, + ], + 'simple2' => [ + 'row_total' => 11, + 'base_row_total' => 11, + 'taxable_amount' => 11, + 'base_taxable_amount' => 11, + 'tax_percent' => 8.25, + 'price' => 11, + 'base_price' => 11, + 'price_incl_tax' => 11.91, + 'base_price_incl_tax' => 11.91, + 'row_total_incl_tax' => 11.91, + 'base_row_total_incl_tax' => 11.91, + 'tax_amount' => 0.91, + 'base_tax_amount' => 0.91, + 'discount_amount' => 0, + 'base_discount_amount' => 0, + 'discount_percent' => 0, + '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/excluding_tax_row.php b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_row.php new file mode 100644 index 0000000000000..2ab70e7f36b24 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_row.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) + */ + +use Magento\Tax\Model\Config; +use Magento\Tax\Model\Sales\Total\Quote\SetupUtil; +use Magento\Tax\Model\Calculation; + +$taxCalculationData['excluding_tax_row'] = [ + 'config_data' => [ + SetupUtil::CONFIG_OVERRIDES => [ + Config::CONFIG_XML_PATH_APPLY_AFTER_DISCOUNT => 1, + Config::XML_PATH_ALGORITHM => Calculation::CALC_ROW_BASE, + ], + SetupUtil::TAX_RATE_OVERRIDES => [ + SetupUtil::TAX_RATE_TX => 8.25, + ], + SetupUtil::TAX_RULE_OVERRIDES => [ + ], + ], + 'quote_data' => [ + 'billing_address' => [ + 'region_id' => SetupUtil::REGION_TX, + ], + 'shipping_address' => [ + 'region_id' => SetupUtil::REGION_TX, + ], + 'items' => [ + [ + 'sku' => 'simple1', + 'price' => 10, + 'qty' => 2, + ], + ], + ], + 'expected_results' => [ + 'address_data' => [ + 'subtotal' => 20, + 'base_subtotal' => 20, + 'subtotal_incl_tax' => 21.65, + 'base_subtotal_incl_tax' => 21.65, + 'tax_amount' => 1.65, + 'base_tax_amount' => 1.65, + 'shipping_amount' => 0, + 'base_shipping_amount' => 0, + 'shipping_incl_tax' => 0, + 'base_shipping_incl_tax' => 0, + 'shipping_taxable' => 0, + 'base_shipping_taxable' => 0, + 'shipping_tax_amount' => 0, + 'base_shipping_tax_amount' => 0, + 'discount_amount' => 0, + 'base_discount_amount' => 0, + 'hidden_tax_amount' => 0, + 'base_hidden_tax_amount' => 0, + 'shipping_hidden_tax_amount' => 0, + 'base_shipping_hidden_tax_amount' => 0, + 'grand_total' => 21.65, + 'base_grand_total' => 21.65, + ], + 'items_data' => [ + 'simple1' => [ + 'row_total' => 20, + 'base_row_total' => 20, + 'taxable_amount' => 20, + 'base_taxable_amount' => 20, + 'tax_percent' => 8.25, + 'price' => 10, + 'base_price' => 10, + 'price_incl_tax' => 10.83, + 'base_price_incl_tax' => 10.83, + 'row_total_incl_tax' => 21.65, + 'base_row_total_incl_tax' => 21.65, + 'tax_amount' => 1.65, + 'base_tax_amount' => 1.65, + 'discount_amount' => 0, + 'base_discount_amount' => 0, + 'discount_percent' => 0, + '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/excluding_tax_total.php b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_total.php new file mode 100644 index 0000000000000..73befba2bdc84 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_total.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) + */ + +use Magento\Tax\Model\Config; +use Magento\Tax\Model\Sales\Total\Quote\SetupUtil; +use Magento\Tax\Model\Calculation; + +$taxCalculationData['excluding_tax_total'] = [ + 'config_data' => [ + SetupUtil::CONFIG_OVERRIDES => [ + Config::CONFIG_XML_PATH_APPLY_AFTER_DISCOUNT => 1, + Config::XML_PATH_ALGORITHM => Calculation::CALC_TOTAL_BASE, + ], + SetupUtil::TAX_RATE_OVERRIDES => [ + SetupUtil::TAX_RATE_TX => 8.25, + ], + SetupUtil::TAX_RULE_OVERRIDES => [ + ], + ], + 'quote_data' => [ + 'billing_address' => [ + 'region_id' => SetupUtil::REGION_TX, + ], + 'shipping_address' => [ + 'region_id' => SetupUtil::REGION_TX, + ], + 'items' => [ + [ + 'sku' => 'simple1', + 'price' => 10, + 'qty' => 2, + ], + ], + ], + 'expected_results' => [ + 'address_data' => [ + 'subtotal' => 20, + 'base_subtotal' => 20, + 'subtotal_incl_tax' => 21.65, + 'base_subtotal_incl_tax' => 21.65, + 'tax_amount' => 1.65, + 'base_tax_amount' => 1.65, + 'shipping_amount' => 0, + 'base_shipping_amount' => 0, + 'shipping_incl_tax' => 0, + 'base_shipping_incl_tax' => 0, + 'shipping_taxable' => 0, + 'base_shipping_taxable' => 0, + 'shipping_tax_amount' => 0, + 'base_shipping_tax_amount' => 0, + 'discount_amount' => 0, + 'base_discount_amount' => 0, + 'hidden_tax_amount' => 0, + 'base_hidden_tax_amount' => 0, + 'shipping_hidden_tax_amount' => 0, + 'base_shipping_hidden_tax_amount' => 0, + 'grand_total' => 21.65, + 'base_grand_total' => 21.65, + ], + 'items_data' => [ + 'simple1' => [ + 'row_total' => 20, + 'base_row_total' => 20, + 'taxable_amount' => 20, + 'base_taxable_amount' => 20, + 'tax_percent' => 8.25, + 'price' => 10, + 'base_price' => 10, + 'price_incl_tax' => 10.83, + 'base_price_incl_tax' => 10.83, + 'row_total_incl_tax' => 21.65, + 'base_row_total_incl_tax' => 21.65, + 'tax_amount' => 1.65, + 'base_tax_amount' => 1.65, + 'discount_amount' => 0, + 'base_discount_amount' => 0, + 'discount_percent' => 0, + '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/excluding_tax_unit.php b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_unit.php new file mode 100644 index 0000000000000..2e64a8a5b5c53 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_unit.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) + */ + +use Magento\Tax\Model\Config; +use Magento\Tax\Model\Sales\Total\Quote\SetupUtil; +use Magento\Tax\Model\Calculation; + +$taxCalculationData['excluding_tax_unit'] = [ + 'config_data' => [ + SetupUtil::CONFIG_OVERRIDES => [ + Config::CONFIG_XML_PATH_APPLY_AFTER_DISCOUNT => 1, + Config::XML_PATH_ALGORITHM => Calculation::CALC_UNIT_BASE, + ], + SetupUtil::TAX_RATE_OVERRIDES => [ + SetupUtil::TAX_RATE_TX => 8.25, + ], + SetupUtil::TAX_RULE_OVERRIDES => [ + ], + ], + 'quote_data' => [ + 'billing_address' => [ + 'region_id' => SetupUtil::REGION_TX, + ], + 'shipping_address' => [ + 'region_id' => SetupUtil::REGION_TX, + ], + 'items' => [ + [ + 'sku' => 'simple1', + 'price' => 10, + 'qty' => 2, + ], + ], + ], + 'expected_results' => [ + 'address_data' => [ + 'subtotal' => 20, + 'base_subtotal' => 20, + 'subtotal_incl_tax' => 21.66, + 'base_subtotal_incl_tax' => 21.66, + 'tax_amount' => 1.66, + 'base_tax_amount' => 1.66, + 'shipping_amount' => 0, + 'base_shipping_amount' => 0, + 'shipping_incl_tax' => 0, + 'base_shipping_incl_tax' => 0, + 'shipping_taxable' => 0, + 'base_shipping_taxable' => 0, + 'shipping_tax_amount' => 0, + 'base_shipping_tax_amount' => 0, + 'discount_amount' => 0, + 'base_discount_amount' => 0, + 'hidden_tax_amount' => 0, + 'base_hidden_tax_amount' => 0, + 'shipping_hidden_tax_amount' => 0, + 'base_shipping_hidden_tax_amount' => 0, + 'grand_total' => 21.66, + 'base_grand_total' => 21.66, + ], + 'items_data' => [ + 'simple1' => [ + 'row_total' => 20, + 'base_row_total' => 20, + 'taxable_amount' => 10, + 'base_taxable_amount' => 10, + 'tax_percent' => 8.25, + 'price' => 10, + 'base_price' => 10, + 'price_incl_tax' => 10.83, + 'base_price_incl_tax' => 10.83, + 'row_total_incl_tax' => 21.66, + 'base_row_total_incl_tax' => 21.66, + 'tax_amount' => 1.66, + 'base_tax_amount' => 1.66, + 'discount_amount' => 0, + 'base_discount_amount' => 0, + 'discount_percent' => 0, + '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/including_tax_row.php b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/including_tax_row.php new file mode 100644 index 0000000000000..65e4c3691257c --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/including_tax_row.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) + */ + +use Magento\Tax\Model\Config; +use Magento\Tax\Model\Sales\Total\Quote\SetupUtil; +use Magento\Tax\Model\Calculation; + +$taxCalculationData['including_tax_row'] = [ + 'config_data' => [ + SetupUtil::CONFIG_OVERRIDES => [ + Config::CONFIG_XML_PATH_APPLY_AFTER_DISCOUNT => 1, + Config::CONFIG_XML_PATH_PRICE_INCLUDES_TAX => 1, + Config::XML_PATH_ALGORITHM => Calculation::CALC_ROW_BASE, + ], + SetupUtil::TAX_RATE_OVERRIDES => [ + SetupUtil::TAX_RATE_TX => 20, + SetupUtil::TAX_STORE_RATE => 20, + ], + SetupUtil::TAX_RULE_OVERRIDES => [ + ], + ], + 'quote_data' => [ + 'billing_address' => [ + 'region_id' => SetupUtil::REGION_TX, + ], + 'shipping_address' => [ + 'region_id' => SetupUtil::REGION_TX, + ], + 'items' => [ + [ + 'sku' => 'simple1', + 'price' => 9.99, + 'qty' => 2, + ], + ], + ], + 'expected_results' => [ + 'address_data' => [ + 'subtotal' => 16.65, + 'base_subtotal' => 16.65, + 'subtotal_incl_tax' => 19.98, + 'base_subtotal_incl_tax' => 19.98, + 'tax_amount' => 3.33, + 'base_tax_amount' => 3.33, + 'shipping_amount' => 0, + 'base_shipping_amount' => 0, + 'shipping_incl_tax' => 0, + 'base_shipping_incl_tax' => 0, + 'shipping_taxable' => 0, + 'base_shipping_taxable' => 0, + 'shipping_tax_amount' => 0, + 'base_shipping_tax_amount' => 0, + 'discount_amount' => 0, + 'base_discount_amount' => 0, + 'hidden_tax_amount' => 0, + 'base_hidden_tax_amount' => 0, + 'shipping_hidden_tax_amount' => 0, + 'base_shipping_hidden_tax_amount' => 0, + 'grand_total' => 19.98, + 'base_grand_total' => 19.98, + ], + 'items_data' => [ + 'simple1' => [ + 'row_total' => 16.65, + 'base_row_total' => 16.65, + 'taxable_amount' => 19.98, + 'base_taxable_amount' => 19.98, + 'tax_percent' => 20, + 'price' => 8.33, + 'base_price' => 8.33, + 'price_incl_tax' => 9.99, + 'base_price_incl_tax' => 9.99, + 'row_total_incl_tax' => 19.98, + 'base_row_total_incl_tax' => 19.98, + 'tax_amount' => 3.33, + 'base_tax_amount' => 3.33, + 'discount_amount' => 0, + 'base_discount_amount' => 0, + 'discount_percent' => 0, + '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/including_tax_total.php b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/including_tax_total.php new file mode 100644 index 0000000000000..c737425c6563c --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/including_tax_total.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) + */ + +use Magento\Tax\Model\Config; +use Magento\Tax\Model\Sales\Total\Quote\SetupUtil; +use Magento\Tax\Model\Calculation; + +$taxCalculationData['including_tax_total'] = [ + 'config_data' => [ + SetupUtil::CONFIG_OVERRIDES => [ + Config::CONFIG_XML_PATH_APPLY_AFTER_DISCOUNT => 1, + Config::CONFIG_XML_PATH_PRICE_INCLUDES_TAX => 1, + Config::XML_PATH_ALGORITHM => Calculation::CALC_TOTAL_BASE, + ], + SetupUtil::TAX_RATE_OVERRIDES => [ + SetupUtil::TAX_RATE_TX => 20, + SetupUtil::TAX_STORE_RATE => 20, + ], + SetupUtil::TAX_RULE_OVERRIDES => [ + ], + ], + 'quote_data' => [ + 'billing_address' => [ + 'region_id' => SetupUtil::REGION_TX, + ], + 'shipping_address' => [ + 'region_id' => SetupUtil::REGION_TX, + ], + 'items' => [ + [ + 'sku' => 'simple1', + 'price' => 9.99, + 'qty' => 2, + ], + ], + ], + 'expected_results' => [ + 'address_data' => [ + 'subtotal' => 16.65, + 'base_subtotal' => 16.65, + 'subtotal_incl_tax' => 19.98, + 'base_subtotal_incl_tax' => 19.98, + 'tax_amount' => 3.33, + 'base_tax_amount' => 3.33, + 'shipping_amount' => 0, + 'base_shipping_amount' => 0, + 'shipping_incl_tax' => 0, + 'base_shipping_incl_tax' => 0, + 'shipping_taxable' => 0, + 'base_shipping_taxable' => 0, + 'shipping_tax_amount' => 0, + 'base_shipping_tax_amount' => 0, + 'discount_amount' => 0, + 'base_discount_amount' => 0, + 'hidden_tax_amount' => 0, + 'base_hidden_tax_amount' => 0, + 'shipping_hidden_tax_amount' => 0, + 'base_shipping_hidden_tax_amount' => 0, + 'grand_total' => 19.98, + 'base_grand_total' => 19.98, + ], + 'items_data' => [ + 'simple1' => [ + 'row_total' => 16.65, + 'base_row_total' => 16.65, + 'taxable_amount' => 19.98, + 'base_taxable_amount' => 19.98, + 'tax_percent' => 20, + 'price' => 8.33, + 'base_price' => 8.33, + 'price_incl_tax' => 9.99, + 'base_price_incl_tax' => 9.99, + 'row_total_incl_tax' => 19.98, + 'base_row_total_incl_tax' => 19.98, + 'tax_amount' => 3.33, + 'base_tax_amount' => 3.33, + 'discount_amount' => 0, + 'base_discount_amount' => 0, + 'discount_percent' => 0, + '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/including_tax_unit.php b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/including_tax_unit.php new file mode 100644 index 0000000000000..18ec0c995ad3a --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/including_tax_unit.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) + */ + +use Magento\Tax\Model\Config; +use Magento\Tax\Model\Sales\Total\Quote\SetupUtil; +use Magento\Tax\Model\Calculation; + +$taxCalculationData['including_tax_unit'] = [ + 'config_data' => [ + SetupUtil::CONFIG_OVERRIDES => [ + Config::CONFIG_XML_PATH_APPLY_AFTER_DISCOUNT => 1, + Config::CONFIG_XML_PATH_PRICE_INCLUDES_TAX => 1, + Config::XML_PATH_ALGORITHM => Calculation::CALC_UNIT_BASE, + ], + SetupUtil::TAX_RATE_OVERRIDES => [ + SetupUtil::TAX_RATE_TX => 20, + SetupUtil::TAX_STORE_RATE => 20, + ], + SetupUtil::TAX_RULE_OVERRIDES => [ + ], + ], + 'quote_data' => [ + 'billing_address' => [ + 'region_id' => SetupUtil::REGION_TX, + ], + 'shipping_address' => [ + 'region_id' => SetupUtil::REGION_TX, + ], + 'items' => [ + [ + 'sku' => 'simple1', + 'price' => 9.99, + 'qty' => 2, + ], + ], + ], + 'expected_results' => [ + 'address_data' => [ + 'subtotal' => 16.64, + 'base_subtotal' => 16.64, + 'subtotal_incl_tax' => 19.98, + 'base_subtotal_incl_tax' => 19.98, + 'tax_amount' => 3.34, + 'base_tax_amount' => 3.34, + 'shipping_amount' => 0, + 'base_shipping_amount' => 0, + 'shipping_incl_tax' => 0, + 'base_shipping_incl_tax' => 0, + 'shipping_taxable' => 0, + 'base_shipping_taxable' => 0, + 'shipping_tax_amount' => 0, + 'base_shipping_tax_amount' => 0, + 'discount_amount' => 0, + 'base_discount_amount' => 0, + 'hidden_tax_amount' => 0, + 'base_hidden_tax_amount' => 0, + 'shipping_hidden_tax_amount' => 0, + 'base_shipping_hidden_tax_amount' => 0, + 'grand_total' => 19.98, + 'base_grand_total' => 19.98, + ], + 'items_data' => [ + 'simple1' => [ + 'row_total' => 16.64, + 'base_row_total' => 16.64, + 'taxable_amount' => 9.99, + 'base_taxable_amount' => 9.99, + 'tax_percent' => 20, + 'price' => 8.32, + 'base_price' => 8.32, + 'price_incl_tax' => 9.99, + 'base_price_incl_tax' => 9.99, + 'row_total_incl_tax' => 19.98, + 'base_row_total_incl_tax' => 19.98, + 'tax_amount' => 3.34, + 'base_tax_amount' => 3.34, + 'discount_amount' => 0, + 'base_discount_amount' => 0, + 'discount_percent' => 0, + '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/tax_calculation_data_aggregated.php b/dev/tests/integration/testsuite/Magento/Tax/_files/tax_calculation_data_aggregated.php new file mode 100644 index 0000000000000..13097905b486d --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Tax/_files/tax_calculation_data_aggregated.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) + */ + +/** + * Global array that holds test scenarios data + * + * @var array + */ +$taxCalculationData = []; + +require_once __DIR__ . '/scenarios/excluding_tax_apply_tax_after_discount.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'; +require_once __DIR__ . '/scenarios/excluding_tax_total.php'; +require_once __DIR__ . '/scenarios/including_tax_unit.php'; +require_once __DIR__ . '/scenarios/including_tax_row.php'; +require_once __DIR__ . '/scenarios/including_tax_total.php'; +require_once __DIR__ . '/scenarios/excluding_tax_multi_item_unit.php'; +require_once __DIR__ . '/scenarios/excluding_tax_multi_item_row.php'; +require_once __DIR__ . '/scenarios/excluding_tax_multi_item_total.php'; + diff --git a/dev/tests/js/testsuite/mage/_demo/test.js b/dev/tests/js/testsuite/mage/_demo/test.js index 15043dc1e1605..6db8bddc8d166 100644 --- a/dev/tests/js/testsuite/mage/_demo/test.js +++ b/dev/tests/js/testsuite/mage/_demo/test.js @@ -20,6 +20,6 @@ * @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) */ -test( "hello test", function() { +TestCase( "hello test", function() { ok( 1 == "1", "Passed!" ); }); \ No newline at end of file diff --git a/dev/tests/js/testsuite/mage/loader/jquery-loader-test.js b/dev/tests/js/testsuite/mage/loader/jquery-loader-test.js index 883aeafc0cab2..493c49887131f 100644 --- a/dev/tests/js/testsuite/mage/loader/jquery-loader-test.js +++ b/dev/tests/js/testsuite/mage/loader/jquery-loader-test.js @@ -20,7 +20,7 @@ * @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) */ -test('options', function() { +TestCase('options', function() { expect(3); var element = $("#loader").loader({ @@ -39,7 +39,7 @@ test('options', function() { }); -test( 'element init', function() { +TestCase( 'element init', function() { expect(1); //Initialize Loader on element @@ -57,7 +57,7 @@ test( 'element init', function() { }); -test( 'body init', function() { +TestCase( 'body init', function() { expect(1); //Initialize Loader on Body @@ -68,7 +68,7 @@ test( 'body init', function() { }); -test( 'show/hide', function() { +TestCase( 'show/hide', function() { expect(3); var element = $('body').loader(); @@ -90,7 +90,7 @@ test( 'show/hide', function() { }); -test( 'destroy', function() { +TestCase( 'destroy', function() { expect(1); var element = $("#loader").loader({ diff --git a/dev/tests/js/testsuite/mage/search/regular-search-test.js b/dev/tests/js/testsuite/mage/search/regular-search-test.js new file mode 100644 index 0000000000000..451105229fc31 --- /dev/null +++ b/dev/tests/js/testsuite/mage/search/regular-search-test.js @@ -0,0 +1,64 @@ +/** + * 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. + * + * @category mage.js + * @package test + * @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) + */ +//Code to be tested for /app/code/Magento/CatalogSearch/view/frontend/form-mini.js (_onSubmit) +function regularSearch() { + if (this.document.getElementById('search').value === this.document.getElementById('search').placeholder || this.document.getElementById('search').value === '') { + this.document.getElementById('search').placeholder = 'Please specify at least one search term'; + this.document.getElementById('search').value = this.document.getElementById('search').placeholder; + } +} +//The test case +RegularSearchTest = TestCase("RegularSearchTest"); +RegularSearchTest.prototype.setUp = function() { + /*:DOC += + <div id='main'> + <form id="search_mini_form" action="" method="get"> + <div> + <label><span>Search</span></label> + <div> + <input id="search" + type="text" + name="q" + value="" + placeholder="Search entire store here..."/> + </div> + <div> + <button id="submit" type="submit" + title="Search"> + <span>Search</span> + </button> + </div> + </form> + </div>*/ +}; +RegularSearchTest.prototype.testRegularSearch = function(){ + //before + var inputValue = document.getElementById('search'); + assertEquals("", inputValue.value); + regularSearch(); + //after + inputValue = document.getElementById('search'); + assertEquals("Please specify at least one search term", inputValue.value); +}; diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/ClassesTest.php b/dev/tests/static/testsuite/Magento/Test/Integrity/ClassesTest.php index bf58e69147d1b..f0b157d619d6e 100644 --- a/dev/tests/static/testsuite/Magento/Test/Integrity/ClassesTest.php +++ b/dev/tests/static/testsuite/Magento/Test/Integrity/ClassesTest.php @@ -348,6 +348,7 @@ function ($file) { $newObjectPattern = '/^' . '.*new\s(?<venderClass>\\\\Magento(?:\\\\[a-zA-Z0-9_]+)+)\(.*\)' . '|.*new\s(?<badClass>[A-Z][a-zA-Z0-9]+[a-zA-Z0-9_\\\\]*)\(.*\)\;' . + '|use [A-Z][a-zA-Z0-9_\\\\]+ as (?<aliasClass>[A-Z][a-zA-Z0-9]+)' . '/m'; $result1 = array(); preg_match_all($newObjectPattern, $contents, $result1); @@ -356,6 +357,7 @@ function ($file) { $staticCallPattern = '/^' . '((?!Magento).)*(?<venderClass>\\\\Magento(?:\\\\[a-zA-Z0-9_]+)+)\:\:.*\;' . '|[^\\\\^a-z^A-Z^0-9^_^:](?<badClass>[A-Z][a-zA-Z0-9_]+)\:\:.*\;' . + '|use [A-Z][a-zA-Z0-9_\\\\]+ as (?<aliasClass>[A-Z][a-zA-Z0-9]+)' . '/m'; $result2 = array(); preg_match_all($staticCallPattern, $contents, $result2); @@ -365,6 +367,7 @@ function ($file) { '[\s]*\*\s\@(?:return|throws)\s(?<venderClass>\\\\Magento(?:\\\\[a-zA-Z0-9_]+)+)' . '|[\s]*\*\s\@return\s(?<badClass>[A-Z][a-zA-Z0-9_\\\\]+)' . '|[\s]*\*\s\@throws\s(?<exception>[A-Z][a-zA-Z0-9_\\\\]+)' . + '|use [A-Z][a-zA-Z0-9_\\\\]+ as (?<aliasClass>[A-Z][a-zA-Z0-9]+)' . '/m'; $result3 = array(); preg_match_all($annotationPattern, $contents, $result3); @@ -377,6 +380,10 @@ function ($file) { array_merge_recursive($result1['badClass'], $result2['badClass'], $result3['badClass']) ); + $aliasClasses = array_unique( + array_merge_recursive($result1['aliasClass'], $result2['aliasClass'], $result3['aliasClass']) + ); + $vendorClasses = array_filter($vendorClasses, 'strlen'); $vendorClasses = $this->referenceBlacklistFilter($vendorClasses); if (!empty($vendorClasses)) { @@ -391,6 +398,12 @@ function ($file) { if (empty($badClasses)) { return; } + + $aliasClasses = array_filter($aliasClasses, 'strlen'); + if (!empty($aliasClasses)) { + $badClasses = $this->handleAliasClasses($aliasClasses, $badClasses); + } + $badClasses = $this->referenceBlacklistFilter($badClasses); $badClasses = $this->removeSpecialCases($badClasses, $file, $contents, $namespacePath); $this->_assertClassReferences($badClasses, $file); @@ -399,6 +412,24 @@ function ($file) { ); } + /** + * Remove alias class name references that have been identified as 'bad'. + * + * @param $aliasClasses + * @param $badClasses + */ + protected function handleAliasClasses($aliasClasses, $badClasses) + { + foreach ($aliasClasses as $aliasClass) { + foreach ($badClasses as $badClass) { + if (strpos($badClass, $aliasClass) === 0) { + unset($badClasses[array_search($badClass, $badClasses)]); + } + } + } + return $badClasses; + } + /** * This function is to remove legacy code usages according to _files/blacklist/reference.txt * @param $classes 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 b90f6b315ac49..21f633cb716b4 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 @@ -1005,6 +1005,9 @@ array('getMigrationInstance', 'Magento\Customer\Model\Resource\Setup', '$this->_migrationFactory->create()'), array('turnOnReadCommittedMode', 'Magento\Backup\Model\Resource\Db'), array('turnOnSerializableMode', 'Magento\Backup\Model\Resource\Db', 'prepareTransactionIsolationLevel'), + array('turnOnMaintenanceMode', 'Magento\Backup\Helper\Data', 'Magento\Framework\App\State::turnOnMaintenanceMode'), + array('turnOffMaintenanceMode', 'Magento\Backup\Helper\Data', 'Magento\Framework\App\State::turnOffMaintenanceMode'), + array('getMaintenanceFlagFilePath', 'Magento\Backup\Helper\Data',), array('_getResourceModel', '\Magento\Webapi\Model\Source\Acl\Role', '$this->_resource'), array('_getSession', '\Magento\GiftMessage\Model\Save', '$this->_session'), array('run', '\Magento\Framework\AppInterface'), diff --git a/dev/tests/unit/testsuite/Magento/Backend/Block/System/Config/Form/Field/ImageTest.php b/dev/tests/unit/testsuite/Magento/Backend/Block/System/Config/Form/Field/ImageTest.php new file mode 100644 index 0000000000000..44ea57719b795 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Backend/Block/System/Config/Form/Field/ImageTest.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) + */ + +/** + * Tests for \Magento\Framework\Data\Form\Element\Image + */ +namespace Magento\Backend\Block\System\Config\Form\Field; + +class ImageTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $_objectManagerMock; + + /** + * @var \Magento\Framework\Url|\PHPUnit_Framework_MockObject_MockObject + */ + protected $urlBuilderMock; + + /** + * @var \Magento\Backend\Block\System\Config\Form\Field\Image + */ + protected $_image; + + protected function setUp() + { + $factoryMock = $this->getMock('Magento\Framework\Data\Form\Element\Factory', array(), array(), '', false); + $collectionFactoryMock = $this->getMock( + 'Magento\Framework\Data\Form\Element\CollectionFactory', + array(), + array(), + '', + false + ); + $escaperMock = $this->getMock('Magento\Framework\Escaper', array(), array(), '', false); + $this->urlBuilderMock = $this->getMock('Magento\Framework\Url', array(), array(), '', false); + $this->_image = new \Magento\Backend\Block\System\Config\Form\Field\Image( + $factoryMock, + $collectionFactoryMock, + $escaperMock, + $this->urlBuilderMock + ); + $formMock = new \Magento\Framework\Object(); + $formMock->getHtmlIdPrefix('id_prefix'); + $formMock->getHtmlIdPrefix('id_suffix'); + $this->_image->setForm($formMock); + } + + /** + * @covers \Magento\Backend\Block\System\Config\Form\Field\Image::_getUrl + */ + public function testGetElementHtmlWithValue() + { + $type = 'media'; + $url = 'http://test.example.com/media/'; + $this->urlBuilderMock->expects($this->once())->method('getBaseUrl') + ->with(['_type' => $type])->will($this->returnValue($url)); + + + $this->_image->setValue('test_value'); + $this->_image->setFieldConfig( + array( + 'id' => 'placeholder', + 'type' => 'image', + 'sortOrder' => '1', + 'showInDefault' => '1', + 'showInWebsite' => '1', + 'showInStore' => '1', + 'label' => null, + 'backend_model' => 'Magento\\Backend\\Model\\Config\\Backend\\Image', + 'upload_dir' => array( + 'config' => 'system/filesystem/media', + 'scope_info' => '1', + 'value' => 'catalog/product/placeholder', + ), + 'base_url' => array( + 'type' => $type, + 'scope_info' => '1', + 'value' => 'catalog/product/placeholder', + ), + '_elementType' => 'field', + 'path' => 'catalog/placeholder', + )); + + $html = $this->_image->getElementHtml(); + $this->assertContains('class="input-file"', $html); + $this->assertContains('<input', $html); + $this->assertContains('type="file"', $html); + $this->assertContains('value="test_value"', $html); + $this->assertContains( + '<a href="' . $url + . 'catalog/product/placeholder/test_value" onclick="imagePreview(\'_image\'); return false;"', + $html + ); + $this->assertContains('<input type="checkbox"', $html); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Backup/Helper/DataTest.php b/dev/tests/unit/testsuite/Magento/Backup/Helper/DataTest.php index 365e8f698934c..a15a786a7db12 100644 --- a/dev/tests/unit/testsuite/Magento/Backup/Helper/DataTest.php +++ b/dev/tests/unit/testsuite/Magento/Backup/Helper/DataTest.php @@ -23,35 +23,111 @@ */ namespace Magento\Backup\Helper; +use Magento\Framework\App\Filesystem; +use Magento\Framework\App\State\MaintenanceMode; + class DataTest extends \PHPUnit_Framework_TestCase { - public function testInvalidateIndexer() + /** + * @var \Magento\Backup\Helper\Data + */ + protected $helper; + + /** + * @var \Magento\Framework\App\Filesystem | \PHPUnit_Framework_MockObject_MockObject + */ + protected $filesystem; + + /** + * @var \Magento\Index\Model\Resource\Process\CollectionFactory | \PHPUnit_Framework_MockObject_MockObject + */ + protected $processFactory; + + public function setUp() { - $helper = new \Magento\TestFramework\Helper\ObjectManager($this); + $this->filesystem = $this->getMockBuilder('Magento\Framework\App\Filesystem')->disableOriginalConstructor() + ->getMock(); + $this->processFactory = $this->getMockBuilder('Magento\Index\Model\Resource\Process\CollectionFactory') + ->setMethods(['create'])->disableOriginalConstructor()->getMock(); + $this->helper = (new \Magento\TestFramework\Helper\ObjectManager($this)) + ->getObject('Magento\Backup\Helper\Data', [ + 'filesystem' => $this->filesystem, + 'processFactory' => $this->processFactory + ]); + } + + public function testInvalidateIndexer() + { $process = $this->getMockBuilder('Magento\Index\Model\Process')->disableOriginalConstructor()->getMock(); $process->expects( $this->once() )->method( - 'changeStatus' - )->with( - \Magento\Index\Model\Process::STATUS_REQUIRE_REINDEX - ); - $iterator = $this->returnValue(new \ArrayIterator(array($process))); - + 'changeStatus' + )->with( + \Magento\Index\Model\Process::STATUS_REQUIRE_REINDEX + ); + $iterator = $this->returnValue(new \ArrayIterator([$process])); $collection = $this->getMockBuilder( 'Magento\Index\Model\Resource\Process\Collection' )->disableOriginalConstructor()->getMock(); $collection->expects($this->at(0))->method('getIterator')->will($iterator); + $this->processFactory->expects($this->any())->method('create')->will($this->returnValue($collection)); - $processFactory = $this->getMockBuilder( - 'Magento\Index\Model\Resource\Process\CollectionFactory' - )->setMethods( - array('create') - )->disableOriginalConstructor()->getMock(); - $processFactory->expects($this->any())->method('create')->will($this->returnValue($collection)); + $this->helper->invalidateIndexer(); + } + + public function testGetBackupIgnorePaths() + { + $this->filesystem->expects($this->any())->method('getPath') + ->will($this->returnValueMap([ + [MaintenanceMode::FLAG_DIR, MaintenanceMode::FLAG_DIR], + [Filesystem::SESSION_DIR, Filesystem::SESSION_DIR], + [Filesystem::CACHE_DIR, Filesystem::CACHE_DIR], + [Filesystem::LOG_DIR, Filesystem::LOG_DIR], + [Filesystem::VAR_DIR, Filesystem::VAR_DIR], + ])); + + $this->assertEquals( + [ + '.git', + '.svn', + 'var/maintenance.flag', + Filesystem::SESSION_DIR, + Filesystem::CACHE_DIR, + Filesystem::LOG_DIR, + Filesystem::VAR_DIR . '/full_page_cache', + Filesystem::VAR_DIR . '/locks', + Filesystem::VAR_DIR . '/report', + ], + $this->helper->getBackupIgnorePaths() + ); + } - $object = $helper->getObject('Magento\Backup\Helper\Data', array('processFactory' => $processFactory)); - $object->invalidateIndexer(); + public function testGetRollbackIgnorePaths() + { + $this->filesystem->expects($this->any())->method('getPath') + ->will($this->returnValueMap([ + [MaintenanceMode::FLAG_DIR, MaintenanceMode::FLAG_DIR], + [Filesystem::SESSION_DIR, Filesystem::SESSION_DIR], + [Filesystem::ROOT_DIR, Filesystem::ROOT_DIR], + [Filesystem::LOG_DIR, Filesystem::LOG_DIR], + [Filesystem::VAR_DIR, Filesystem::VAR_DIR], + ])); + + $this->assertEquals( + [ + '.svn', + '.git', + 'var/maintenance.flag', + Filesystem::SESSION_DIR, + Filesystem::LOG_DIR, + Filesystem::VAR_DIR . '/locks', + Filesystem::VAR_DIR . '/report', + Filesystem::ROOT_DIR . '/errors', + Filesystem::ROOT_DIR . '/index.php', + ], + $this->helper->getRollbackIgnorePaths() + ); } } diff --git a/dev/tests/unit/testsuite/Magento/Checkout/Block/Onepage/ProgressTest.php b/dev/tests/unit/testsuite/Magento/Checkout/Block/Onepage/ProgressTest.php new file mode 100644 index 0000000000000..07d4674b5b134 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Checkout/Block/Onepage/ProgressTest.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\Checkout\Block\Onepage; + +use Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper; + +class ProgressTest extends \PHPUnit_Framework_TestCase +{ + /** + * Selected shipping method + */ + const SHIPPING_METHOD = 'shipping method'; + + /** + * Price of selected shipping method + */ + const SHIPPING_PRICE = 13.02; + + /** + * Price of selected shipping method wrapped with tax helper + */ + const SHIPPING_PRICE_WITH_TAX = 13.03; + + /** + * Price of selected shipping method formatted with current store + */ + const SHIPPING_PRICE_FORMATTED = '$13.38'; + + /** + * @var \Magento\Checkout\Block\Onepage\Progress + */ + protected $model; + + /** + * @var \Magento\Checkout\Model\Session|\PHPUnit_Framework_MockObject_MockObject + */ + protected $checkoutSession; + + /** + * @var \Magento\Store\Model\Store|\PHPUnit_Framework_MockObject_MockObject + */ + protected $store; + + /** + * @var \Magento\Tax\Helper\Data|\PHPUnit_Framework_MockObject_MockObject + */ + protected $taxHelper; + + /** + * @var \Magento\Sales\Model\Quote\Address|\PHPUnit_Framework_MockObject_MockObject + */ + protected $shippingAddress; + + protected function setUp() + { + $this->checkoutSession = $this->getMock('Magento\Checkout\Model\Session', [], [], '', false); + $this->taxHelper = $this->getMock('Magento\Tax\Helper\Data', [], [], '', false); + + $objectManagerHelper = new ObjectManagerHelper($this); + $this->model = $objectManagerHelper->getObject( + 'Magento\Checkout\Block\Onepage\Progress', + ['resourceSession' => $this->checkoutSession, 'taxData' => $this->taxHelper] + ); + $this->shippingAddress = $this->getMock( + 'Magento\Sales\Model\Quote\Address', + ['getShippingRateByCode', '__wakeup'], + [], + '', + false + ); + $this->store = $this->getMock('Magento\Store\Model\Store', [], [], '', false); + $quote = $this->getMock('Magento\Sales\Model\Quote', [], [], '', false); + $quote->expects($this->any())->method('getShippingAddress')->will($this->returnValue($this->shippingAddress)); + $quote->expects($this->any())->method('getStore')->will($this->returnValue($this->store)); + $this->checkoutSession->expects($this->any())->method('getQuote')->will($this->returnValue($quote)); + } + + /** + * @param bool $inclTax + */ + private function _prepareTestGetShippingPrice($inclTax) + { + $rate = $this->getMock('Magento\Sales\Model\Quote\Address\Rate', ['__wakeup'], [], '', false); + $rate->setPrice(self::SHIPPING_PRICE); + $this->shippingAddress->setShippingMethod(self::SHIPPING_METHOD); + $this->shippingAddress->expects($this->once()) + ->method('getShippingRateByCode') + ->with(self::SHIPPING_METHOD) + ->will($this->returnValue($rate)); + $this->taxHelper->expects($this->once()) + ->method('getShippingPrice') + ->with(self::SHIPPING_PRICE, $inclTax ? $this->isTrue() : $this->isFalse(), $this->shippingAddress) + ->will($this->returnValue(self::SHIPPING_PRICE_WITH_TAX)); + $this->store->expects($this->once()) + ->method('formatPrice') + ->with(self::SHIPPING_PRICE_WITH_TAX) + ->will($this->returnValue(self::SHIPPING_PRICE_FORMATTED)); + } + + public function testGetShippingPriceInclTax() + { + $this->_prepareTestGetShippingPrice(true); + $this->assertEquals(self::SHIPPING_PRICE_FORMATTED, $this->model->getShippingPriceInclTax()); + + } + + public function testGetShippingPriceExclTax() + { + $this->_prepareTestGetShippingPrice(false); + $this->assertEquals(self::SHIPPING_PRICE_FORMATTED, $this->model->getShippingPriceExclTax()); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Core/Model/App/StateTest.php b/dev/tests/unit/testsuite/Magento/Core/Model/App/StateTest.php index 85bda142a8ece..93cecc9627501 100644 --- a/dev/tests/unit/testsuite/Magento/Core/Model/App/StateTest.php +++ b/dev/tests/unit/testsuite/Magento/Core/Model/App/StateTest.php @@ -23,13 +23,10 @@ */ namespace Magento\Core\Model\App; +use Magento\Framework\App\State; + class StateTest extends \PHPUnit_Framework_TestCase { - /** - * @var \Magento\Framework\App\State - */ - protected $_model; - /** * @param string $mode * @dataProvider constructorDataProvider diff --git a/dev/tests/unit/testsuite/Magento/Downloadable/Helper/DownloadTest.php b/dev/tests/unit/testsuite/Magento/Downloadable/Helper/DownloadTest.php index 7d91ade57577c..f0a63231c88bf 100644 --- a/dev/tests/unit/testsuite/Magento/Downloadable/Helper/DownloadTest.php +++ b/dev/tests/unit/testsuite/Magento/Downloadable/Helper/DownloadTest.php @@ -48,6 +48,8 @@ class DownloadTest extends \PHPUnit_Framework_TestCase /** @var DownloadableFile|\PHPUnit_Framework_MockObject_MockObject */ protected $_downloadableFileMock; + /** @var \Magento\Framework\Session\SessionManagerInterface|\PHPUnit_Framework_MockObject_MockObject */ + protected $sessionManager; /** @var bool Result of function_exists() */ public static $functionExists; @@ -86,14 +88,15 @@ public function setUp() false ); $this->_downloadableFileMock = $this->getMock('Magento\Downloadable\Helper\File', array(), array(), '', false); - + $this->sessionManager = $this->getMockForAbstractClass('Magento\Framework\Session\SessionManagerInterface'); $this->_helper = new DownloadHelper( $this->getMock('Magento\Framework\App\Helper\Context', array(), array(), '', false), $this->getMock('Magento\Core\Helper\Data', array(), array(), '', false), $this->_downloadableFileMock, $this->getMock('Magento\Core\Helper\File\Storage\Database', array(), array(), '', false), $this->getMock('Magento\Framework\App\Config\ScopeConfigInterface'), - $this->_filesystemMock + $this->_filesystemMock, + $this->sessionManager ); } @@ -262,4 +265,12 @@ protected function _setupUrlMocks($size = self::FILE_SIZE, $url = self::URL, $ad $this->_helper->setResource($url, DownloadHelper::LINK_TYPE_URL); } + + public function testOutput() + { + $this->sessionManager + ->expects($this->once())->method('writeClose'); + $this->_setupUrlMocks(self::FILE_SIZE, self::URL, array('disposition' => "inline; filename=test.txt")); + $this->_helper->output(); + } } diff --git a/dev/tests/unit/testsuite/Magento/Framework/App/State/MaintenanceModeTest.php b/dev/tests/unit/testsuite/Magento/Framework/App/State/MaintenanceModeTest.php new file mode 100644 index 0000000000000..b64a61335c43f --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Framework/App/State/MaintenanceModeTest.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\App\State; + +class MaintenanceModeTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Framework\App\State\MaintenanceMode + */ + protected $model; + + /** + * @var \Magento\Framework\Filesystem\Directory\Write | \PHPUnit_Framework_MockObject_MockObject + */ + protected $directoryWrite; + + /** + * @var \Magento\Framework\App\Filesystem | \PHPUnit_Framework_MockObject_MockObject + */ + protected $filesystem; + + protected function setUp() + { + $this->directoryWrite = $this->getMock('Magento\Framework\Filesystem\Directory\Write', [], [], '', false); + $this->filesystem = $this->getMock('Magento\Framework\App\Filesystem', [], [], '', false); + + $this->model = (new \Magento\TestFramework\Helper\ObjectManager($this))->getObject( + 'Magento\Framework\App\State\MaintenanceMode', + ['filesystem' => $this->filesystem] + ); + } + + protected function getDirectory() + { + $this->filesystem->expects($this->once())->method('getDirectoryWrite')->with(MaintenanceMode::FLAG_DIR) + ->will($this->returnValue($this->directoryWrite)); + } + + public function testTurnOnMaintenanceMode() + { + $this->getDirectory(); + $this->directoryWrite->expects($this->once())->method('writeFile') + ->with(MaintenanceMode::FLAG_FILENAME, 'data') + ->will($this->returnValue(123)); + + $this->assertTrue($this->model->turnOn('data')); + } + + public function testTurnOnMaintenanceModeFailed() + { + $this->getDirectory(); + $this->directoryWrite->expects($this->once())->method('writeFile') + ->with(MaintenanceMode::FLAG_FILENAME, 'data') + ->will($this->throwException(new \Magento\Framework\Filesystem\FilesystemException('failed'))); + + $this->assertFalse($this->model->turnOn('data')); + } + + public function testTurnOffMaintenanceMode() + { + $this->getDirectory(); + $this->directoryWrite->expects($this->once())->method('delete')->with(MaintenanceMode::FLAG_FILENAME); + + $this->assertTrue($this->model->turnOff()); + } + + public function testTurnOffMaintenanceModeFailed() + { + $this->getDirectory(); + $this->directoryWrite->expects($this->once())->method('delete')->with(MaintenanceMode::FLAG_FILENAME) + ->will($this->throwException(new \Magento\Framework\Filesystem\FilesystemException('failed'))); + + $this->assertFalse($this->model->turnOff()); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Framework/Math/RandomTest.php b/dev/tests/unit/testsuite/Magento/Framework/Math/RandomTest.php index 26f9fd3f02128..23d1ce477bdef 100644 --- a/dev/tests/unit/testsuite/Magento/Framework/Math/RandomTest.php +++ b/dev/tests/unit/testsuite/Magento/Framework/Math/RandomTest.php @@ -28,7 +28,7 @@ class RandomTest extends \PHPUnit_Framework_TestCase { /** - * @param int $length + * @param int $length * @param string $chars * * @dataProvider getRandomStringDataProvider @@ -81,4 +81,30 @@ protected function _assertContainsOnlyChars($string, $chars) $this->fail(sprintf('Unexpected char "%s" found', $matches[0])); } } + + /** + * @param $min + * @param $max + * + * @dataProvider testGetRandomNumberProvider + */ + public function testGetRandomNumber($min, $max) + { + $number = \Magento\Framework\Math\Random::getRandomNumber($min, $max); + $this->assertLessThanOrEqual($max, $number); + $this->assertGreaterThanOrEqual($min, $number); + } + + public function testGetRandomNumberProvider() + { + return [ + [0, 100], + [0, 1], + [0, 0], + [-1, 0], + [-100, 0], + [-1, 1], + [-100, 100] + ]; + } } diff --git a/dev/tests/unit/testsuite/Magento/Framework/View/Element/Html/CalendarTest.php b/dev/tests/unit/testsuite/Magento/Framework/View/Element/Html/CalendarTest.php new file mode 100644 index 0000000000000..1f1fc04c882ea --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Framework/View/Element/Html/CalendarTest.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\Html; + +class CalendarTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\TestFramework\Helper\ObjectManager + */ + protected $objectManagerHelper; + + /** @var \Magento\Framework\View\Element\Html\Calendar */ + protected $block; + + /** @var \Magento\Framework\View\Element\Template\Context */ + protected $context; + + /** @var \Magento\Framework\Stdlib\DateTime\TimezoneInterface|\PHPUnit_Framework_MockObject_MockObject */ + protected $localeDate; + + protected function setUp() + { + $this->objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this); + $this->localeDate = $this->getMockBuilder('Magento\Framework\Stdlib\DateTime\TimezoneInterface') + ->getMock(); + + /** @var \Magento\Framework\View\Element\Template\Context $context */ + $this->context = $this->objectManagerHelper->getObject( + 'Magento\Framework\View\Element\Template\Context', + array( + 'localeDate' => $this->localeDate, + ) + ); + + /** @var \Magento\Framework\View\Element\Html\Links $block */ + $this->block = $this->objectManagerHelper->getObject( + 'Magento\Framework\View\Element\Html\Calendar', + array('context' => $this->context) + ); + } + + /** + * @test + */ + public function testGetYearRange() + { + $testCurrentYear = 2123; + $date = $this->getMockBuilder('Magento\Framework\Stdlib\DateTime\DateInterface') + ->getMock(); + + $date->expects($this->any()) + ->method('__toString') + ->will($this->returnValue($testCurrentYear)); + + $this->localeDate->expects($this->any()) + ->method('date') + ->with($this->equalTo('Y')) + ->will($this->returnValue($date)); + + $this->assertEquals((int)$testCurrentYear - 100 . ':' . $testCurrentYear, $this->block->getYearRange()); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Ogone/Model/ConfigTest.php b/dev/tests/unit/testsuite/Magento/Ogone/Model/ConfigTest.php new file mode 100644 index 0000000000000..d4ae5ff18b5b0 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Ogone/Model/ConfigTest.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\Ogone\Model; + +class ConfigTest extends \PHPUnit_Framework_TestCase +{ + const EXPECTED_VALUE = 'abcdef1234567890'; + + /** + * @var Config + */ + protected $_model; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $_scopeConfig; + + protected function setUp() + { + $this->_scopeConfig = $this->getMock('\Magento\Framework\App\Config\ScopeConfigInterface', [], [], '', false); + $helper = new \Magento\TestFramework\Helper\ObjectManager($this); + $this->_model = $helper->getObject('Magento\Ogone\Model\Config', [ + 'scopeConfig' => $this->_scopeConfig + ]); + } + + public function testGetShaInCode() + { + $this->_scopeConfig->expects($this->any())->method('getValue')->with('payment/ogone/secret_key_in')->will( + $this->returnValue(self::EXPECTED_VALUE) + ); + $this->assertEquals(self::EXPECTED_VALUE, $this->_model->getShaInCode()); + } + + public function testGetShaOutCode() + { + $this->_scopeConfig->expects($this->any())->method('getValue')->with('payment/ogone/secret_key_out')->will( + $this->returnValue(self::EXPECTED_VALUE) + ); + $this->assertEquals(self::EXPECTED_VALUE, $this->_model->getShaOutCode()); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Sales/Block/Adminhtml/Order/Totals/TaxTest.php b/dev/tests/unit/testsuite/Magento/Sales/Block/Adminhtml/Order/Totals/TaxTest.php index efe3186c90039..84b1dbe72ebd1 100644 --- a/dev/tests/unit/testsuite/Magento/Sales/Block/Adminhtml/Order/Totals/TaxTest.php +++ b/dev/tests/unit/testsuite/Magento/Sales/Block/Adminhtml/Order/Totals/TaxTest.php @@ -30,123 +30,85 @@ class TaxTest extends \PHPUnit_Framework_TestCase { /** - * @var \Magento\Sales\Block\Adminhtml\Order\Totals\Tax + * Test method for getFullTaxInfo + * + * @param \Magento\Sales\Model\Order $source + * @param array $getCalculatedTax + * @param array $getShippingTax + * @param array $expectedResult + * + * @dataProvider getFullTaxInfoDataProvider */ - protected $_block; + public function testGetFullTaxInfo($source, $getCalculatedTax, $getShippingTax, $expectedResult) + { + $taxHelperMock = $this->getMockBuilder('Magento\Tax\Helper\Data') + ->setMethods(array('getCalculatedTaxes', 'getShippingTax')) + ->disableOriginalConstructor() + ->getMock(); + $taxHelperMock->expects($this->any()) + ->method('getCalculatedTaxes') + ->will($this->returnValue($getCalculatedTax)); + $taxHelperMock->expects($this->any()) + ->method('getShippingTax') + ->will($this->returnValue($getShippingTax)); - /** - * @var \Magento\Framework\ObjectManager|\PHPUnit_Framework_MockObject_MockObject - */ - protected $_objectManager; + $mockObject = $this->getMockBuilder('Magento\Sales\Block\Adminhtml\Order\Totals\Tax') + ->setConstructorArgs($this->_getConstructArguments($taxHelperMock)) + ->setMethods(array('getOrder')) + ->getMock(); + $mockObject->expects($this->once()) + ->method('getOrder') + ->will($this->returnValue($source)); - /** - * Instantiate \Magento\Sales\Block\Adminhtml\Order\Totals\Tax block - */ - protected function setUp() - { - $this->_block = $this->getMockBuilder( - 'Magento\Sales\Block\Adminhtml\Order\Totals\Tax' - )->setConstructorArgs( - $this->_getModelArgument() - )->setMethods( - array('getOrder') - )->getMock(); + $actualResult = $mockObject->getFullTaxInfo(); + $this->assertEquals($expectedResult, $actualResult); } /** - * Module arguments for \Magento\Sales\Block\Adminhtml\Order\Totals\Tax + * Provide the tax helper mock as a constructor argument * + * @param $taxHelperMock * @return array */ - protected function _getModelArgument() + protected function _getConstructArguments($taxHelperMock) { $objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this); - $attributeFactory = $this->getMock( - 'Magento\Eav\Model\Entity\AttributeFactory', - array('create'), - array(), - '', - false - ); - $taxItemFactory = $this->getMock( - 'Magento\Tax\Model\Resource\Sales\Order\Tax\ItemFactory', - array('create'), - array(), - '', - false - ); - $taxHelperMock = $objectManagerHelper->getObject( - 'Magento\Tax\Helper\Data', - array('attributeFactory' => $attributeFactory, 'taxItemFactory' => $taxItemFactory) - ); - - $taxOrderFactory = $this->getMock( - 'Magento\Tax\Model\Sales\Order\TaxFactory', - array('create'), - array(), - '', - false - ); - return $objectManagerHelper->getConstructArguments( 'Magento\Sales\Block\Adminhtml\Order\Totals\Tax', - array('taxHelper' => $taxHelperMock, 'taxOrderFactory' => $taxOrderFactory) + array('taxHelper' => $taxHelperMock) ); } /** - * @return \Magento\Sales\Model\Order|\PHPUnit_Framework_MockObject_MockObject - */ - protected function _getSalesOrderMock() - { - $orderMock = $this->getMockBuilder( - 'Magento\Sales\Model\Order' - )->setMethods( - array('getItemsCollection', '__wakeup') - )->disableOriginalConstructor()->getMock(); - $orderMock->expects($this->any())->method('getItemsCollection')->will($this->returnValue(array())); - return $orderMock; - } - - /** - * Test MAGETWO-1653: Incorrect tax summary for partial credit memos/invoices - * - * @dataProvider getSampleData - */ - public function testAddAttributesToForm($actual, $expected) - { - $orderMock = $this->_getSalesOrderMock(); - $orderMock->setData($actual); - $this->_block->expects($this->any())->method('getOrder')->will($this->returnValue($orderMock)); - $fullTaxInfo = $this->_block->getFullTaxInfo(); - $this->assertEquals(reset($fullTaxInfo), $expected); - $this->assertTrue(true); - } - - /** - * Data provider with sample data for tax order + * Data provider. + * 1st Case : $source is not an instance of \Magento\Sales\Model\Order + * 2nd Case : getCalculatedTaxes and getShippingTax return value * * @return array */ - public function getSampleData() + public function getFullTaxInfoDataProvider() { + $notAnInstanceOfASalesModelOrder = $this->getMock('stdClass'); + + $salesModelOrderMock = $this->getMockBuilder('Magento\Sales\Model\Order') + ->disableOriginalConstructor() + ->getMock(); + + $getCalculatedTax = array( + 'tax' => 'tax', + 'shipping_tax' => 'shipping_tax' + ); + $getShippingTax = array( + 'shipping_tax' => 'shipping_tax', + 'shipping_and_handing' => 'shipping_and_handing' + ); + return array( - array( - 'actual' => array( - 'calculated_taxes' => array(), - 'shipping_tax' => array(), - 'shipping_tax_amount' => 1.25, - 'base_shipping_tax_amount' => 3.25, - 'tax_amount' => 0.16, - 'base_tax_amount' => 2 - ), - 'expected' => array( - 'tax_amount' => 1.25, - 'base_tax_amount' => 3.25, - 'title' => 'Shipping & Handling Tax', - 'percent' => null - ) - ) + 'source is not an instance of \Magento\Sales\Model\Order' => + array($notAnInstanceOfASalesModelOrder, $getCalculatedTax, $getShippingTax, array()), + 'source is an instance of \Magento\Sales\Model\Order and has reasonable data' => + array($salesModelOrderMock, $getCalculatedTax, $getShippingTax, array('tax' => 'tax', + 'shipping_tax' => 'shipping_tax', 'shipping_and_handing' => 'shipping_and_handing')) ); } } diff --git a/dev/tools/Magento/Tools/Di/entity_generator.php b/dev/tools/Magento/Tools/Di/entity_generator.php index 1739a98d10410..0729797407b03 100644 --- a/dev/tools/Magento/Tools/Di/entity_generator.php +++ b/dev/tools/Magento/Tools/Di/entity_generator.php @@ -22,41 +22,49 @@ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ +use Magento\Framework\Code\Generator; +use Magento\Framework\Code\Generator\Io; +use Magento\Framework\Filesystem\Driver\File; +use Magento\Framework\ObjectManager\Code\Generator\Factory; +use Magento\Framework\ObjectManager\Code\Generator\Proxy; +use Magento\Framework\Interception\Code\Generator\Interceptor; +use Magento\Framework\Exception; + require __DIR__ . '/../../../../../app/bootstrap.php'; // default generation dir -$generationDir = BP . '/' . \Magento\Framework\Code\Generator\Io::DEFAULT_DIRECTORY; +$generationDir = BP . '/' . Io::DEFAULT_DIRECTORY; try { - $opt = new Zend_Console_Getopt( - array( + $opt = new \Zend_Console_Getopt( + [ 'type|t=w' => 'entity type(required)', - 'class|c=w' => 'entity class name(required)', + 'class|c=s' => 'entity class name(required)', 'generation|g=s' => 'generation dir. Default value ' . $generationDir - ) + ] ); $opt->parse(); $entityType = $opt->getOption('t'); if (empty($entityType)) { - throw new Zend_Console_Getopt_Exception('type is a required parameter'); + throw new \Zend_Console_Getopt_Exception('type is a required parameter'); } $className = $opt->getOption('c'); if (empty($className)) { - throw new Zend_Console_Getopt_Exception('class is a required parameter'); + throw new \Zend_Console_Getopt_Exception('class is a required parameter'); } - $substitutions = array('proxy' => '_Proxy', 'factory' => 'Factory', 'interceptor' => '_Interceptor'); + $substitutions = ['proxy' => '_Proxy', 'factory' => 'Factory', 'interceptor' => '_Interceptor']; if (!in_array($entityType, array_keys($substitutions))) { - throw new Zend_Console_Getopt_Exception('unrecognized type: ' . $entityType); + throw new \Zend_Console_Getopt_Exception('unrecognized type: ' . $entityType); } $className .= $substitutions[$entityType]; if ($opt->getOption('g')) { $generationDir = $opt->getOption('g'); } -} catch (Zend_Console_Getopt_Exception $e) { - $generator = new \Magento\Framework\Code\Generator(); +} catch (\Zend_Console_Getopt_Exception $e) { + $generator = new Generator(); $entities = $generator->getGeneratedEntities(); $allowedTypes = 'Allowed entity types are: ' . implode(', ', $entities) . '.'; @@ -74,15 +82,26 @@ (new \Magento\Framework\Autoload\IncludePath())->addIncludePath($generationDir); //reinit generator with correct generation path -$io = new \Magento\Framework\Code\Generator\Io(new \Magento\Framework\Filesystem\Driver\File(), null, $generationDir); -$generator = new \Magento\Framework\Code\Generator(null, null, $io); +$io = new Io(new File(), null, $generationDir); +$generator = new Generator( + null, + $io, + [ + Proxy::ENTITY_TYPE => + 'Magento\Framework\ObjectManager\Code\Generator\Proxy', + Factory::ENTITY_TYPE => + 'Magento\Framework\ObjectManager\Code\Generator\Factory', + Interceptor::ENTITY_TYPE => + 'Magento\Framework\Interception\Code\Generator\Interceptor' + ] +); try { - if (\Magento\Framework\Code\Generator::GENERATION_SUCCESS == $generator->generateClass($className)) { + if (Generator::GENERATION_SUCCESS == $generator->generateClass($className)) { print "Class {$className} was successfully generated.\n"; } else { print "Can't generate class {$className}. This class either not generated entity, or it already exists.\n"; } -} catch (\Magento\Framework\Exception $e) { +} catch (Exception $e) { print "Error! {$e->getMessage()}\n"; } diff --git a/downloader/app/Magento/Downloader/Controller.php b/downloader/app/Magento/Downloader/Controller.php index 02144621d07ca..7032bcdc51b2e 100644 --- a/downloader/app/Magento/Downloader/Controller.php +++ b/downloader/app/Magento/Downloader/Controller.php @@ -876,13 +876,14 @@ protected function _getMaintenanceFlag() /** * Retrieve Maintenance Flag file path + * Path for maintenance flag: web_root/var/maintenance.flag * * @return string */ protected function _getMaintenanceFilePath() { if (is_null($this->_maintenanceFile)) { - $path = dirname(dirname(__DIR__)) . '/'; + $path = dirname(dirname(__DIR__)) . '/var/'; $this->_maintenanceFile = $path . 'maintenance.flag'; } return $this->_maintenanceFile; @@ -897,7 +898,7 @@ protected function _getMaintenanceFilePath() public function startInstall() { if ($this->_getMaintenanceFlag()) { - $maintenance_filename = 'maintenance.flag'; + $maintenance_filename = 'var/maintenance.flag'; $config = $this->config(); if (!$this->isWritable() || strlen($config->__get('remote_config')) > 0) { $ftpObj = new \Magento\Framework\Connect\Ftp(); @@ -987,7 +988,7 @@ protected function cleanCache() } if ($result && $this->_getMaintenanceFlag()) { - $maintenance_filename = 'maintenance.flag'; + $maintenance_filename = 'var/maintenance.flag'; $config = $this->config(); if (!$this->isWritable() && strlen($config->__get('remote_config')) > 0) { $ftpObj = new \Magento\Framework\Connect\Ftp(); @@ -1115,7 +1116,7 @@ protected function _getBackupIgnorePaths() return array( '.git', '.svn', - 'maintenance.flag', + 'var/maintenance.flag', \Mage::getBaseDir('var') . '/session', \Mage::getBaseDir('var') . '/cache', \Mage::getBaseDir('var') . '/full_page_cache', diff --git a/lib/Magento/Framework/App/State/MaintenanceMode.php b/lib/Magento/Framework/App/State/MaintenanceMode.php new file mode 100644 index 0000000000000..adc1bb357a60c --- /dev/null +++ b/lib/Magento/Framework/App/State/MaintenanceMode.php @@ -0,0 +1,87 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 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\State; + +use Magento\Framework\App\Filesystem; + +/** + * Application Maintenance Mode + */ +class MaintenanceMode +{ + /** + * Maintenance flag name + */ + const FLAG_FILENAME = 'maintenance.flag'; + + /** + * Maintenance flag dir + */ + const FLAG_DIR = Filesystem::VAR_DIR; + + /** + * @var \Magento\Framework\App\Filesystem + */ + protected $filesystem; + + /** + * @param \Magento\Framework\App\Filesystem $filesystem + */ + public function __construct(Filesystem $filesystem) + { + $this->filesystem = $filesystem; + } + + /** + * Turn on store maintenance mode + * + * @param string $data + * @return bool + */ + public function turnOn($data = 'maintenance') + { + try { + $this->filesystem->getDirectoryWrite(self::FLAG_DIR) + ->writeFile(self::FLAG_FILENAME, $data); + } catch (\Exception $e) { + return false; + } + return true; + } + + /** + * Turn off store maintenance mode + * + * @return bool + */ + public function turnOff() + { + try { + $this->filesystem->getDirectoryWrite(self::FLAG_DIR)->delete(self::FLAG_FILENAME); + } catch (\Exception $e) { + return false; + } + return true; + } +} diff --git a/lib/Magento/Framework/AppInterface.php b/lib/Magento/Framework/AppInterface.php index 0f3b466114275..bedbc39d1cb6a 100644 --- a/lib/Magento/Framework/AppInterface.php +++ b/lib/Magento/Framework/AppInterface.php @@ -35,7 +35,7 @@ interface AppInterface /** * Magento version */ - const VERSION = '2.0.0.0-dev78'; + const VERSION = '2.0.0.0-dev79'; /** * Launch application diff --git a/lib/Magento/Framework/Math/Random.php b/lib/Magento/Framework/Math/Random.php index 15db9373707f7..ca701b15a3f90 100644 --- a/lib/Magento/Framework/Math/Random.php +++ b/lib/Magento/Framework/Math/Random.php @@ -42,20 +42,79 @@ class Random /** * Get random string * - * @param int $length + * @param int $length * @param null|string $chars * @return string */ public function getRandomString($length, $chars = null) { - if (is_null($chars)) { + $str = ''; + if (null === $chars) { $chars = self::CHARS_LOWERS . self::CHARS_UPPERS . self::CHARS_DIGITS; } - mt_srand(10000000 * (double)microtime()); - for ($i = 0,$string = '',$lc = strlen($chars) - 1; $i < $length; $i++) { - $string .= $chars[mt_rand(0, $lc)]; + + if (function_exists('openssl_random_pseudo_bytes')) { + // use openssl lib if it is installed + for ($i = 0, $lc = strlen($chars) - 1; $i < $length; $i++) { + $bytes = openssl_random_pseudo_bytes(PHP_INT_SIZE); + $hex = bin2hex($bytes); // hex() doubles the length of the string + $rand = abs(hexdec($hex) % $lc); // random integer from 0 to $lc + $str .= $chars[$rand]; // random character in $chars + } + } elseif ($fp = @fopen('/dev/urandom', 'rb')) { + // attempt to use /dev/urandom if it exists but openssl isn't available + for ($i = 0, $lc = strlen($chars) - 1; $i < $length; $i++) { + $bytes = @fread($fp, PHP_INT_SIZE); + $hex = bin2hex($bytes); // hex() doubles the length of the string + $rand = abs(hexdec($hex) % $lc); // random integer from 0 to $lc + $str .= $chars[$rand]; // random character in $chars + } + fclose($fp); + } else { + // fallback to mt_rand() if all else fails + mt_srand(10000000 * (double)microtime()); + for ($i = 0, $lc = strlen($chars) - 1; $i < $length; $i++) { + $rand = mt_rand(0, $lc); // random integer from 0 to $lc + $str .= $chars[$rand]; // random character in $chars + } + } + + return $str; + } + + /** + * Return a random number in the specified range + * + * @param $min [optional] + * @param $max [optional] + * @return int A random integer value between min (or 0) and max + */ + public static function getRandomNumber($min = 0, $max = null) + { + if (null === $max) { + $max = mt_getrandmax(); } - return $string; + $range = $max - $min + 1; + $offset = 0; + + if (function_exists('openssl_random_pseudo_bytes')) { + // use openssl lib if it is installed + $bytes = openssl_random_pseudo_bytes(PHP_INT_SIZE); + $hex = bin2hex($bytes); // hex() doubles the length of the string + $offset = abs(hexdec($hex) % $range); // random integer from 0 to $range + } elseif ($fp = @fopen('/dev/urandom', 'rb')) { + // attempt to use /dev/urandom if it exists but openssl isn't available + $bytes = @fread($fp, PHP_INT_SIZE); + $hex = bin2hex($bytes); // hex() doubles the length of the string + $offset = abs(hexdec($hex) % $range); // random integer from 0 to $range + fclose($fp); + } else { + // fallback to mt_rand() if all else fails + mt_srand(mt_rand() + (100000000 * microtime()) % PHP_INT_MAX); + return mt_rand($min, $max); // random integer from $min to $max + } + + return $min + $offset; // random integer from $min to $max } /** @@ -66,6 +125,6 @@ public function getRandomString($length, $chars = null) */ public function getUniqueHash($prefix = '') { - return $prefix . md5(uniqid(microtime() . mt_rand(), true)); + return $prefix . md5(uniqid(microtime() . self::getRandomNumber(), true)); } } diff --git a/lib/Magento/Framework/Oauth/Helper/Oauth.php b/lib/Magento/Framework/Oauth/Helper/Oauth.php index ef40a39875fd5..acddceabb8a2b 100644 --- a/lib/Magento/Framework/Oauth/Helper/Oauth.php +++ b/lib/Magento/Framework/Oauth/Helper/Oauth.php @@ -80,22 +80,10 @@ public function __construct(\Magento\Framework\Math\Random $mathRandom) */ public function generateRandomString($length) { - if (function_exists('openssl_random_pseudo_bytes')) { - // use openssl lib if it is install. It provides a better randomness. - $bytes = openssl_random_pseudo_bytes(ceil($length / 2)); - // hex() doubles the length of the string - $hex = bin2hex($bytes); - // truncate at most 1 char if length parameter is an odd number - $randomString = substr($hex, 0, $length); - } else { - // fallback to mt_rand() if openssl is not installed - $randomString = $this->_mathRandom->getRandomString( - $length, - \Magento\Framework\Math\Random::CHARS_DIGITS . \Magento\Framework\Math\Random::CHARS_LOWERS - ); - } - - return $randomString; + return $this->_mathRandom->getRandomString( + $length, + \Magento\Framework\Math\Random::CHARS_DIGITS . \Magento\Framework\Math\Random::CHARS_LOWERS + ); } /** diff --git a/lib/Magento/Framework/View/Element/Html/Calendar.php b/lib/Magento/Framework/View/Element/Html/Calendar.php index 97a6a28b9c641..03d54d9c9efe5 100644 --- a/lib/Magento/Framework/View/Element/Html/Calendar.php +++ b/lib/Magento/Framework/View/Element/Html/Calendar.php @@ -174,4 +174,15 @@ public function getStoreTimestamp($store = null) { return $this->_localeDate->scopeTimeStamp($store); } + + /** + * Getter for yearRange option in datepicker + * + * @return string + */ + public function getYearRange() + { + return (int)$this->_localeDate->date('Y')->__toString() - 100 + . ':' . $this->_localeDate->date('Y')->__toString(); + } } diff --git a/lib/Magento/Framework/View/Element/Template.php b/lib/Magento/Framework/View/Element/Template.php index 9b285ab74bed3..ed5dfa921d3f2 100644 --- a/lib/Magento/Framework/View/Element/Template.php +++ b/lib/Magento/Framework/View/Element/Template.php @@ -219,7 +219,7 @@ public function getTemplateFile() */ public function getArea() { - return $this->_appState->getAreaCode(); + return $this->_getData('area') ? $this->_getData('area') : $this->_appState->getAreaCode(); } /** diff --git a/pub/lib/css/source/lib/dropdowns.less b/pub/lib/css/source/lib/dropdowns.less index 4e52aeeea26a1..66e1826036c94 100644 --- a/pub/lib/css/source/lib/dropdowns.less +++ b/pub/lib/css/source/lib/dropdowns.less @@ -28,7 +28,9 @@ @_options-selector : ~"ul.dropdown", @_dropdown-actions-padding: @dropdown-actions-padding, - + @_dropdown-list-min-width: @dropdown-list-min-width, + @_dropdown-list-width: @dropdown-list-width, + @_dropdown-list-height: @dropdown-list-height, @_dropdown-list-position-top: @dropdown-list-position-top, @_dropdown-list-position-bottom: @dropdown-list-position-bottom, @_dropdown-list-position-left: @dropdown-list-position-left, @@ -37,6 +39,9 @@ @_dropdown-list-border: @dropdown-list-border, @_dropdown-list-pointer: @dropdown-list-pointer, @_dropdown-list-pointer-border: @dropdown-list-pointer-border, + @_dropdown-list-pointer-position: @dropdown-list-pointer-position, + @_dropdown-list-pointer-position-top: @dropdown-list-pointer-position-top, + @_dropdown-list-pointer-position-left-right: @dropdown-list-pointer-position-left-right, @_dropdown-list-item-border: @dropdown-list-item-border, @_dropdown-list-item-padding: @dropdown-list-item-padding, @_dropdown-list-item-margin: @dropdown-list-item-margin, @@ -82,13 +87,14 @@ } ._dropdown-styles( @_options-selector: @_options-selector, + @_dropdown-list-min-width, + @_dropdown-list-width, + @_dropdown-list-height, @_dropdown-list-background, @_dropdown-list-border, @_dropdown-list-z-index, @_dropdown-list-shadow, - @_dropdown-list-pointer, @_dropdown-list-background, - @_dropdown-list-pointer-border, @_dropdown-list-item-padding, @_dropdown-list-item-margin, @_dropdown-list-item-border, @@ -96,7 +102,12 @@ @_dropdown-list-position-top, @_dropdown-list-position-bottom, @_dropdown-list-position-left, - @_dropdown-list-position-right + @_dropdown-list-position-right, + @_dropdown-list-pointer, + @_dropdown-list-pointer-border, + @_dropdown-list-pointer-position, + @_dropdown-list-pointer-position-top, + @_dropdown-list-pointer-position-left-right ); } @@ -110,6 +121,9 @@ @_dropdown-split-button-actions-padding: @dropdown-split-button-actions-padding, @_dropdown-split-toggle-actions-padding: @dropdown-split-toggle-actions-padding, @_dropdown-split-toggle-position: @dropdown-split-toggle-position, + @_dropdown-split-list-min-width: @dropdown-split-list-min-width, + @_dropdown-split-list-width: @dropdown-split-list-width, + @_dropdown-split-list-height: @dropdown-split-list-height, @_dropdown-split-list-position-top: @dropdown-split-list-position-top, @_dropdown-split-list-position-bottom: @dropdown-split-list-position-bottom, @_dropdown-split-list-position-left: @dropdown-split-list-position-left, @@ -118,6 +132,9 @@ @_dropdown-split-list-border: @dropdown-split-list-border, @_dropdown-split-list-pointer: @dropdown-split-list-pointer, @_dropdown-split-list-pointer-border: @dropdown-split-list-pointer-border, + @_dropdown-split-list-pointer-position: @dropdown-split-list-pointer-position, + @_dropdown-split-list-pointer-position-top: @dropdown-split-list-pointer-position-top, + @_dropdown-split-list-pointer-position-left-right: @dropdown-split-list-pointer-position-left-right, @_dropdown-split-list-item-border: @dropdown-split-list-item-border, @_dropdown-split-list-item-padding: @dropdown-split-list-item-padding, @_dropdown-split-list-item-margin: @dropdown-split-list-item-margin, @@ -172,13 +189,14 @@ } ._dropdown-styles( @_options-selector: @_options-selector, + @_dropdown-split-list-min-width, + @_dropdown-split-list-width, + @_dropdown-split-list-height, @_dropdown-split-list-background, @_dropdown-split-list-border, @_dropdown-split-list-z-index, @_dropdown-split-list-shadow, - @_dropdown-split-list-pointer, @_dropdown-split-list-background, - @_dropdown-split-list-pointer-border, @_dropdown-split-list-item-padding, @_dropdown-split-list-item-margin, @_dropdown-split-list-item-border, @@ -186,29 +204,26 @@ @_dropdown-split-list-position-top, @_dropdown-split-list-position-bottom, @_dropdown-split-list-position-left, - @_dropdown-split-list-position-right + @_dropdown-split-list-position-right, + @_dropdown-split-list-pointer, + @_dropdown-split-list-pointer-border, + @_dropdown-split-list-pointer-position, + @_dropdown-split-list-pointer-position-top, + @_dropdown-split-list-pointer-position-left-right ); - @{_options-selector} { - ._dropdown-split-list-position-default ( - @_dropdown-split-list-position-top, - @_dropdown-split-list-position-bottom, - @_dropdown-split-list-position-left, - @_dropdown-split-list-position-right, - @_dropdown-split-toggle-position - ); - } } // Internal use mixins ._dropdown-styles( @_options-selector, + @_dropdown-list-min-width, + @_dropdown-list-width, + @_dropdown-list-height, @_dropdown-list-background, @_dropdown-list-border, @_dropdown-list-z-index, @_dropdown-list-shadow, - @_dropdown-list-pointer, @_dropdown-list-background, - @_dropdown-list-pointer-border, @_dropdown-list-item-padding, @_dropdown-list-item-margin, @_dropdown-list-item-border, @@ -216,7 +231,12 @@ @_dropdown-list-position-top, @_dropdown-list-position-bottom, @_dropdown-list-position-left, - @_dropdown-list-position-right + @_dropdown-list-position-right, + @_dropdown-list-pointer, + @_dropdown-list-pointer-border, + @_dropdown-list-pointer-position, + @_dropdown-list-pointer-position-top, + @_dropdown-list-pointer-position-left-right, ) { @{_options-selector} { .list-reset-styles(); @@ -231,7 +251,9 @@ @_dropdown-list-position-left, @_dropdown-list-position-right ); - min-width: 100%; + .css(min-width, @_dropdown-list-min-width); + .css(width, @_dropdown-list-width); + .css(height, @_dropdown-list-height); display: none; ._dropdown-list-shadow(@_dropdown-list-shadow); li { @@ -246,9 +268,11 @@ } } ._dropdown-list-pointer( - @_dropdown-list-pointer, @_dropdown-list-background, - @_dropdown-list-pointer-border + @_dropdown-list-pointer-border, + @_dropdown-list-pointer-position, + @_dropdown-list-pointer-position-top, + @_dropdown-list-pointer-position-left-right, ); } &.active { @@ -296,30 +320,6 @@ .css(right, @_dropdown-list-position-right); } -// Dropdown list position - Default -._dropdown-split-list-position-default ( - @_dropdown-list-position-top, - @_dropdown-list-position-bottom, - @_dropdown-list-position-left, - @_dropdown-list-position-right, - @_dropdown-split-toggle-position -) when (@_dropdown-list-position-top = false) and (@_dropdown-list-position-left = false) and (@_dropdown-list-position-right = false) and (@_dropdown-list-position-bottom = false) and (@_dropdown-split-toggle-position = right) { - top: 100%; - left: 100%; - margin-left: -36px; -} - -._dropdown-split-list-position-default ( - @_dropdown-list-position-top, - @_dropdown-list-position-bottom, - @_dropdown-list-position-left, - @_dropdown-list-position-right, - @_dropdown-split-toggle-position -) when (@_dropdown-list-position-top = false) and (@_dropdown-list-position-left = false) and (@_dropdown-list-position-right = false) and (@_dropdown-list-position-bottom = false) and (@_dropdown-split-toggle-position = left) { - top: 100%; - left: 0; -} - // Simple dropdown icon ._dropdown-icon( @_dropdown-toggle-icon-content, @@ -494,18 +494,65 @@ // Dropdown show pointer ._dropdown-list-pointer( - @_dropdown-list-pointer, @_dropdown-list-background, - @_dropdown-list-pointer-border + @_dropdown-list-pointer-border, + @_dropdown-list-pointer-position, + @_dropdown-list-pointer-position-top, + @_dropdown-list-pointer-position-left-right ) when (@_dropdown-list-pointer = true) { margin-top: 4px; ._dropdown-pointer( + @_dropdown-list-background, + @_dropdown-list-pointer-border, + @_dropdown-list-pointer-position, + @_dropdown-list-pointer-position-top, + @_dropdown-list-pointer-position-left-right + ); +} + +._dropdown-pointer( + @_dropdown-list-background, + @_dropdown-list-pointer-border, + @_dropdown-list-pointer-position, + @_dropdown-list-pointer-position-top, + @_dropdown-list-pointer-position-left-right +) when (@_dropdown-list-pointer-position = left) { + ._dropdown-pointer-default( @_dropdown-list-background, @_dropdown-list-pointer-border ); + &:before { + .css(top, @_dropdown-list-pointer-position-top); + .css(left, @_dropdown-list-pointer-position-left-right); + } + &:after { + .css(top, @_dropdown-list-pointer-position-top - 2); + .css(left, @_dropdown-list-pointer-position-left-right - 1); + } } ._dropdown-pointer( + @_dropdown-list-background, + @_dropdown-list-pointer-border, + @_dropdown-list-pointer-position, + @_dropdown-list-pointer-position-top, + @_dropdown-list-pointer-position-left-right +) when (@_dropdown-list-pointer-position = right) { + ._dropdown-pointer-default( + @_dropdown-list-background, + @_dropdown-list-pointer-border + ); + &:before { + .css(top, @_dropdown-list-pointer-position-top); + .css(right, @_dropdown-list-pointer-position-left-right); + } + &:after { + .css(top, @_dropdown-list-pointer-position-top - 2); + .css(right, @_dropdown-list-pointer-position-left-right - 1); + } +} + +._dropdown-pointer-default( @_dropdown-list-background, @_dropdown-list-pointer-border ) { @@ -519,15 +566,11 @@ border-bottom-style: solid; } &:before { - top: -12px; - left: 10px; z-index: 99; border: solid 6px; border-color: transparent transparent @_dropdown-list-background transparent; } &:after { - top: -14px; - left: 9px; z-index: 98; border: solid 7px; border-color: transparent transparent @_dropdown-list-pointer-border transparent; diff --git a/pub/lib/css/source/lib/variables.less b/pub/lib/css/source/lib/variables.less index 1240fe0a81fec..a4e01f2aff2e1 100644 --- a/pub/lib/css/source/lib/variables.less +++ b/pub/lib/css/source/lib/variables.less @@ -1182,6 +1182,9 @@ //-------------------------------------- // Variables simple dropdown @dropdown-actions-padding: false; +@dropdown-list-min-width: 100%; // Also used in: @dropdown-split-list-min-width +@dropdown-list-width: false; // Also used in: @dropdown-split-list-width +@dropdown-list-height: false; // Also used in: @dropdown-split-list-height @dropdown-list-position-top: false; @dropdown-list-position-bottom: false; @dropdown-list-position-left: false; @@ -1190,6 +1193,9 @@ @dropdown-list-background: #fff; @dropdown-list-border: 1px solid #bbb; @dropdown-list-pointer-border: #bbb; +@dropdown-list-pointer-position: left; // right +@dropdown-list-pointer-position-top: -12px; +@dropdown-list-pointer-position-left-right: 10px; @dropdown-list-item-border: 0; @dropdown-list-item-padding: 3px 5px; @dropdown-list-item-margin: 0; @@ -1214,7 +1220,10 @@ @dropdown-split-actions-padding: 0 5px; @dropdown-split-toggle-actions-padding: false; @dropdown-split-button-actions-padding: false; -@dropdown-split-toggle-position: right; +@dropdown-split-toggle-position: right; // Also used in: @dropdown-split-list-pointer-position +@dropdown-split-list-min-width: @dropdown-list-min-width; +@dropdown-split-list-width: @dropdown-list-width; +@dropdown-split-list-height: @dropdown-list-height; @dropdown-split-list-position-top: @dropdown-list-position-top; @dropdown-split-list-position-bottom: @dropdown-list-position-bottom; @dropdown-split-list-position-left: @dropdown-list-position-left; @@ -1223,6 +1232,9 @@ @dropdown-split-list-border: @dropdown-list-border; @dropdown-split-list-pointer: @dropdown-list-pointer; @dropdown-split-list-pointer-border: @dropdown-list-pointer-border; +@dropdown-split-list-pointer-position: @dropdown-split-toggle-position; +@dropdown-split-list-pointer-position-top: @dropdown-list-pointer-position-top; +@dropdown-split-list-pointer-position-left-right: @dropdown-list-pointer-position-left-right; @dropdown-split-list-item-border: @dropdown-list-item-border; @dropdown-split-list-item-padding: @dropdown-list-item-padding; @dropdown-split-list-item-margin: @dropdown-list-item-margin;