Skip to content

Commit 956a0d1

Browse files
author
Oleksii Korshenko
authored
MAGETWO-82808: #9768: Admin dashboard Most Viewed Products Tab only gives default attribute set's products #11725
2 parents fdf4a1c + 55b88a6 commit 956a0d1

File tree

2 files changed

+289
-5
lines changed

2 files changed

+289
-5
lines changed

app/code/Magento/Reports/Model/ResourceModel/Product/Collection.php

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ public function setOrder($attribute, $dir = self::SORT_ORDER_DESC)
298298
}
299299

300300
/**
301-
* Add views count
301+
* Add views count.
302302
*
303303
* @param string $from
304304
* @param string $to
@@ -322,10 +322,7 @@ public function addViewsCount($from = '', $to = '')
322322
['views' => 'COUNT(report_table_views.event_id)']
323323
)->join(
324324
['e' => $this->getProductEntityTableName()],
325-
$this->getConnection()->quoteInto(
326-
'e.entity_id = report_table_views.object_id AND e.attribute_set_id = ?',
327-
$this->getProductAttributeSetId()
328-
)
325+
'e.entity_id = report_table_views.object_id'
329326
)->where(
330327
'report_table_views.event_type_id = ?',
331328
$productViewEvent
@@ -341,6 +338,7 @@ public function addViewsCount($from = '', $to = '')
341338
if ($from != '' && $to != '') {
342339
$this->getSelect()->where('logged_at >= ?', $from)->where('logged_at <= ?', $to);
343340
}
341+
344342
return $this;
345343
}
346344

Lines changed: 286 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,286 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\Reports\Test\Unit\Model\ResourceModel\Product;
8+
9+
use Magento\Catalog\Model\Indexer\Product\Flat\State;
10+
use Magento\Catalog\Model\Product\Attribute\DefaultAttributes;
11+
use Magento\Catalog\Model\Product\OptionFactory;
12+
use Magento\Catalog\Model\Product\Type as ProductType;
13+
use Magento\Catalog\Model\ResourceModel\Helper;
14+
use Magento\Catalog\Model\ResourceModel\Product as ResourceProduct;
15+
use Magento\Catalog\Model\ResourceModel\Url;
16+
use Magento\Customer\Api\GroupManagementInterface;
17+
use Magento\Customer\Model\Session;
18+
use Magento\Eav\Model\Config;
19+
use Magento\Eav\Model\Entity\Context;
20+
use Magento\Eav\Model\Entity\Type;
21+
use Magento\Eav\Model\EntityFactory as EavEntityFactory;
22+
use Magento\Framework\App\Config\ScopeConfigInterface;
23+
use Magento\Framework\App\ResourceConnection;
24+
use Magento\Framework\Data\Collection\Db\FetchStrategyInterface;
25+
use Magento\Framework\Data\Collection\EntityFactory;
26+
use Magento\Framework\DB\Adapter\AdapterInterface;
27+
use Magento\Framework\DB\Select;
28+
use Magento\Framework\Event\ManagerInterface;
29+
use Magento\Framework\Module\Manager;
30+
use Magento\Framework\Stdlib\DateTime;
31+
use Magento\Framework\Stdlib\DateTime\TimezoneInterface;
32+
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
33+
use Magento\Framework\Validator\UniversalFactory;
34+
use Magento\Quote\Model\ResourceModel\Quote\Collection;
35+
use Magento\Reports\Model\Event\TypeFactory;
36+
use Magento\Reports\Model\ResourceModel\Product\Collection as ProductCollection;
37+
use Magento\Store\Model\StoreManagerInterface;
38+
use Psr\Log\LoggerInterface;
39+
40+
/**
41+
* Test for Magento\Reports\Model\ResourceModel\Product\Collection.
42+
*
43+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
44+
*
45+
*/
46+
class CollectionTest extends \PHPUnit\Framework\TestCase
47+
{
48+
/**
49+
* @var ProductCollection
50+
*/
51+
private $collection;
52+
53+
/**
54+
* @var \PHPUnit_Framework_MockObject_MockObject
55+
*/
56+
private $eventTypeFactoryMock;
57+
58+
/**
59+
* @var ObjectManager
60+
*/
61+
private $objectManager;
62+
63+
/**
64+
* @var \PHPUnit_Framework_MockObject_MockObject
65+
*/
66+
private $connectionMock;
67+
68+
/**
69+
* @var \PHPUnit_Framework_MockObject_MockObject
70+
*/
71+
private $resourceMock;
72+
73+
/**
74+
* @var \PHPUnit_Framework_MockObject_MockObject
75+
*/
76+
private $selectMock;
77+
78+
protected function setUp()
79+
{
80+
$this->objectManager = new ObjectManager($this);
81+
$context = $this->createPartialMock(Context::class, ['getResource', 'getEavConfig']);
82+
$entityFactoryMock = $this->createMock(EntityFactory::class);
83+
$loggerMock = $this->createMock(LoggerInterface::class);
84+
$fetchStrategyMock = $this->createMock(FetchStrategyInterface::class);
85+
$eventManagerMock = $this->createMock(ManagerInterface::class);
86+
$eavConfigMock = $this->createMock(Config::class);
87+
$this->resourceMock = $this->createPartialMock(ResourceConnection::class, ['getTableName', 'getConnection']);
88+
$eavEntityFactoryMock = $this->createMock(EavEntityFactory::class);
89+
$resourceHelperMock = $this->createMock(Helper::class);
90+
$universalFactoryMock = $this->createMock(UniversalFactory::class);
91+
$storeManagerMock = $this->createPartialMockForAbstractClass(
92+
StoreManagerInterface::class,
93+
['getStore', 'getId']
94+
);
95+
$moduleManagerMock = $this->createMock(Manager::class);
96+
$productFlatStateMock = $this->createMock(State::class);
97+
$scopeConfigMock = $this->createMock(ScopeConfigInterface::class);
98+
$optionFactoryMock = $this->createMock(OptionFactory::class);
99+
$catalogUrlMock = $this->createMock(Url::class);
100+
$localeDateMock = $this->createMock(TimezoneInterface::class);
101+
$customerSessionMock = $this->createMock(Session::class);
102+
$dateTimeMock = $this->createMock(DateTime::class);
103+
$groupManagementMock = $this->createMock(GroupManagementInterface::class);
104+
$eavConfig = $this->createPartialMock(Config::class, ['getEntityType']);
105+
$entityType = $this->createMock(Type::class);
106+
107+
$eavConfig->expects($this->atLeastOnce())->method('getEntityType')->willReturn($entityType);
108+
$context->expects($this->atLeastOnce())->method('getResource')->willReturn($this->resourceMock);
109+
$context->expects($this->atLeastOnce())->method('getEavConfig')->willReturn($eavConfig);
110+
111+
$defaultAttributes = $this->createPartialMock(DefaultAttributes::class, ['_getDefaultAttributes']);
112+
$productMock = $this->objectManager->getObject(
113+
ResourceProduct::class,
114+
['context' => $context, 'defaultAttributes' => $defaultAttributes]
115+
);
116+
117+
$this->eventTypeFactoryMock = $this->createMock(TypeFactory::class);
118+
$productTypeMock = $this->createMock(ProductType::class);
119+
$quoteResourceMock = $this->createMock(Collection::class);
120+
$this->connectionMock = $this->createPartialMockForAbstractClass(AdapterInterface::class, ['select']);
121+
$this->selectMock = $this->createPartialMock(
122+
Select::class,
123+
[
124+
'reset',
125+
'from',
126+
'join',
127+
'where',
128+
'group',
129+
'order',
130+
'having',
131+
]
132+
);
133+
134+
$storeManagerMock->expects($this->atLeastOnce())->method('getStore')->willReturn($storeManagerMock);
135+
$storeManagerMock->expects($this->atLeastOnce())->method('getId')->willReturn(1);
136+
$universalFactoryMock->expects($this->atLeastOnce())->method('create')->willReturn($productMock);
137+
$this->resourceMock->expects($this->atLeastOnce())->method('getTableName')->willReturn('test_table');
138+
$this->resourceMock->expects($this->atLeastOnce())->method('getConnection')->willReturn($this->connectionMock);
139+
$this->connectionMock->expects($this->atLeastOnce())->method('select')->willReturn($this->selectMock);
140+
141+
$this->collection = new ProductCollection(
142+
$entityFactoryMock,
143+
$loggerMock,
144+
$fetchStrategyMock,
145+
$eventManagerMock,
146+
$eavConfigMock,
147+
$this->resourceMock,
148+
$eavEntityFactoryMock,
149+
$resourceHelperMock,
150+
$universalFactoryMock,
151+
$storeManagerMock,
152+
$moduleManagerMock,
153+
$productFlatStateMock,
154+
$scopeConfigMock,
155+
$optionFactoryMock,
156+
$catalogUrlMock,
157+
$localeDateMock,
158+
$customerSessionMock,
159+
$dateTimeMock,
160+
$groupManagementMock,
161+
$productMock,
162+
$this->eventTypeFactoryMock,
163+
$productTypeMock,
164+
$quoteResourceMock,
165+
$this->connectionMock
166+
);
167+
}
168+
169+
/**
170+
* Test addViewsCount behavior.
171+
*/
172+
public function testAddViewsCount()
173+
{
174+
$context = $this->createPartialMock(
175+
\Magento\Framework\Model\ResourceModel\Db\Context::class,
176+
['getResources']
177+
);
178+
$context->expects($this->atLeastOnce())
179+
->method('getResources')
180+
->willReturn($this->resourceMock);
181+
$abstractResourceMock = $this->getMockForAbstractClass(
182+
\Magento\Framework\Model\ResourceModel\Db\AbstractDb::class,
183+
['context' => $context],
184+
'',
185+
true,
186+
true,
187+
true,
188+
[
189+
'getTableName',
190+
'getConnection',
191+
'getMainTable',
192+
]
193+
);
194+
195+
$abstractResourceMock->expects($this->atLeastOnce())
196+
->method('getConnection')
197+
->willReturn($this->connectionMock);
198+
$abstractResourceMock->expects($this->atLeastOnce())
199+
->method('getMainTable')
200+
->willReturn('catalog_product');
201+
202+
/** @var \Magento\Reports\Model\ResourceModel\Event\Type\Collection $eventTypesCollection */
203+
$eventTypesCollection = $this->objectManager->getObject(
204+
\Magento\Reports\Model\ResourceModel\Event\Type\Collection::class,
205+
['resource' => $abstractResourceMock]
206+
);
207+
$eventTypeMock = $this->createPartialMock(
208+
\Magento\Reports\Model\Event\Type::class,
209+
[
210+
'getEventName',
211+
'getId',
212+
'getCollection',
213+
]
214+
);
215+
216+
$eventTypesCollection->addItem($eventTypeMock);
217+
218+
$this->eventTypeFactoryMock->expects($this->once())
219+
->method('create')
220+
->willReturn($eventTypeMock);
221+
$eventTypeMock->expects($this->atLeastOnce())
222+
->method('getCollection')
223+
->willReturn($eventTypesCollection);
224+
$eventTypeMock->expects($this->atLeastOnce())
225+
->method('getEventName')
226+
->willReturn('catalog_product_view');
227+
$eventTypeMock->expects($this->atLeastOnce())
228+
->method('getId')
229+
->willReturn(1);
230+
231+
$this->selectMock->expects($this->atLeastOnce())
232+
->method('reset')
233+
->willReturn($this->selectMock);
234+
$this->selectMock->expects($this->atLeastOnce())
235+
->method('from')
236+
->with(
237+
['report_table_views' => 'test_table'],
238+
['views' => 'COUNT(report_table_views.event_id)']
239+
)->willReturn($this->selectMock);
240+
$this->selectMock->expects($this->atLeastOnce())
241+
->method('join')
242+
->with(
243+
['e' => 'test_table'],
244+
'e.entity_id = report_table_views.object_id'
245+
)->willReturn($this->selectMock);
246+
$this->selectMock->expects($this->atLeastOnce())
247+
->method('where')
248+
->with('report_table_views.event_type_id = ?', 1)
249+
->willReturn($this->selectMock);
250+
$this->selectMock->expects($this->atLeastOnce())
251+
->method('group')
252+
->with('e.entity_id')
253+
->willReturn($this->selectMock);
254+
$this->selectMock->expects($this->atLeastOnce())
255+
->method('order')
256+
->with('views DESC')
257+
->willReturn($this->selectMock);
258+
$this->selectMock->expects($this->atLeastOnce())
259+
->method('having')
260+
->with('COUNT(report_table_views.event_id) > ?', 0)
261+
->willReturn($this->selectMock);
262+
263+
$this->collection->addViewsCount();
264+
}
265+
266+
/**
267+
* Get mock for abstract class with methods.
268+
*
269+
* @param string $className
270+
* @param array $methods
271+
*
272+
* @return \PHPUnit_Framework_MockObject_MockObject
273+
*/
274+
private function createPartialMockForAbstractClass($className, $methods)
275+
{
276+
return $this->getMockForAbstractClass(
277+
$className,
278+
[],
279+
'',
280+
true,
281+
true,
282+
true,
283+
$methods
284+
);
285+
}
286+
}

0 commit comments

Comments
 (0)