diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Eav/Attribute.php b/app/code/Magento/Catalog/Model/ResourceModel/Eav/Attribute.php index 8e93868dc7e51916a1c44997ad98045edbe1bd4f..8fdb867c9dbd84a2903a9a3372144d05c54922f4 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Eav/Attribute.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Eav/Attribute.php @@ -417,6 +417,9 @@ class Attribute extends \Magento\Eav\Model\Entity\Attribute implements if ($this->getAttributeCode() == 'price') { return false; } + if ($this->getAttributeCode() == 'visibility') { + return true; + } if (!$this->getIsFilterableInSearch() && !$this->getIsVisibleInAdvancedSearch() && !$this->getIsFilterable()) { return false; diff --git a/app/code/Magento/CatalogInventory/Setup/InstallSchema.php b/app/code/Magento/CatalogInventory/Setup/InstallSchema.php index a19eb9d1cc57344e6f2fcce5f94b81be113cc84f..cbe1aa3d066651a7d90f75b655da1ef79c95cf49 100644 --- a/app/code/Magento/CatalogInventory/Setup/InstallSchema.php +++ b/app/code/Magento/CatalogInventory/Setup/InstallSchema.php @@ -254,10 +254,10 @@ class InstallSchema implements InstallSchemaInterface ->addIndex( $installer->getIdxName( 'cataloginventory_stock_item', - ['product_id', 'website_id'], + ['product_id', 'stock_id'], \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE ), - ['product_id', 'website_id'], + ['product_id', 'stock_id'], ['type' => \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE] ) ->addIndex( diff --git a/app/code/Magento/CatalogInventory/Setup/UpgradeSchema.php b/app/code/Magento/CatalogInventory/Setup/UpgradeSchema.php new file mode 100644 index 0000000000000000000000000000000000000000..8fd3d264ee67d6a5bef74cebb829f82b9a324e92 --- /dev/null +++ b/app/code/Magento/CatalogInventory/Setup/UpgradeSchema.php @@ -0,0 +1,123 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\CatalogInventory\Setup; + +use Magento\Framework\Setup\UpgradeSchemaInterface; +use Magento\Framework\Setup\ModuleContextInterface; +use Magento\Framework\Setup\SchemaSetupInterface; +use Magento\CatalogInventory\Model\Stock\Item as StockItem; + +class UpgradeSchema implements UpgradeSchemaInterface +{ + /** + * @var string + */ + private $productCompositeKeyVersion = '2.2.0'; + + /** + * {@inheritdoc} + */ + public function upgrade(SchemaSetupInterface $setup, ModuleContextInterface $context) + { + $setup->startSetup(); + + if (version_compare($context->getVersion(), $this->productCompositeKeyVersion, '<')) { + $this->upgradeProductCompositeKey($setup); + } + + $setup->endSetup(); + } + + /** + * @param SchemaSetupInterface $setup + * @return void + */ + private function upgradeProductCompositeKey(SchemaSetupInterface $setup) + { + $oldCompositeKeyColumns = ['product_id', 'website_id']; + $newCompositeKeyColumns = ['product_id', 'stock_id']; + + $foreignKeys = $this->getForeignKeys($setup, $oldCompositeKeyColumns); + // drop foreign keys + $this->dropForeignKeys($setup, $foreignKeys); + + $oldIndexName = $setup->getIdxName( + $setup->getTable(StockItem::ENTITY), + $oldCompositeKeyColumns, + \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE + ); + + $newIndexName = $setup->getIdxName( + $setup->getTable(StockItem::ENTITY), + $newCompositeKeyColumns, + \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE + ); + + // Drop a key based on the following columns: "product_id","website_id" + $setup->getConnection()->dropIndex($setup->getTable(StockItem::ENTITY), $oldIndexName); + + // Create a key based on the following columns: "product_id","stock_id" + $setup->getConnection() + ->addIndex( + $setup->getTable(StockItem::ENTITY), + $newIndexName, + $newCompositeKeyColumns, + \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE + ); + // restore deleted foreign keys + $this->createForeignKeys($setup, $foreignKeys); + } + + /** + * @param SchemaSetupInterface $setup + * @param array $keys + * @return void + */ + private function dropForeignKeys(SchemaSetupInterface $setup, array $keys) + { + foreach ($keys as $key) { + $setup->getConnection()->dropForeignKey($key['TABLE_NAME'], $key['FK_NAME']); + } + } + + /** + * @param SchemaSetupInterface $setup + * @param array $keys + * @return void + */ + private function createForeignKeys(SchemaSetupInterface $setup, array $keys) + { + foreach ($keys as $key) { + $setup->getConnection()->addForeignKey( + $key['FK_NAME'], + $key['TABLE_NAME'], + $key['COLUMN_NAME'], + $key['REF_TABLE_NAME'], + $key['REF_COLUMN_NAME'], + $key['ON_DELETE'] + ); + } + } + + /** + * @param SchemaSetupInterface $setup + * @param array $compositeKeys + * @return array + */ + private function getForeignKeys(SchemaSetupInterface $setup, array $compositeKeys) + { + $foreignKeys = []; + $allForeignKeys = $setup->getConnection()->getForeignKeys($setup->getTable(StockItem::ENTITY)); + foreach ($allForeignKeys as $key) { + if (in_array($key['COLUMN_NAME'], $compositeKeys)) { + $foreignKeys[] = $key; + } + } + + return $foreignKeys; + } +} diff --git a/app/code/Magento/Checkout/view/frontend/web/template/billing-address/details.html b/app/code/Magento/Checkout/view/frontend/web/template/billing-address/details.html index da625c51d4b7734ccc4808fd9161502e15acf1a9..798be1f978f54e3cd7e4c51bfb0e3e20e8ae82e2 100644 --- a/app/code/Magento/Checkout/view/frontend/web/template/billing-address/details.html +++ b/app/code/Magento/Checkout/view/frontend/web/template/billing-address/details.html @@ -15,7 +15,12 @@ <!-- /ko --><br/> <!-- ko foreach: { data: currentBillingAddress().customAttributes, as: 'element' } --> <!-- ko foreach: { data: Object.keys(element), as: 'attribute' } --> - <!-- ko text: element[attribute].value --><!-- /ko --> + <!-- ko if: (typeof element[attribute] === "object") --> + <!-- ko text: element[attribute].value --><!-- /ko --> + <!-- /ko --> + <!-- ko if: (typeof element[attribute] === "string") --> + <!-- ko text: element[attribute] --><!-- /ko --> + <!-- /ko --><br/> <!-- /ko --> <!-- /ko --> <button type="button" diff --git a/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html b/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html index a2b83ead6b354451b99a4a1003a0f04df905dbbc..92469fdec3d7fcc8660d7d5a385cfa9c28c18252 100644 --- a/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html +++ b/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html @@ -15,7 +15,12 @@ <!-- /ko --><br/> <!-- ko foreach: { data: address().customAttributes, as: 'element' } --> <!-- ko foreach: { data: Object.keys(element), as: 'attribute' } --> - <!-- ko text: element[attribute].value --><!-- /ko --> + <!-- ko if: (typeof element[attribute] === "object") --> + <!-- ko text: element[attribute].value --><!-- /ko --> + <!-- /ko --> + <!-- ko if: (typeof element[attribute] === "string") --> + <!-- ko text: element[attribute] --><!-- /ko --> + <!-- /ko --><br/> <!-- /ko --> <!-- /ko --> <!-- ko if: (address().isEditable()) --> diff --git a/app/code/Magento/Checkout/view/frontend/web/template/shipping-information/address-renderer/default.html b/app/code/Magento/Checkout/view/frontend/web/template/shipping-information/address-renderer/default.html index 440a2c7fc468fc493d10eb0cb57320c5593e1bf8..36ea556ae9ec95f09496094771a1340305ffdd43 100644 --- a/app/code/Magento/Checkout/view/frontend/web/template/shipping-information/address-renderer/default.html +++ b/app/code/Magento/Checkout/view/frontend/web/template/shipping-information/address-renderer/default.html @@ -15,7 +15,12 @@ <!-- /ko --><br/> <!-- ko foreach: { data: address().customAttributes, as: 'element' } --> <!-- ko foreach: { data: Object.keys(element), as: 'attribute' } --> - <!-- ko text: element[attribute].value --><!-- /ko --> + <!-- ko if: (typeof element[attribute] === "object") --> + <!-- ko text: element[attribute].value --><!-- /ko --> + <!-- /ko --> + <!-- ko if: (typeof element[attribute] === "string") --> + <!-- ko text: element[attribute] --><!-- /ko --> + <!-- /ko --><br/> <!-- /ko --> <!-- /ko --> <!-- /ko --> diff --git a/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php b/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php index 02ff894df7c1fb1ed6ec7b6af07f019cece1b8cb..74a7e8112aa0ddb528b46168a16df15310fd227c 100644 --- a/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php +++ b/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php @@ -202,7 +202,7 @@ class Grouped extends \Magento\Catalog\Model\Product\Type\AbstractType $collection = $this->getAssociatedProductCollection( $product )->addAttributeToSelect( - ['name', 'price', 'special_price', 'special_from_date', 'special_to_date'] + ['name', 'price', 'special_price', 'special_from_date', 'special_to_date', 'tax_class_id'] )->addFilterByRequiredOptions()->setPositionOrder()->addStoreFilter( $this->getStoreFilter($product) )->addAttributeToFilter( diff --git a/app/code/Magento/Quote/Model/Product/Plugin/RemoveQuoteItems.php b/app/code/Magento/Quote/Model/Product/Plugin/RemoveQuoteItems.php index 49d9be6bcf8ff748b00f67166856185b23a15f53..76af26e3c89cc651691f05f19a9689bedf823b1f 100644 --- a/app/code/Magento/Quote/Model/Product/Plugin/RemoveQuoteItems.php +++ b/app/code/Magento/Quote/Model/Product/Plugin/RemoveQuoteItems.php @@ -5,6 +5,8 @@ */ namespace Magento\Quote\Model\Product\Plugin; +use Magento\Catalog\Model\ResourceModel\Product as ProductResource; + class RemoveQuoteItems { /** @@ -21,19 +23,17 @@ class RemoveQuoteItems } /** - * @param \Magento\Catalog\Model\ResourceModel\Product $subject - * @param \Closure $proceed + * @param ProductResource $subject + * @param ProductResource $result * @param \Magento\Catalog\Api\Data\ProductInterface $product - * @return mixed + * @return ProductResource * @SuppressWarnings(PHPMD.UnusedFormalParameter) - * TODO: reimplement with after plugin */ - public function aroundDelete( - \Magento\Catalog\Model\ResourceModel\Product $subject, - \Closure $proceed, + public function afterDelete( + ProductResource $subject, + ProductResource $result, \Magento\Catalog\Api\Data\ProductInterface $product ) { - $result = $proceed($product); $this->quoteItemsCleaner->execute($product); return $result; } diff --git a/app/code/Magento/Quote/Test/Unit/Model/Product/Plugin/RemoveQuoteItemsTest.php b/app/code/Magento/Quote/Test/Unit/Model/Product/Plugin/RemoveQuoteItemsTest.php index 083722f3a1bb3d9044284f7f65ac1b1239b2d0c5..deb6aab3a980a54baf4c69289833d068a78c8d4d 100644 --- a/app/code/Magento/Quote/Test/Unit/Model/Product/Plugin/RemoveQuoteItemsTest.php +++ b/app/code/Magento/Quote/Test/Unit/Model/Product/Plugin/RemoveQuoteItemsTest.php @@ -23,16 +23,13 @@ class RemoveQuoteItemsTest extends \PHPUnit_Framework_TestCase $this->model = new \Magento\Quote\Model\Product\Plugin\RemoveQuoteItems($this->quoteItemsCleanerMock); } - public function testAroundDelete() + public function testAfterDelete() { $productResourceMock = $this->getMock(\Magento\Catalog\Model\ResourceModel\Product::class, [], [], '', false); $productMock = $this->getMock(\Magento\Catalog\Api\Data\ProductInterface::class); - $closure = function () use ($productResourceMock) { - return $productResourceMock; - }; $this->quoteItemsCleanerMock->expects($this->once())->method('execute')->with($productMock); - $result = $this->model->aroundDelete($productResourceMock, $closure, $productMock); + $result = $this->model->afterDelete($productResourceMock, $productResourceMock, $productMock); $this->assertEquals($result, $productResourceMock); } } diff --git a/app/code/Magento/Store/Model/StoreManager.php b/app/code/Magento/Store/Model/StoreManager.php index 13840b120636773dd108adcdf4a9f590e629383d..f64f2fe84a8cd9a496c0c85f8135e3274cd75f2f 100644 --- a/app/code/Magento/Store/Model/StoreManager.php +++ b/app/code/Magento/Store/Model/StoreManager.php @@ -152,7 +152,7 @@ class StoreManager implements public function getStore($storeId = null) { if (!isset($storeId) || '' === $storeId || $storeId === true) { - if (!$this->currentStoreId) { + if (null === $this->currentStoreId) { \Magento\Framework\Profiler::start('store.resolve'); $this->currentStoreId = $this->storeResolver->getCurrentStoreId(); \Magento\Framework\Profiler::stop('store.resolve'); diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/date.js b/app/code/Magento/Ui/view/base/web/js/form/element/date.js index c9fe97b64a76f6d79a3f4330fb147b7ef9d1a404..202cfe93069b02bad6ff888a51b9661a54109e54 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/element/date.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/date.js @@ -167,38 +167,22 @@ define([ prepareDateTimeFormats: function () { this.pickerDateTimeFormat = this.options.dateFormat; this.momentFormat = this.options.dateFormat ? - this.convertToMomentFormat(this.options.dateFormat) : this.momentFormat; + utils.convertToMomentFormat(this.options.dateFormat) : this.momentFormat; if (this.options.showsTime) { this.pickerDateTimeFormat += ' ' + this.options.timeFormat; } - this.pickerDateTimeFormat = utils.normalizeDate(this.pickerDateTimeFormat); + this.pickerDateTimeFormat = utils.convertToMomentFormat(this.pickerDateTimeFormat); if (this.dateFormat) { this.inputDateFormat = this.dateFormat; } - this.inputDateFormat = utils.normalizeDate(this.inputDateFormat); - this.outputDateFormat = utils.normalizeDate(this.outputDateFormat); + this.inputDateFormat = utils.convertToMomentFormat(this.inputDateFormat); + this.outputDateFormat = utils.convertToMomentFormat(this.outputDateFormat); this.validationParams.dateFormat = this.outputDateFormat; - }, - - /** - * Converts PHP IntlFormatter format to moment format. - * - * @param {String} format - PHP format - * @returns {String} - moment compatible formatting - */ - convertToMomentFormat: function (format) { - var newFormat; - - newFormat = format.replace(/yy|y/gi, 'YYYY'); // replace the year - newFormat = newFormat.replace(/dd|d/g, 'DD'); // replace the date - newFormat = newFormat.replace(/mm|m/gi, 'MM'); //replace the month - - return newFormat; } }); }); diff --git a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/datepicker.js b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/datepicker.js index 77d3a069ccef76bbcacad28459820b3359b025e7..4f52aa431632c11115864b22bdc819b9385b20a3 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/datepicker.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/datepicker.js @@ -53,7 +53,7 @@ define([ 'setDate', moment( observable(), - utils.normalizeDate( + utils.convertToMomentFormat( options.dateFormat + (options.showsTime ? ' ' + options.timeFormat : '') ) ).toDate() diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Shipping/AddressModal.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Shipping/AddressModal.php index 8a949c474bc847942f1bd5922d00514cd6133d08..43bd771f609cd86fddcfb99c21ac05687bfe06a9 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Shipping/AddressModal.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Shipping/AddressModal.php @@ -65,4 +65,20 @@ class AddressModal extends Form return $result; } + + /** + * Fixture mapping. + * + * @param array|null $fields + * @param string|null $parent + * @return array + */ + protected function dataMapping(array $fields = null, $parent = null) + { + if (isset($fields['custom_attribute'])) { + $this->placeholders = ['attribute_code' => $fields['custom_attribute']['code']]; + $this->applyPlaceholders(); + } + return parent::dataMapping($fields, $parent); + } } diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Shipping/AddressModal.xml b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Shipping/AddressModal.xml index 13403b792684512c9741bca74a78f7c84036eb48..4a6160698839382c83809824913ebcf3770a0f7f 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Shipping/AddressModal.xml +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Shipping/AddressModal.xml @@ -22,5 +22,8 @@ </country_id> <telephone /> <postcode /> + <custom_attribute> + <selector>[name="custom_attributes[%attribute_code%]"]</selector> + </custom_attribute> </fields> </mapping> diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Address/Edit.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Address/Edit.php index b9d5f3c3af01e10559e2c942e546f4eeda6576c3..78eaf403826bc054996c570c2167600ac4fac0ff 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Address/Edit.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Address/Edit.php @@ -61,4 +61,20 @@ class Edit extends Form { $this->_rootElement->find($this->saveAddress)->click(); } + + /** + * Fixture mapping. + * + * @param array|null $fields + * @param string|null $parent + * @return array + */ + protected function dataMapping(array $fields = null, $parent = null) + { + if (isset($fields['custom_attribute'])) { + $this->placeholders = ['attribute_code' => $fields['custom_attribute']['code']]; + $this->applyPlaceholders(); + } + return parent::dataMapping($fields, $parent); + } } diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAddressEdit.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAddressEdit.php deleted file mode 100644 index 4946f0825870974337a3724fae591e58b8d861be..0000000000000000000000000000000000000000 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAddressEdit.php +++ /dev/null @@ -1,51 +0,0 @@ -<?php -/** - * Copyright © 2016 Magento. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Customer\Test\Page; - -use Magento\Mtf\Client\Locator; -use Magento\Mtf\Factory\Factory; -use Magento\Mtf\Page\Page; - -/** - * Customer Address Edit page. - */ -class CustomerAddressEdit extends Page -{ - /** - * URL for Customer Address Edit page. - */ - const MCA = 'customer/address/edit'; - - /** - * Customer Address Edit form. - * - * @var string - */ - protected $editForm = '#form-validate'; - - /** - * Init page. Set page url. - * - * @return void - */ - protected function initUrl() - { - $this->url = $_ENV['app_frontend_url'] . self::MCA; - } - - /** - * Get Customer Address Edit form. - * - * @return \Magento\Customer\Test\Block\Address\Edit - */ - public function getEditForm() - { - return Factory::getBlockFactory()->getMagentoCustomerAddressEdit( - $this->browser->find($this->editForm, Locator::SELECTOR_CSS) - ); - } -} diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAddressEdit.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAddressEdit.xml new file mode 100644 index 0000000000000000000000000000000000000000..2f3738d05e5e3d0439496b2df70532613b9144d8 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAddressEdit.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + --> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/pages.xsd"> + <page name="CustomerAddressEdit" mca="customer/address/edit" module="Magento_Customer"> + <block name="editForm" class="Magento\Customer\Test\Block\Address\Edit" locator="#form-validate" strategy="css selector" /> + </page> +</config> diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Catalog/Product/View.php b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Catalog/Product/View.php index bd774f806053eb90b28ff70003cd703f315e1b2d..31ce18926b51ba89d70d8e5a73508562d405c9cf 100644 --- a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Catalog/Product/View.php +++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Catalog/Product/View.php @@ -94,4 +94,19 @@ class View extends ParentView { $this->getGroupedProductBlock()->fill($product); } + + /** + * Set quantity and click add to cart. + * @param FixtureInterface $product + * @param string|int $qty + */ + public function setQtyAndClickAddToCartGrouped(FixtureInterface $product, $qty) + { + $associatedProducts = $product->getAssociated()['products']; + $groupedProductBlock = $this->getGroupedProductBlock(); + foreach ($associatedProducts as $product) { + $groupedProductBlock->setQty($product->getId(), $qty); + } + $this->clickAddToCart(); + } } diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Catalog/Product/View/Type/Grouped.php b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Catalog/Product/View/Type/Grouped.php index 42b3b0dfcf76047bcd3c23ed1fcf117e497dcbf2..7498c3c56587dd1bace2b00727c90428af19435d 100644 --- a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Catalog/Product/View/Type/Grouped.php +++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Catalog/Product/View/Type/Grouped.php @@ -65,6 +65,18 @@ class Grouped extends Block return $this->_rootElement->find(sprintf($this->qtySubProductById, $subProductId))->getValue(); } + /** + * Set qty to subproduct block + * + * @param int $subProductId + * @param string|int $qty + * @return void + */ + public function setQty($subProductId, $qty) + { + $this->_rootElement->find(sprintf($this->qtySubProductById, $subProductId))->setValue($qty); + } + /** * Fill product options on view page. * diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Checkout/Cart/CartItem.php b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Checkout/Cart/CartItem.php index f843482eca1ca860869bb3a4413f71c632f05719..9db1477946df13464d6fabbb2a95cfed7a4046c6 100644 --- a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Checkout/Cart/CartItem.php +++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Checkout/Cart/CartItem.php @@ -8,6 +8,7 @@ namespace Magento\GroupedProduct\Test\Block\Checkout\Cart; use Magento\Checkout\Test\Block\Cart\AbstractCartItem; use Magento\Checkout\Test\Block\Cart\CartItem as CheckoutCartItem; +use Magento\Mtf\Client\Locator; /** * Class CartItem @@ -119,4 +120,57 @@ class CartItem extends AbstractCartItem $cartItem->removeItem(); } } + + /** + * Get product price including tax + * + * @return string|null + */ + public function getPriceInclTax() + { + return $this->getPriceByType($this->priceInclTax, Locator::SELECTOR_XPATH); + } + + /** + * Get product price excluding tax + * + * @return string|null + */ + public function getPriceExclTax() + { + return $this->getPriceByType($this->priceExclTax, Locator::SELECTOR_XPATH); + } + + /** + * Get sub-total excluding tax for the specified item in the cart + * + * @return string|null + */ + public function getSubtotalPriceExclTax() + { + return $this->getPriceByType($this->subTotalPriceExclTax); + } + + /** + * Get price for the specified item in the cart by the price type + * + * @return string|null + */ + public function getSubtotalPriceInclTax() + { + return $this->getPriceByType($this->subTotalPriceInclTax); + } + + /** + * @param string $priceType + * @param string $strategy + * @return mixed|null + */ + private function getPriceByType($priceType, $strategy = Locator::SELECTOR_CSS) + { + $cartProductPrice = $this->_rootElement->find($priceType, $strategy); + return $cartProductPrice->isVisible() + ? str_replace(',', '', $this->escapeCurrency($cartProductPrice->getText())) + : null; + } } diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Constraint/AbstractAssertTaxRuleIsAppliedToAllPricesOnGroupedProductPage.php b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Constraint/AbstractAssertTaxRuleIsAppliedToAllPricesOnGroupedProductPage.php new file mode 100644 index 0000000000000000000000000000000000000000..9fd3ebe177b3a2f5b0cfb10141f4a3e64f41a8b9 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Constraint/AbstractAssertTaxRuleIsAppliedToAllPricesOnGroupedProductPage.php @@ -0,0 +1,82 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\GroupedProduct\Test\Constraint; + +use Magento\Cms\Test\Page\CmsIndex; +use Magento\Catalog\Test\Page\Category\CatalogCategoryView; +use Magento\Catalog\Test\Page\Product\CatalogProductView; +use Magento\Checkout\Test\Page\CheckoutCart; +use Magento\Tax\Test\Constraint\AbstractAssertTaxRuleIsAppliedToAllPrices; +use Magento\Mtf\Fixture\FixtureFactory; +use Magento\Mtf\Fixture\FixtureInterface; +use Magento\Mtf\Fixture\InjectableFixture; + +/** + * Checks that prices excl tax on category, product and cart pages are equal to specified in dataset. + */ +abstract class AbstractAssertTaxRuleIsAppliedToAllPricesOnGroupedProductPage extends + AbstractAssertTaxRuleIsAppliedToAllPrices +{ + + /** + * Get grouped product view prices. + * + * @param FixtureInterface $product + * @param array $actualPrices + * @return array + */ + abstract protected function getGroupedProductPagePrices(FixtureInterface $product, array $actualPrices); + + /** + * Assert that specified prices are actual on category, product and cart pages. + * + * @param InjectableFixture $product + * @param array $prices + * @param int $qty + * @param CmsIndex $cmsIndex + * @param CatalogCategoryView $catalogCategoryView + * @param CatalogProductView $catalogProductView + * @param CheckoutCart $checkoutCart + * @param FixtureFactory $fixtureFactory + * @return void + */ + public function processAssert( + InjectableFixture $product, + array $prices, + $qty, + CmsIndex $cmsIndex, + CatalogCategoryView $catalogCategoryView, + CatalogProductView $catalogProductView, + CheckoutCart $checkoutCart, + FixtureFactory $fixtureFactory + ) { + $this->cmsIndex = $cmsIndex; + $this->catalogCategoryView = $catalogCategoryView; + $this->catalogProductView = $catalogProductView; + $this->checkoutCart = $checkoutCart; + //Preconditions + $address = $fixtureFactory->createByCode('address', ['dataset' => 'US_address_NY']); + $shipping = ['shipping_service' => 'Flat Rate', 'shipping_method' => 'Fixed']; + $actualPrices = []; + //Assertion steps + $productCategory = $product->getCategoryIds()[0]; + $this->openCategory($productCategory); + $actualPrices = $this->getCategoryPrices($product, $actualPrices); + $catalogCategoryView->getListProductBlock()->getProductItem($product)->open(); + $catalogProductView->getGroupedProductViewBlock()->fillOptions($product); + $actualPrices = $this->getGroupedProductPagePrices($product, $actualPrices); + $catalogProductView->getGroupedProductViewBlock()->setQtyAndClickAddToCartGrouped($product, $qty); + $catalogProductView->getMessagesBlock()->waitSuccessMessage(); + $this->checkoutCart->open(); + $this->fillEstimateBlock($address, $shipping); + $actualPrices = $this->getCartPrices($product, $actualPrices); + $actualPrices = $this->getTotals($actualPrices); + //Prices verification + $message = 'Prices from dataset should be equal to prices on frontend.'; + \PHPUnit_Framework_Assert::assertEquals($prices, $actualPrices, $message); + } +} diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Constraint/AssertTaxRuleIsAppliedToAllPricesGroupedExcludingIncludingTax.php b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Constraint/AssertTaxRuleIsAppliedToAllPricesGroupedExcludingIncludingTax.php new file mode 100644 index 0000000000000000000000000000000000000000..57853d344672b0e09a2f6aa9a821146108295cb4 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Constraint/AssertTaxRuleIsAppliedToAllPricesGroupedExcludingIncludingTax.php @@ -0,0 +1,74 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\GroupedProduct\Test\Constraint; + +use Magento\Mtf\Fixture\FixtureInterface; + +/** + * Checks that prices excl tax on category, product and cart pages are equal to specified in dataset. + */ +class AssertTaxRuleIsAppliedToAllPricesGroupedExcludingIncludingTax extends + AbstractAssertTaxRuleIsAppliedToAllPricesOnGroupedProductPage +{ + /** + * @inheritdoc + */ + public function getCategoryPrices(FixtureInterface $product, $actualPrices) + { + $priceBlock = $this->catalogCategoryView->getListProductBlock()->getProductItem($product)->getPriceBlock(); + $actualPrices['category_price_excl_tax'] = $priceBlock->getPriceExcludingTax(); + $actualPrices['category_price_incl_tax'] = $priceBlock->getPriceIncludingTax(); + + return $actualPrices; + } + + /** + * @inheritdoc + */ + public function getGroupedProductPagePrices(FixtureInterface $product, array $actualPrices) + { + $associatedProducts = $product->getAssociated(); + /** @var \Magento\GroupedProduct\Test\Block\Catalog\Product\View $groupedProductBlock */ + $this->catalogProductView = $this->catalogProductView->getGroupedProductViewBlock(); + foreach (array_keys($associatedProducts['products']) as $productIndex) { + //Process assertions + $this->catalogProductView ->itemPriceProductBlock(++$productIndex); + $actualPrices['sub_product_view_prices_' . $productIndex] = $this->getProductPagePrices($actualPrices); + } + return $actualPrices; + } + + /** + * @inheritdoc + */ + public function getProductPagePrices($actualPrices) + { + $priceBlock = $this->catalogProductView ->getPriceBlock(); + $productPrices['product_view_price_excl_tax'] = $priceBlock->getPriceExcludingTax(); + $productPrices['product_view_price_incl_tax'] = $priceBlock->getPriceIncludingTax(); + + return $productPrices; + } + + /** + * @inheritdoc + */ + public function getTotals($actualPrices) + { + $totalsBlock = $this->checkoutCart->getTotalsBlock(); + $actualPrices['subtotal_excl_tax'] = $totalsBlock->getSubtotalExcludingTax(); + $actualPrices['subtotal_incl_tax'] = $totalsBlock->getSubtotalIncludingTax(); + $actualPrices['discount'] = $totalsBlock->getDiscount(); + $actualPrices['shipping_excl_tax'] = $totalsBlock->getShippingPrice(); + $actualPrices['shipping_incl_tax'] = $totalsBlock->getShippingPriceInclTax(); + $actualPrices['tax'] = $totalsBlock->getTax(); + $actualPrices['grand_total_excl_tax'] = $totalsBlock->getGrandTotalExcludingTax(); + $actualPrices['grand_total_incl_tax'] = $totalsBlock->getGrandTotalIncludingTax(); + + return $actualPrices; + } +} diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Repository/GroupedProduct.xml b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Repository/GroupedProduct.xml index bbdbc011ae8c9c8859d16dcfbd6b2e7428d46246..7648899060f8f3314d1a33b26082724ae1495fa8 100644 --- a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Repository/GroupedProduct.xml +++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Repository/GroupedProduct.xml @@ -125,5 +125,33 @@ <item name="dataset" xsi:type="string">grouped_three_simple_products</item> </field> </dataset> + + <dataset name="grouped_product_with_special_price"> + <field name="name" xsi:type="string">Test grouped product with special price %isolation%</field> + <field name="sku" xsi:type="string">sku_test_grouped_product_with_special_price_%isolation%</field> + <field name="category_ids" xsi:type="array"> + <item name="dataset" xsi:type="string">default</item> + </field> + <field name="associated" xsi:type="array"> + <item name="dataset" xsi:type="string">defaultSimpleProduct_with_specialPrice</item> + </field> + <field name="status" xsi:type="string">Yes</field> + <field name="visibility" xsi:type="string">Catalog, Search</field> + <field name="tax_class_id" xsi:type="array"> + <item name="dataset" xsi:type="string">taxable_goods</item> + </field> + <field name="url_key" xsi:type="string">test-grouped-product-with-special-price-%isolation%</field> + <field name="quantity_and_stock_status" xsi:type="array"> + <item name="is_in_stock" xsi:type="string">In Stock</item> + </field> + <field name="website_ids" xsi:type="array"> + <item name="0" xsi:type="array"> + <item name="dataset" xsi:type="string">default</item> + </item> + </field> + <field name="attribute_set_id" xsi:type="array"> + <item name="dataset" xsi:type="string">default</item> + </field> + </dataset> </repository> </config> diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/TaxCalculationTest.xml b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/TaxCalculationTest.xml new file mode 100644 index 0000000000000000000000000000000000000000..c57afc28b88683e3b08917ae2c1d8942a7c3b614 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/TaxCalculationTest.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + --> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> + <testCase name="Magento\Tax\Test\TestCase\TaxCalculationTest" summary="Apply Taxes for grouped products" ticketId="MAGETWO-60576"> + <variation name="TaxCalculationTestGroupedProduct"> + <data name="product" xsi:type="string">groupedProduct::grouped_product_with_special_price</data> + <data name="taxRule" xsi:type="string">us_full_tax_rule</data> + <data name="shippingAddress/dataset" xsi:type="string">US_address_1</data> + <data name="customer/dataset" xsi:type="string">johndoe_unique</data> + <data name="salesRule" xsi:type="string">active_sales_rule_for_all_groups_no_coupon</data> + <data name="catalogRule" xsi:type="string">-</data> + <data name="configData" xsi:type="string">total_cat_excl_ship_incl_after_disc_on_excl, display_excluding_including_tax</data> + <data name="flushCache" xsi:type="boolean">true</data> + <data name="qty" xsi:type="string">3</data> + <data name="prices/category_price_excl_tax" xsi:type="string">9.00</data> + <data name="prices/category_price_incl_tax" xsi:type="string">9.90</data> + <data name="prices/sub_product_view_prices_1/product_view_price_excl_tax" xsi:type="string">9.00</data> + <data name="prices/sub_product_view_prices_1/product_view_price_incl_tax" xsi:type="string">9.90</data> + <data name="prices/sub_product_view_prices_2/product_view_price_excl_tax" xsi:type="string">9.00</data> + <data name="prices/sub_product_view_prices_2/product_view_price_incl_tax" xsi:type="string">9.90</data> + <data name="prices/cart_item_price_excl_tax" xsi:type="string">9.00</data> + <data name="prices/cart_item_price_incl_tax" xsi:type="string">9.90</data> + <data name="prices/cart_item_subtotal_excl_tax" xsi:type="string">27.00</data> + <data name="prices/cart_item_subtotal_incl_tax" xsi:type="string">29.70</data> + <data name="prices/subtotal_excl_tax" xsi:type="string">54.00</data> + <data name="prices/subtotal_incl_tax" xsi:type="string">59.40</data> + <data name="prices/shipping_excl_tax" xsi:type="string">30.00</data> + <data name="prices/shipping_incl_tax" xsi:type="string">30.00</data> + <data name="prices/discount" xsi:type="string">27.00</data> + <data name="prices/tax" xsi:type="string">2.70</data> + <data name="prices/grand_total_excl_tax" xsi:type="string">57.00</data> + <data name="prices/grand_total_incl_tax" xsi:type="string">59.70</data> + <constraint name="Magento\GroupedProduct\Test\Constraint\AssertTaxRuleIsAppliedToAllPricesGroupedExcludingIncludingTax" /> + </variation> + </testCase> +</config> diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Action/AttributeTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Action/AttributeTest.php index fc2763aea017dee37b05216a1b881665a29dc551..c17553629ae59a3b0c8ef7c1643112743cd82bf8 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Action/AttributeTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Action/AttributeTest.php @@ -45,6 +45,47 @@ class AttributeTest extends \Magento\TestFramework\TestCase\AbstractBackendContr $this->assertTrue($isRedirectPresent); } + /** + * @covers \Magento\Catalog\Controller\Adminhtml\Product\Action\Attribute\Save::execute + * + * @dataProvider saveActionVisibilityAttrDataProvider + * @param array $attributes + * @magentoDataFixture Magento/Catalog/_files/product_simple.php + */ + public function testSaveActionChangeVisibility($attributes) + { + $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $repository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + \Magento\Catalog\Model\ProductRepository::class + ); + $product = $repository->get('simple'); + $product->setOrigData(); + $product->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_NOT_VISIBLE); + $product->save(); + + /** @var $session \Magento\Backend\Model\Session */ + $session = $objectManager->get(\Magento\Backend\Model\Session::class); + $session->setProductIds([$product->getId()]); + $this->getRequest()->setParam('attributes', $attributes); + + $this->dispatch('backend/catalog/product_action_attribute/save/store/0'); + /** @var \Magento\Catalog\Model\Category $category */ + $categoryFactory = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( + \Magento\Catalog\Model\CategoryFactory::class + ); + /** @var \Magento\Catalog\Block\Product\ListProduct $listProduct */ + $listProduct = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( + \Magento\Catalog\Block\Product\ListProduct::class + ); + + $category = $categoryFactory->create()->load(2); + $layer = $listProduct->getLayer(); + $layer->setCurrentCategory($category); + $productCollection = $layer->getProductCollection(); + $productItem = $productCollection->getFirstItem(); + $this->assertEquals($session->getProductIds(), [$productItem->getId()]); + } + /** * @covers \Magento\Catalog\Controller\Adminhtml\Product\Action\Attribute\Validate::execute * @@ -97,4 +138,17 @@ class AttributeTest extends \Magento\TestFramework\TestCase\AbstractBackendContr ] ]; } + + /** + * Data Provider for save with visibility attribute + * + * @return array + */ + public function saveActionVisibilityAttrDataProvider() + { + return [ + ['arguments' => ['visibility' => \Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH]], + ['arguments' => ['visibility' => \Magento\Catalog\Model\Product\Visibility::VISIBILITY_IN_CATALOG]] + ]; + } } diff --git a/dev/tests/integration/testsuite/Magento/Store/Model/StoreManagerTest.php b/dev/tests/integration/testsuite/Magento/Store/Model/StoreManagerTest.php new file mode 100644 index 0000000000000000000000000000000000000000..c42856d865649d5206df2c76de323fff521c5482 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Store/Model/StoreManagerTest.php @@ -0,0 +1,48 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Store\Model; + +use Magento\Framework\ObjectManagerInterface as ObjectManager; +use Magento\Store\Model\Store; +use Magento\Store\Model\StoreManagerInterface; +use Magento\TestFramework\Helper\Bootstrap; + +class StoreManagerTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var StoreManagerInterface + */ + private $storeManager; + + /** + * @var ObjectManager + */ + private $objectManager; + + /** + * Class dependencies initialization + * + * @return void + */ + protected function setUp() + { + $this->objectManager = Bootstrap::getObjectManager(); + $this->storeManager = $this->objectManager->get(StoreManagerInterface::class); + } + + /** + * Check that behavior of setting and getting store into StoreManager is correct + * Setting: Magento\Store\Model\StoreManagerInterface::setCurrentStore + * Getting: Magento\Store\Model\StoreManagerInterface::getStore + * + * @return void + */ + public function testDefaultStoreIdIsSetCorrectly() + { + $this->storeManager->setCurrentStore(Store::DEFAULT_STORE_ID); + $this->assertEquals(Store::DEFAULT_STORE_ID, $this->storeManager->getStore()->getId()); + } +} diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/form/element/date.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/form/element/date.test.js index 0ac9ddc56e00ada18da9842e53791128440150cd..51a998e6eb2a04ea2e63c64933a90335dadd96cc 100644 --- a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/form/element/date.test.js +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/form/element/date.test.js @@ -7,9 +7,8 @@ define([ 'Magento_Ui/js/form/element/date', - 'mageUtils', - 'moment' -], function (DateElement, utils, moment) { + 'mageUtils' +], function (DateElement, utils) { 'use strict'; describe('Magento_Ui/js/form/element/date', function () { @@ -22,637 +21,11 @@ define([ model = new DateElement(params); }); - it('Check convertToMomentFormat function', function () { - var format, - momentFormat; - - format = 'M/d/yy'; - momentFormat = 'MM/DD/YYYY'; - expect(model.convertToMomentFormat(format)).toBe(momentFormat); - }); - it('Check prepareDateTimeFormats function', function () { - spyOn(model, 'convertToMomentFormat'); - spyOn(utils, 'normalizeDate'); + spyOn(utils, 'convertToMomentFormat'); model.prepareDateTimeFormats(); - expect(model.convertToMomentFormat).toHaveBeenCalled(); - expect(utils.normalizeDate).toHaveBeenCalled(); + expect(utils.convertToMomentFormat).toHaveBeenCalled(); }); - it('Check convertToMomentFormat function for all Magento supported locales', function () { - - var fixture, - localeValues, - format, - expectedValue, - momentFormat, - dt, - m, - p; - - fixture = { - 'af_ZA': { - 'locale': 'af_ZA', - 'localeInfo': { - 'format': 'y-MM-dd', - 'expectedValue': '2016-11-17' - } - }, - 'az_Latn_AZ': { - 'locale': 'az_Latn_AZ', - 'localeInfo': { - 'format': 'dd.MM.yy', - 'expectedValue': '17.11.2016' - } - }, - 'id_ID': { - 'locale': 'id_ID', - 'localeInfo': { - 'format': 'dd/MM/yy', - 'expectedValue': '17/11/2016' - } - }, - 'ms_Latn_MY': { - 'locale': 'ms_Latn_MY', - 'localeInfo': { - 'format': 'd/MM/yy', - 'expectedValue': '17/11/2016' - } - }, - 'bs_Latn_BA': { - 'locale': 'bs_Latn_BA', - 'localeInfo': { - 'format': 'dd.MM.yy.', - 'expectedValue': '17.11.2016.' - } - }, - 'ca_ES': { - 'locale': 'ca_ES', - 'localeInfo': { - 'format': 'd/M/yy', - 'expectedValue': '17/11/2016' - } - }, - 'cy_GB': { - 'locale': 'cy_GB', - 'localeInfo': { - 'format': 'dd/MM/yy', - 'expectedValue': '17/11/2016' - } - }, - 'da_DK': { - 'locale': 'da_DK', - 'localeInfo': { - 'format': 'dd/MM/y', - 'expectedValue': '17/11/2016' - } - }, - 'de_DE': { - 'locale': 'de_DE', - 'localeInfo': { - 'format': 'dd.MM.yy', - 'expectedValue': '17.11.2016' - } - }, - 'de_CH': { - 'locale': 'de_CH', - 'localeInfo': { - 'format': 'dd.MM.yy', - 'expectedValue': '17.11.2016' - } - }, - 'de_AT': { - 'locale': 'de_AT', - 'localeInfo': { - 'format': 'dd.MM.yy', - 'expectedValue': '17.11.2016' - } - }, - 'et_EE': { - 'locale': 'et_EE', - 'localeInfo': { - 'format': 'dd.MM.yy', - 'expectedValue': '17.11.2016' - } - }, - 'en_AU': { - 'locale': 'en_AU', - 'localeInfo': { - 'format': 'd/MM/y', - 'expectedValue': '17/11/2016' - } - }, - 'en_CA': { - 'locale': 'en_CA', - 'localeInfo': { - 'format': 'y-MM-dd', - 'expectedValue': '2016-11-17' - } - }, - 'en_IE': { - 'locale': 'en_IE', - 'localeInfo': { - 'format': 'dd/MM/y', - 'expectedValue': '17/11/2016' - } - }, - 'en_NZ': { - 'locale': 'en_NZ', - 'localeInfo': { - 'format': 'd/MM/yy', - 'expectedValue': '17/11/2016' - } - }, - 'en_GB': { - 'locale': 'en_GB', - 'localeInfo': { - 'format': 'dd/MM/y', - 'expectedValue': '17/11/2016' - } - }, - 'en_US': { - 'locale': 'en_US', - 'localeInfo': { - 'format': 'M/d/yy', - 'expectedValue': '11/17/2016' - } - }, - 'es_AR': { - 'locale': 'es_AR', - 'localeInfo': { - 'format': 'd/M/yy', - 'expectedValue': '17/11/2016' - } - }, - 'es_CL': { - 'locale': 'es_CL', - 'localeInfo': { - 'format': 'dd-MM-yy', - 'expectedValue': '17-11-2016' - } - }, - 'es_CO': { - 'locale': 'es_CO', - 'localeInfo': { - 'format': 'd/MM/yy', - 'expectedValue': '17/11/2016' - } - }, - 'es_CR': { - 'locale': 'es_CR', - 'localeInfo': { - 'format': 'd/M/yy', - 'expectedValue': '17/11/2016' - } - }, - 'es_ES': { - 'locale': 'es_ES', - 'localeInfo': { - 'format': 'd/M/yy', - 'expectedValue': '17/11/2016' - } - }, - 'es_MX': { - 'locale': 'es_MX', - 'localeInfo': { - 'format': 'dd/MM/yy', - 'expectedValue': '17/11/2016' - } - }, - 'es_PA': { - 'locale': 'es_PA', - 'localeInfo': { - 'format': 'MM/dd/yy', - 'expectedValue': '11/17/2016' - } - }, - 'es_PE': { - 'locale': 'es_PE', - 'localeInfo': { - 'format': 'd/MM/yy', - 'expectedValue': '17/11/2016' - } - }, - 'es_VE': { - 'locale': 'es_VE', - 'localeInfo': { - 'format': 'd/M/yy', - 'expectedValue': '17/11/2016' - } - }, - 'eu_ES': { - 'locale': 'eu_ES', - 'localeInfo': { - 'format': 'y/MM/dd', - 'expectedValue': '2016/11/17' - } - }, - 'fil_PH': { - 'locale': 'fil_PH', - 'localeInfo': { - 'format': 'M/d/yy', - 'expectedValue': '11/17/2016' - } - }, - 'fr_BE': { - 'locale': 'fr_BE', - 'localeInfo': { - 'format': 'd/MM/yy', - 'expectedValue': '17/11/2016' - } - }, - 'fr_CA': { - 'locale': 'fr_CA', - 'localeInfo': { - 'format': 'yy-MM-dd', - 'expectedValue': '2016-11-17' - } - }, - 'fr_FR': { - 'locale': 'fr_FR', - 'localeInfo': { - 'format': 'dd/MM/y', - 'expectedValue': '17/11/2016' - } - }, - 'gl_ES': { - 'locale': 'gl_ES', - 'localeInfo': { - 'format': 'dd/MM/yy', - 'expectedValue': '17/11/2016' - } - }, - 'hr_HR': { - 'locale': 'hr_HR', - 'localeInfo': { - 'format': 'dd.MM.y.', - 'expectedValue': '17.11.2016.' - } - }, - 'it_IT': { - 'locale': 'it_IT', - 'localeInfo': { - 'format': 'dd/MM/yy', - 'expectedValue': '17/11/2016' - } - }, - 'it_CH': { - 'locale': 'it_CH', - 'localeInfo': { - 'format': 'dd.MM.yy', - 'expectedValue': '17.11.2016' - } - }, - 'sw_KE': { - 'locale': 'sw_KE', - 'localeInfo': { - 'format': 'dd/MM/y', - 'expectedValue': '17/11/2016' - } - }, - 'lv_LV': { - 'locale': 'lv_LV', - 'localeInfo': { - 'format': 'dd.MM.yy', - 'expectedValue': '17.11.2016' - } - }, - 'lt_LT': { - 'locale': 'lt_LT', - 'localeInfo': { - 'format': 'y-MM-dd', - 'expectedValue': '2016-11-17' - } - }, - 'hu_HU': { - 'locale': 'hu_HU', - 'localeInfo': { - 'format': 'y. MM. dd.', - 'expectedValue': '2016. 11. 17.' - } - }, - 'nl_BE': { - 'locale': 'nl_BE', - 'localeInfo': { - 'format': 'd/MM/yy', - 'expectedValue': '17/11/2016' - } - }, - 'nl_NL': { - 'locale': 'nl_NL', - 'localeInfo': { - 'format': 'dd-MM-yy', - 'expectedValue': '17-11-2016' - } - }, - 'nb_NO': { - 'locale': 'nb_NO', - 'localeInfo': { - 'format': 'dd.MM.y', - 'expectedValue': '17.11.2016' - } - }, - 'nn_NO': { - 'locale': 'nn_NO', - 'localeInfo': { - 'format': 'dd.MM.y', - 'expectedValue': '17.11.2016' - } - }, - 'pl_PL': { - 'locale': 'pl_PL', - 'localeInfo': { - 'format': 'dd.MM.y', - 'expectedValue': '17.11.2016' - } - }, - 'pt_BR': { - 'locale': 'pt_BR', - 'localeInfo': { - 'format': 'dd/MM/yy', - 'expectedValue': '17/11/2016' - } - }, - 'pt_PT': { - 'locale': 'pt_PT', - 'localeInfo': { - 'format': 'dd/MM/yy', - 'expectedValue': '17/11/2016' - } - }, - 'ro_RO': { - 'locale': 'ro_RO', - 'localeInfo': { - 'format': 'dd.MM.y', - 'expectedValue': '17.11.2016' - } - }, - 'sq_AL': { - 'locale': 'sq_AL', - 'localeInfo': { - 'format': 'd.M.yy', - 'expectedValue': '17.11.2016' - } - }, - 'sk_SK': { - 'locale': 'sk_SK', - 'localeInfo': { - 'format': 'dd.MM.yy', - 'expectedValue': '17.11.2016' - } - }, - 'sl_SI': { - 'locale': 'sl_SI', - 'localeInfo': { - 'format': 'd. MM. yy', - 'expectedValue': '17. 11. 2016' - } - }, - 'fi_FI': { - 'locale': 'fi_FI', - 'localeInfo': { - 'format': 'd.M.y', - 'expectedValue': '17.11.2016' - } - }, - 'sv_SE': { - 'locale': 'sv_SE', - 'localeInfo': { - 'format': 'y-MM-dd', - 'expectedValue': '2016-11-17' - } - }, - 'vi_VN': { - 'locale': 'vi_VN', - 'localeInfo': { - 'format': 'dd/MM/y', - 'expectedValue': '17/11/2016' - } - }, - 'tr_TR': { - 'locale': 'tr_TR', - 'localeInfo': { - 'format': 'd.MM.y', - 'expectedValue': '17.11.2016' - } - }, - 'is_IS': { - 'locale': 'is_IS', - 'localeInfo': { - 'format': 'd.M.y', - 'expectedValue': '17.11.2016' - } - }, - 'cs_CZ': { - 'locale': 'cs_CZ', - 'localeInfo': { - 'format': 'dd.MM.yy', - 'expectedValue': '17.11.2016' - } - }, - 'el_GR': { - 'locale': 'el_GR', - 'localeInfo': { - 'format': 'd/M/yy', - 'expectedValue': '17/11/2016' - } - }, - 'be_BY': { - 'locale': 'be_BY', - 'localeInfo': { - 'format': 'd.M.yy', - 'expectedValue': '17.11.2016' - } - }, - 'bg_BG': { - 'locale': 'bg_BG', - 'localeInfo': { - 'format': 'd.MM.yy г.', - 'expectedValue': '17.11.2016 г.' - } - }, - 'mk_MK': { - 'locale': 'mk_MK', - 'localeInfo': { - 'format': 'dd.M.yy', - 'expectedValue': '17.11.2016' - } - }, - 'mn_Cyrl_MN': { - 'locale': 'mn_Cyrl_MN', - 'localeInfo': { - 'format': 'y-MM-dd', - 'expectedValue': '2016-11-17' - } - }, - 'ru_RU': { - 'locale': 'ru_RU', - 'localeInfo': { - 'format': 'dd.MM.yy', - 'expectedValue': '17.11.2016' - } - }, - 'sr_Cyrl_RS': { - 'locale': 'sr_Cyrl_RS', - 'localeInfo': { - 'format': 'd.M.yy.', - 'expectedValue': '17.11.2016.' - } - }, - 'uk_UA': { - 'locale': 'uk_UA', - 'localeInfo': { - 'format': 'dd.MM.yy', - 'expectedValue': '17.11.2016' - } - }, - 'he_IL': { - 'locale': 'he_IL', - 'localeInfo': { - 'format': 'd.M.y', - 'expectedValue': '17.11.2016' - } - }, - 'ar_DZ': { - 'locale': 'ar_DZ', - 'localeInfo': { - 'format': 'dâ€/Mâ€/y', - 'expectedValue': '17â€/11â€/2016' - } - }, - 'ar_KW': { - 'locale': 'ar_KW', - 'localeInfo': { - 'format': 'dâ€/Mâ€/y', - 'expectedValue': '17â€/11â€/2016' - } - }, - 'ar_MA': { - 'locale': 'ar_MA', - 'localeInfo': { - 'format': 'dâ€/Mâ€/y', - 'expectedValue': '17â€/11â€/2016' - } - }, - 'ar_SA': { - 'locale': 'ar_SA', - 'localeInfo': { - 'format': 'dâ€/Mâ€/y', - 'expectedValue': '17â€/11â€/2016' - } - }, - 'ar_EG': { - 'locale': 'ar_EG', - 'localeInfo': { - 'format': 'dâ€/Mâ€/y', - 'expectedValue': '17â€/11â€/2016' - } - }, - 'fa_IR': { - 'locale': 'fa_IR', - 'localeInfo': { - 'format': 'y/M/d G', - 'expectedValue': '2016/11/17 G' - } - }, - 'hi_IN': { - 'locale': 'hi_IN', - 'localeInfo': { - 'format': 'd/M/yy', - 'expectedValue': '17/11/2016' - } - }, - 'bn_BD': { - 'locale': 'bn_BD', - 'localeInfo': { - 'format': 'd/M/yy', - 'expectedValue': '17/11/2016' - } - }, - 'gu_IN': { - 'locale': 'gu_IN', - 'localeInfo': { - 'format': 'd/M/yy', - 'expectedValue': '17/11/2016' - } - }, - 'th_TH': { - 'locale': 'th_TH', - 'localeInfo': { - 'format': 'd/M/yy', - 'expectedValue': '17/11/2016' - } - }, - 'lo_LA': { - 'locale': 'lo_LA', - 'localeInfo': { - 'format': 'd/M/y', - 'expectedValue': '17/11/2016' - } - }, - 'ka_GE': { - 'locale': 'ka_GE', - 'localeInfo': { - 'format': 'dd.MM.yy', - 'expectedValue': '17.11.2016' - } - }, - 'km_KH': { - 'locale': 'km_KH', - 'localeInfo': { - 'format': 'd/M/yy', - 'expectedValue': '17/11/2016' - } - }, - 'zh_Hans_CN': { - 'locale': 'zh_Hans_CN', - 'localeInfo': { - 'format': 'yy/M/d', - 'expectedValue': '2016/11/17' - } - }, - 'zh_Hant_HK': { - 'locale': 'zh_Hant_HK', - 'localeInfo': { - 'format': 'd/M/yy', - 'expectedValue': '17/11/2016' - } - }, - 'zh_Hant_TW': { - 'locale': 'zh_Hant_TW', - 'localeInfo': { - 'format': 'y/M/d', - 'expectedValue': '2016/11/17' - } - }, - 'ja_JP': { - 'locale': 'ja_JP', - 'localeInfo': { - 'format': 'y/MM/dd', - 'expectedValue': '2016/11/17' - } - }, - 'ko_KR': { - 'locale': 'ko_KR', - 'localeInfo': { - 'format': 'yy. M. d.', - 'expectedValue': '2016. 11. 17.' - } - } - }; - - for (p in fixture) { - if (fixture.hasOwnProperty(p)) { - localeValues = fixture[p]; - format = localeValues.localeInfo.format; - expectedValue = localeValues.localeInfo.expectedValue; - momentFormat = model.convertToMomentFormat(format); - dt = moment('2016-11-17'); - m = moment(dt, momentFormat); - - expect(m.format(momentFormat)).toBe(expectedValue); - } - } - }); }); }); diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/lib/ko/bind/datepicker.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/lib/ko/bind/datepicker.test.js index a8c06b7b34cc055ce052f73d0a231613f8944f1c..e5f90863ec63071f191b82b0df7fdbba0ac411fa 100644 --- a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/lib/ko/bind/datepicker.test.js +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/lib/ko/bind/datepicker.test.js @@ -7,21 +7,32 @@ define([ 'ko', 'jquery', 'moment', + 'mageUtils', 'Magento_Ui/js/lib/knockout/bindings/datepicker' -], function (ko, $, moment) { +], function (ko, $, moment, utils) { 'use strict'; describe('Datepicker binding', function () { var observable, - element; + element, + config; beforeEach(function () { element = $('<input />'); observable = ko.observable(); + config = { + options : { + dateFormat: 'M/d/yy', + 'storeLocale': 'en_US', + 'timeFormat': 'h:mm: a' + }, + storage:ko.observable(moment().format('MM/DD/YYYY')) + }; + $(document.body).append(element); - ko.applyBindingsToNode(element[0], { datepicker: observable }); + ko.applyBindingsToNode(element[0], { datepicker: config }); }); afterEach(function () { @@ -29,22 +40,18 @@ define([ }); it('writes picked date\'s value to assigned observable', function () { - var openBtn, - todayBtn, - todayDate, - dateFormat, - result; + var todayDate, + momentFormat, + result, + inputFormat; - dateFormat = element.datepicker('option', 'dateFormat'); - todayDate = moment().format(dateFormat); + inputFormat = 'M/d/yy'; - openBtn = $('img.ui-datepicker-trigger'); - todayBtn = $('[data-handler="today"]'); + momentFormat = utils.convertToMomentFormat(inputFormat); - openBtn.click(); - todayBtn.click(); + todayDate = moment().format(momentFormat); - result = moment(observable()).format(dateFormat); + result = $('input:last').val(); expect(todayDate).toEqual(result); }); diff --git a/dev/tests/js/jasmine/tests/lib/mage/misc.test.js b/dev/tests/js/jasmine/tests/lib/mage/misc.test.js new file mode 100644 index 0000000000000000000000000000000000000000..a9ea5ed90192fa46e3e223802d872be0a32afba2 --- /dev/null +++ b/dev/tests/js/jasmine/tests/lib/mage/misc.test.js @@ -0,0 +1,638 @@ +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +define([ + 'mageUtils', + 'moment' +], function (utils, moment) { + 'use strict'; + + describe('mageUtils', function () { + + it('Check convertToMomentFormat function', function () { + var format, momentFormat; + + format = 'M/d/yy'; + momentFormat = 'MM/DD/YYYY'; + expect(utils.convertToMomentFormat(format)).toBe(momentFormat); + }); + + it('Check convertToMomentFormat function for all Magento supported locales', function () { + + var fixture, + localeValues, + format, + expectedValue, + momentFormat, + dt, + m, + p; + + fixture = { + 'af_ZA': { + 'locale': 'af_ZA', + 'localeInfo': { + 'format': 'y-MM-dd', + 'expectedValue': '2016-11-17' + } + }, + 'az_Latn_AZ': { + 'locale': 'az_Latn_AZ', + 'localeInfo': { + 'format': 'dd.MM.yy', + 'expectedValue': '17.11.2016' + } + }, + 'id_ID': { + 'locale': 'id_ID', + 'localeInfo': { + 'format': 'dd/MM/yy', + 'expectedValue': '17/11/2016' + } + }, + 'ms_Latn_MY': { + 'locale': 'ms_Latn_MY', + 'localeInfo': { + 'format': 'd/MM/yy', + 'expectedValue': '17/11/2016' + } + }, + 'bs_Latn_BA': { + 'locale': 'bs_Latn_BA', + 'localeInfo': { + 'format': 'dd.MM.yy.', + 'expectedValue': '17.11.2016.' + } + }, + 'ca_ES': { + 'locale': 'ca_ES', + 'localeInfo': { + 'format': 'd/M/yy', + 'expectedValue': '17/11/2016' + } + }, + 'cy_GB': { + 'locale': 'cy_GB', + 'localeInfo': { + 'format': 'dd/MM/yy', + 'expectedValue': '17/11/2016' + } + }, + 'da_DK': { + 'locale': 'da_DK', + 'localeInfo': { + 'format': 'dd/MM/y', + 'expectedValue': '17/11/2016' + } + }, + 'de_DE': { + 'locale': 'de_DE', + 'localeInfo': { + 'format': 'dd.MM.yy', + 'expectedValue': '17.11.2016' + } + }, + 'de_CH': { + 'locale': 'de_CH', + 'localeInfo': { + 'format': 'dd.MM.yy', + 'expectedValue': '17.11.2016' + } + }, + 'de_AT': { + 'locale': 'de_AT', + 'localeInfo': { + 'format': 'dd.MM.yy', + 'expectedValue': '17.11.2016' + } + }, + 'et_EE': { + 'locale': 'et_EE', + 'localeInfo': { + 'format': 'dd.MM.yy', + 'expectedValue': '17.11.2016' + } + }, + 'en_AU': { + 'locale': 'en_AU', + 'localeInfo': { + 'format': 'd/MM/y', + 'expectedValue': '17/11/2016' + } + }, + 'en_CA': { + 'locale': 'en_CA', + 'localeInfo': { + 'format': 'y-MM-dd', + 'expectedValue': '2016-11-17' + } + }, + 'en_IE': { + 'locale': 'en_IE', + 'localeInfo': { + 'format': 'dd/MM/y', + 'expectedValue': '17/11/2016' + } + }, + 'en_NZ': { + 'locale': 'en_NZ', + 'localeInfo': { + 'format': 'd/MM/yy', + 'expectedValue': '17/11/2016' + } + }, + 'en_GB': { + 'locale': 'en_GB', + 'localeInfo': { + 'format': 'dd/MM/y', + 'expectedValue': '17/11/2016' + } + }, + 'en_US': { + 'locale': 'en_US', + 'localeInfo': { + 'format': 'M/d/yy', + 'expectedValue': '11/17/2016' + } + }, + 'es_AR': { + 'locale': 'es_AR', + 'localeInfo': { + 'format': 'd/M/yy', + 'expectedValue': '17/11/2016' + } + }, + 'es_CL': { + 'locale': 'es_CL', + 'localeInfo': { + 'format': 'dd-MM-yy', + 'expectedValue': '17-11-2016' + } + }, + 'es_CO': { + 'locale': 'es_CO', + 'localeInfo': { + 'format': 'd/MM/yy', + 'expectedValue': '17/11/2016' + } + }, + 'es_CR': { + 'locale': 'es_CR', + 'localeInfo': { + 'format': 'd/M/yy', + 'expectedValue': '17/11/2016' + } + }, + 'es_ES': { + 'locale': 'es_ES', + 'localeInfo': { + 'format': 'd/M/yy', + 'expectedValue': '17/11/2016' + } + }, + 'es_MX': { + 'locale': 'es_MX', + 'localeInfo': { + 'format': 'dd/MM/yy', + 'expectedValue': '17/11/2016' + } + }, + 'es_PA': { + 'locale': 'es_PA', + 'localeInfo': { + 'format': 'MM/dd/yy', + 'expectedValue': '11/17/2016' + } + }, + 'es_PE': { + 'locale': 'es_PE', + 'localeInfo': { + 'format': 'd/MM/yy', + 'expectedValue': '17/11/2016' + } + }, + 'es_VE': { + 'locale': 'es_VE', + 'localeInfo': { + 'format': 'd/M/yy', + 'expectedValue': '17/11/2016' + } + }, + 'eu_ES': { + 'locale': 'eu_ES', + 'localeInfo': { + 'format': 'y/MM/dd', + 'expectedValue': '2016/11/17' + } + }, + 'fil_PH': { + 'locale': 'fil_PH', + 'localeInfo': { + 'format': 'M/d/yy', + 'expectedValue': '11/17/2016' + } + }, + 'fr_BE': { + 'locale': 'fr_BE', + 'localeInfo': { + 'format': 'd/MM/yy', + 'expectedValue': '17/11/2016' + } + }, + 'fr_CA': { + 'locale': 'fr_CA', + 'localeInfo': { + 'format': 'yy-MM-dd', + 'expectedValue': '2016-11-17' + } + }, + 'fr_FR': { + 'locale': 'fr_FR', + 'localeInfo': { + 'format': 'dd/MM/y', + 'expectedValue': '17/11/2016' + } + }, + 'gl_ES': { + 'locale': 'gl_ES', + 'localeInfo': { + 'format': 'dd/MM/yy', + 'expectedValue': '17/11/2016' + } + }, + 'hr_HR': { + 'locale': 'hr_HR', + 'localeInfo': { + 'format': 'dd.MM.y.', + 'expectedValue': '17.11.2016.' + } + }, + 'it_IT': { + 'locale': 'it_IT', + 'localeInfo': { + 'format': 'dd/MM/yy', + 'expectedValue': '17/11/2016' + } + }, + 'it_CH': { + 'locale': 'it_CH', + 'localeInfo': { + 'format': 'dd.MM.yy', + 'expectedValue': '17.11.2016' + } + }, + 'sw_KE': { + 'locale': 'sw_KE', + 'localeInfo': { + 'format': 'dd/MM/y', + 'expectedValue': '17/11/2016' + } + }, + 'lv_LV': { + 'locale': 'lv_LV', + 'localeInfo': { + 'format': 'dd.MM.yy', + 'expectedValue': '17.11.2016' + } + }, + 'lt_LT': { + 'locale': 'lt_LT', + 'localeInfo': { + 'format': 'y-MM-dd', + 'expectedValue': '2016-11-17' + } + }, + 'hu_HU': { + 'locale': 'hu_HU', + 'localeInfo': { + 'format': 'y. MM. dd.', + 'expectedValue': '2016. 11. 17.' + } + }, + 'nl_BE': { + 'locale': 'nl_BE', + 'localeInfo': { + 'format': 'd/MM/yy', + 'expectedValue': '17/11/2016' + } + }, + 'nl_NL': { + 'locale': 'nl_NL', + 'localeInfo': { + 'format': 'dd-MM-yy', + 'expectedValue': '17-11-2016' + } + }, + 'nb_NO': { + 'locale': 'nb_NO', + 'localeInfo': { + 'format': 'dd.MM.y', + 'expectedValue': '17.11.2016' + } + }, + 'nn_NO': { + 'locale': 'nn_NO', + 'localeInfo': { + 'format': 'dd.MM.y', + 'expectedValue': '17.11.2016' + } + }, + 'pl_PL': { + 'locale': 'pl_PL', + 'localeInfo': { + 'format': 'dd.MM.y', + 'expectedValue': '17.11.2016' + } + }, + 'pt_BR': { + 'locale': 'pt_BR', + 'localeInfo': { + 'format': 'dd/MM/yy', + 'expectedValue': '17/11/2016' + } + }, + 'pt_PT': { + 'locale': 'pt_PT', + 'localeInfo': { + 'format': 'dd/MM/yy', + 'expectedValue': '17/11/2016' + } + }, + 'ro_RO': { + 'locale': 'ro_RO', + 'localeInfo': { + 'format': 'dd.MM.y', + 'expectedValue': '17.11.2016' + } + }, + 'sq_AL': { + 'locale': 'sq_AL', + 'localeInfo': { + 'format': 'd.M.yy', + 'expectedValue': '17.11.2016' + } + }, + 'sk_SK': { + 'locale': 'sk_SK', + 'localeInfo': { + 'format': 'dd.MM.yy', + 'expectedValue': '17.11.2016' + } + }, + 'sl_SI': { + 'locale': 'sl_SI', + 'localeInfo': { + 'format': 'd. MM. yy', + 'expectedValue': '17. 11. 2016' + } + }, + 'fi_FI': { + 'locale': 'fi_FI', + 'localeInfo': { + 'format': 'd.M.y', + 'expectedValue': '17.11.2016' + } + }, + 'sv_SE': { + 'locale': 'sv_SE', + 'localeInfo': { + 'format': 'y-MM-dd', + 'expectedValue': '2016-11-17' + } + }, + 'vi_VN': { + 'locale': 'vi_VN', + 'localeInfo': { + 'format': 'dd/MM/y', + 'expectedValue': '17/11/2016' + } + }, + 'tr_TR': { + 'locale': 'tr_TR', + 'localeInfo': { + 'format': 'd.MM.y', + 'expectedValue': '17.11.2016' + } + }, + 'is_IS': { + 'locale': 'is_IS', + 'localeInfo': { + 'format': 'd.M.y', + 'expectedValue': '17.11.2016' + } + }, + 'cs_CZ': { + 'locale': 'cs_CZ', + 'localeInfo': { + 'format': 'dd.MM.yy', + 'expectedValue': '17.11.2016' + } + }, + 'el_GR': { + 'locale': 'el_GR', + 'localeInfo': { + 'format': 'd/M/yy', + 'expectedValue': '17/11/2016' + } + }, + 'be_BY': { + 'locale': 'be_BY', + 'localeInfo': { + 'format': 'd.M.yy', + 'expectedValue': '17.11.2016' + } + }, + 'bg_BG': { + 'locale': 'bg_BG', + 'localeInfo': { + 'format': 'd.MM.yy г.', + 'expectedValue': '17.11.2016 г.' + } + }, + 'mk_MK': { + 'locale': 'mk_MK', + 'localeInfo': { + 'format': 'dd.M.yy', + 'expectedValue': '17.11.2016' + } + }, + 'mn_Cyrl_MN': { + 'locale': 'mn_Cyrl_MN', + 'localeInfo': { + 'format': 'y-MM-dd', + 'expectedValue': '2016-11-17' + } + }, + 'ru_RU': { + 'locale': 'ru_RU', + 'localeInfo': { + 'format': 'dd.MM.yy', + 'expectedValue': '17.11.2016' + } + }, + 'sr_Cyrl_RS': { + 'locale': 'sr_Cyrl_RS', + 'localeInfo': { + 'format': 'd.M.yy.', + 'expectedValue': '17.11.2016.' + } + }, + 'uk_UA': { + 'locale': 'uk_UA', + 'localeInfo': { + 'format': 'dd.MM.yy', + 'expectedValue': '17.11.2016' + } + }, + 'he_IL': { + 'locale': 'he_IL', + 'localeInfo': { + 'format': 'd.M.y', + 'expectedValue': '17.11.2016' + } + }, + 'ar_DZ': { + 'locale': 'ar_DZ', + 'localeInfo': { + 'format': 'dâ€/Mâ€/y', + 'expectedValue': '17â€/11â€/2016' + } + }, + 'ar_KW': { + 'locale': 'ar_KW', + 'localeInfo': { + 'format': 'dâ€/Mâ€/y', + 'expectedValue': '17â€/11â€/2016' + } + }, + 'ar_MA': { + 'locale': 'ar_MA', + 'localeInfo': { + 'format': 'dâ€/Mâ€/y', + 'expectedValue': '17â€/11â€/2016' + } + }, + 'ar_SA': { + 'locale': 'ar_SA', + 'localeInfo': { + 'format': 'dâ€/Mâ€/y', + 'expectedValue': '17â€/11â€/2016' + } + }, + 'ar_EG': { + 'locale': 'ar_EG', + 'localeInfo': { + 'format': 'dâ€/Mâ€/y', + 'expectedValue': '17â€/11â€/2016' + } + }, + 'fa_IR': { + 'locale': 'fa_IR', + 'localeInfo': { + 'format': 'y/M/d G', + 'expectedValue': '2016/11/17 G' + } + }, + 'hi_IN': { + 'locale': 'hi_IN', + 'localeInfo': { + 'format': 'd/M/yy', + 'expectedValue': '17/11/2016' + } + }, + 'bn_BD': { + 'locale': 'bn_BD', + 'localeInfo': { + 'format': 'd/M/yy', + 'expectedValue': '17/11/2016' + } + }, + 'gu_IN': { + 'locale': 'gu_IN', + 'localeInfo': { + 'format': 'd/M/yy', + 'expectedValue': '17/11/2016' + } + }, + 'th_TH': { + 'locale': 'th_TH', + 'localeInfo': { + 'format': 'd/M/yy', + 'expectedValue': '17/11/2016' + } + }, + 'lo_LA': { + 'locale': 'lo_LA', + 'localeInfo': { + 'format': 'd/M/y', + 'expectedValue': '17/11/2016' + } + }, + 'ka_GE': { + 'locale': 'ka_GE', + 'localeInfo': { + 'format': 'dd.MM.yy', + 'expectedValue': '17.11.2016' + } + }, + 'km_KH': { + 'locale': 'km_KH', + 'localeInfo': { + 'format': 'd/M/yy', + 'expectedValue': '17/11/2016' + } + }, + 'zh_Hans_CN': { + 'locale': 'zh_Hans_CN', + 'localeInfo': { + 'format': 'yy/M/d', + 'expectedValue': '2016/11/17' + } + }, + 'zh_Hant_HK': { + 'locale': 'zh_Hant_HK', + 'localeInfo': { + 'format': 'd/M/yy', + 'expectedValue': '17/11/2016' + } + }, + 'zh_Hant_TW': { + 'locale': 'zh_Hant_TW', + 'localeInfo': { + 'format': 'y/M/d', + 'expectedValue': '2016/11/17' + } + }, + 'ja_JP': { + 'locale': 'ja_JP', + 'localeInfo': { + 'format': 'y/MM/dd', + 'expectedValue': '2016/11/17' + } + }, + 'ko_KR': { + 'locale': 'ko_KR', + 'localeInfo': { + 'format': 'yy. M. d.', + 'expectedValue': '2016. 11. 17.' + } + } + }; + + for (p in fixture) { + if (fixture.hasOwnProperty(p)) { + localeValues = fixture[p]; + format = localeValues.localeInfo.format; + expectedValue = localeValues.localeInfo.expectedValue; + momentFormat = utils.convertToMomentFormat(format); + dt = moment('2016-11-17'); + m = moment(dt, momentFormat); + + expect(m.format(momentFormat)).toBe(expectedValue); + } + } + }); + }); +}); diff --git a/lib/web/mage/utils/misc.js b/lib/web/mage/utils/misc.js index c6440b8929395419053ab53961f5fcc231ab7eee..29fed485f290c86f92099fc6cba68734711980d2 100644 --- a/lib/web/mage/utils/misc.js +++ b/lib/web/mage/utils/misc.js @@ -207,6 +207,22 @@ define([ } return formData; + }, + + /** + * Converts PHP IntlFormatter format to moment format. + * + * @param {String} format - PHP format + * @returns {String} - moment compatible formatting + */ + convertToMomentFormat: function (format) { + var newFormat; + + newFormat = format.replace(/yy|y/gi, 'YYYY'); // replace the year + newFormat = newFormat.replace(/dd|d/g, 'DD'); // replace the date + newFormat = newFormat.replace(/mm|m/gi, 'MM'); //replace the month + + return newFormat; } }; });