Skip to content

Commit f0978c7

Browse files
committed
Merge branch 'develop' into Fearless-Kiwis-MAGETWO-50123-Unable-to-assign-blank-value-to-attribute
2 parents eb5422a + 25b6600 commit f0978c7

File tree

143 files changed

+6396
-741
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

143 files changed

+6396
-741
lines changed

app/code/Magento/Braintree/Gateway/Response/RiskDataHandler.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ class RiskDataHandler implements HandlerInterface
2424
*/
2525
const RISK_DATA_DECISION = 'riskDataDecision';
2626

27+
/**
28+
* Risk data Review status
29+
*/
30+
private static $statusReview = 'Review';
31+
2732
/**
2833
* @var SubjectReader
2934
*/
@@ -62,5 +67,10 @@ public function handle(array $handlingSubject, array $response)
6267

6368
$payment->setAdditionalInformation(self::RISK_DATA_ID, $transaction->riskData->id);
6469
$payment->setAdditionalInformation(self::RISK_DATA_DECISION, $transaction->riskData->decision);
70+
71+
// mark payment as fraud
72+
if ($transaction->riskData->decision === self::$statusReview) {
73+
$payment->setIsFraudDetected(true);
74+
}
6575
}
6676
}

app/code/Magento/Braintree/Test/Unit/Gateway/Response/RiskDataHandlerTest.php

Lines changed: 57 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55
*/
66
namespace Magento\Braintree\Test\Unit\Gateway\Response;
77

8-
use Braintree\RiskData;
98
use Braintree\Transaction;
10-
use Magento\Sales\Model\Order\Payment;
119
use Magento\Braintree\Gateway\Helper\SubjectReader;
1210
use Magento\Braintree\Gateway\Response\RiskDataHandler;
1311
use Magento\Payment\Gateway\Data\PaymentDataObjectInterface;
12+
use Magento\Sales\Model\Order\Payment;
13+
use PHPUnit_Framework_MockObject_MockObject as MockObject;
1414

1515
/**
1616
* Class RiskDataHandlerTest
@@ -25,99 +25,95 @@ class RiskDataHandlerTest extends \PHPUnit_Framework_TestCase
2525
private $riskDataHandler;
2626

2727
/**
28-
* @var SubjectReader|\PHPUnit_Framework_MockObject_MockObject
28+
* @var SubjectReader|MockObject
2929
*/
30-
private $subjectReaderMock;
30+
private $subjectReader;
3131

3232
/**
3333
* Set up
3434
*/
3535
protected function setUp()
3636
{
37-
$this->subjectReaderMock = $this->getMockBuilder(SubjectReader::class)
37+
$this->subjectReader = $this->getMockBuilder(SubjectReader::class)
3838
->disableOriginalConstructor()
39+
->setMethods(['readPayment', 'readTransaction'])
3940
->getMock();
4041

41-
$this->riskDataHandler = new RiskDataHandler($this->subjectReaderMock);
42+
$this->riskDataHandler = new RiskDataHandler($this->subjectReader);
4243
}
4344

