Skip to content

Commit f175469

Browse files
author
Alexander Akimov
authored
Merge pull request magento#198 from magento-dragons/PR-8
[Dragons] Bug Fixes
2 parents c800ca3 + f818be8 commit f175469

File tree

14 files changed

+467
-38
lines changed

14 files changed

+467
-38
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
/**
3+
* Copyright © 2016 Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Catalog\Api;
7+
8+
/**
9+
* @api
10+
*/
11+
interface CategoryListInterface
12+
{
13+
/**
14+
* Get category list
15+
*
16+
* @param \Magento\Framework\Api\SearchCriteriaInterface $searchCriteria
17+
* @return \Magento\Catalog\Api\Data\CategorySearchResultsInterface
18+
*/
19+
public function getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCriteria);
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
/**
3+
* Copyright © 2016 Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Catalog\Api\Data;
7+
8+
use Magento\Framework\Api\SearchResultsInterface;
9+
10+
/**
11+
* @api
12+
*/
13+
interface CategorySearchResultsInterface extends SearchResultsInterface
14+
{
15+
/**
16+
* Get categories
17+
*
18+
* @return \Magento\Catalog\Api\Data\CategoryInterface[]
19+
*/
20+
public function getItems();
21+
22+
/**
23+
* Set categories
24+
*
25+
* @param \Magento\Catalog\Api\Data\CategoryInterface[] $items
26+
* @return $this
27+
*/
28+
public function setItems(array $items);
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
<?php
2+
/**
3+
* Copyright © 2016 Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Catalog\Model;
7+
8+
use Magento\Catalog\Api\CategoryListInterface;
9+
use Magento\Catalog\Api\CategoryRepositoryInterface;
10+
use Magento\Catalog\Api\Data\CategorySearchResultsInterface;
11+
use Magento\Catalog\Api\Data\CategorySearchResultsInterfaceFactory;
12+
use Magento\Catalog\Model\ResourceModel\Category\Collection;
13+
use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory;
14+
use Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface;
15+
use Magento\Framework\Api\Search\FilterGroup;
16+
use Magento\Framework\Api\SearchCriteriaInterface;
17+
use Magento\Framework\Api\SortOrder;
18+
use Magento\Framework\App\ObjectManager;
19+
20+
class CategoryList implements CategoryListInterface
21+
{
22+
/**
23+
* @var CollectionFactory
24+
*/
25+
private $categoryCollectionFactory;
26+
27+
/**
28+
* @var JoinProcessorInterface
29+
*/
30+
private $extensionAttributesJoinProcessor;
31+
32+
/**
33+
* @var CategorySearchResultsInterfaceFactory
34+
*/
35+
private $categorySearchResultsFactory;
36+
37+
/**
38+
* @var CategoryRepositoryInterface
39+
*/
40+
private $categoryRepository;
41+
42+
/**
43+
* @param CollectionFactory $categoryCollectionFactory
44+
* @param JoinProcessorInterface $extensionAttributesJoinProcessor
45+
* @param CategorySearchResultsInterfaceFactory $categorySearchResultsFactory
46+
* @param CategoryRepositoryInterface $categoryRepository
47+
*/
48+
public function __construct(
49+
CollectionFactory $categoryCollectionFactory,
50+
JoinProcessorInterface $extensionAttributesJoinProcessor,
51+
CategorySearchResultsInterfaceFactory $categorySearchResultsFactory,
52+
CategoryRepositoryInterface $categoryRepository
53+
) {
54+
$this->categoryCollectionFactory = $categoryCollectionFactory;
55+
$this->extensionAttributesJoinProcessor = $extensionAttributesJoinProcessor;
56+
$this->categorySearchResultsFactory = $categorySearchResultsFactory;
57+
$this->categoryRepository = $categoryRepository;
58+
}
59+
60+
/**
61+
* {@inheritdoc}
62+
*/
63+
public function getList(SearchCriteriaInterface $searchCriteria)
64+
{
65+
/** @var Collection $collection */
66+
$collection = $this->categoryCollectionFactory->create();
67+
$this->extensionAttributesJoinProcessor->process($collection);
68+
69+
foreach ($searchCriteria->getFilterGroups() as $group) {
70+
$this->addFilterGroupToCollection($group, $collection);
71+
}
72+
73+
/** @var SortOrder $sortOrder */
74+
$sortOrders = $searchCriteria->getSortOrders();
75+
if ($sortOrders) {
76+
foreach ($sortOrders as $sortOrder) {
77+
$collection->addOrder(
78+
$sortOrder->getField(),
79+
($sortOrder->getDirection() === SortOrder::SORT_ASC) ? SortOrder::SORT_ASC : SortOrder::SORT_DESC
80+
);
81+
}
82+
}
83+
84+
$collection->setCurPage($searchCriteria->getCurrentPage());
85+
$collection->setPageSize($searchCriteria->getPageSize());
86+
87+
$items = [];
88+
foreach ($collection->getAllIds() as $id) {
89+
$items[] = $this->categoryRepository->get($id);
90+
}
91+
92+
/** @var CategorySearchResultsInterface $searchResult */
93+
$searchResult = $this->categorySearchResultsFactory->create();
94+
$searchResult->setSearchCriteria($searchCriteria);
95+
$searchResult->setItems($items);
96+
$searchResult->setTotalCount($collection->getSize());
97+
return $searchResult;
98+
}
99+
100+
/**
101+
* Add filter group to collection
102+
*
103+
* @param FilterGroup $filterGroup
104+
* @param Collection $collection
105+
* @return void
106+
*/
107+
private function addFilterGroupToCollection(FilterGroup $filterGroup, Collection $collection)
108+
{
109+
$filters = $filterGroup->getFilters();
110+
if ($filters) {
111+
$fields = [];
112+
foreach ($filters as $filter) {
113+
$conditionType = $filter->getConditionType() ? $filter->getConditionType() : 'eq';
114+
$fields[] = ['attribute' => $filter->getField(), $conditionType => $filter->getValue()];
115+
}
116+
$collection->addFieldToFilter($fields);
117+
}
118+
}
119+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
<?php
2+
/**
3+
* Copyright © 2016 Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Catalog\Test\Unit\Model;
7+
8+
use Magento\Catalog\Api\CategoryRepositoryInterface;
9+
use Magento\Catalog\Api\Data\CategorySearchResultsInterface;
10+
use Magento\Catalog\Model\Category;
11+
use Magento\Catalog\Model\CategoryList;
12+
use Magento\Catalog\Model\ResourceModel\Category\Collection;
13+
use Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface;
14+
use Magento\Framework\Api\Filter;
15+
use Magento\Framework\Api\Search\FilterGroup;
16+
use Magento\Framework\Api\SearchCriteriaInterface;
17+
use Magento\Framework\Api\SortOrder;
18+
use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory;
19+
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
20+
use Magento\Catalog\Api\Data\CategorySearchResultsInterfaceFactory;
21+
22+
/**
23+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
24+
*/
25+
class CategoryListTest extends \PHPUnit_Framework_TestCase
26+
{
27+
/**
28+
* @var CategoryList
29+
*/
30+
protected $model;
31+
32+
/**
33+
* @var CollectionFactory|\PHPUnit_Framework_MockObject_MockObject
34+
*/
35+
private $categoryCollectionFactory;
36+
37+
/**
38+
* @var JoinProcessorInterface|\PHPUnit_Framework_MockObject_MockObject
39+
*/
40+
private $extensionAttributesJoinProcessor;
41+
42+
/**
43+
* @var CategorySearchResultsInterfaceFactory|\PHPUnit_Framework_MockObject_MockObject
44+
*/
45+
private $categorySearchResultsFactory;
46+
47+
/**
48+
* @var CategoryRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject
49+
*/
50+
private $categoryRepository;
51+
52+
protected function setUp()
53+
{
54+
$this->categoryCollectionFactory = $this->getMockBuilder(CollectionFactory::class)
55+
->disableOriginalConstructor()
56+
->setMethods(['create'])
57+
->getMock();
58+
$this->extensionAttributesJoinProcessor = $this->getMock(JoinProcessorInterface::class);
59+
$this->categorySearchResultsFactory = $this->getMockBuilder(CategorySearchResultsInterfaceFactory::class)
60+
->disableOriginalConstructor()
61+
->setMethods(['create'])
62+
->getMock();
63+
$this->categoryRepository = $this->getMock(CategoryRepositoryInterface::class);
64+
65+
$this->model = (new ObjectManager($this))->getObject(
66+
CategoryList::class,
67+
[
68+
'categoryCollectionFactory' => $this->categoryCollectionFactory,
69+
'extensionAttributesJoinProcessor' => $this->extensionAttributesJoinProcessor,
70+
'categorySearchResultsFactory' => $this->categorySearchResultsFactory,
71+
'categoryRepository' => $this->categoryRepository,
72+
]
73+
);
74+
}
75+
76+
public function testGetList()
77+
{
78+
$fieldName = 'field_1';
79+
$value = 'value_1';
80+
$conditionType = 'eq';
81+
$currentPage = 2;
82+
$pageSize = 1;
83+
$totalCount = 2;
84+
$categoryIdFirst = 1;
85+
$categoryIdSecond = 2;
86+
87+
$categoryFirst = $this->getMockBuilder(Category::class)->disableOriginalConstructor()->getMock();
88+
$categorySecond = $this->getMockBuilder(Category::class)->disableOriginalConstructor()->getMock();
89+
90+
$filter = $this->getMockBuilder(Filter::class)->disableOriginalConstructor()->getMock();
91+
$filter->expects($this->atLeastOnce())->method('getConditionType')->willReturn($conditionType);
92+
$filter->expects($this->atLeastOnce())->method('getField')->willReturn($fieldName);
93+
$filter->expects($this->once())->method('getValue')->willReturn($value);
94+
95+
$filterGroup = $this->getMockBuilder(FilterGroup::class)->disableOriginalConstructor()->getMock();
96+
$filterGroup->expects($this->once())->method('getFilters')->willReturn([$filter]);
97+
98+
$sortOrder = $this->getMockBuilder(SortOrder::class)->disableOriginalConstructor()->getMock();
99+
$sortOrder->expects($this->once())->method('getField')->willReturn($fieldName);
100+
$sortOrder->expects($this->once())->method('getDirection')->willReturn(SortOrder::SORT_ASC);
101+
102+
/** @var SearchCriteriaInterface|\PHPUnit_Framework_MockObject_MockObject $searchCriteria */
103+
$searchCriteria = $this->getMock(SearchCriteriaInterface::class);
104+
$searchCriteria->expects($this->once())->method('getFilterGroups')->willReturn([$filterGroup]);
105+
$searchCriteria->expects($this->once())->method('getCurrentPage')->willReturn($currentPage);
106+
$searchCriteria->expects($this->once())->method('getPageSize')->willReturn($pageSize);
107+
$searchCriteria->expects($this->once())->method('getSortOrders')->willReturn([$sortOrder]);
108+
109+
$collection = $this->getMockBuilder(Collection::class)->disableOriginalConstructor()->getMock();
110+
$collection->expects($this->once())
111+
->method('addFieldToFilter')
112+
->with([['attribute' => $fieldName, $conditionType => $value]]);
113+
$collection->expects($this->once())->method('addOrder')->with($fieldName, SortOrder::SORT_ASC);
114+
$collection->expects($this->once())->method('setCurPage')->with($currentPage);
115+
$collection->expects($this->once())->method('setPageSize')->with($pageSize);
116+
$collection->expects($this->once())->method('getSize')->willReturn($totalCount);
117+
$collection->expects($this->once())->method('getAllIds')->willReturn([$categoryIdFirst, $categoryIdSecond]);
118+
119+
$searchResult = $this->getMock(CategorySearchResultsInterface::class);
120+
$searchResult->expects($this->once())->method('setSearchCriteria')->with($searchCriteria);
121+
$searchResult->expects($this->once())->method('setItems')->with([$categoryFirst, $categorySecond]);
122+
$searchResult->expects($this->once())->method('setTotalCount')->with($totalCount);
123+
124+
$this->categoryRepository->expects($this->exactly(2))
125+
->method('get')
126+
->willReturnMap([
127+
[$categoryIdFirst, $categoryFirst],
128+
[$categoryIdSecond, $categorySecond],
129+
])
130+
->willReturn($categoryFirst);
131+
132+
$this->categorySearchResultsFactory->expects($this->once())->method('create')->willReturn($searchResult);
133+
$this->categoryCollectionFactory->expects($this->once())->method('create')->willReturn($collection);
134+
$this->extensionAttributesJoinProcessor->expects($this->once())->method('process')->with($collection);
135+
136+
$this->assertEquals($searchResult, $this->model->getList($searchCriteria));
137+
}
138+
}

app/code/Magento/Catalog/Test/Unit/Model/CategoryRepositoryTest.php

+15-31
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,15 @@
55
*/
66
namespace Magento\Catalog\Test\Unit\Model;
77

8+
use Magento\Catalog\Model\Category;
9+
use Magento\Catalog\Model\CategoryRepository;
10+
use Magento\Catalog\Model\ResourceModel\Category\Collection;
11+
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
12+
813
class CategoryRepositoryTest extends \PHPUnit_Framework_TestCase
914
{
1015
/**
11-
* @var \Magento\Catalog\Model\CategoryRepository
16+
* @var CategoryRepository
1217
*/
1318
protected $model;
1419

@@ -88,21 +93,16 @@ protected function setUp()
8893
->with(\Magento\Catalog\Api\Data\CategoryInterface::class)
8994
->willReturn($metadataMock);
9095

91-
$this->model = new \Magento\Catalog\Model\CategoryRepository(
92-
$this->categoryFactoryMock,
93-
$this->categoryResourceMock,
94-
$this->storeManagerMock
96+
$this->model = (new ObjectManager($this))->getObject(
97+
CategoryRepository::class,
98+
[
99+
'categoryFactory' => $this->categoryFactoryMock,
100+
'categoryResource' => $this->categoryResourceMock,
101+
'storeManager' => $this->storeManagerMock,
102+
'metadataPool' => $this->metadataPoolMock,
103+
'extensibleDataObjectConverter' => $this->extensibleDataObjectConverterMock,
104+
]
95105
);
96-
97-
$this->setProperties($this->model, [
98-
'metadataPool' => $this->metadataPoolMock
99-
]);
100-
101-
// Todo: \Magento\Framework\TestFramework\Unit\Helper\ObjectManager to do this automatically (MAGETWO-49793)
102-
$reflection = new \ReflectionClass(get_class($this->model));
103-
$reflectionProperty = $reflection->getProperty('extensibleDataObjectConverter');
104-
$reflectionProperty->setAccessible(true);
105-
$reflectionProperty->setValue($this->model, $this->extensibleDataObjectConverterMock);
106106
}
107107

108108
public function testGet()
@@ -370,20 +370,4 @@ public function testDeleteByIdentifierWithException()
370370
);
371371
$this->model->deleteByIdentifier($categoryId);
372372
}
373-
374-
/**
375-
* @param $object
376-
* @param array $properties
377-
*/
378-
private function setProperties($object, $properties = [])
379-
{
380-
$reflectionClass = new \ReflectionClass(get_class($object));
381-
foreach ($properties as $key => $value) {
382-
if ($reflectionClass->hasProperty($key)) {
383-
$reflectionProperty = $reflectionClass->getProperty($key);
384-
$reflectionProperty->setAccessible(true);
385-
$reflectionProperty->setValue($object, $value);
386-
}
387-
}
388-
}
389373
}

app/code/Magento/Catalog/etc/di.xml

+2
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@
4444
<preference for="Magento\Catalog\Api\AttributeSetRepositoryInterface" type="Magento\Catalog\Model\Product\Attribute\SetRepository" />
4545
<preference for="Magento\Catalog\Api\ProductManagementInterface" type="Magento\Catalog\Model\ProductManagement" />
4646
<preference for="Magento\Catalog\Api\AttributeSetFinderInterface" type="Magento\Catalog\Model\Product\Attribute\AttributeSetFinder" />
47+
<preference for="Magento\Catalog\Api\CategoryListInterface" type="Magento\Catalog\Model\CategoryList" />
48+
<preference for="Magento\Catalog\Api\Data\CategorySearchResultsInterface" type="Magento\Framework\Api\SearchResults" />
4749
<type name="Magento\Customer\Model\ResourceModel\Visitor">
4850
<plugin name="catalogLog" type="Magento\Catalog\Model\Plugin\Log" />
4951
</type>

0 commit comments

Comments
 (0)