diff --git a/app/code/Magento/Downloadable/Model/Product/Type.php b/app/code/Magento/Downloadable/Model/Product/Type.php index acc82eb4af636..6ebad1632c6e5 100644 --- a/app/code/Magento/Downloadable/Model/Product/Type.php +++ b/app/code/Magento/Downloadable/Model/Product/Type.php @@ -170,7 +170,14 @@ public function hasLinks($product) { $hasLinks = $product->getData('links_exist'); if (null === $hasLinks) { - $hasLinks = (count($this->getLinks($product)) > 0); + $links = $product->getDownloadableLinks(); + if ($links !== null) { + $hasLinks = !empty($links); + } else { + $hasLinks = $this->_linksFactory->create() + ->addProductToFilter($product->getEntityId()) + ->getSize() > 0; + } } return $hasLinks; } @@ -238,7 +245,14 @@ public function getSamples($product) */ public function hasSamples($product) { - return count($this->getSamples($product)) > 0; + $samples = $product->getDownloadableSamples(); + if ($samples !== null) { + return $samples->getSize() > 0; + } + + return $this->_samplesFactory->create() + ->addProductToFilter($product->getEntityId()) + ->getSize() > 0; } /** diff --git a/app/code/Magento/Downloadable/Test/Unit/Model/Product/TypeTest.php b/app/code/Magento/Downloadable/Test/Unit/Model/Product/TypeTest.php index e12dbaed61961..b94cec95fe299 100644 --- a/app/code/Magento/Downloadable/Test/Unit/Model/Product/TypeTest.php +++ b/app/code/Magento/Downloadable/Test/Unit/Model/Product/TypeTest.php @@ -16,6 +16,8 @@ use Magento\Downloadable\Model\ResourceModel\Link; use Magento\Downloadable\Model\ResourceModel\Link\Collection; use Magento\Downloadable\Model\ResourceModel\Link\CollectionFactory; +use Magento\Downloadable\Model\ResourceModel\Sample\Collection as SampleCollection; +use Magento\Downloadable\Model\ResourceModel\Sample\CollectionFactory as SampleCollectionFactory; use Magento\Downloadable\Model\ResourceModel\SampleFactory; use Magento\Eav\Model\Config; use Magento\Framework\Event\ManagerInterface; @@ -70,6 +72,11 @@ class TypeTest extends TestCase */ private $linksFactory; + /** + * @var SampleCollectionFactory|MockObject + */ + private $samplesFactory; + /** * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ @@ -88,7 +95,7 @@ protected function setUp(): void CollectionFactory::class, ['create'] ); - $samplesFactory = $this->createMock(\Magento\Downloadable\Model\ResourceModel\Sample\CollectionFactory::class); + $this->samplesFactory = $this->createMock(SampleCollectionFactory::class); $sampleFactory = $this->createMock(\Magento\Downloadable\Model\SampleFactory::class); $linkFactory = $this->createMock(LinkFactory::class); @@ -127,6 +134,7 @@ function ($value) { 'setTypeHasOptions', 'setLinksExist', 'getDownloadableLinks', + 'getDownloadableSamples', 'getResource', 'canAffectOptions', '__wakeup', @@ -162,7 +170,7 @@ function ($value) { 'sampleResFactory' => $sampleResFactory, 'linkResource' => $linkResource, 'linksFactory' => $this->linksFactory, - 'samplesFactory' => $samplesFactory, + 'samplesFactory' => $this->samplesFactory, 'sampleFactory' => $sampleFactory, 'linkFactory' => $linkFactory, 'eavConfig' => $eavConfigMock, @@ -185,13 +193,99 @@ public function testBeforeSave() public function testHasLinks() { - $this->product->method('getLinksPurchasedSeparately')->willReturn(true); - $this->product->expects($this->exactly(2)) + $this->product->expects($this->once()) ->method('getDownloadableLinks') ->willReturn(['link1', 'link2']); $this->assertTrue($this->target->hasLinks($this->product)); } + public function testHasLinksReturnsFalseWhenCachedLinksAreEmpty(): void + { + $this->product->expects($this->once()) + ->method('getDownloadableLinks') + ->willReturn([]); + + $this->assertFalse($this->target->hasLinks($this->product)); + } + + public function testHasLinksUsesDbFallbackWhenCachedLinksAreUnavailable(): void + { + $linksCollection = $this->createPartialMock( + Collection::class, + ['addProductToFilter', 'getSize'] + ); + + $this->product->expects($this->once()) + ->method('getDownloadableLinks') + ->willReturn(null); + $this->product->expects($this->once()) + ->method('getEntityId') + ->willReturn(123); + $this->linksFactory->expects($this->once()) + ->method('create') + ->willReturn($linksCollection); + $linksCollection->expects($this->once()) + ->method('addProductToFilter') + ->with(123) + ->willReturnSelf(); + $linksCollection->expects($this->once()) + ->method('getSize') + ->willReturn(1); + + $this->assertTrue($this->target->hasLinks($this->product)); + } + + public function testHasSamplesReturnsTrueWhenSampleCollectionHasItems(): void + { + $sampleCollection = $this->createMock(SampleCollection::class); + + $this->product->setData('downloadable_samples', $sampleCollection); + $sampleCollection->expects($this->once()) + ->method('getSize') + ->willReturn(1); + + $this->assertTrue($this->target->hasSamples($this->product)); + } + + public function testHasSamplesReturnsFalseWhenSampleCollectionIsEmpty(): void + { + $sampleCollection = $this->createMock(SampleCollection::class); + + $this->product->setData('downloadable_samples', $sampleCollection); + $sampleCollection->expects($this->once()) + ->method('getSize') + ->willReturn(0); + + $this->assertFalse($this->target->hasSamples($this->product)); + } + + public function testHasSamplesUsesDbFallbackWhenCachedSamplesAreUnavailable(): void + { + $sampleCollection = $this->createPartialMock( + SampleCollection::class, + ['addProductToFilter', 'getSize'] + ); + + $this->product->expects($this->once()) + ->method('getDownloadableSamples') + ->willReturn(null); + $this->product->expects($this->once()) + ->method('getEntityId') + ->willReturn(123); + $this->samplesFactory->expects($this->once()) + ->method('create') + ->willReturn($sampleCollection); + $sampleCollection->expects($this->once()) + ->method('addProductToFilter') + ->with(123) + ->willReturnSelf(); + $sampleCollection->expects($this->once()) + ->method('getSize') + ->willReturn(1); + + $this->assertTrue($this->target->hasSamples($this->product)); + } + public function testCheckProductBuyState() { $optionMock = $this->createPartialMock(Option::class, ['getValue']);