Skip to content

Commit fb6fc35

Browse files
committed
Merge remote-tracking branch 'origin/MAGETWO-67352' into bugfix
2 parents b3d6dc8 + f6757ba commit fb6fc35

File tree

9 files changed

+698
-3
lines changed

9 files changed

+698
-3
lines changed
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+
}

app/code/Magento/CheckoutAgreements/etc/di.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,7 @@
1919
<plugin name="validate-agreements" type="Magento\CheckoutAgreements\Model\Checkout\Plugin\Validation"/>
2020
</type>
2121
<preference for="Magento\Checkout\Api\AgreementsValidatorInterface" type="Magento\CheckoutAgreements\Model\AgreementsValidator" />
22+
<type name="Magento\Checkout\Api\GuestPaymentInformationManagementInterface">
23+
<plugin name="validate-guest-agreements" type="Magento\CheckoutAgreements\Model\Checkout\Plugin\GuestValidation"/>
24+
</type>
2225
</config>

app/code/Magento/CheckoutAgreements/etc/module.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@
66
*/
77
-->
88
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
9-
<module name="Magento_CheckoutAgreements" setup_version="2.0.1">
9+
<module name="Magento_CheckoutAgreements" setup_version="2.2.0">
1010
<sequence>
1111
<module name="Magento_Store"/>
12+
<module name="Magento_Checkout"/>
1213
</sequence>
1314
</module>
1415
</config>

app/code/Magento/CheckoutAgreements/view/frontend/web/js/model/agreement-validator.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,21 @@ define([
2020
* @returns {Boolean}
2121
*/
2222
validate: function () {
23+
var isValid = true;
24+
2325
if (!agreementsConfig.isEnabled || $(agreementsInputPath).length === 0) {
2426
return true;
2527
}
2628

27-
return $.validator.validateSingleElement(agreementsInputPath, {
28-
errorElement: 'div'
29+
$(agreementsInputPath).each(function (index, element) {
30+
if (!$.validator.validateSingleElement(element, {
31+
errorElement: 'div'
32+
})) {
33+
isValid = false;
34+
}
2935
});
36+
37+
return isValid;
3038
}
3139
};
3240
});

0 commit comments

Comments
 (0)