Skip to content

Commit 153c1d9

Browse files
author
Bohdan Korablov
committed
Merge remote-tracking branch 'mainline/develop' into MAGETWO-69983
2 parents e4baef0 + ca01449 commit 153c1d9

File tree

33 files changed

+1365
-450
lines changed

33 files changed

+1365
-450
lines changed

app/code/Magento/Bundle/Model/CartItemProcessor.php

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -84,26 +84,28 @@ public function processOptions(CartItemInterface $cartItem)
8484
$productOptions = [];
8585
$bundleOptions = $cartItem->getBuyRequest()->getBundleOption();
8686
$bundleOptionsQty = $cartItem->getBuyRequest()->getBundleOptionQty();
87-
foreach ($bundleOptions as $optionId => $optionSelections) {
88-
if (empty($optionSelections)) {
89-
continue;
90-
}
91-
$optionSelections = is_array($optionSelections) ? $optionSelections : [$optionSelections];
92-
$optionQty = isset($bundleOptionsQty[$optionId]) ? $bundleOptionsQty[$optionId] : 1;
87+
if (is_array($bundleOptions)) {
88+
foreach ($bundleOptions as $optionId => $optionSelections) {
89+
if (empty($optionSelections)) {
90+
continue;
91+
}
92+
$optionSelections = is_array($optionSelections) ? $optionSelections : [$optionSelections];
93+
$optionQty = isset($bundleOptionsQty[$optionId]) ? $bundleOptionsQty[$optionId] : 1;
9394

94-
/** @var \Magento\Bundle\Api\Data\BundleOptionInterface $productOption */
95-
$productOption = $this->bundleOptionFactory->create();
96-
$productOption->setOptionId($optionId);
97-
$productOption->setOptionSelections($optionSelections);
98-
$productOption->setOptionQty($optionQty);
99-
$productOptions[] = $productOption;
100-
}
95+
/** @var \Magento\Bundle\Api\Data\BundleOptionInterface $productOption */
96+
$productOption = $this->bundleOptionFactory->create();
97+
$productOption->setOptionId($optionId);
98+
$productOption->setOptionSelections($optionSelections);
99+
$productOption->setOptionQty($optionQty);
100+
$productOptions[] = $productOption;
101+
}
101102

102-
$extension = $this->productOptionExtensionFactory->create()->setBundleOptions($productOptions);
103-
if (!$cartItem->getProductOption()) {
104-
$cartItem->setProductOption($this->productOptionFactory->create());
103+
$extension = $this->productOptionExtensionFactory->create()->setBundleOptions($productOptions);
104+
if (!$cartItem->getProductOption()) {
105+
$cartItem->setProductOption($this->productOptionFactory->create());
106+
}
107+
$cartItem->getProductOption()->setExtensionAttributes($extension);
105108
}
106-
$cartItem->getProductOption()->setExtensionAttributes($extension);
107109
return $cartItem;
108110
}
109111
}

app/code/Magento/Bundle/Test/Unit/Model/CartItemProcessorTest.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,4 +180,22 @@ public function testProcessProductOptionsInvalidType()
180180
$cartItemMock->expects($this->once())->method('getProductType')->willReturn(Type::TYPE_SIMPLE);
181181
$this->assertSame($cartItemMock, $this->model->processOptions($cartItemMock));
182182
}
183+
184+
public function testProcessProductOptionsifBundleOptionsNotExists()
185+
{
186+
$buyRequestMock = new \Magento\Framework\DataObject(
187+
[]
188+
);
189+
$methods = ['getProductType', 'getBuyRequest'];
190+
$cartItemMock = $this->getMock(
191+
\Magento\Quote\Model\Quote\Item::class,
192+
$methods,
193+
[],
194+
'',
195+
false
196+
);
197+
$cartItemMock->expects($this->once())->method('getProductType')->willReturn(Type::TYPE_BUNDLE);
198+
$cartItemMock->expects($this->exactly(2))->method('getBuyRequest')->willReturn($buyRequestMock);
199+
$this->assertSame($cartItemMock, $this->model->processOptions($cartItemMock));
200+
}
183201
}