4445
/**
45-
* Run test for handle method
46+
* Test for handle method
47+
* @covers \Magento\Braintree\Gateway\Response\RiskDataHandler::handle
48+
* @param string $riskDecision
49+
* @param boolean $isFraud
50+
* @dataProvider riskDataProvider
4651
*/
47-
public function testHandle()
52+
public function testHandle($riskDecision, $isFraud)
4853
{
49-
$paymentData = $this->getPaymentDataObjectMock();
50-
$transaction = $this->getBraintreeTransactionMock();
54+
/** @var Payment|MockObject $payment */
55+
$payment = $this->getMockBuilder(Payment::class)
56+
->disableOriginalConstructor()
57+
->setMethods(['setAdditionalInformation', 'setIsFraudDetected'])
58+
->getMock();
59+
/** @var PaymentDataObjectInterface|MockObject $paymentDO */
60+
$paymentDO = $this->getMock(PaymentDataObjectInterface::class);
61+
$paymentDO->expects(self::once())
62+
->method('getPayment')
63+
->willReturn($payment);
64+
65+
$transaction = Transaction::factory([
66+
'riskData' => [
67+
'id' => 'test-id',
68+
'decision' => $riskDecision
69+
]
70+
]);
5171

5272
$response = [
5373
'object' => $transaction
5474
];
5575
$handlingSubject = [
56-
'payment' =>$paymentData,
76+
'payment' => $paymentDO,
5777
];
5878

59-
$this->subjectReaderMock->expects(self::once())
79+
$this->subjectReader->expects(static::once())
6080
->method('readPayment')
6181
->with($handlingSubject)
62-
->willReturn($paymentData);
63-
$this->subjectReaderMock->expects(self::once())
82+
->willReturn($paymentDO);
83+
$this->subjectReader->expects(static::once())
6484
->method('readTransaction')
6585
->with($response)
6686
->willReturn($transaction);
6787

68-
$this->riskDataHandler->handle($handlingSubject, $response);
69-
}
70-
71-
/**
72-
* @return \PHPUnit_Framework_MockObject_MockObject
73-
*/
74-
private function getBraintreeTransactionMock()
75-
{
76-
$transaction = \Braintree\Transaction::factory([]);
77-
$transaction->_set(
78-
'riskData',
79-
RiskData::factory(
80-
[
81-
'id' => 'test-id',
82-
'decision' => 'test-decision',
83-
]
84-
)
85-
);
86-
87-
return $transaction;
88-
}
89-
90-
/**
91-
* @return \PHPUnit_Framework_MockObject_MockObject
92-
*/
93-
private function getPaymentDataObjectMock()
94-
{
95-
$mock = $this->getMockBuilder(PaymentDataObjectInterface::class)
96-
->getMockForAbstractClass();
88+
$payment->expects(static::at(0))
89+
->method('setAdditionalInformation')
90+
->with(RiskDataHandler::RISK_DATA_ID, 'test-id');
91+
$payment->expects(static::at(1))
92+
->method('setAdditionalInformation')
93+
->with(RiskDataHandler::RISK_DATA_DECISION, $riskDecision);
9794

98-
$mock->expects(static::once())
99-
->method('getPayment')
100-
->willReturn($this->getPaymentMock());
95+
if (!$isFraud) {
96+
$payment->expects(static::never())
97+
->method('setIsFraudDetected');
98+
} else {
99+
$payment->expects(static::once())
100+
->method('setIsFraudDetected')
101+
->with(true);
102+
}
101103

102-
return $mock;
104+
$this->riskDataHandler->handle($handlingSubject, $response);
103105
}
104106

105107
/**
106-
* @return \PHPUnit_Framework_MockObject_MockObject
108+
* Get list of variations to test fraud
109+
* @return array
107110
*/
108-
private function getPaymentMock()
111+
public function riskDataProvider()
109112
{
110-
$paymentMock = $this->getMockBuilder(Payment::class)
111-
->disableOriginalConstructor()
112-
->getMock();
113-
114-
$paymentMock->expects(self::at(0))
115-
->method('setAdditionalInformation')
116-
->with(RiskDataHandler::RISK_DATA_ID, 'test-id');
117-
$paymentMock->expects(self::at(1))
118-
->method('setAdditionalInformation')
119-
->with(RiskDataHandler::RISK_DATA_DECISION, 'test-decision');
120-
121-
return $paymentMock;
113+
return [
114+
['decision' => 'Not Evaluated', 'isFraud' => false],
115+
['decision' => 'Approve', 'isFraud' => false],
116+
['decision' => 'Review', 'isFraud' => true],
117+
];
122118
}
123119
}

