diff --git a/app/code/Magento/Reports/Model/ResourceModel/Product/Collection.php b/app/code/Magento/Reports/Model/ResourceModel/Product/Collection.php index 4f5c6d1c3c996..bf7af4983ffff 100644 --- a/app/code/Magento/Reports/Model/ResourceModel/Product/Collection.php +++ b/app/code/Magento/Reports/Model/ResourceModel/Product/Collection.php @@ -296,7 +296,7 @@ public function setOrder($attribute, $dir = self::SORT_ORDER_DESC) } /** - * Add views count + * Add views count. * * @param string $from * @param string $to @@ -320,10 +320,7 @@ public function addViewsCount($from = '', $to = '') ['views' => 'COUNT(report_table_views.event_id)'] )->join( ['e' => $this->getProductEntityTableName()], - $this->getConnection()->quoteInto( - 'e.entity_id = report_table_views.object_id AND e.attribute_set_id = ?', - $this->getProductAttributeSetId() - ) + 'e.entity_id = report_table_views.object_id' )->where( 'report_table_views.event_type_id = ?', $productViewEvent @@ -339,6 +336,7 @@ public function addViewsCount($from = '', $to = '') if ($from != '' && $to != '') { $this->getSelect()->where('logged_at >= ?', $from)->where('logged_at <= ?', $to); } + return $this; } diff --git a/app/code/Magento/Reports/Test/Unit/Model/ResourceModel/Product/CollectionTest.php b/app/code/Magento/Reports/Test/Unit/Model/ResourceModel/Product/CollectionTest.php new file mode 100644 index 0000000000000..f201e735379bf --- /dev/null +++ b/app/code/Magento/Reports/Test/Unit/Model/ResourceModel/Product/CollectionTest.php @@ -0,0 +1,323 @@ +objectManager = new ObjectManager($this); + $context = $this->createPartialMock(Context::class, ['getResource', 'getEavConfig']); + $entityFactoryMock = $this->createMock(EntityFactory::class); + $loggerMock = $this->createMock(LoggerInterface::class); + $fetchStrategyMock = $this->createMock(FetchStrategyInterface::class); + $eventManagerMock = $this->createMock(ManagerInterface::class); + $eavConfigMock = $this->createMock(Config::class); + $this->resourceMock = $this->createPartialMock(ResourceConnection::class, ['getTableName', 'getConnection']); + $eavEntityFactoryMock = $this->createMock(EavEntityFactory::class); + $resourceHelperMock = $this->createMock(Helper::class); + $universalFactoryMock = $this->createMock(UniversalFactory::class); + $storeManagerMock = $this->createPartialMockForAbstractClass( + StoreManagerInterface::class, + ['getStore', 'getId'] + ); + $moduleManagerMock = $this->createMock(Manager::class); + $productFlatStateMock = $this->createMock(State::class); + $scopeConfigMock = $this->createMock(ScopeConfigInterface::class); + $optionFactoryMock = $this->createMock(OptionFactory::class); + $catalogUrlMock = $this->createMock(Url::class); + $localeDateMock = $this->createMock(TimezoneInterface::class); + $customerSessionMock = $this->createMock(Session::class); + $dateTimeMock = $this->createMock(DateTime::class); + $groupManagementMock = $this->createMock(GroupManagementInterface::class); + $eavConfig = $this->createPartialMock(Config::class, ['getEntityType']); + $entityType = $this->createMock(Type::class); + + $eavConfig->expects($this->atLeastOnce())->method('getEntityType')->willReturn($entityType); + $context->expects($this->atLeastOnce())->method('getResource')->willReturn($this->resourceMock); + $context->expects($this->atLeastOnce())->method('getEavConfig')->willReturn($eavConfig); + + $defaultAttributes = $this->createPartialMock(DefaultAttributes::class, ['_getDefaultAttributes']); + $productMock = $this->objectManager->getObject( + ResourceProduct::class, + ['context' => $context, 'defaultAttributes' => $defaultAttributes] + ); + + $this->eventTypeFactoryMock = $this->createPartialMock(TypeFactory::class, ['create']); + $productTypeMock = $this->createMock(ProductType::class); + $quoteResourceMock = $this->createMock(Collection::class); + $this->connectionMock = $this->createPartialMockForAbstractClass(AdapterInterface::class, ['select']); + $this->selectMock = $this->createPartialMock( + Select::class, + [ + 'reset', + 'from', + 'join', + 'where', + 'group', + 'order', + 'having', + ] + ); + + $storeManagerMock->expects($this->atLeastOnce())->method('getStore')->willReturn($storeManagerMock); + $storeManagerMock->expects($this->atLeastOnce())->method('getId')->willReturn(1); + $universalFactoryMock->expects($this->atLeastOnce())->method('create')->willReturn($productMock); + $this->resourceMock->expects($this->atLeastOnce())->method('getTableName')->willReturn('test_table'); + $this->resourceMock->expects($this->atLeastOnce())->method('getConnection')->willReturn($this->connectionMock); + $this->connectionMock->expects($this->atLeastOnce())->method('select')->willReturn($this->selectMock); + + $objectManagerMock = $this->getMock(\Magento\Framework\ObjectManagerInterface::class); + \Magento\Framework\App\ObjectManager::setInstance($objectManagerMock); + + $this->collection = new ProductCollection( + $entityFactoryMock, + $loggerMock, + $fetchStrategyMock, + $eventManagerMock, + $eavConfigMock, + $this->resourceMock, + $eavEntityFactoryMock, + $resourceHelperMock, + $universalFactoryMock, + $storeManagerMock, + $moduleManagerMock, + $productFlatStateMock, + $scopeConfigMock, + $optionFactoryMock, + $catalogUrlMock, + $localeDateMock, + $customerSessionMock, + $dateTimeMock, + $groupManagementMock, + $productMock, + $this->eventTypeFactoryMock, + $productTypeMock, + $quoteResourceMock, + $this->connectionMock + ); + } + + /** + * Test addViewsCount behavior. + */ + public function testAddViewsCount() + { + $context = $this->createPartialMock( + \Magento\Framework\Model\ResourceModel\Db\Context::class, + ['getResources'] + ); + $context->expects($this->atLeastOnce()) + ->method('getResources') + ->willReturn($this->resourceMock); + $abstractResourceMock = $this->getMockForAbstractClass( + \Magento\Framework\Model\ResourceModel\Db\AbstractDb::class, + ['context' => $context], + '', + true, + true, + true, + [ + 'getTableName', + 'getConnection', + 'getMainTable', + ] + ); + + $abstractResourceMock->expects($this->atLeastOnce()) + ->method('getConnection') + ->willReturn($this->connectionMock); + $abstractResourceMock->expects($this->atLeastOnce()) + ->method('getMainTable') + ->willReturn('catalog_product'); + + /** @var \Magento\Reports\Model\ResourceModel\Event\Type\Collection $eventTypesCollection */ + $eventTypesCollection = $this->objectManager->getObject( + \Magento\Reports\Model\ResourceModel\Event\Type\Collection::class, + ['resource' => $abstractResourceMock] + ); + $eventTypeMock = $this->createPartialMock( + \Magento\Reports\Model\Event\Type::class, + [ + 'getEventName', + 'getId', + 'getCollection', + ] + ); + + $eventTypesCollection->addItem($eventTypeMock); + + $this->eventTypeFactoryMock->expects($this->once()) + ->method('create') + ->willReturn($eventTypeMock); + $eventTypeMock->expects($this->atLeastOnce()) + ->method('getCollection') + ->willReturn($eventTypesCollection); + $eventTypeMock->expects($this->atLeastOnce()) + ->method('getEventName') + ->willReturn('catalog_product_view'); + $eventTypeMock->expects($this->atLeastOnce()) + ->method('getId') + ->willReturn(1); + + $this->selectMock->expects($this->atLeastOnce()) + ->method('reset') + ->willReturn($this->selectMock); + $this->selectMock->expects($this->atLeastOnce()) + ->method('from') + ->with( + ['report_table_views' => 'test_table'], + ['views' => 'COUNT(report_table_views.event_id)'] + )->willReturn($this->selectMock); + $this->selectMock->expects($this->atLeastOnce()) + ->method('join') + ->with( + ['e' => 'test_table'], + 'e.entity_id = report_table_views.object_id' + )->willReturn($this->selectMock); + $this->selectMock->expects($this->atLeastOnce()) + ->method('where') + ->with('report_table_views.event_type_id = ?', 1) + ->willReturn($this->selectMock); + $this->selectMock->expects($this->atLeastOnce()) + ->method('group') + ->with('e.entity_id') + ->willReturn($this->selectMock); + $this->selectMock->expects($this->atLeastOnce()) + ->method('order') + ->with('views DESC') + ->willReturn($this->selectMock); + $this->selectMock->expects($this->atLeastOnce()) + ->method('having') + ->with('COUNT(report_table_views.event_id) > ?', 0) + ->willReturn($this->selectMock); + + $this->collection->addViewsCount(); + } + + /** + * Get mock for abstract class with methods. + * + * @param string $className + * @param array $methods + * + * @return \PHPUnit_Framework_MockObject_MockObject + */ + private function createPartialMockForAbstractClass($className, $methods) + { + return $this->getMockForAbstractClass( + $className, + [], + '', + true, + true, + true, + $methods + ); + } + + /** + * Returns a partial test double for the specified class. + * + * @param string $originalClassName + * @param string[] $methods + * + * @return \PHPUnit_Framework_MockObject_MockObject + */ + private function createPartialMock($originalClassName, array $methods) + { + return $this->getMockBuilder($originalClassName) + ->disableOriginalConstructor() + ->disableOriginalClone() + ->disableArgumentCloning() + ->setMethods(empty($methods) ? null : $methods) + ->getMock(); + } + + /** + * Returns a test double for the specified class. + * + * @param string $originalClassName + * + * @return \PHPUnit_Framework_MockObject_MockObject + */ + private function createMock($originalClassName) + { + return $this->getMockBuilder($originalClassName) + ->disableOriginalConstructor() + ->disableOriginalClone() + ->disableArgumentCloning() + ->getMock(); + } +}