diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php index 33c8cea3262a4d589a1d5b37b66ece85e614a2c3..53360de08b434b4a0314fe341760c55fef476ef4 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php @@ -493,7 +493,6 @@ class AdvancedPricing extends AbstractModifier 'data' => [ 'config' => [ 'componentType' => Field::NAME, - 'component' => 'Magento_Catalog/js/form/element/price-input', 'formElement' => Input::NAME, 'dataType' => Price::NAME, 'label' => __('Price'), diff --git a/app/code/Magento/Catalog/view/adminhtml/web/js/form/element/price-input.js b/app/code/Magento/Catalog/view/adminhtml/web/js/form/element/price-input.js deleted file mode 100644 index 0939619809a460b49cc7f254702797357c3b06f5..0000000000000000000000000000000000000000 --- a/app/code/Magento/Catalog/view/adminhtml/web/js/form/element/price-input.js +++ /dev/null @@ -1,15 +0,0 @@ -/** - * Copyright © 2016 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -define([ - 'Magento_Ui/js/form/element/abstract' -], function (Abstract) { - 'use strict'; - - return Abstract.extend({ - defaults: { - elementTmpl: 'Magento_Catalog/form/element/price-input' - } - }); -}); diff --git a/app/code/Magento/Catalog/view/adminhtml/web/template/form/element/price-input.html b/app/code/Magento/Catalog/view/adminhtml/web/template/form/element/price-input.html deleted file mode 100644 index ce8ae751e6702ff11099db5a06c8dbb8d4b1cbb9..0000000000000000000000000000000000000000 --- a/app/code/Magento/Catalog/view/adminhtml/web/template/form/element/price-input.html +++ /dev/null @@ -1,22 +0,0 @@ -<!-- -/** - * Copyright © 2016 Magento. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<input class="admin__control-text" type="text" - data-bind=" - event: { - change: userChanges, - input: onInput - }, - value: value, - hasFocus: focused, - valueUpdate: valueUpdate, - attr: { - name: inputName, - placeholder: placeholder, - 'aria-describedby': noticeId, - id: uid, - disabled: disabled - }"/> diff --git a/app/code/Magento/CatalogSearch/Block/Advanced/Result.php b/app/code/Magento/CatalogSearch/Block/Advanced/Result.php index 7b720c8c7c87a33bb55cd51e50deac5472e56ebf..4351b134e4a1100f2decc3b5e1d8f39a0bead78f 100644 --- a/app/code/Magento/CatalogSearch/Block/Advanced/Result.php +++ b/app/code/Magento/CatalogSearch/Block/Advanced/Result.php @@ -64,6 +64,7 @@ class Result extends Template */ protected function _prepareLayout() { + $this->pageConfig->getTitle()->set($this->getPageTitle()); $breadcrumbs = $this->getLayout()->getBlock('breadcrumbs'); if ($breadcrumbs) { $breadcrumbs->addCrumb( @@ -84,6 +85,16 @@ class Result extends Template return parent::_prepareLayout(); } + /** + * Get page title + * + * @return \Magento\Framework\Phrase + */ + private function getPageTitle() + { + return __('Advanced Search Results'); + } + /** * Set order options * diff --git a/app/code/Magento/CatalogSearch/Model/Advanced.php b/app/code/Magento/CatalogSearch/Model/Advanced.php index ef332a675e8a84f2aeb85a9c1b8443713ca57afa..f469820b3bb2db88821119e6435fe20adb4d1279 100644 --- a/app/code/Magento/CatalogSearch/Model/Advanced.php +++ b/app/code/Magento/CatalogSearch/Model/Advanced.php @@ -368,9 +368,11 @@ class Advanced extends \Magento\Framework\Model\AbstractModel $value = $value['label']; } } elseif ($attribute->getFrontendInput() == 'boolean') { - $value = $value == 1 - ? __('Yes') - : __('No'); + if (is_numeric($value)) { + $value = $value == 1 ? __('Yes') : __('No'); + } else { + $value = false; + } } return $value; diff --git a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator.php b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator.php index 2ca347aae83c29ee3b10923245fe618d84d54a6c..1dc33743d76c187b2f20dec9149c3bd10dd2ddd3 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator.php +++ b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator.php @@ -8,7 +8,8 @@ namespace Magento\CatalogSearch\Model\Search; use Magento\Catalog\Api\Data\EavAttributeInterface; use Magento\Catalog\Model\Entity\Attribute; use Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory; -use Magento\Framework\Search\Request\BucketInterface; +use Magento\CatalogSearch\Model\Search\RequestGenerator\GeneratorResolver; +use Magento\Framework\App\ObjectManager; use Magento\Framework\Search\Request\FilterInterface; use Magento\Framework\Search\Request\QueryInterface; @@ -25,12 +26,22 @@ class RequestGenerator */ private $productAttributeCollectionFactory; + /** + * @var GeneratorResolver + */ + private $generatorResolver; + /** * @param CollectionFactory $productAttributeCollectionFactory + * @param GeneratorResolver $generatorResolver */ - public function __construct(CollectionFactory $productAttributeCollectionFactory) - { + public function __construct( + CollectionFactory $productAttributeCollectionFactory, + GeneratorResolver $generatorResolver = null + ) { $this->productAttributeCollectionFactory = $productAttributeCollectionFactory; + $this->generatorResolver = $generatorResolver + ?: ObjectManager::getInstance()->get(GeneratorResolver::class); } /** @@ -62,7 +73,7 @@ class RequestGenerator $request = []; foreach ($this->getSearchableAttributes() as $attribute) { if ($attribute->getData($attributeType)) { - if (!in_array($attribute->getAttributeCode(), ['price', 'category_ids'])) { + if (!in_array($attribute->getAttributeCode(), ['price', 'category_ids'], true)) { $queryName = $attribute->getAttributeCode() . '_query'; $request['queries'][$container]['queryReference'][] = [ @@ -76,58 +87,33 @@ class RequestGenerator 'filterReference' => [['ref' => $filterName]], ]; $bucketName = $attribute->getAttributeCode() . self::BUCKET_SUFFIX; - if ($attribute->getBackendType() == 'decimal') { - $request['filters'][$filterName] = [ - 'type' => FilterInterface::TYPE_RANGE, - 'name' => $filterName, - 'field' => $attribute->getAttributeCode(), - 'from' => '$' . $attribute->getAttributeCode() . '.from$', - 'to' => '$' . $attribute->getAttributeCode() . '.to$', - ]; - $request['aggregations'][$bucketName] = [ - 'type' => BucketInterface::TYPE_DYNAMIC, - 'name' => $bucketName, - 'field' => $attribute->getAttributeCode(), - 'method' => 'manual', - 'metric' => [["type" => "count"]], - ]; - } else { - $request['filters'][$filterName] = [ - 'type' => FilterInterface::TYPE_TERM, - 'name' => $filterName, - 'field' => $attribute->getAttributeCode(), - 'value' => '$' . $attribute->getAttributeCode() . '$', - ]; - $request['aggregations'][$bucketName] = [ - 'type' => BucketInterface::TYPE_TERM, - 'name' => $bucketName, - 'field' => $attribute->getAttributeCode(), - 'metric' => [["type" => "count"]], - ]; - } + $generator = $this->generatorResolver->getGeneratorForType($attribute->getBackendType()); + $request['filters'][$filterName] = $generator->getFilterData($attribute, $filterName); + $request['aggregations'][$bucketName] = $generator->getAggregationData($attribute, $bucketName); } } /** @var $attribute Attribute */ - if (in_array($attribute->getAttributeCode(), ['price', 'sku']) - || !$attribute->getIsSearchable() - ) { - //same fields have special semantics + if (!$attribute->getIsSearchable() || in_array($attribute->getAttributeCode(), ['price', 'sku'], true)) { + // Some fields have their own specific handlers continue; } - if ($useFulltext) { + + // Match search by custom price attribute isn't supported + if ($useFulltext && $attribute->getFrontendInput() !== 'price') { $request['queries']['search']['match'][] = [ 'field' => $attribute->getAttributeCode(), 'boost' => $attribute->getSearchWeight() ?: 1, ]; } } + return $request; } /** * Retrieve searchable attributes * - * @return \Magento\Catalog\Model\Entity\Attribute[] + * @return \Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection */ protected function getSearchableAttributes() { @@ -231,6 +217,7 @@ class RequestGenerator ]; } } + return $request; } } diff --git a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/Decimal.php b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/Decimal.php new file mode 100644 index 0000000000000000000000000000000000000000..52cab1c6ff942b3a94418a808ac96ff6ff5f678a --- /dev/null +++ b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/Decimal.php @@ -0,0 +1,44 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\CatalogSearch\Model\Search\RequestGenerator; + + +use Magento\Catalog\Model\ResourceModel\Eav\Attribute; +use Magento\Framework\Search\Request\BucketInterface; +use Magento\Framework\Search\Request\FilterInterface; + +class Decimal implements GeneratorInterface +{ + + /** + * {@inheritdoc} + */ + public function getFilterData(Attribute $attribute, $filterName) + { + return [ + 'type' => FilterInterface::TYPE_RANGE, + 'name' => $filterName, + 'field' => $attribute->getAttributeCode(), + 'from' => '$' . $attribute->getAttributeCode() . '.from$', + 'to' => '$' . $attribute->getAttributeCode() . '.to$', + ]; + } + + /** + * {@inheritdoc} + */ + public function getAggregationData(Attribute $attribute, $bucketName) + { + return [ + 'type' => BucketInterface::TYPE_DYNAMIC, + 'name' => $bucketName, + 'field' => $attribute->getAttributeCode(), + 'method' => 'manual', + 'metric' => [['type' => 'count']], + ]; + } +} diff --git a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/General.php b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/General.php new file mode 100644 index 0000000000000000000000000000000000000000..96362ce484b1ee8981d45c0661b760d62b1b7303 --- /dev/null +++ b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/General.php @@ -0,0 +1,42 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\CatalogSearch\Model\Search\RequestGenerator; + + +use Magento\Catalog\Model\ResourceModel\Eav\Attribute; +use Magento\Framework\Search\Request\BucketInterface; +use Magento\Framework\Search\Request\FilterInterface; + +class General implements GeneratorInterface +{ + + /** + * {@inheritdoc} + */ + public function getFilterData(Attribute $attribute, $filterName) + { + return [ + 'type' => FilterInterface::TYPE_TERM, + 'name' => $filterName, + 'field' => $attribute->getAttributeCode(), + 'value' => '$' . $attribute->getAttributeCode() . '$', + ]; + } + + /** + * {@inheritdoc} + */ + public function getAggregationData(Attribute $attribute, $bucketName) + { + return [ + 'type' => BucketInterface::TYPE_TERM, + 'name' => $bucketName, + 'field' => $attribute->getAttributeCode(), + 'metric' => [['type' => 'count']], + ]; + } +} diff --git a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/GeneratorInterface.php b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/GeneratorInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..c43786db2b6968761e4586f40bba9e4a8628f30a --- /dev/null +++ b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/GeneratorInterface.php @@ -0,0 +1,29 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\CatalogSearch\Model\Search\RequestGenerator; + + +use Magento\Catalog\Model\ResourceModel\Eav\Attribute; + +interface GeneratorInterface +{ + /** + * Get filter data for specific attribute + * @param Attribute $attribute + * @param string $filterName + * @return array + */ + public function getFilterData(Attribute $attribute, $filterName); + + /** + * Get aggregation data for specific attribute + * @param Attribute $attribute + * @param string $bucketName + * @return array + */ + public function getAggregationData(Attribute $attribute, $bucketName); +} diff --git a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/GeneratorResolver.php b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/GeneratorResolver.php new file mode 100644 index 0000000000000000000000000000000000000000..129a036ff2544fe4c84a70da98cbf0bb31ace4cb --- /dev/null +++ b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/GeneratorResolver.php @@ -0,0 +1,46 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\CatalogSearch\Model\Search\RequestGenerator; + +class GeneratorResolver +{ + /** + * @var GeneratorInterface[] + */ + private $generators; + + /** + * @var GeneratorInterface + */ + private $defaultGenerator; + + /** + * @param GeneratorInterface $defaultGenerator + * @param GeneratorInterface[] $generators + */ + public function __construct(GeneratorInterface $defaultGenerator, array $generators) + { + $this->defaultGenerator = $defaultGenerator; + $this->generators = $generators; + } + + /** + * @param string $type + * @return GeneratorInterface + * @throws \InvalidArgumentException + */ + public function getGeneratorForType($type) + { + $generator = isset($this->generators[$type]) ? $this->generators[$type] : $this->defaultGenerator; + if (!($generator instanceof GeneratorInterface)) { + throw new \InvalidArgumentException( + 'Generator must implement ' . GeneratorInterface::class + ); + } + return $generator; + } +} diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/AdvancedTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/AdvancedTest.php index e15b9b7818181180a22f55417e269d0dece2362e..afff7722fdec7b2eea34a590c85e048080489395 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/AdvancedTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/AdvancedTest.php @@ -170,7 +170,7 @@ class AdvancedTest extends \PHPUnit_Framework_TestCase 'static' ) ], - 'values' => ['is_active' => false], + 'values' => ['is_active' => 0], 'currentCurrencyCode' => 'GBP', 'baseCurrencyCode' => 'USD' ], diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/RequestGenerator/DecimalTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/RequestGenerator/DecimalTest.php new file mode 100644 index 0000000000000000000000000000000000000000..67a991f51856516ce3e2678bf768729f1d0aa86f --- /dev/null +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/RequestGenerator/DecimalTest.php @@ -0,0 +1,67 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\CatalogSearch\Test\Unit\Model\Search\RequestGenerator; + +use Magento\Catalog\Model\ResourceModel\Eav\Attribute; +use Magento\CatalogSearch\Model\Search\RequestGenerator\Decimal; +use Magento\Framework\Search\Request\BucketInterface; +use Magento\Framework\Search\Request\FilterInterface; + +class DecimalTest extends \PHPUnit_Framework_TestCase +{ + /** @var Decimal */ + private $decimal; + + /** @var Attribute|\PHPUnit_Framework_MockObject_MockObject */ + private $attribute; + + protected function setUp() + { + $this->attribute = $this->getMockBuilder(Attribute::class) + ->disableOriginalConstructor() + ->setMethods(['getAttributeCode']) + ->getMockForAbstractClass(); + $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $this->decimal = $objectManager->getObject(Decimal::class); + } + + public function testGetFilterData() + { + $filterName = 'test_filter_name'; + $attributeCode = 'test_attribute_code'; + $expected = [ + 'type' => FilterInterface::TYPE_RANGE, + 'name' => $filterName, + 'field' => $attributeCode, + 'from' => '$' . $attributeCode . '.from$', + 'to' => '$' . $attributeCode . '.to$', + ]; + $this->attribute->expects($this->atLeastOnce()) + ->method('getAttributeCode') + ->willReturn($attributeCode); + $actual = $this->decimal->getFilterData($this->attribute, $filterName); + $this->assertEquals($expected, $actual); + } + + public function testGetAggregationData() + { + $bucketName = 'test_bucket_name'; + $attributeCode = 'test_attribute_code'; + $expected = [ + 'type' => BucketInterface::TYPE_DYNAMIC, + 'name' => $bucketName, + 'field' => $attributeCode, + 'method' => 'manual', + 'metric' => [['type' => 'count']], + ]; + $this->attribute->expects($this->atLeastOnce()) + ->method('getAttributeCode') + ->willReturn($attributeCode); + $actual = $this->decimal->getAggregationData($this->attribute, $bucketName); + $this->assertEquals($expected, $actual); + } +} diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/RequestGenerator/GeneralTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/RequestGenerator/GeneralTest.php new file mode 100644 index 0000000000000000000000000000000000000000..d40829e6e53de8883b8f0b4ec4abb2b6d980da68 --- /dev/null +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/RequestGenerator/GeneralTest.php @@ -0,0 +1,65 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\CatalogSearch\Test\Unit\Model\Search\RequestGenerator; + +use Magento\Catalog\Model\ResourceModel\Eav\Attribute; +use Magento\CatalogSearch\Model\Search\RequestGenerator\General; +use Magento\Framework\Search\Request\BucketInterface; +use Magento\Framework\Search\Request\FilterInterface; + +class GeneralTest extends \PHPUnit_Framework_TestCase +{ + /** @var General */ + private $general; + + /** @var Attribute|\PHPUnit_Framework_MockObject_MockObject */ + private $attribute; + + protected function setUp() + { + $this->attribute = $this->getMockBuilder(Attribute::class) + ->disableOriginalConstructor() + ->setMethods(['getAttributeCode']) + ->getMockForAbstractClass(); + $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $this->general = $objectManager->getObject(General::class); + } + + public function testGetFilterData() + { + $filterName = 'test_general_filter_name'; + $attributeCode = 'test_general_attribute_code'; + $expected = [ + 'type' => FilterInterface::TYPE_TERM, + 'name' => $filterName, + 'field' => $attributeCode, + 'value' => '$' . $attributeCode . '$', + ]; + $this->attribute->expects($this->atLeastOnce()) + ->method('getAttributeCode') + ->willReturn($attributeCode); + $actual = $this->general->getFilterData($this->attribute, $filterName); + $this->assertEquals($expected, $actual); + } + + public function testGetAggregationData() + { + $bucketName = 'test_bucket_name'; + $attributeCode = 'test_attribute_code'; + $expected = [ + 'type' => BucketInterface::TYPE_TERM, + 'name' => $bucketName, + 'field' => $attributeCode, + 'metric' => [['type' => 'count']], + ]; + $this->attribute->expects($this->atLeastOnce()) + ->method('getAttributeCode') + ->willReturn($attributeCode); + $actual = $this->general->getAggregationData($this->attribute, $bucketName); + $this->assertEquals($expected, $actual); + } +} diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/RequestGenerator/GeneratorResolverTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/RequestGenerator/GeneratorResolverTest.php new file mode 100644 index 0000000000000000000000000000000000000000..0b8bf882b850e05d9a5eac0d4887d8756cf56331 --- /dev/null +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/RequestGenerator/GeneratorResolverTest.php @@ -0,0 +1,76 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\CatalogSearch\Test\Unit\Model\Search\RequestGenerator; + + +use Magento\CatalogSearch\Model\Search\RequestGenerator\GeneratorResolver; +use Magento\CatalogSearch\Model\Search\RequestGenerator\GeneratorInterface; + +class GeneratorResolverTest extends \PHPUnit_Framework_TestCase +{ + /** @var GeneratorResolver */ + private $resolver; + + /** @var GeneratorInterface|\PHPUnit_Framework_MockObject_MockObject */ + private $defaultGenerator; + + /** @var GeneratorInterface|\PHPUnit_Framework_MockObject_MockObject */ + private $datetimeGenerator; + + /** @var GeneratorInterface|\PHPUnit_Framework_MockObject_MockObject */ + private $rangeGenerator; + + protected function setUp() + { + $this->defaultGenerator = $this->getMockBuilder(GeneratorInterface::class) + ->setMethods([]) + ->getMockForAbstractClass(); + + $this->datetimeGenerator = $this->getMockBuilder(GeneratorInterface::class) + ->setMethods([]) + ->getMockForAbstractClass(); + + $this->rangeGenerator = $this->getMockBuilder(GeneratorInterface::class) + ->setMethods([]) + ->getMockForAbstractClass(); + + $invalidTypeGenerator = $this->getMockBuilder(\stdClass::class) + ->setMethods([]); + + $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $this->resolver = $objectManager->getObject( + GeneratorResolver::class, + [ + 'defaultGenerator' => $this->defaultGenerator, + 'generators' => [ + 'datetime' => $this->datetimeGenerator, + 'range' => $this->datetimeGenerator, + 'invalid_type' => $invalidTypeGenerator, + ], + ] + ); + } + + public function testGetSpecificGenerator() + { + $this->assertEquals($this->rangeGenerator, $this->resolver->getGeneratorForType('range')); + $this->assertEquals($this->datetimeGenerator, $this->resolver->getGeneratorForType('datetime')); + } + + public function testGetFallbackGenerator() + { + $this->assertEquals($this->defaultGenerator, $this->resolver->getGeneratorForType('unknown_type')); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testGetInvalidGeneratorType() + { + $this->resolver->getGeneratorForType('invalid_type'); + } +} diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/RequestGeneratorTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/RequestGeneratorTest.php index f66bacfad306a0cd41cfc1a44206c3f0e60e6aa7..ca56dd83444b2b01d92b6c8e65023acdeeea277f 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/RequestGeneratorTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/RequestGeneratorTest.php @@ -6,6 +6,8 @@ namespace Magento\CatalogSearch\Test\Unit\Model\Search; use Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory; +use Magento\CatalogSearch\Model\Search\RequestGenerator\GeneratorResolver; +use Magento\CatalogSearch\Model\Search\RequestGenerator\GeneratorInterface; class RequestGeneratorTest extends \PHPUnit_Framework_TestCase { @@ -25,11 +27,29 @@ class RequestGeneratorTest extends \PHPUnit_Framework_TestCase ->setMethods(['create']) ->disableOriginalConstructor() ->getMock(); + $generatorResolver = $this->getMockBuilder(GeneratorResolver::class) + ->disableOriginalConstructor() + ->setMethods(['getGeneratorForType']) + ->getMock(); + $generator = $this->getMockBuilder(GeneratorInterface::class) + ->setMethods(['getFilterData', 'getAggregationData']) + ->getMockForAbstractClass(); + $generator->expects($this->any()) + ->method('getFilterData') + ->willReturn(['some filter data goes here']); + $generator->expects($this->any()) + ->method('getAggregationData') + ->willReturn(['some aggregation data goes here']); + $generatorResolver->method('getGeneratorForType') + ->willReturn($generator); $this->objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); $this->object = $this->objectManagerHelper->getObject( \Magento\CatalogSearch\Model\Search\RequestGenerator::class, - ['productAttributeCollectionFactory' => $this->productAttributeCollectionFactory] + [ + 'productAttributeCollectionFactory' => $this->productAttributeCollectionFactory, + 'generatorResolver' => $generatorResolver + ] ); } @@ -87,6 +107,14 @@ class RequestGeneratorTest extends \PHPUnit_Framework_TestCase ], ['attr_int', 'int', 0, 1, 0] ], + [ + [ + 'quick_search_container' => ['queries' => 2, 'filters' => 1, 'aggregations' => 1], + 'advanced_search_container' => ['queries' => 0, 'filters' => 0, 'aggregations' => 0], + 'catalog_view_container' => ['queries' => 0, 'filters' => 0, 'aggregations' => 0], + ], + ['custom_price_attr', 'price', 0, 1, 0], + ], ]; } @@ -124,19 +152,23 @@ class RequestGeneratorTest extends \PHPUnit_Framework_TestCase $this->assertEquals( $countResult['quick_search_container']['queries'], - $this->countVal($result['quick_search_container']['queries']) + $this->countVal($result['quick_search_container']['queries']), + 'Queries count for "quick_search_container" doesn\'t match' ); $this->assertEquals( $countResult['advanced_search_container']['queries'], - $this->countVal($result['advanced_search_container']['queries']) + $this->countVal($result['advanced_search_container']['queries']), + 'Queries count for "advanced_search_container" doesn\'t match' ); $this->assertEquals( $countResult['advanced_search_container']['filters'], - $this->countVal($result['advanced_search_container']['filters']) + $this->countVal($result['advanced_search_container']['filters']), + 'Filters count for "advanced_search_container" doesn\'t match' ); $this->assertEquals( $countResult['catalog_view_container']['queries'], - $this->countVal($result['catalog_view_container']['queries']) + $this->countVal($result['catalog_view_container']['queries']), + 'Queries count for "catalog_view_container" doesn\'t match' ); } @@ -144,11 +176,12 @@ class RequestGeneratorTest extends \PHPUnit_Framework_TestCase * Create attribute mock * * @param $attributeOptions - * @return \PHPUnit_Framework_MockObject_MockObject + * @return \Magento\Catalog\Model\Entity\Attribute|\PHPUnit_Framework_MockObject_MockObject */ private function createAttributeMock($attributeOptions) { - $attribute = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Product\Attribute::class) + /** @var \Magento\Catalog\Model\Entity\Attribute|\PHPUnit_Framework_MockObject_MockObject $attribute */ + $attribute = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class) ->disableOriginalConstructor() ->setMethods( [ @@ -184,8 +217,8 @@ class RequestGeneratorTest extends \PHPUnit_Framework_TestCase ->method('getData') ->willReturnMap( [ - ['is_filterable', $attributeOptions[2]], - ['is_filterable_in_search', $attributeOptions[3]] + ['is_filterable', null, $attributeOptions[2]], + ['is_filterable_in_search', null, $attributeOptions[3]], ] ); diff --git a/app/code/Magento/CatalogSearch/etc/di.xml b/app/code/Magento/CatalogSearch/etc/di.xml index e715b5fea7cd05edc4f1fa50e894f685d9747bd2..f62b4e47767a25230c5c2ad8372f99acc6bda2eb 100644 --- a/app/code/Magento/CatalogSearch/etc/di.xml +++ b/app/code/Magento/CatalogSearch/etc/di.xml @@ -237,4 +237,12 @@ </argument> </arguments> </type> + <type name="Magento\CatalogSearch\Model\Search\RequestGenerator\GeneratorResolver"> + <arguments> + <argument name="defaultGenerator" xsi:type="object">\Magento\CatalogSearch\Model\Search\RequestGenerator\General</argument> + <argument name="generators" xsi:type="array"> + <item name="decimal" xsi:type="object">Magento\CatalogSearch\Model\Search\RequestGenerator\Decimal</item> + </argument> + </arguments> + </type> </config> diff --git a/app/code/Magento/Checkout/view/frontend/layout/checkout_cart_configure.xml b/app/code/Magento/Checkout/view/frontend/layout/checkout_cart_configure.xml index 403e07c64d3ede27b5830a44ccdffbcaa5961273..c255f17cd36974518b8dc932e2a74e6726e6a266 100644 --- a/app/code/Magento/Checkout/view/frontend/layout/checkout_cart_configure.xml +++ b/app/code/Magento/Checkout/view/frontend/layout/checkout_cart_configure.xml @@ -6,6 +6,9 @@ */ --> <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> + <head> + <link src="Magento_Checkout::js/view/configure/product-customer-data.js"/> + </head> <update handle="catalog_product_view"/> <body> <referenceBlock name="head.components"> diff --git a/app/code/Magento/Checkout/view/frontend/templates/cart/item/configure/updatecart.phtml b/app/code/Magento/Checkout/view/frontend/templates/cart/item/configure/updatecart.phtml index fe39e9c44ada8b421966103b8d1810d82c21bc7b..0f221a393f5eb181f31a778ce4d01da1b0cc109b 100644 --- a/app/code/Magento/Checkout/view/frontend/templates/cart/item/configure/updatecart.phtml +++ b/app/code/Magento/Checkout/view/frontend/templates/cart/item/configure/updatecart.phtml @@ -17,7 +17,7 @@ <div class="field qty"> <label class="label" for="qty"><span><?php /* @escapeNotVerified */ echo __('Qty') ?></span></label> <div class="control"> - <input type="number" name="qty" id="qty" maxlength="12" value="<?php /* @escapeNotVerified */ echo $block->getProductDefaultQty() * 1 ?>" title="<?php /* @escapeNotVerified */ echo __('Qty') ?>" class="input-text qty" data-validate="{'required-number':true,digits:true}"/> + <input type="number" name="qty" id="qty" maxlength="12" value="" title="<?php /* @escapeNotVerified */ echo __('Qty') ?>" class="input-text qty" data-validate="{'required-number':true,digits:true}"/> </div> </div> <?php endif; ?> diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/configure/product-customer-data.js b/app/code/Magento/Checkout/view/frontend/web/js/view/configure/product-customer-data.js new file mode 100644 index 0000000000000000000000000000000000000000..a612b5e2dc6b7d38fa365911b81d67e5a3ca2aaa --- /dev/null +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/configure/product-customer-data.js @@ -0,0 +1,59 @@ +require([ + 'jquery', + 'Magento_Customer/js/customer-data' +], function ($, customerData) { + 'use strict'; + + var selectors = { + qtySelector: '#product_addtocart_form [name="qty"]', + productIdSelector: '#product_addtocart_form [name="product"]' + }, + cartData = customerData.get('cart'), + productId = $(selectors.productIdSelector).val(), + productQty, + productQtyInput, + + /** + * Updates product's qty input value according to actual data + */ + updateQty = function () { + + if (productQty || productQty === 0) { + productQtyInput = productQtyInput || $(selectors.qtySelector); + + if (productQtyInput && productQty.toString() !== productQtyInput.val()) { + productQtyInput.val(productQty); + } + } + }, + + /** + * Sets productQty according to cart data from customer-data + * + * @param {Object} data - cart data from customer-data + */ + setProductQty = function (data) { + var product; + + if (!(data && data.items && data.items.length && productId)) { + return; + } + product = data.items.find(function (item) { + return item['product_id'] === productId || + item['item_id'] === productId; + }); + + if (!product) { + return; + } + productQty = product.qty; + }; + + cartData.subscribe(function (updateCartData) { + setProductQty(updateCartData); + updateQty(); + }); + + setProductQty(cartData()); + updateQty(); +}); diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/View/Tab/History.php b/app/code/Magento/Sales/Block/Adminhtml/Order/View/Tab/History.php index 8a6674aa154b060cf1030101ff1fb1a9c3e0b6cc..a68c543acf731f5f435eaea029c57e069acd5e87 100644 --- a/app/code/Magento/Sales/Block/Adminhtml/Order/View/Tab/History.php +++ b/app/code/Magento/Sales/Block/Adminhtml/Order/View/Tab/History.php @@ -157,13 +157,10 @@ class History extends \Magento\Backend\Block\Template implements \Magento\Backen if (!isset($item['created_at'])) { return ''; } - $date = $item['created_at'] instanceof \DateTimeInterface - ? $item['created_at'] - : new \DateTime($item['created_at']); if ('date' === $dateType) { - return $this->_localeDate->formatDateTime($date, $format, $format); + return $this->formatDate($item['created_at'], $format); } - return $this->_localeDate->formatDateTime($date, \IntlDateFormatter::NONE, $format); + return $this->formatTime($item['created_at'], $format); } /** diff --git a/app/code/Magento/Sales/Test/Unit/Block/Adminhtml/Order/View/Tab/HistoryTest.php b/app/code/Magento/Sales/Test/Unit/Block/Adminhtml/Order/View/Tab/HistoryTest.php index 6445fd36dd14669afda748c05a0d9b558f1c31e0..0edeac71709290d7a3f3a8ace81604e35dd92feb 100644 --- a/app/code/Magento/Sales/Test/Unit/Block/Adminhtml/Order/View/Tab/HistoryTest.php +++ b/app/code/Magento/Sales/Test/Unit/Block/Adminhtml/Order/View/Tab/HistoryTest.php @@ -30,6 +30,16 @@ class HistoryTest extends \PHPUnit_Framework_TestCase */ protected $coreRegistryMock; + /** + * @var \Magento\Framework\Stdlib\DateTime\TimezoneInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $localeDateMock; + + /** + * @var \Magento\Backend\Block\Template\Context|\PHPUnit_Framework_MockObject_MockObject + */ + protected $contextMock; + protected function setUp() { $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); @@ -37,11 +47,25 @@ class HistoryTest extends \PHPUnit_Framework_TestCase $this->coreRegistryMock = $this->getMock(\Magento\Framework\Registry::class, [], [], '', false); $this->adminHelperMock = $this->getMock(\Magento\Sales\Helper\Admin::class, [], [], '', false); + $this->contextMock = $this->getMockBuilder(\Magento\Backend\Block\Template\Context::class) + ->disableOriginalConstructor() + ->setMethods(['getLocaleDate']) + ->getMock(); + + $this->localeDateMock = $this->getMockBuilder(\Magento\Framework\Stdlib\DateTime\TimezoneInterface::class) + ->getMock(); + + $this->contextMock->expects($this->any())->method('getLocaleDate')->will( + $this->returnValue($this->localeDateMock) + ); + $this->commentsHistory = $this->objectManager->getObject( \Magento\Sales\Block\Adminhtml\Order\View\Tab\History::class, [ 'adminHelper' => $this->adminHelperMock, - 'registry' => $this->coreRegistryMock + 'registry' => $this->coreRegistryMock, + 'context' => $this->contextMock, + 'localeDate' => $this->localeDateMock ] ); } @@ -63,4 +87,39 @@ class HistoryTest extends \PHPUnit_Framework_TestCase $this->adminHelperMock->expects($this->never())->method('escapeHtmlWithLinks'); $this->assertEquals('', $this->commentsHistory->getItemComment($item)); } + + public function testGetItemCreatedAtDate() + { + $date = new \DateTime; + $item = ['created_at' => $date ]; + + $this->localeDateMock->expects($this->once()) + ->method('formatDateTime') + ->with($date, \IntlDateFormatter::MEDIUM, \IntlDateFormatter::NONE) + ->willReturn('date'); + + $this->assertEquals('date', $this->commentsHistory->getItemCreatedAt($item)); + } + + public function testGetItemCreatedAtTime() + { + $date = new \DateTime; + $item = ['created_at' => $date ]; + + $this->localeDateMock->expects($this->once()) + ->method('formatDateTime') + ->with($date, \IntlDateFormatter::NONE, \IntlDateFormatter::MEDIUM) + ->willReturn('time'); + + $this->assertEquals('time', $this->commentsHistory->getItemCreatedAt($item, 'time')); + } + + public function testGetItemCreatedAtEmpty() + { + $item = ['title' => "Test" ]; + + $this->localeDateMock->expects($this->never())->method('formatDateTime'); + $this->assertEquals('', $this->commentsHistory->getItemCreatedAt($item)); + $this->assertEquals('', $this->commentsHistory->getItemCreatedAt($item, 'time')); + } } diff --git a/app/code/Magento/Ui/view/base/layout/default.xml b/app/code/Magento/Ui/view/base/layout/default.xml index 7f2efbd8558728f386856acb5dd38bd1c4dcbb31..64d5f1483a2f307b85966eccb316ad8ee782507a 100644 --- a/app/code/Magento/Ui/view/base/layout/default.xml +++ b/app/code/Magento/Ui/view/base/layout/default.xml @@ -5,7 +5,7 @@ * See COPYING.txt for license details. */ --> -<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="admin-1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> +<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <body> <referenceContainer name="after.body.start"> <block class="Magento\Ui\Block\Logger" name="logger" template="Magento_Ui::logger.phtml"/> diff --git a/dev/tests/integration/testsuite/Magento/Setup/Fixtures/FixtureModelTest.php b/dev/tests/integration/testsuite/Magento/Setup/Fixtures/FixtureModelTest.php index 358786901713b987d897e2147a6f574a590fc832..b47d45e3815e7c55334ca24ef73788a929497506 100644 --- a/dev/tests/integration/testsuite/Magento/Setup/Fixtures/FixtureModelTest.php +++ b/dev/tests/integration/testsuite/Magento/Setup/Fixtures/FixtureModelTest.php @@ -27,6 +27,14 @@ class FixtureModelTest extends \Magento\TestFramework\Indexer\TestCase public static function setUpBeforeClass() { + $db = \Magento\TestFramework\Helper\Bootstrap::getInstance()->getBootstrap() + ->getApplication() + ->getDbInstance(); + if (!$db->isDbDumpExists()) { + throw new \LogicException('DB dump does not exist.'); + } + $db->restoreFromDbDump(); + self::$_generatorWorkingDir = realpath(__DIR__ . '/../../../../../../../setup/src/Magento/Setup/Fixtures'); copy( self::$_generatorWorkingDir . '/tax_rates.csv', @@ -72,38 +80,4 @@ class FixtureModelTest extends \Magento\TestFramework\Indexer\TestCase ] ); } - - /** - * Apply fixture file - * - * @param string $fixtureFilename - */ - public function applyFixture($fixtureFilename) - { - require $fixtureFilename; - } - - /** - * Get object manager - * - * @return \Magento\Framework\ObjectManagerInterface - */ - public function getObjectManager() - { - if (!$this->_objectManager) { - $this->_objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); - } - return $this->_objectManager; - } - - /** - * Reset object manager - * - * @return \Magento\Framework\ObjectManagerInterface - */ - public function resetObjectManager() - { - $this->_objectManager = null; - return $this; - } } diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/CopyrightTest.php b/dev/tests/static/testsuite/Magento/Test/Legacy/CopyrightTest.php index 582a63ceb19ed8dbb079fdc19abb2358004d891a..a1ede987dac78a6f5de8a2519d481bb81490ac16 100644 --- a/dev/tests/static/testsuite/Magento/Test/Legacy/CopyrightTest.php +++ b/dev/tests/static/testsuite/Magento/Test/Legacy/CopyrightTest.php @@ -27,7 +27,7 @@ class CopyrightTest extends \PHPUnit_Framework_TestCase public function copyrightDataProvider() { - $blackList = include __DIR__ . '/_files/copyright/blacklist.php'; + $blackList = $this->getFilesData('blacklist*.php'); $changedFiles = []; foreach (glob(__DIR__ . '/../_files/changed_files*') as $listFile) { @@ -56,4 +56,18 @@ class CopyrightTest extends \PHPUnit_Framework_TestCase ); return $changedFiles; } + + /** + * @param string $filePattern + * @return array + */ + protected function getFilesData($filePattern) + { + $result = []; + foreach (glob(__DIR__ . '/_files/copyright/' . $filePattern) as $file) { + $fileData = include $file; + $result = array_merge($result, $fileData); + } + return $result; + } }