diff --git a/app/code/Magento/Backend/Model/Search/Config.php b/app/code/Magento/Backend/Model/Search/Config.php new file mode 100644 index 0000000000000..4272e24b2f084 --- /dev/null +++ b/app/code/Magento/Backend/Model/Search/Config.php @@ -0,0 +1,116 @@ +configStructure = $configStructure; + $this->resultBuilder = $resultBuilder; + } + + /** + * @param string $query + * @return $this + */ + public function setQuery($query) + { + $this->setData('query', $query); + return $this; + } + + /** + * @return string|null + */ + public function getQuery() + { + return $this->getData('query'); + } + + /** + * @return bool + */ + public function hasQuery() + { + return $this->hasData('query'); + } + + /** + * @param array $results + * @return $this + */ + public function setResults(array $results) + { + $this->setData('results', $results); + return $this; + } + + /** + * @return array|null + */ + public function getResults() + { + return $this->getData('results'); + } + + /** + * Load search results + * + * @return $this + */ + public function load() + { + $this->findInStructure($this->configStructure->getTabs(), $this->getQuery()); + $this->setResults($this->resultBuilder->getAll()); + return $this; + } + + /** + * @param ElementIterator $structureElementIterator + * @param string $searchTerm + * @param string $pathLabel + * @return void + * @SuppressWarnings(PHPMD.LongVariable) + */ + private function findInStructure(ElementIterator $structureElementIterator, $searchTerm, $pathLabel = '') + { + if (empty($searchTerm)) { + return; + } + foreach ($structureElementIterator as $structureElement) { + if (mb_stripos((string)$structureElement->getLabel(), $searchTerm) !== false) { + $this->resultBuilder->add($structureElement, $pathLabel); + } + $elementPathLabel = $pathLabel . ' / ' . $structureElement->getLabel(); + if ($structureElement instanceof AbstractComposite && $structureElement->hasChildren()) { + $this->findInStructure($structureElement->getChildren(), $searchTerm, $elementPathLabel); + } + } + } +} diff --git a/app/code/Magento/Backend/Model/Search/Config/Result/Builder.php b/app/code/Magento/Backend/Model/Search/Config/Result/Builder.php new file mode 100644 index 0000000000000..fd01e19119d54 --- /dev/null +++ b/app/code/Magento/Backend/Model/Search/Config/Result/Builder.php @@ -0,0 +1,78 @@ +urlBuilder = $urlBuilder; + $this->structureElementTypes = $structureElementTypes; + } + + /** + * @return array + */ + public function getAll() + { + return $this->results; + } + + /** + * @param StructureElementInterface $structureElement + * @param string $elementPathLabel + * @return void + */ + public function add(StructureElementInterface $structureElement, $elementPathLabel) + { + $urlParams = []; + $elementData = $structureElement->getData(); + + if (!in_array($elementData['_elementType'], array_keys($this->structureElementTypes))) { + return; + } + + if (isset($this->structureElementTypes[$elementData['_elementType']])) { + $urlParamsBuilder = $this->structureElementTypes[$elementData['_elementType']]; + $urlParams = $urlParamsBuilder->build($structureElement); + } + + $this->results[] = [ + 'id' => $structureElement->getPath(), + 'type' => null, + 'name' => (string)$structureElement->getLabel(), + 'description' => $elementPathLabel, + 'url' => $this->urlBuilder->getUrl('*/system_config/edit', $urlParams), + ]; + } +} diff --git a/app/code/Magento/Backend/Model/Search/Config/Structure/Element/Builder/Field.php b/app/code/Magento/Backend/Model/Search/Config/Structure/Element/Builder/Field.php new file mode 100644 index 0000000000000..96cde2a4ff4db --- /dev/null +++ b/app/code/Magento/Backend/Model/Search/Config/Structure/Element/Builder/Field.php @@ -0,0 +1,25 @@ +getPath()); + return [ + 'section' => $elementPathParts[0], + 'group' => $elementPathParts[1], + 'field' => $structureElement->getId(), + ]; + } +} diff --git a/app/code/Magento/Backend/Model/Search/Config/Structure/Element/Builder/Group.php b/app/code/Magento/Backend/Model/Search/Config/Structure/Element/Builder/Group.php new file mode 100644 index 0000000000000..f6a6e35463aa8 --- /dev/null +++ b/app/code/Magento/Backend/Model/Search/Config/Structure/Element/Builder/Group.php @@ -0,0 +1,24 @@ +getPath()); + return [ + 'section' => $elementPathParts[0], + 'group' => $elementPathParts[1], + ]; + } +} diff --git a/app/code/Magento/Backend/Model/Search/Config/Structure/Element/Builder/Section.php b/app/code/Magento/Backend/Model/Search/Config/Structure/Element/Builder/Section.php new file mode 100644 index 0000000000000..0d67f13c931bd --- /dev/null +++ b/app/code/Magento/Backend/Model/Search/Config/Structure/Element/Builder/Section.php @@ -0,0 +1,21 @@ +getPath()); + return ['section' => $elementPathParts[1]]; + } +} diff --git a/app/code/Magento/Backend/Model/Search/Config/Structure/ElementBuilderInterface.php b/app/code/Magento/Backend/Model/Search/Config/Structure/ElementBuilderInterface.php new file mode 100644 index 0000000000000..86b796355946d --- /dev/null +++ b/app/code/Magento/Backend/Model/Search/Config/Structure/ElementBuilderInterface.php @@ -0,0 +1,17 @@ +urlBuilderMock = $this->getMockForAbstractClass(UrlInterface::class); + $this->structureElementMock = $this->getMockForAbstractClass(StructureElementInterface::class); + $this->structureElementUrlParamsBuilderMock = $this->getMockForAbstractClass(ElementBuilderInterface::class); + $this->model = new Builder($this->urlBuilderMock, ['section' => $this->structureElementUrlParamsBuilderMock]); + } + + public function testAddWithNotSupportedStructureElementReturnsNothing() + { + $this->structureElementMock + ->expects($this->once()) + ->method('getData') + ->will($this->returnValue(['_elementType' => 'not_declared_structure_element_type'])); + $this->model->add($this->structureElementMock, ''); + $this->assertEquals([], $this->model->getAll()); + } + + public function testAddWithSupportedStructureElements() + { + $structureElementPath = '/section_code'; + $structureElementLabel = 'Section Label'; + $buildUrlParams = ['param_key' => 'param_value']; + $generatedUrl = 'http://example.com'; + + $expectedSearchResult = [ + [ + 'id' => $structureElementPath, + 'type' => null, + 'name' => 'Section Label', + 'description' => 'Section Label', + 'url' => 'http://example.com', + ], + ]; + + $this->structureElementMock + ->expects($this->once()) + ->method('getData') + ->willReturn(['_elementType' => 'section']); + $this->structureElementMock + ->expects($this->once()) + ->method('getPath') + ->willReturn($structureElementPath); + $this->structureElementMock + ->expects($this->once()) + ->method('getLabel') + ->willReturn($structureElementLabel); + + $this->structureElementUrlParamsBuilderMock->expects($this->once()) + ->method('build') + ->willReturn($buildUrlParams); + + $this->urlBuilderMock + ->expects($this->once()) + ->method('getUrl') + ->with('*/system_config/edit', $buildUrlParams) + ->will($this->returnValue($generatedUrl)); + + $this->model->add($this->structureElementMock, $structureElementLabel); + $this->assertEquals($expectedSearchResult, $this->model->getAll()); + } +} diff --git a/app/code/Magento/Backend/Test/Unit/Model/Search/Config/Structure/Element/Builder/FieldTest.php b/app/code/Magento/Backend/Test/Unit/Model/Search/Config/Structure/Element/Builder/FieldTest.php new file mode 100644 index 0000000000000..2e712ff867887 --- /dev/null +++ b/app/code/Magento/Backend/Test/Unit/Model/Search/Config/Structure/Element/Builder/FieldTest.php @@ -0,0 +1,51 @@ +structureElementMock = $this->getMockForAbstractClass(StructureElementInterface::class); + $this->model = new Field(); + } + + public function testBuild() + { + $structureElementId = 42; + $structureElementPath = 'path_part_1/path_part_2'; + + $this->structureElementMock->expects($this->once()) + ->method('getId') + ->willReturn($structureElementId); + $this->structureElementMock->expects($this->once()) + ->method('getPath') + ->willReturn($structureElementPath); + $this->assertEquals( + [ + 'section' => 'path_part_1', + 'group' => 'path_part_2', + 'field' => $structureElementId, + ], + $this->model->build($this->structureElementMock) + ); + } +} diff --git a/app/code/Magento/Backend/Test/Unit/Model/Search/Config/Structure/Element/Builder/GroupTest.php b/app/code/Magento/Backend/Test/Unit/Model/Search/Config/Structure/Element/Builder/GroupTest.php new file mode 100644 index 0000000000000..1640588678f4e --- /dev/null +++ b/app/code/Magento/Backend/Test/Unit/Model/Search/Config/Structure/Element/Builder/GroupTest.php @@ -0,0 +1,48 @@ +structureElementMock = $this->getMockForAbstractClass(StructureElementInterface::class); + $this->model = new Group(); + } + + public function testBuild() + { + $structureElementPath = 'path_part_1/path_part_2'; + + $this->structureElementMock->expects($this->never()) + ->method('getId'); + $this->structureElementMock->expects($this->once()) + ->method('getPath') + ->willReturn($structureElementPath); + $this->assertEquals( + [ + 'section' => 'path_part_1', + 'group' => 'path_part_2', + ], + $this->model->build($this->structureElementMock) + ); + } +} diff --git a/app/code/Magento/Backend/Test/Unit/Model/Search/Config/Structure/Element/Builder/SectionTest.php b/app/code/Magento/Backend/Test/Unit/Model/Search/Config/Structure/Element/Builder/SectionTest.php new file mode 100644 index 0000000000000..68365ff7f0c93 --- /dev/null +++ b/app/code/Magento/Backend/Test/Unit/Model/Search/Config/Structure/Element/Builder/SectionTest.php @@ -0,0 +1,42 @@ +structureElementMock = $this->getMockForAbstractClass(StructureElementInterface::class); + $this->model = new Section(); + } + + public function testBuild() + { + $structureElementPath = '/path_part_1'; + + $this->structureElementMock->expects($this->never()) + ->method('getId'); + $this->structureElementMock->expects($this->once()) + ->method('getPath') + ->willReturn($structureElementPath); + $this->assertEquals(['section' => 'path_part_1'], $this->model->build($this->structureElementMock)); + } +} diff --git a/app/code/Magento/Backend/etc/adminhtml/di.xml b/app/code/Magento/Backend/etc/adminhtml/di.xml index 5154c4eb56c91..050115087c26e 100644 --- a/app/code/Magento/Backend/etc/adminhtml/di.xml +++ b/app/code/Magento/Backend/etc/adminhtml/di.xml @@ -147,4 +147,13 @@ + + + + Magento\Backend\Model\Search\Config\Structure\Element\Builder\Section + Magento\Backend\Model\Search\Config\Structure\Element\Builder\Group + Magento\Backend\Model\Search\Config\Structure\Element\Builder\Field + + + diff --git a/app/code/Magento/Backend/etc/di.xml b/app/code/Magento/Backend/etc/di.xml index c4a624fe7b8f2..c526703da9975 100644 --- a/app/code/Magento/Backend/etc/di.xml +++ b/app/code/Magento/Backend/etc/di.xml @@ -99,6 +99,10 @@ Magento\Backend\Model\Search\Order Magento_Sales::sales + + Magento\Backend\Model\Search\Config + Magento_Config::config + diff --git a/app/code/Magento/Backend/i18n/en_US.csv b/app/code/Magento/Backend/i18n/en_US.csv index 2730d4d92835b..36db734d44cd4 100644 --- a/app/code/Magento/Backend/i18n/en_US.csv +++ b/app/code/Magento/Backend/i18n/en_US.csv @@ -458,3 +458,4 @@ Pagination,Pagination "Alternative text for the next pages link in the pagination menu. If empty, default arrow image is used.","Alternative text for the next pages link in the pagination menu. If empty, default arrow image is used." "Anchor Text for Next","Anchor Text for Next" "Theme Name","Theme Name" +"Config","Config" diff --git a/app/code/Magento/Config/Block/System/Config/Edit.php b/app/code/Magento/Config/Block/System/Config/Edit.php index 23acfc1ec628c..ba27cb33b20f0 100644 --- a/app/code/Magento/Config/Block/System/Config/Edit.php +++ b/app/code/Magento/Config/Block/System/Config/Edit.php @@ -11,6 +11,9 @@ */ namespace Magento\Config\Block\System\Config; +use \Magento\Framework\App\ObjectManager; +use \Magento\Framework\Serialize\Serializer\Json; + /** * @api * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -41,17 +44,25 @@ class Edit extends \Magento\Backend\Block\Widget */ protected $_configStructure; + /** + * @var \Magento\Framework\Serialize\Serializer\Json + */ + private $jsonSerializer; + /** * @param \Magento\Backend\Block\Template\Context $context * @param \Magento\Config\Model\Config\Structure $configStructure * @param array $data + * @param Json|null $jsonSerializer */ public function __construct( \Magento\Backend\Block\Template\Context $context, \Magento\Config\Model\Config\Structure $configStructure, - array $data = [] + array $data = [], + Json $jsonSerializer = null ) { $this->_configStructure = $configStructure; + $this->jsonSerializer = $jsonSerializer ?: ObjectManager::getInstance()->get(Json::class); parent::__construct($context, $data); } @@ -107,4 +118,22 @@ public function getSaveUrl() { return $this->getUrl('*/system_config/save', ['_current' => true]); } + + /** + * @return string + */ + public function getConfigSearchParamsJson() + { + $params = []; + if ($this->getRequest()->getParam('section')) { + $params['section'] = $this->getRequest()->getParam('section'); + } + if ($this->getRequest()->getParam('group')) { + $params['group'] = $this->getRequest()->getParam('group'); + } + if ($this->getRequest()->getParam('field')) { + $params['field'] = $this->getRequest()->getParam('field'); + } + return $this->jsonSerializer->serialize($params); + } } diff --git a/app/code/Magento/Config/Model/Config/Structure/AbstractElement.php b/app/code/Magento/Config/Model/Config/Structure/AbstractElement.php index 0f625ba9fff0e..78025587c49ba 100644 --- a/app/code/Magento/Config/Model/Config/Structure/AbstractElement.php +++ b/app/code/Magento/Config/Model/Config/Structure/AbstractElement.php @@ -5,6 +5,7 @@ */ namespace Magento\Config\Model\Config\Structure; +use Magento\Config\Model\Config\StructureElementInterface; use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Store\Model\StoreManagerInterface; use Magento\Framework\App\ObjectManager; @@ -13,7 +14,7 @@ * @api * @since 100.0.2 */ -abstract class AbstractElement implements ElementInterface +abstract class AbstractElement implements StructureElementInterface { /** * Element data diff --git a/app/code/Magento/Config/Model/Config/Structure/Element/Iterator.php b/app/code/Magento/Config/Model/Config/Structure/Element/Iterator.php index fc5c8b769c88b..f53ecd710b28c 100644 --- a/app/code/Magento/Config/Model/Config/Structure/Element/Iterator.php +++ b/app/code/Magento/Config/Model/Config/Structure/Element/Iterator.php @@ -14,7 +14,7 @@ class Iterator implements \Iterator /** * List of element data * - * @var \Magento\Config\Model\Config\Structure\ElementInterface[] + * @var \Magento\Config\Model\Config\StructureElementInterface[] */ protected $_elements; @@ -67,7 +67,7 @@ public function setElements(array $elements, $scope) /** * Return the current element * - * @return \Magento\Config\Model\Config\Structure\ElementInterface + * @return \Magento\Config\Model\Config\StructureElementInterface */ public function current() { diff --git a/app/code/Magento/Config/Model/Config/Structure/ElementInterface.php b/app/code/Magento/Config/Model/Config/Structure/ElementInterface.php index ca3548ac39fdb..5ba6221601725 100644 --- a/app/code/Magento/Config/Model/Config/Structure/ElementInterface.php +++ b/app/code/Magento/Config/Model/Config/Structure/ElementInterface.php @@ -5,9 +5,13 @@ */ namespace Magento\Config\Model\Config\Structure; +use Magento\Config\Model\Config\StructureElementInterface; + /** * @api * @since 100.0.2 + * @deprecated + * @see StructureElementInterface */ interface ElementInterface { diff --git a/app/code/Magento/Config/Model/Config/StructureElementInterface.php b/app/code/Magento/Config/Model/Config/StructureElementInterface.php new file mode 100644 index 0000000000000..946d6e3c766a4 --- /dev/null +++ b/app/code/Magento/Config/Model/Config/StructureElementInterface.php @@ -0,0 +1,20 @@ +_systemConfigMock = $this->createMock(\Magento\Config\Model\Config\Structure::class); @@ -67,12 +72,15 @@ protected function setUp() $this->returnValue($this->_sectionMock) ); + $this->_jsonMock = $this->createMock(\Magento\Framework\Serialize\Serializer\Json::class); + $data = [ 'data' => ['systemConfig' => $this->_systemConfigMock], 'request' => $this->_requestMock, 'layout' => $this->_layoutMock, 'urlBuilder' => $this->_urlModelMock, 'configStructure' => $this->_systemConfigMock, + 'jsonSerializer' => $this->_jsonMock, ]; $helper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); @@ -164,4 +172,85 @@ public function testPrepareLayout() $this->_object->setNameInLayout($expectedBlock); $this->_object->setLayout($this->_layoutMock); } + + /** + * @param array $requestData + * @param array $expected + * @dataProvider getConfigSearchParamsJsonData + */ + public function testGetConfigSearchParamsJson(array $requestData, array $expected) + { + $requestMock = $this->createMock(\Magento\Framework\App\RequestInterface::class); + + $requestMock->expects($this->any()) + ->method('getParam') + ->will($this->returnValueMap($requestData)); + $this->_jsonMock->expects($this->once()) + ->method('serialize') + ->with($expected); + + $data = [ + 'data' => ['systemConfig' => $this->_systemConfigMock], + 'request' => $requestMock, + 'layout' => $this->_layoutMock, + 'urlBuilder' => $this->_urlModelMock, + 'configStructure' => $this->_systemConfigMock, + 'jsonSerializer' => $this->_jsonMock, + ]; + + $helper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $object = $helper->getObject(\Magento\Config\Block\System\Config\Edit::class, $data); + + $object->getConfigSearchParamsJson(); + } + + /** + * @return array + */ + public function getConfigSearchParamsJsonData() + { + return [ + [ + [ + ['section', null, null], + ['group', null, null], + ['field', null, null], + ], + [], + ], + [ + [ + ['section', null, 'section_code'], + ['group', null, null], + ['field', null, null], + ], + [ + 'section' => 'section_code', + ], + ], + [ + [ + ['section', null, 'section_code'], + ['group', null, 'group_code'], + ['field', null, null], + ], + [ + 'section' => 'section_code', + 'group' => 'group_code', + ], + ], + [ + [ + ['section', null, 'section_code'], + ['group', null, 'group_code'], + ['field', null, 'field_code'], + ], + [ + 'section' => 'section_code', + 'group' => 'group_code', + 'field' => 'field_code', + ], + ], + ]; + } } diff --git a/app/code/Magento/Config/view/adminhtml/templates/system/config/edit.phtml b/app/code/Magento/Config/view/adminhtml/templates/system/config/edit.phtml index 9bdca2bdfd280..82305c956ee7a 100644 --- a/app/code/Magento/Config/view/adminhtml/templates/system/config/edit.phtml +++ b/app/code/Magento/Config/view/adminhtml/templates/system/config/edit.phtml @@ -14,8 +14,14 @@ * getSaveUrl() - string * getSections() - array * getForm() - html + * getConfigSearchParamsJson() - string */ ?> +
getBlockHtml('formkey') ?>
@@ -30,10 +36,41 @@ require([ "mage/mage", "prototype", "mage/adminhtml/form", - "domReady!" + "domReady!", + "jquery/ui" ], function(jQuery, registry){ var adminSystemConfig = { + navigateToElement: function (searchRequest) { + if ('section' in searchRequest) { + var section = searchRequest.section; + } + if ('group' in searchRequest) { + var group = searchRequest.group; + } + if ('field' in searchRequest) { + var field = searchRequest.field; + } + if (typeof section === 'undefined') { + return; + } + if (typeof group !== 'undefined') { + var groupElement = jQuery('#' + section + '_' + group); + + var parentSection = groupElement.parents('.section-config'); + if (!parentSection.hasClass('active')) { + Fieldset.toggleCollapse(section + '_' + group); + } + } + if ((typeof group !== 'undefined') && (typeof field !== 'undefined')) { + var fieldElement = jQuery('#' + section + '_' + group + '_' + field); + fieldElement.focus(); + fieldElement.addClass('highlighted'); + setTimeout(function() { + fieldElement.removeClass('highlighted', 2000, "easeInBack"); + }, 3000); + } + }, getUp: function (element, tag) { var $element = Element.extend(element); if (typeof $element.upTag == 'undefined') { @@ -350,5 +387,7 @@ require([ handleHash(); registry.set('adminSystemConfig', adminSystemConfig); + + adminSystemConfig.navigateToElement(getConfigSearchParamsJson(); ?>); }); diff --git a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_search.less b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_search.less index 3265c8b2fc387..5e65faec60d4e 100644 --- a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_search.less +++ b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_search.less @@ -80,6 +80,8 @@ box-shadow: @component__box-shadow__base; left: 0; margin-top: -2px; + max-height: 80vh; + overflow: auto; padding: 0; position: absolute; right: 0; diff --git a/dev/tests/integration/testsuite/Magento/Backend/Model/Search/AuthorizationMock.php b/dev/tests/integration/testsuite/Magento/Backend/Model/Search/AuthorizationMock.php new file mode 100644 index 0000000000000..3f6a57c122ffd --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Backend/Model/Search/AuthorizationMock.php @@ -0,0 +1,25 @@ +getConfigSearchInstance(); + $configSearch->setQuery($query); + $configSearch->load(); + + /** SUT Execution */ + $searchResults = $configSearch->getResults(); + + /** Ensure that search results are correct */ + $this->assertCount(count($expectedResult), $searchResults, 'Quantity of search result items is invalid.'); + foreach ($expectedResult as $itemIndex => $expectedItem) { + /** Validate URL to item */ + $elementPathParts = explode('/', $expectedItem['id']); + // filter empty values + $elementPathParts = array_values(array_filter($elementPathParts)); + foreach ($elementPathParts as $elementPathPart) { + $this->assertContains($elementPathPart, $searchResults[$itemIndex]['url'], 'Item URL is invalid.'); + } + unset($searchResults[$itemIndex]['url']); + + /** Validate other item data */ + $this->assertEquals($expectedItem, $searchResults[$itemIndex], "Data of item #$itemIndex is invalid."); + } + } + + /** + * @return \Magento\Backend\Model\Search\Config + */ + private function getConfigSearchInstance() + { + Bootstrap::getInstance()->reinitialize([ + State::PARAM_BAN_CACHE => true, + ]); + Bootstrap::getObjectManager() + ->get(ScopeInterface::class) + ->setCurrentScope(FrontNameResolver::AREA_CODE); + Bootstrap::getObjectManager()->get(AreaList::class) + ->getArea(FrontNameResolver::AREA_CODE) + ->load(Area::PART_CONFIG); + + Bootstrap::getObjectManager()->configure([ + 'preferences' => [ + AuthorizationInterface::class => \Magento\Backend\Model\Search\AuthorizationMock::class + ] + ]); + + $fileResolverMock = $this->getMockBuilder(FileResolver::class)->disableOriginalConstructor()->getMock(); + $fileIteratorFactory = Bootstrap::getObjectManager()->get(FileIteratorFactory::class); + $fileIterator = $fileIteratorFactory->create( + [__DIR__ . '/_files/test_config.xml'] + ); + $fileResolverMock->expects($this->any())->method('get')->will($this->returnValue($fileIterator)); + + $objectManager = Bootstrap::getObjectManager(); + /** @var \Magento\Config\Model\Config\Structure\Reader $structureReader */ + $structureReader = $objectManager->create( + \Magento\Config\Model\Config\Structure\Reader::class, + ['fileResolver' => $fileResolverMock] + ); + /** @var \Magento\Config\Model\Config\Structure\Data $structureData */ + $structureData = $objectManager->create( + \Magento\Config\Model\Config\Structure\Data::class, + ['reader' => $structureReader] + ); + /** @var \Magento\Config\Model\Config\Structure $structure */ + $structure = $objectManager->create( + \Magento\Config\Model\Config\Structure::class, + ['structureData' => $structureData] + ); + + return $objectManager->create( + \Magento\Backend\Model\Search\Config::class, + ['configStructure' => $structure] + ); + } + + /** + * @return array + */ + public static function loadDataProvider() + { + return [ + 'Search by field name' => [ + 'Test Field', + [ + [ + 'id' => 'test_section/test_group/test_field_1', + 'type' => null, + 'name' => 'Test Field', + 'description' => ' / Test Tab / Test Section / Test Group', + ], + [ + 'id' => 'test_section/test_group/test_field_2', + 'type' => null, + 'name' => 'Test Field', + 'description' => ' / Test Tab / Test Section / Test Group', + ], + ], + ], + 'Search by group name' => [ + 'Test Group', + [ + [ + 'id' => 'test_section/test_group', + 'type' => null, + 'name' => 'Test Group', + 'description' => ' / Test Tab / Test Section', + ], + ], + ], + 'Search by section name' => [ + 'Test Section', + [ + [ + 'id' => '/test_section', + 'type' => null, + 'name' => 'Test Section', + 'description' => ' / Test Tab', + ], + ], + ], + ]; + } +} diff --git a/dev/tests/integration/testsuite/Magento/Backend/Model/Search/_files/test_config.xml b/dev/tests/integration/testsuite/Magento/Backend/Model/Search/_files/test_config.xml new file mode 100644 index 0000000000000..a0688213aa549 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Backend/Model/Search/_files/test_config.xml @@ -0,0 +1,28 @@ + + + + + + + +
+ + test + Magento_Backend::test + + + + + + + + + +
+
+