app/code/Magento/Braintree/etc/adminhtml/system.xml

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,14 @@
88
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
99
<system>
1010
<section id="payment">
11-
<group id="braintree_section" translate="label" type="text" sortOrder="2" showInDefault="1" showInWebsite="1" showInStore="1">
12-
<label>Braintree</label>
13-
<comment><![CDATA[Accept credit/debit cards and PayPal in your Magento store. No setup or monthly fees and your customers never leave your store to complete the purchase.]]></comment>
14-
<attribute type="expanded">1</attribute>
15-
<fieldset_css>complex braintree-section</fieldset_css>
16-
<frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Group</frontend_model>
17-
<group id="braintree" translate="label" type="text" sortOrder="25" showInDefault="1" showInWebsite="1" showInStore="1">
18-
<label><![CDATA[&nbsp;]]></label>
11+
<group id="braintree_section" sortOrder="6" showInDefault="0" showInWebsite="0" showInStore="0">
12+
<group id="braintree" translate="label comment" type="text" showInDefault="1" showInWebsite="1" showInStore="1">
13+
<label>Braintree</label>
14+
<comment><![CDATA[Accept credit/debit cards and PayPal in your Magento store.<br/>No setup or monthly fees and your customers never leave your store to complete the purchase.]]></comment>
15+
<fieldset_css>complex braintree-section</fieldset_css>
1916
<frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Payment</frontend_model>
2017
<attribute type="activity_path">payment/braintree/active</attribute>
21-
<more_url>https://articles.braintreepayments.com/guides/magento/configuration</more_url>
18+
<attribute type="displayIn">recommended_solutions</attribute>
2219
<field id="active" translate="label" type="select" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="0">
2320
<label>Enable this Solution</label>
2421
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
@@ -43,8 +40,11 @@
4340
<group id="braintree_required"/>
4441
</requires>
4542
</field>
43+
<group id="configuration_details" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="4">
44+
<comment>http://docs.magento.com/m2/ce/user_guide/payment/braintree.html</comment>
45+
<frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Hint</frontend_model>
46+
</group>
4647
<group id="braintree_required" translate="label" showInDefault="1" showInWebsite="1" sortOrder="5">
47-
<comment><![CDATA[<a href="https://www.braintreegateway.com/login" target="_blank">Click here to login to your existing Braintree account</a>. Or to setup a new account and accept payments on your website, <a href="https://apply.braintreegateway.com/signup/us" target="_blank">click here to signup for a Braintree account</a>.<br><br>Powered by <a href="https://www.braintreepayments.com/features/hosted-fields" target="_blank">Braintree v.zero with Hosted Fields</a> latest technology. Hosted Fields are small, transparent iframes that replace the sensitive credit card inputs in your checkout flow - helping you meet the latest data security requirements while ensuring your customization doesn't suffer. <a href="https://www.braintreepayments.com/features/hosted-fields" target="_blank">Find out more</a>.]]></comment>
4848
<label>Basic Braintree Settings</label>
4949
<attribute type="expanded">1</attribute>
5050
<frontend_model>Magento\Config\Block\System\Config\Form\Fieldset</frontend_model>

app/code/Magento/Braintree/etc/config.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
<can_void>1</can_void>
2727
<can_cancel>1</can_cancel>
2828
<can_edit>1</can_edit>
29+
<can_review_payment>1</can_review_payment>
30+
<can_deny_payment>1</can_deny_payment>
2931
<cctypes>AE,VI,MC,DI,JCB,CUP,DN,MI</cctypes>
3032
<useccv>1</useccv>
3133
<cctypes_braintree_mapper><![CDATA[{"american-express":"AE","discover":"DI","jcb":"JCB","mastercard":"MC","master-card":"MC","visa":"VI","maestro":"MI","diners-club":"DN","unionpay":"CUP"}]]></cctypes_braintree_mapper>

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@
133133
<item name="void" xsi:type="string">BraintreeVoidCommand</item>
134134
<item name="refund" xsi:type="string">BraintreeRefundCommand</item>
135135
<item name="cancel" xsi:type="string">BraintreeVoidCommand</item>
136+
<item name="deny_payment" xsi:type="string">BraintreeVoidCommand</item>
136137
</argument>
137138
</arguments>
138139
</virtualType>

app/code/Magento/Braintree/i18n/en_US.csv

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,4 +164,5 @@ Debug,Debug
164164
"europe_bank_accout","Europe bank account"
165165
"credit_card","Credit card"
166166
"apple_pay_card","Apple pay card"
167-
"android_pay_card","Android pay card"
167+
"android_pay_card","Android pay card"
168+
"Accept credit/debit cards and PayPal in your Magento store.<br/>No setup or monthly fees and your customers never leave your store to complete the purchase.","Accept credit/debit cards and PayPal in your Magento store.<br/>No setup or monthly fees and your customers never leave your store to complete the purchase."

app/code/Magento/Braintree/view/adminhtml/web/styles.css

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33
* See COPYING.txt for license details.
44
*/
55

6-
.braintree-section .entry-edit-head > .config-heading .heading strong {padding-left:150px;background:url(images/braintree_logo.png) no-repeat 0 0 / 145px auto;line-height:36px;}
7-
.braintree-section .entry-edit-head > .config-heading:before {background: url("images/braintree_allinone.png") no-repeat 0 0 / 100% auto;content: "";display: inline;float: right;height: 35px;width: 280px;}
6+
.braintree-section .heading {display: inline-block; background: url("images/braintree_logo.png") no-repeat 0 50% / 18rem auto; padding-left: 20rem;}
7+
.braintree-section .button-container {display: inline-block; float: right;}
8+
.braintree-section .config-alt {background: url("images/braintree_allinone.png") no-repeat scroll 0 0 / 100% auto; height: 28px; margin: 0.5rem 0 0; width: 230px;}

app/code/Magento/Catalog/Controller/Adminhtml/Product/Save.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ public function execute()
9797
$productTypeId = $this->getRequest()->getParam('type');
9898
if ($data) {
9999
try {
100+
$this->unserializeProductData($data);
100101
$product = $this->initializationHelper->initialize(
101102
$this->productBuilder->build($this->getRequest())
102103
);
@@ -180,6 +181,30 @@ public function execute()
180181
return $resultRedirect;
181182
}
182183

184+
/**
185+
* Unserialize product data for configurable products
186+
*
187+
* @param array $postData
188+
* @return void
189+
*/
190+
private function unserializeProductData($postData)
191+
{
192+
if (isset($postData["configurable-matrix-serialized"])) {
193+
$configurableMatrixSerialized = $postData["configurable-matrix-serialized"];
194+
if ($configurableMatrixSerialized != null && !empty($configurableMatrixSerialized)) {
195+
$postData["configurable-matrix"] = json_decode($configurableMatrixSerialized, true);
196+
unset($postData["configurable-matrix-serialized"]);
197+
}
198+
}
199+
if (isset($postData["associated_product_ids_serialized"])) {
200+
$associatedProductIdsSerialized = $postData["associated_product_ids_serialized"];
201+
if ($associatedProductIdsSerialized != null && !empty($associatedProductIdsSerialized)) {
202+
$postData["associated_product_ids"] = json_decode($associatedProductIdsSerialized, true);
203+
unset($postData["associated_product_ids_serialized"]);
204+
}
205+
}
206+
}
207+
183208
/**
184209
* Notify customer when image was not deleted in specific case.
185210
* TODO: temporary workaround must be eliminated in MAGETWO-45306

app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/LinkedProductSelectBuilderByIndexPrice.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,15 +56,16 @@ public function __construct(
5656
public function build($productId)
5757
{
5858
$linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField();
59+
$productTable = $this->resource->getTableName('catalog_product_entity');
5960

6061
return [$this->resource->getConnection()->select()
61-
->from(['parent' => 'catalog_product_entity'], '')
62+
->from(['parent' => $productTable], '')
6263
->joinInner(
6364
['link' => $this->resource->getTableName('catalog_product_relation')],
6465
"link.parent_id = parent.$linkField",
6566
[]
6667
)->joinInner(
67-
['child' => 'catalog_product_entity'],
68+
['child' => $productTable],
6869
"child.entity_id = link.child_id",
6970
['entity_id']
7071
)->joinInner(

app/code/Magento/Catalog/Model/ResourceModel/Product/LinkedProductSelectBuilderByBasePrice.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,16 @@ public function build($productId)
6565
{
6666
$linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField();
6767
$priceAttribute = $this->eavConfig->getAttribute(Product::ENTITY, 'price');
68+
$productTable = $this->resource->getTableName('catalog_product_entity');
69+
6870
$priceSelect = $this->resource->getConnection()->select()
69-
->from(['parent' => 'catalog_product_entity'], '')
71+
->from(['parent' => $productTable], '')
7072
->joinInner(
7173
['link' => $this->resource->getTableName('catalog_product_relation')],
7274
"link.parent_id = parent.$linkField",
7375
[]
7476
)->joinInner(
75-
['child' => 'catalog_product_entity'],
77+
['child' => $productTable],
7678
"child.entity_id = link.child_id",
7779
['entity_id']
7880
)->joinInner(

0 commit comments

Comments
 (0)