diff --git a/app/code/Magento/Catalog/Model/ProductRepository.php b/app/code/Magento/Catalog/Model/ProductRepository.php index c9fbc7d553807..ceacfea5ec020 100644 --- a/app/code/Magento/Catalog/Model/ProductRepository.php +++ b/app/code/Magento/Catalog/Model/ProductRepository.php @@ -308,7 +308,7 @@ private function cacheProduct($cacheKey, \Magento\Catalog\Api\Data\ProductInterf if ($this->cacheLimit && count($this->instances) > $this->cacheLimit) { $offset = round($this->cacheLimit / -2); - $this->instancesById = array_slice($this->instancesById, $offset); + $this->instancesById = array_slice($this->instancesById, $offset, null, true); $this->instances = array_slice($this->instances, $offset); } } diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php index a0c9f4c6c92e2..68905331723a3 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php @@ -153,6 +153,13 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase */ private $serializerMock; + /** + * Product repository cache limit. + * + * @var int + */ + private $cacheLimit = 2; + /** * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ @@ -337,6 +344,7 @@ function ($value) { 'mediaGalleryProcessor' => $this->mediaGalleryProcessor, 'collectionProcessor' => $this->collectionProcessorMock, 'serializer' => $this->serializerMock, + 'cacheLimit' => $this->cacheLimit ] ); } @@ -469,6 +477,60 @@ public function testGetByIdForcedReload() $this->assertEquals($this->productMock, $this->model->getById($identifier, $editMode, $storeId, true)); } + /** + * Test for getById() method if we try to get products when cache is already filled and is reduced. + * + * @return void + */ + public function testGetByIdWhenCacheReduced() + { + $result = []; + $expectedResult = []; + $productsCount = $this->cacheLimit * 2; + + $productMocks = $this->getProductMocksForReducedCache(); + $productFactoryInvMock = $this->productFactoryMock->expects($this->exactly($productsCount)) + ->method('create'); + call_user_func_array([$productFactoryInvMock, 'willReturnOnConsecutiveCalls'], $productMocks); + $this->serializerMock->expects($this->atLeastOnce())->method('serialize'); + + for ($i = 1; $i <= $productsCount; $i ++) { + $product = $this->model->getById($i, false, 0); + $result[] = $product->getId(); + $expectedResult[] = $i; + } + + $this->assertEquals($expectedResult, $result); + } + + /** + * Get product mocks for testGetByIdWhenCacheReduced() method. + * + * @return array + */ + private function getProductMocksForReducedCache() + { + $productMocks = []; + + for ($i = 1; $i <= $this->cacheLimit * 2; $i ++) { + $productMock = $this->getMockBuilder(\Magento\Catalog\Model\Product::class) + ->disableOriginalConstructor() + ->setMethods([ + 'getId', + 'getSku', + 'load', + 'setData', + ]) + ->getMock(); + $productMock->expects($this->once())->method('load'); + $productMock->expects($this->atLeastOnce())->method('getId')->willReturn($i); + $productMock->expects($this->atLeastOnce())->method('getSku')->willReturn($i . uniqid()); + $productMocks[] = $productMock; + } + + return $productMocks; + } + /** * Test forceReload parameter *