Skip to content

Commit

Permalink
Merge pull request #632 from magento-dragons/dragons-pr-2.1
Browse files Browse the repository at this point in the history
[DRAGONS] Bugfixes for 2.1.3
  • Loading branch information
Yaroslav Onischenko authored Nov 30, 2016
2 parents ec5a7f5 + 25fb122 commit b9c9449
Show file tree
Hide file tree
Showing 10 changed files with 588 additions and 95 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php
/**
* Copyright © 2016 Magento. All rights reserved.
* See COPYING.txt for license details.
*/

namespace Magento\Catalog\Model\Product\Pricing\Renderer;

/**
* Resolver provided to check is product available for sale
*/
class SalableResolver implements SalableResolverInterface
{
/**
* Check is product available for sale
*
* @param \Magento\Framework\Pricing\SaleableInterface $salableItem
* @return boolean
*/
public function isSalable(\Magento\Framework\Pricing\SaleableInterface $salableItem)
{
return $salableItem->getCanShowPrice() !== false && $salableItem->isSalable();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php
/**
* Copyright © 2016 Magento. All rights reserved.
* See COPYING.txt for license details.
*/

namespace Magento\Catalog\Model\Product\Pricing\Renderer;

/**
* Interface resolver provided to check is product available for sale
*/
interface SalableResolverInterface
{
/**
* Check is product available for sale
*
* @param \Magento\Framework\Pricing\SaleableInterface $salableItem
* @return boolean
*/
public function isSalable(\Magento\Framework\Pricing\SaleableInterface $salableItem);
}
33 changes: 32 additions & 1 deletion app/code/Magento/Catalog/Pricing/Render/FinalPriceBox.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@
use Magento\Framework\Pricing\Render;
use Magento\Framework\Pricing\Render\PriceBox as BasePriceBox;
use Magento\Msrp\Pricing\Price\MsrpPrice;
use Magento\Catalog\Model\Product\Pricing\Renderer\SalableResolverInterface;
use Magento\Framework\View\Element\Template\Context;
use Magento\Framework\Pricing\SaleableInterface;
use Magento\Framework\Pricing\Price\PriceInterface;
use Magento\Framework\Pricing\Render\RendererPool;

/**
* Class for final_price rendering
Expand All @@ -19,12 +24,38 @@
*/
class FinalPriceBox extends BasePriceBox
{
/**
* @var SalableResolverInterface
*/
private $salableResolver;

/**
* @param Context $context
* @param SaleableInterface $saleableItem
* @param PriceInterface $price
* @param RendererPool $rendererPool
* @param array $data
* @param SalableResolverInterface $salableResolver
*/
public function __construct(
Context $context,
SaleableInterface $saleableItem,
PriceInterface $price,
RendererPool $rendererPool,
array $data = [],
SalableResolverInterface $salableResolver = null
) {
parent::__construct($context, $saleableItem, $price, $rendererPool, $data);
$this->salableResolver = $salableResolver ?: \Magento\Framework\App\ObjectManager::getInstance()
->get(SalableResolverInterface::class);
}

/**
* @return string
*/
protected function _toHtml()
{
if (!$this->getSaleableItem() || $this->getSaleableItem()->getCanShowPrice() === false) {
if (!$this->salableResolver->isSalable($this->getSaleableItem())) {
return '';
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php
/**
* Copyright © 2016 Magento. All rights reserved.
* See COPYING.txt for license details.
*/

namespace Magento\Catalog\Test\Unit\Model\Product\Pricing\Renderer;

class SalableResolverTest extends \PHPUnit_Framework_TestCase
{
/**
* @var \Magento\Catalog\Model\Product\Pricing\Renderer\SalableResolver
*/
protected $object;

/**
* @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject
*/
protected $product;

protected function setUp()
{
$this->product = $this->getMock(
\Magento\Catalog\Model\Product::class,
['__wakeup', 'getCanShowPrice', 'isSalable'],
[],
'',
false
);

$objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
$this->object = $objectManager->getObject(
\Magento\Catalog\Model\Product\Pricing\Renderer\SalableResolver::class
);
}

public function testSalableItem()
{
$this->product->expects($this->any())
->method('getCanShowPrice')
->willReturn(true);

$this->product->expects($this->any())->method('isSalable')->willReturn(true);

$result = $this->object->isSalable($this->product);
$this->assertTrue($result);
}

public function testNotSalableItem()
{
$this->product->expects($this->any())
->method('getCanShowPrice')
->willReturn(true);

$this->product->expects($this->any())->method('isSalable')->willReturn(false);

$result = $this->object->isSalable($this->product);
$this->assertFalse($result);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

namespace Magento\Catalog\Test\Unit\Pricing\Render;

use Magento\Catalog\Model\Product\Pricing\Renderer\SalableResolverInterface;

/**
* Class FinalPriceBoxTest
*/
Expand Down Expand Up @@ -56,11 +58,16 @@ class FinalPriceBoxTest extends \PHPUnit_Framework_TestCase
*/
protected $price;

/**
* @var SalableResolverInterface|\PHPUnit_Framework_MockObject_MockObject
*/
private $salableResolverMock;

protected function setUp()
{
$this->product = $this->getMock(
'Magento\Catalog\Model\Product',
['getPriceInfo', '__wakeup', 'getCanShowPrice'],
\Magento\Catalog\Model\Product::class,
['getPriceInfo', '__wakeup', 'getCanShowPrice', 'isSalable'],
[],
'',
false
Expand All @@ -77,9 +84,7 @@ protected function setUp()
$this->priceBox = $this->getMock('Magento\Framework\Pricing\Render\PriceBox', [], [], '', false);
$this->logger = $this->getMock('Psr\Log\LoggerInterface');

$this->layout->expects($this->any())
->method('getBlock')
->will($this->returnValue($this->priceBox));
$this->layout->expects($this->any())->method('getBlock')->willReturn($this->priceBox);

$cacheState = $this->getMockBuilder(\Magento\Framework\App\Cache\StateInterface::class)
->getMockForAbstractClass();
Expand All @@ -92,13 +97,10 @@ protected function setUp()
->disableOriginalConstructor()
->getMock();

$urlBuilder = $this->getMockBuilder(\Magento\Framework\UrlInterface::class)
->getMockForAbstractClass();
$urlBuilder = $this->getMockBuilder(\Magento\Framework\UrlInterface::class)->getMockForAbstractClass();

$store = $this->getMockBuilder(\Magento\Store\Api\Data\StoreInterface::class)
->getMockForAbstractClass();

$storeManager = $this->getMockBuilder('\Magento\Store\Model\StoreManagerInterface')
$store = $this->getMockBuilder(\Magento\Store\Api\Data\StoreInterface::class)->getMockForAbstractClass();
$storeManager = $this->getMockBuilder(\Magento\Store\Model\StoreManagerInterface::class)
->setMethods(['getStore', 'getCode'])
->getMockForAbstractClass();
$storeManager->expects($this->any())->method('getStore')->will($this->returnValue($store));
Expand Down Expand Up @@ -146,14 +148,19 @@ protected function setUp()
->will($this->returnValue(\Magento\Catalog\Pricing\Price\FinalPrice::PRICE_CODE));

$objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
$this->salableResolverMock = $this->getMockBuilder(SalableResolverInterface::class)
->disableOriginalConstructor()
->getMockForAbstractClass();

$this->object = $objectManager->getObject(
'Magento\Catalog\Pricing\Render\FinalPriceBox',
[
'context' => $context,
'saleableItem' => $this->product,
'rendererPool' => $this->rendererPool,
'price' => $this->price,
'data' => ['zone' => 'test_zone', 'list_category_page' => true]
'data' => ['zone' => 'test_zone', 'list_category_page' => true],
'salableResolver' => $this->salableResolverMock
]
);
}
Expand All @@ -171,6 +178,8 @@ public function testRenderMsrpDisabled()
->with($this->equalTo($this->product))
->will($this->returnValue(false));

$this->salableResolverMock->expects($this->once())->method('isSalable')->with($this->product)->willReturn(true);

$result = $this->object->toHtml();

//assert price wrapper
Expand All @@ -179,6 +188,18 @@ public function testRenderMsrpDisabled()
$this->assertRegExp('/[final_price]/', $result);
}

public function testNotSalableItem()
{
$this->salableResolverMock
->expects($this->once())
->method('isSalable')
->with($this->product)
->willReturn(false);
$result = $this->object->toHtml();

$this->assertEmpty($result);
}

public function testRenderMsrpEnabled()
{
$priceType = $this->getMock('Magento\Msrp\Pricing\Price\MsrpPrice', [], [], '', false);
Expand Down Expand Up @@ -213,6 +234,8 @@ public function testRenderMsrpEnabled()
->with('msrp_price', $this->product, $arguments)
->will($this->returnValue($priceBoxRender));

$this->salableResolverMock->expects($this->once())->method('isSalable')->with($this->product)->willReturn(true);

$result = $this->object->toHtml();

//assert price wrapper
Expand All @@ -232,6 +255,8 @@ public function testRenderMsrpNotRegisteredException()
->with($this->equalTo('msrp_price'))
->will($this->throwException(new \InvalidArgumentException()));

$this->salableResolverMock->expects($this->once())->method('isSalable')->with($this->product)->willReturn(true);

$result = $this->object->toHtml();

//assert price wrapper
Expand Down
3 changes: 2 additions & 1 deletion app/code/Magento/Catalog/etc/di.xml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
<preference for="Magento\Catalog\Api\AttributeSetRepositoryInterface" type="Magento\Catalog\Model\Product\Attribute\SetRepository" />
<preference for="Magento\Catalog\Api\ProductManagementInterface" type="Magento\Catalog\Model\ProductManagement" />
<preference for="Magento\Catalog\Api\AttributeSetFinderInterface" type="Magento\Catalog\Model\Product\Attribute\AttributeSetFinder" />
<preference for="Magento\Catalog\Model\Product\Pricing\Renderer\SalableResolverInterface" type="Magento\Catalog\Model\Product\Pricing\Renderer\SalableResolver"/>
<type name="Magento\Customer\Model\ResourceModel\Visitor">
<plugin name="catalogLog" type="Magento\Catalog\Model\Plugin\Log" />
</type>
Expand Down Expand Up @@ -615,7 +616,7 @@
</arguments>
</type>
<type name="Magento\Eav\Model\EavCustomAttributeTypeLocator">
<arguments>
<arguments>
<argument name="serviceEntityTypeMap" xsi:type="array">
<item name="Magento\Catalog\Api\Data\ProductInterface" xsi:type="const">Magento\Catalog\Api\Data\ProductAttributeInterface::ENTITY_TYPE_CODE</item>
</argument>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,7 @@ public function __construct(

/**
* @param \Magento\Framework\Pricing\SaleableInterface|\Magento\Catalog\Model\Product $product
* @return float
* @throws \Magento\Framework\Exception\LocalizedException
* @return float|null
*/
public function resolvePrice(\Magento\Framework\Pricing\SaleableInterface $product)
{
Expand All @@ -64,12 +63,7 @@ public function resolvePrice(\Magento\Framework\Pricing\SaleableInterface $produ
$productPrice = $this->priceResolver->resolvePrice($subProduct);
$price = $price ? min($price, $productPrice) : $productPrice;
}
if ($price === null) {
throw new \Magento\Framework\Exception\LocalizedException(
__('Configurable product "%1" does not have sub-products', $product->getSku())
);
}

return (float)$price;
return $price === null ? null : (float)$price;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,20 +53,18 @@ protected function setUp()

/**
* situation: There are no used products, thus there are no prices
*
* @expectedException \Magento\Framework\Exception\LocalizedException
*/
public function testResolvePriceWithNoPrices()
{
$product = $this->getMockBuilder(
\Magento\Catalog\Model\Product::class
)->disableOriginalConstructor()->getMock();

$product->expects($this->once())->method('getSku')->willReturn('Kiwi');
$product->expects($this->never())->method('getSku');

$this->lowestPriceOptionsProvider->expects($this->once())->method('getProducts')->willReturn([]);

$this->resolver->resolvePrice($product);
$this->assertNull($this->resolver->resolvePrice($product));
}

/**
Expand Down
Loading

0 comments on commit b9c9449

Please sign in to comment.