Skip to content
This repository was archived by the owner on Apr 29, 2019. It is now read-only.

Commit 90fd5e4

Browse files
committed
Merge remote-tracking branch 'origin/MAGETWO-90035' into 2.3-develop-pr9
2 parents ebb266f + 5262595 commit 90fd5e4

File tree

2 files changed

+134
-28
lines changed

2 files changed

+134
-28
lines changed

app/code/Magento/Sales/CustomerData/LastOrderedItems.php

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
namespace Magento\Sales\CustomerData;
77

88
use Magento\Customer\CustomerData\SectionSourceInterface;
9+
use Magento\Catalog\Api\ProductRepositoryInterface;
10+
use Magento\Framework\Exception\NoSuchEntityException;
11+
use Psr\Log\LoggerInterface;
912

1013
/**
1114
* Returns information for "Recently Ordered" widget.
@@ -54,25 +57,41 @@ class LastOrderedItems implements SectionSourceInterface
5457
*/
5558
private $_storeManager;
5659

60+
/**
61+
* @var \Magento\Catalog\Api\ProductRepositoryInterface
62+
*/
63+
private $productRepository;
64+
65+
/**
66+
* @var LoggerInterface
67+
*/
68+
private $logger;
69+
5770
/**
5871
* @param \Magento\Sales\Model\ResourceModel\Order\CollectionFactory $orderCollectionFactory
5972
* @param \Magento\Sales\Model\Order\Config $orderConfig
6073
* @param \Magento\Customer\Model\Session $customerSession
6174
* @param \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry
6275
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
76+
* @param ProductRepositoryInterface $productRepository
77+
* @param LoggerInterface $logger
6378
*/
6479
public function __construct(
6580
\Magento\Sales\Model\ResourceModel\Order\CollectionFactory $orderCollectionFactory,
6681
\Magento\Sales\Model\Order\Config $orderConfig,
6782
\Magento\Customer\Model\Session $customerSession,
6883
\Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry,
69-
\Magento\Store\Model\StoreManagerInterface $storeManager
84+
\Magento\Store\Model\StoreManagerInterface $storeManager,
85+
ProductRepositoryInterface $productRepository,
86+
LoggerInterface $logger
7087
) {
7188
$this->_orderCollectionFactory = $orderCollectionFactory;
7289
$this->_orderConfig = $orderConfig;
7390
$this->_customerSession = $customerSession;
7491
$this->stockRegistry = $stockRegistry;
7592
$this->_storeManager = $storeManager;
93+
$this->productRepository = $productRepository;
94+
$this->logger = $logger;
7695
}
7796

7897
/**
@@ -108,11 +127,23 @@ protected function getItems()
108127
$website = $this->_storeManager->getStore()->getWebsiteId();
109128
/** @var \Magento\Sales\Model\Order\Item $item */
110129
foreach ($order->getParentItemsRandomCollection($limit) as $item) {
111-
if ($item->hasData('product') && in_array($website, $item->getProduct()->getWebsiteIds())) {
130+
/** @var \Magento\Catalog\Model\Product $product */
131+
try {
132+
$product = $this->productRepository->getById(
133+
$item->getProductId(),
134+
false,
135+
$this->_storeManager->getStore()->getId()
136+
);
137+
} catch (NoSuchEntityException $noEntityException) {
138+
$this->logger->critical($noEntityException);
139+
continue;
140+
}
141+
if (isset($product) && in_array($website, $product->getWebsiteIds())) {
142+
$url = $product->isVisibleInSiteVisibility() ? $product->getProductUrl() : null;
112143
$items[] = [
113144
'id' => $item->getId(),
114145
'name' => $item->getName(),
115-
'url' => $item->getProduct()->getProductUrl(),
146+
'url' => $url,
116147
'is_saleable' => $this->isItemAvailableForReorder($item),
117148
];
118149
}
@@ -136,7 +167,7 @@ protected function isItemAvailableForReorder(\Magento\Sales\Model\Order\Item $or
136167
$orderItem->getStore()->getWebsiteId()
137168
);
138169
return $stockItem->getIsInStock();
139-
} catch (\Magento\Framework\Exception\NoSuchEntityException $noEntityException) {
170+
} catch (NoSuchEntityException $noEntityException) {
140171
return false;
141172
}
142173
}

app/code/Magento/Sales/Test/Unit/CustomerData/LastOrderedItemsTest.php

Lines changed: 99 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,21 @@ class LastOrderedItemsTest extends \PHPUnit\Framework\TestCase
4848
*/
4949
private $orderMock;
5050

51+
/**
52+
* @var \PHPUnit_Framework_MockObject_MockObject
53+
*/
54+
private $productRepositoryMock;
55+
5156
/**
5257
* @var \Magento\Sales\CustomerData\LastOrderedItems
5358
*/
5459
private $section;
5560