app/code/Magento/CatalogWidget/Model/Rule/Condition/Product.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ protected function addNotGlobalAttribute(
222222
public function getMappedSqlField()
223223
{
224224
$result = '';
225-
if ($this->getAttribute() == 'category_ids') {
225+
if (in_array($this->getAttribute(), ['category_ids', 'sku'])) {
226226
$result = parent::getMappedSqlField();
227227
} elseif (isset($this->joinedAttributes[$this->getAttribute()])) {
228228
$result = $this->joinedAttributes[$this->getAttribute()];

app/code/Magento/CatalogWidget/Test/Unit/Model/Rule/Condition/ProductTest.php

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,11 @@ protected function setUp()
3636
'',
3737
false
3838
);
39-
$eavConfig->expects($this->once())->method('getAttribute')->willReturn($this->attributeMock);
39+
$eavConfig->expects($this->any())->method('getAttribute')->willReturn($this->attributeMock);
4040
$ruleMock = $this->getMock(\Magento\SalesRule\Model\Rule::class, [], [], '', false);
4141
$storeManager = $this->getMock(\Magento\Store\Model\StoreManagerInterface::class);
4242
$storeMock = $this->getMock(\Magento\Store\Api\Data\StoreInterface::class);
43-
$storeManager->expects($this->once())->method('getStore')->willReturn($storeMock);
43+
$storeManager->expects($this->any())->method('getStore')->willReturn($storeMock);
4444
$this->resourceMock = $this->getMock(
4545
\Magento\Indexer\Model\ResourceModel\FrontendResource::class,
4646
[],
@@ -49,8 +49,8 @@ protected function setUp()
4949
false
5050
);
5151
$productResource = $this->getMock(\Magento\Catalog\Model\ResourceModel\Product::class, [], [], '', false);
52-
$productResource->expects($this->once())->method('loadAllAttributes')->willReturnSelf();
53-
$productResource->expects($this->once())->method('getAttributesByCode')->willReturn([]);
52+
$productResource->expects($this->any())->method('loadAllAttributes')->willReturnSelf();
53+
$productResource->expects($this->any())->method('getAttributesByCode')->willReturn([]);
5454
$this->model = $objectManagerHelper->getObject(
5555
\Magento\CatalogWidget\Model\Rule\Condition\Product::class,
5656
[
@@ -88,4 +88,10 @@ public function testAddToCollection()
8888
$this->resourceMock->expects($this->once())->method('getMainTable')->willReturn('catalog_product_index_eav');
8989
$this->model->addToCollection($collectionMock);
9090
}
91+
92+
public function testGetMappedSqlFieldSku()
93+
{
94+
$this->model->setAttribute('sku');
95+
$this->assertEquals('e.sku', $this->model->getMappedSqlField());
96+
}
9197
}
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\CheckoutAgreements\Model\Checkout\Plugin;
7+
8+
use Magento\CheckoutAgreements\Model\AgreementsProvider;
9+
use Magento\Store\Model\ScopeInterface;
10+
11+
/**
12+
* Class GuestValidation
13+
*
14+
* Plugin that checks if checkout agreement enabled and validates all agreements.
15+
* Current plugin is duplicate from Magento\CheckoutAgreements\Model\Checkout\Plugin\Validation due to different
16+
* interfaces of payment information and makes check before processing of payment information.
17+
*/
18+
class GuestValidation
19+
{
20+
/**
21+
* @var \Magento\Framework\App\Config\ScopeConfigInterface
22+
*/
23+
private $scopeConfiguration;
24+
25+
/**
26+
* @var \Magento\CheckoutAgreements\Api\CheckoutAgreementsRepositoryInterface
27+
*/
28+
private $checkoutAgreementsRepository;
29+
30+
/**
31+
* @var \Magento\Checkout\Api\AgreementsValidatorInterface
32+
*/
33+
private $agreementsValidator;
34+
35+
/**
36+
* @param \Magento\Checkout\Api\AgreementsValidatorInterface $agreementsValidator
37+
* @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfiguration
38+
* @param \Magento\CheckoutAgreements\Api\CheckoutAgreementsRepositoryInterface $checkoutAgreementsRepository
39+
*/
40+
public function __construct(
41+
\Magento\Checkout\Api\AgreementsValidatorInterface $agreementsValidator,
42+
\Magento\Framework\App\Config\ScopeConfigInterface $scopeConfiguration,
43+
\Magento\CheckoutAgreements\Api\CheckoutAgreementsRepositoryInterface $checkoutAgreementsRepository
44+
) {
45+
$this->agreementsValidator = $agreementsValidator;
46+
$this->scopeConfiguration = $scopeConfiguration;
47+
$this->checkoutAgreementsRepository = $checkoutAgreementsRepository;
48+
}
49+
50+
/**
51+
* @param \Magento\Checkout\Api\GuestPaymentInformationManagementInterface $subject
52+
* @param string $cartId
53+
* @param string $email
54+
* @param \Magento\Quote\Api\Data\PaymentInterface $paymentMethod
55+
* @param \Magento\Quote\Api\Data\AddressInterface|null $billingAddress
56+
* @return void
57+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
58+
*/
59+
public function beforeSavePaymentInformationAndPlaceOrder(
60+
\Magento\Checkout\Api\GuestPaymentInformationManagementInterface $subject,
61+
$cartId,
62+
$email,
63+
\Magento\Quote\Api\Data\PaymentInterface $paymentMethod,
64+
\Magento\Quote\Api\Data\AddressInterface $billingAddress = null
65+
) {
66+
if ($this->isAgreementEnabled()) {
67+
$this->validateAgreements($paymentMethod);
68+
}
69+
}
70+
71+
/**
72+
* @param \Magento\Checkout\Api\GuestPaymentInformationManagementInterface $subject
73+
* @param string $cartId
74+
* @param string $email
75+
* @param \Magento\Quote\Api\Data\PaymentInterface $paymentMethod
76+
* @param \Magento\Quote\Api\Data\AddressInterface|null $billingAddress
77+
* @return void
78+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
79+
*/
80+
public function beforeSavePaymentInformation(
81+
\Magento\Checkout\Api\GuestPaymentInformationManagementInterface $subject,
82+
$cartId,
83+
$email,
84+
\Magento\Quote\Api\Data\PaymentInterface $paymentMethod,
85+
\Magento\Quote\Api\Data\AddressInterface $billingAddress = null
86+
) {
87+
if ($this->isAgreementEnabled()) {
88+
$this->validateAgreements($paymentMethod);
89+
}
90+
}
91+
92+
/**
93+
* @param \Magento\Quote\Api\Data\PaymentInterface $paymentMethod
94+
* @throws \Magento\Framework\Exception\CouldNotSaveException
95+
* @return void
96+
*/
97+
private function validateAgreements(\Magento\Quote\Api\Data\PaymentInterface $paymentMethod)
98+
{
99+
$agreements = $paymentMethod->getExtensionAttributes() === null
100+
? []
101+
: $paymentMethod->getExtensionAttributes()->getAgreementIds();
102+
103+
if (!$this->agreementsValidator->isValid($agreements)) {
104+
throw new \Magento\Framework\Exception\CouldNotSaveException(
105+
__('Please agree to all the terms and conditions before placing the order.')
106+
);
107+
}
108+
}
109+
110+
/**
111+
* Verify if agreement validation needed
112+
* @return bool
113+
*/
114+
private function isAgreementEnabled()
115+
{
116+
$isAgreementsEnabled = $this->scopeConfiguration->isSetFlag(
117+
AgreementsProvider::PATH_ENABLED,
118+
ScopeInterface::SCOPE_STORE
119+
);
120+
$agreementsList = $isAgreementsEnabled ? $this->checkoutAgreementsRepository->getList() : [];
121+
return (bool)($isAgreementsEnabled && count($agreementsList) > 0);
122+
}
123+
}
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\CheckoutAgreements\Test\Unit\Model\Checkout\Plugin;
7+
8+
use Magento\CheckoutAgreements\Model\AgreementsProvider;
9+
use Magento\Store\Model\ScopeInterface;
10+
11+
class GuestValidationTest extends \PHPUnit_Framework_TestCase
12+
{
13+
/**
14+
* @var \Magento\CheckoutAgreements\Model\Checkout\Plugin\GuestValidation
15+
*/
16+
private $model;
17+
18+
/**
19+
* @var \PHPUnit_Framework_MockObject_MockObject
20+
*/
21+
private $agreementsValidatorMock;
22+
23+
/**
24+
* @var \PHPUnit_Framework_MockObject_MockObject
25+
*/
26+
private $subjectMock;
27+
28+
/**
29+
* @var \PHPUnit_Framework_MockObject_MockObject
30+
*/
31+
private $paymentMock;
32+
33+
/**
34+
* @var \PHPUnit_Framework_MockObject_MockObject
35+
*/
36+
private $addressMock;
37+
38+
/**
39+
* @var \PHPUnit_Framework_MockObject_MockObject
40+
*/
41+
private $extensionAttributesMock;
42+
43+
/**
44+
* @var \PHPUnit_Framework_MockObject_MockObject
45+
*/
46+
private $repositoryMock;
47+
48+
/**
49+
* @var \PHPUnit_Framework_MockObject_MockObject
50+
*/
51+
private $scopeConfigMock;
52+
53+
protected function setUp()
54+
{
55+
$this->agreementsValidatorMock = $this->getMock(\Magento\Checkout\Api\AgreementsValidatorInterface::class);
56+
$this->subjectMock = $this->getMock(\Magento\Checkout\Api\GuestPaymentInformationManagementInterface::class);
57+
$this->paymentMock = $this->getMock(\Magento\Quote\Api\Data\PaymentInterface::class);
58+
$this->addressMock = $this->getMock(\Magento\Quote\Api\Data\AddressInterface::class);
59+
$this->extensionAttributesMock = $this->getMock(
60+
\Magento\Quote\Api\Data\PaymentExtension::class,
61+
['getAgreementIds'],
62+
[],
63+
'',
64+
false
65+
);
66+
$this->scopeConfigMock = $this->getMock(\Magento\Framework\App\Config\ScopeConfigInterface::class);
67+
$this->repositoryMock = $this->getMock(
68+
\Magento\CheckoutAgreements\Api\CheckoutAgreementsRepositoryInterface::class
69+
);
70+
71+
$this->model = new \Magento\CheckoutAgreements\Model\Checkout\Plugin\GuestValidation(
72+
$this->agreementsValidatorMock,
73+
$this->scopeConfigMock,
74+
$this->repositoryMock
75+
);
76+
}
77+
78+
public function testBeforeSavePaymentInformationAndPlaceOrder()
79+
{
80+
$cartId = '100';
81+
$email = 'email@example.com';
82+
$agreements = [1, 2, 3];
83+
$this->scopeConfigMock
84+
->expects($this->once())
85+
->method('isSetFlag')
86+
->with(AgreementsProvider::PATH_ENABLED, ScopeInterface::SCOPE_STORE)
87+
->willReturn(true);
88+
$this->repositoryMock->expects($this->once())->method('getList')->willReturn([1]);
89+
$this->extensionAttributesMock->expects($this->once())->method('getAgreementIds')->willReturn($agreements);
90+
$this->agreementsValidatorMock->expects($this->once())->method('isValid')->with($agreements)->willReturn(true);
91+
$this->paymentMock->expects(static::atLeastOnce())
92+
->method('getExtensionAttributes')
93+
->willReturn($this->extensionAttributesMock);
94+
$this->model->beforeSavePaymentInformation(
95+
$this->subjectMock,
96+
$cartId,
97+
$email,
98+
$this->paymentMock,
99+
$this->addressMock
100+
);
101+
}
102+
103+
/**
104+
* @expectedException \Magento\Framework\Exception\CouldNotSaveException
105+
* @expectedExceptionMessage Please agree to all the terms and conditions before placing the order.
106+
*/
107+
public function testBeforeSavePaymentInformationAndPlaceOrderIfAgreementsNotValid()
108+
{
109+
$cartId = 100;
110+
$email = 'email@example.com';
111+
$agreements = [1, 2, 3];
112+
$this->scopeConfigMock
113+
->expects($this->once())
114+
->method('isSetFlag')
115+
->with(AgreementsProvider::PATH_ENABLED, ScopeInterface::SCOPE_STORE)
116+
->willReturn(true);
117+
$this->repositoryMock->expects($this->once())->method('getList')->willReturn([1]);
118+
$this->extensionAttributesMock->expects($this->once())->method('getAgreementIds')->willReturn($agreements);
119+
$this->agreementsValidatorMock->expects($this->once())->method('isValid')->with($agreements)->willReturn(false);
120+
$this->paymentMock->expects(static::atLeastOnce())
121+
->method('getExtensionAttributes')
122+
->willReturn($this->extensionAttributesMock);
123+
$this->model->beforeSavePaymentInformation(
124+
$this->subjectMock,
125+
$cartId,
126+
$email,
127+
$this->paymentMock,
128+
$this->addressMock
129+
);
130+
}
131+
132+
public function testBeforeSavePaymentInformation()
133+
{
134+
$cartId = 100;
135+
$email = 'email@example.com';
136+
$agreements = [1, 2, 3];
137+
$this->scopeConfigMock
138+
->expects($this->once())
139+
->method('isSetFlag')
140+
->with(AgreementsProvider::PATH_ENABLED, ScopeInterface::SCOPE_STORE)
141+
->willReturn(true);
142+
$this->repositoryMock->expects($this->once())->method('getList')->willReturn([1]);
143+
$this->extensionAttributesMock->expects($this->once())->method('getAgreementIds')->willReturn($agreements);
144+
$this->agreementsValidatorMock->expects($this->once())->method('isValid')->with($agreements)->willReturn(true);
145+
$this->paymentMock->expects(static::atLeastOnce())
146+
->method('getExtensionAttributes')
147+
->willReturn($this->extensionAttributesMock);
148+
$this->model->beforeSavePaymentInformation(
149+
$this->subjectMock,
150+
$cartId,
151+
$email,
152+
$this->paymentMock,
153+
$this->addressMock
154+
);
155+
}
156+
}

0 commit comments

Comments
 (0)