61+
/**
62+
* @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject
63+
*/
64+
private $loggerMock;
65+
5666
protected function setUp()
5767
{
5868
$this->objectManagerHelper = new ObjectManagerHelper($this);
@@ -74,62 +84,97 @@ protected function setUp()
7484
$this->orderMock = $this->getMockBuilder(\Magento\Sales\Model\Order::class)
7585
->disableOriginalConstructor()
7686
->getMock();
87+
$this->productRepositoryMock = $this->getMockBuilder(\Magento\Catalog\Api\ProductRepositoryInterface::class)
88+
->getMockForAbstractClass();
89+
$this->loggerMock = $this->getMockBuilder(\Psr\Log\LoggerInterface::class)
90+
->getMockForAbstractClass();
91+
7792
$this->section = new \Magento\Sales\CustomerData\LastOrderedItems(
7893
$this->orderCollectionFactoryMock,
7994
$this->orderConfigMock,
8095
$this->customerSessionMock,
8196
$this->stockRegistryMock,
82-
$this->storeManagerMock
97+
$this->storeManagerMock,
98+
$this->productRepositoryMock,
99+
$this->loggerMock
83100
);
84101
}
85102

86103
public function testGetSectionData()
87104
{
105+
$storeId = 1;
88106
$websiteId = 4;
89-
$expectedItem = [
107+
$expectedItem1 = [
90108
'id' => 1,
91-
'name' => 'Product Name',
109+
'name' => 'Product Name 1',
92110
'url' => 'http://example.com',
93111
'is_saleable' => true,
94112
];
95-
$productId = 10;
113+
$expectedItem2 = [
114+
'id' => 2,
115+
'name' => 'Product Name 2',
116+
'url' => null,
117+
'is_saleable' => true,
118+
];
119+
$productIdVisible = 1;
120+
$productIdNotVisible = 2;
96121
$stockItemMock = $this->getMockBuilder(\Magento\CatalogInventory\Api\Data\StockItemInterface::class)
97122
->getMockForAbstractClass();
98-
$itemWithProductMock = $this->getMockBuilder(\Magento\Sales\Model\Order\Item::class)
123+
$itemWithVisibleProduct = $this->getMockBuilder(\Magento\Sales\Model\Order\Item::class)
124+
->disableOriginalConstructor()
125+
->getMock();
126+
$itemWithNotVisibleProduct = $this->getMockBuilder(\Magento\Sales\Model\Order\Item::class)
99127
->disableOriginalConstructor()
100128
->getMock();
101-
$itemWithoutProductMock = $this->getMockBuilder(\Magento\Sales\Model\Order\Item::class)
129+
$productVisible = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
102130
->disableOriginalConstructor()
103131
->getMock();
104-
$productMock = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
132+
$productNotVisible = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
105133
->disableOriginalConstructor()
106134
->getMock();
107-
$items = [$itemWithoutProductMock, $itemWithProductMock];
135+
$items = [$itemWithVisibleProduct, $itemWithNotVisibleProduct];
108136
$this->getLastOrderMock();
109137
$storeMock = $this->getMockBuilder(\Magento\Store\Api\Data\StoreInterface::class)->getMockForAbstractClass();
110-
$this->storeManagerMock->expects($this->once())->method('getStore')->willReturn($storeMock);
138+
$this->storeManagerMock->expects($this->any())->method('getStore')->willReturn($storeMock);
111139
$storeMock->expects($this->any())->method('getWebsiteId')->willReturn($websiteId);
140+
$storeMock->expects($this->any())->method('getId')->willReturn($storeId);
112141
$this->orderMock->expects($this->once())
113142
->method('getParentItemsRandomCollection')
114143
->with(\Magento\Sales\CustomerData\LastOrderedItems::SIDEBAR_ORDER_LIMIT)
115144
->willReturn($items);
116-
$itemWithProductMock->expects($this->once())->method('hasData')->with('product')->willReturn(true);
117-
$itemWithProductMock->expects($this->any())->method('getProduct')->willReturn($productMock);
118-
$productMock->expects($this->once())->method('getWebsiteIds')->willReturn([1, 4]);
119-
$itemWithProductMock->expects($this->once())->method('getId')->willReturn($expectedItem['id']);
120-
$itemWithProductMock->expects($this->once())->method('getName')->willReturn($expectedItem['name']);
121-
$productMock->expects($this->once())->method('getProductUrl')->willReturn($expectedItem['url']);
122-
$this->stockRegistryMock->expects($this->once())->method('getStockItem')->willReturn($stockItemMock);
123-
$productMock->expects($this->once())->method('getId')->willReturn($productId);
124-
$itemWithProductMock->expects($this->once())->method('getStore')->willReturn($storeMock);
145+
$productVisible->expects($this->once())->method('isVisibleInSiteVisibility')->willReturn(true);
146+
$productVisible->expects($this->once())->method('getProductUrl')->willReturn($expectedItem1['url']);
147+
$productVisible->expects($this->once())->method('getWebsiteIds')->willReturn([1, 4]);
148+
$productVisible->expects($this->once())->method('getId')->willReturn($productIdVisible);
149+
$productNotVisible->expects($this->once())->method('isVisibleInSiteVisibility')->willReturn(false);
150+
$productNotVisible->expects($this->never())->method('getProductUrl');
151+
$productNotVisible->expects($this->once())->method('getWebsiteIds')->willReturn([1, 4]);
152+
$productNotVisible->expects($this->once())->method('getId')->willReturn($productIdNotVisible);
153+
$itemWithVisibleProduct->expects($this->once())->method('getProductId')->willReturn($productIdVisible);
154+
$itemWithVisibleProduct->expects($this->once())->method('getProduct')->willReturn($productVisible);
155+
$itemWithVisibleProduct->expects($this->once())->method('getId')->willReturn($expectedItem1['id']);
156+
$itemWithVisibleProduct->expects($this->once())->method('getName')->willReturn($expectedItem1['name']);
157+
$itemWithVisibleProduct->expects($this->once())->method('getStore')->willReturn($storeMock);
158+
$itemWithNotVisibleProduct->expects($this->once())->method('getProductId')->willReturn($productIdNotVisible);
159+
$itemWithNotVisibleProduct->expects($this->once())->method('getProduct')->willReturn($productNotVisible);
160+
$itemWithNotVisibleProduct->expects($this->once())->method('getId')->willReturn($expectedItem2['id']);
161+
$itemWithNotVisibleProduct->expects($this->once())->method('getName')->willReturn($expectedItem2['name']);
162+
$itemWithNotVisibleProduct->expects($this->once())->method('getStore')->willReturn($storeMock);
163+
$this->productRepositoryMock->expects($this->any())
164+
->method('getById')
165+
->willReturnMap([
166+
[$productIdVisible, false, $storeId, false, $productVisible],
167+
[$productIdNotVisible, false, $storeId, false, $productNotVisible],
168+
]);
125169
$this->stockRegistryMock
126-
->expects($this->once())
170+
->expects($this->any())
127171
->method('getStockItem')
128-
->with($productId, $websiteId)
129-
->willReturn($stockItemMock);
130-
$stockItemMock->expects($this->once())->method('getIsInStock')->willReturn($expectedItem['is_saleable']);
131-
$itemWithoutProductMock->expects($this->once())->method('hasData')->with('product')->willReturn(false);
132-
$this->assertEquals(['items' => [$expectedItem]], $this->section->getSectionData());
172+
->willReturnMap([
173+
[$productIdVisible, $websiteId, $stockItemMock],
174+
[$productIdNotVisible, $websiteId, $stockItemMock],
175+
]);
176+
$stockItemMock->expects($this->exactly(2))->method('getIsInStock')->willReturn($expectedItem1['is_saleable']);
177+
$this->assertEquals(['items' => [$expectedItem1, $expectedItem2]], $this->section->getSectionData());
133178
}
134179

135180
private function getLastOrderMock()
@@ -160,4 +205,34 @@ private function getLastOrderMock()
160205
->willReturnSelf();
161206
return $this->orderMock;
162207
}
208+
209+
public function testGetSectionDataWithNotExistingProduct()
210+
{
211+
$storeId = 1;
212+
$websiteId = 4;
213+
$productId = 1;
214+
$exception = new \Magento\Framework\Exception\NoSuchEntityException(__("Product doesn't exist"));
215+
$orderItemMock = $this->getMockBuilder(\Magento\Sales\Model\Order\Item::class)
216+
->disableOriginalConstructor()
217+
->setMethods(['getProductId'])
218+
->getMock();
219+
$storeMock = $this->getMockBuilder(\Magento\Store\Api\Data\StoreInterface::class)->getMockForAbstractClass();
220+
221+
$this->getLastOrderMock();
222+
$this->storeManagerMock->expects($this->exactly(2))->method('getStore')->willReturn($storeMock);
223+
$storeMock->expects($this->once())->method('getWebsiteId')->willReturn($websiteId);
224+
$storeMock->expects($this->once())->method('getId')->willReturn($storeId);
225+
$this->orderMock->expects($this->once())
226+
->method('getParentItemsRandomCollection')
227+
->with(\Magento\Sales\CustomerData\LastOrderedItems::SIDEBAR_ORDER_LIMIT)
228+
->willReturn([$orderItemMock]);
229+
$orderItemMock->expects($this->once())->method('getProductId')->willReturn($productId);
230+
$this->productRepositoryMock->expects($this->once())
231+
->method('getById')
232+
->with($productId, false, $storeId)
233+
->willThrowException($exception);
234+
$this->loggerMock->expects($this->once())->method('critical')->with($exception);
235+
236+
$this->assertEquals(['items' => []], $this->section->getSectionData());
237+
}
163238
}

0 commit comments

Comments
 (0)