Skip to content
This repository was archived by the owner on Apr 29, 2019. It is now read-only.

Commit 32a7c4b

Browse files
🔃 [EngCom] Public Pull Requests - 2.2-develop
Accepted Public Pull Requests: - magento/magento2#19260: Issue #19205 Fixed: Bundle Product Option with input type is checkbox and add to cart with 3 values only 2 values added to cart. (by @maheshWebkul721) - magento/magento2#19237: [Backport] #18956 Fixes for set root_category_id (by @gelanivishal) - magento/magento2#19240: [Backport] Add missing unit test for WishlistSettings plugin (by @gelanivishal) - magento/magento2#19216: [Backport] Covering the \Magento\Weee observers by Unit Tests (by @eduard13) - magento/magento2#19217: [Backport] Covering the CheckUserLoginBackendObserver by Unit Test (by @eduard13) - magento/magento2#18808: fixed Quote Item Prices are NULL in cart related events. #18685 (by @ashutoshwebkul) - magento/magento2#16342: #14020-Cart-Sales-Rule-with-negated-condition-over-special-price-does� (by @novikor) Fixed GitHub Issues: - magento/magento2#19205: Bundle Product Option with input type is checkbox and add to cart with 3 values only 2 values added to cart (reported by @sneha-panchal) has been fixed in magento/magento2#19260 by @maheshWebkul721 in 2.2-develop branch Related commits: 1. aa379ea 2. 1a321d2 - magento/magento2#18956: Import of RootCategoryId should be possbile (Magento/Store/Model/Config/Importer/Processor/Create.php) (reported by @larsroettig) has been fixed in magento/magento2#19237 by @gelanivishal in 2.2-develop branch Related commits: 1. aa4abec 2. acefdb3 3. 5866a39 4. fee2712 5. 7be21e2 - magento/magento2#18685: Quote Item Prices are NULL in cart related events. (reported by @qsolutions-pl) has been fixed in magento/magento2#18808 by @ashutoshwebkul in 2.2-develop branch Related commits: 1. 09586e4 2. 1638891 3. 175ebc0 4. 59bd874 - magento/magento2#14020: Cart Sales Rule with negated condition over special_price does not work for configurable products (reported by @Filipe-Bicho) has been fixed in magento/magento2#16342 by @novikor in 2.2-develop branch Related commits: 1. 90b6803 2. 2717cb1 3. d2a0de8 4. fae98c0 5. 9a35b45 6. 887ee4a 7. 0c9aa81 8. 4e68337 9. 5b95b22 10. 618f408 11. 7c8482b 12. e7130bf 13. 5a7e78a 14. 8d417ac 15. 90ff989 16. c52e0e8 17. 5c3154b 18. 51adb9d
2 parents b1e26d5 + 9945dc7 commit 32a7c4b

File tree

16 files changed

+840
-39
lines changed

16 files changed

+840
-39
lines changed

app/code/Magento/Bundle/Model/Product/Type.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -821,11 +821,11 @@ private function recursiveIntval(array $array)
821821
private function multiToFlatArray(array $array)
822822
{
823823
$flatArray = [];
824-
foreach ($array as $key => $value) {
824+
foreach ($array as $value) {
825825
if (is_array($value)) {
826826
$flatArray = array_merge($flatArray, $this->multiToFlatArray($value));
827827
} else {
828-
$flatArray[$key] = $value;
828+
$flatArray[] = $value;
829829
}
830830
}
831831

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Captcha\Test\Unit\Observer;
9+
10+
use Magento\Captcha\Helper\Data;
11+
use Magento\Captcha\Model\DefaultModel;
12+
use Magento\Captcha\Observer\CaptchaStringResolver;
13+
use Magento\Captcha\Observer\CheckUserLoginBackendObserver;
14+
use Magento\Framework\App\RequestInterface;
15+
use Magento\Framework\Event;
16+
use Magento\Framework\Event\Observer;
17+
use Magento\Framework\Message\ManagerInterface;
18+
use PHPUnit\Framework\TestCase;
19+
use PHPUnit_Framework_MockObject_MockObject as MockObject;
20+
21+
/**
22+
* Class CheckUserLoginBackendObserverTest
23+
*/
24+
class CheckUserLoginBackendObserverTest extends TestCase
25+
{
26+
/**
27+
* @var CheckUserLoginBackendObserver
28+
*/
29+
private $observer;
30+
31+
/**
32+
* @var ManagerInterface|MockObject
33+
*/
34+
private $messageManagerMock;
35+
36+
/**
37+
* @var CaptchaStringResolver|MockObject
38+
*/
39+
private $captchaStringResolverMock;
40+
41+
/**
42+
* @var RequestInterface|MockObject
43+
*/
44+
private $requestMock;
45+
46+
/**
47+
* @var Data|MockObject
48+
*/
49+
private $helperMock;
50+
51+
/**
52+
* Set Up
53+
*
54+
* @return void
55+
*/
56+
protected function setUp()
57+
{
58+
$this->helperMock = $this->createMock(Data::class);
59+
$this->messageManagerMock = $this->createMock(ManagerInterface::class);
60+
$this->captchaStringResolverMock = $this->createMock(CaptchaStringResolver::class);
61+
$this->requestMock = $this->createMock(RequestInterface::class);
62+
63+
$this->observer = new CheckUserLoginBackendObserver(
64+
$this->helperMock,
65+
$this->captchaStringResolverMock,
66+
$this->requestMock
67+
);
68+
}
69+
70+
/**
71+
* Test check user login in backend with correct captcha
72+
*
73+
* @dataProvider requiredCaptchaDataProvider
74+
* @param bool $isRequired
75+
* @return void
76+
*/
77+
public function testCheckOnBackendLoginWithCorrectCaptcha(bool $isRequired)
78+
{
79+
$formId = 'backend_login';
80+
$login = 'admin';
81+
$captchaValue = 'captcha-value';
82+
83+
/** @var Observer|MockObject $observerMock */
84+
$observerMock = $this->createPartialMock(Observer::class, ['getEvent']);
85+
$eventMock = $this->createPartialMock(Event::class, ['getUsername']);
86+
$captcha = $this->createMock(DefaultModel::class);
87+
88+
$eventMock->method('getUsername')->willReturn('admin');
89+
$observerMock->method('getEvent')->willReturn($eventMock);
90+
$captcha->method('isRequired')->with($login)->willReturn($isRequired);
91+
$captcha->method('isCorrect')->with($captchaValue)->willReturn(true);
92+
$this->helperMock->method('getCaptcha')->with($formId)->willReturn($captcha);
93+
$this->captchaStringResolverMock->method('resolve')->with($this->requestMock, $formId)
94+
->willReturn($captchaValue);
95+
96+
$this->observer->execute($observerMock);
97+
}
98+
99+
/**
100+
* @return array
101+
*/
102+
public function requiredCaptchaDataProvider(): array
103+
{
104+
return [
105+
[true],
106+
[false]
107+
];
108+
}
109+
110+
/**
111+
* Test check user login in backend with wrong captcha
112+
*
113+
* @return void
114+
* @expectedException \Magento\Framework\Exception\Plugin\AuthenticationException
115+
*/
116+
public function testCheckOnBackendLoginWithWrongCaptcha()
117+
{
118+
$formId = 'backend_login';
119+
$login = 'admin';
120+
$captchaValue = 'captcha-value';
121+
122+
/** @var Observer|MockObject $observerMock */
123+
$observerMock = $this->createPartialMock(Observer::class, ['getEvent']);
124+
$eventMock = $this->createPartialMock(Event::class, ['getUsername']);
125+
$captcha = $this->createMock(DefaultModel::class);
126+
127+
$eventMock->method('getUsername')->willReturn($login);
128+
$observerMock->method('getEvent')->willReturn($eventMock);
129+
$captcha->method('isRequired')->with($login)->willReturn(true);
130+
$captcha->method('isCorrect')->with($captchaValue)->willReturn(false);
131+
$this->helperMock->method('getCaptcha')->with($formId)->willReturn($captcha);
132+
$this->captchaStringResolverMock->method('resolve')->with($this->requestMock, $formId)
133+
->willReturn($captchaValue);
134+
135+
$this->observer->execute($observerMock);
136+
}
137+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\ConfigurableProduct\Plugin\SalesRule\Model\Rule\Condition;
9+
10+
use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
11+
12+
/**
13+
* Class Product
14+
*
15+
* @package Magento\ConfigurableProduct\Plugin\SalesRule\Model\Rule\Condition
16+
*/
17+
class Product
18+
{
19+
/**
20+
* @param \Magento\SalesRule\Model\Rule\Condition\Product $subject
21+
* @param \Magento\Framework\Model\AbstractModel $model
22+
*/
23+
public function beforeValidate(
24+
\Magento\SalesRule\Model\Rule\Condition\Product $subject,
25+
\Magento\Framework\Model\AbstractModel $model
26+
) {
27+
$product = $this->getProductToValidate($subject, $model);
28+
if ($model->getProduct() !== $product) {
29+
// We need to replace product only for validation and keep original product for all other cases.
30+
$clone = clone $model;
31+
$clone->setProduct($product);
32+
$model = $clone;
33+
}
34+
35+
return [$model];
36+
}
37+
38+
/**
39+
* @param \Magento\SalesRule\Model\Rule\Condition\Product $subject
40+
* @param \Magento\Framework\Model\AbstractModel $model
41+
*
42+
* @return \Magento\Catalog\Api\Data\ProductInterface|\Magento\Catalog\Model\Product
43+
*/
44+
private function getProductToValidate(
45+
\Magento\SalesRule\Model\Rule\Condition\Product $subject,
46+
\Magento\Framework\Model\AbstractModel $model
47+
) {
48+
/** @var \Magento\Catalog\Model\Product $product */
49+
$product = $model->getProduct();
50+
51+
$attrCode = $subject->getAttribute();
52+
53+
/* Check for attributes which are not available for configurable products */
54+
if ($product->getTypeId() == Configurable::TYPE_CODE && !$product->hasData($attrCode)) {
55+
/** @var \Magento\Catalog\Model\AbstractModel $childProduct */
56+
$childProduct = current($model->getChildren())->getProduct();
57+
if ($childProduct->hasData($attrCode)) {
58+
$product = $childProduct;
59+
}
60+
}
61+
62+
return $product;
63+
}
64+
}

app/code/Magento/ConfigurableProduct/Setup/UpgradeData.php

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@
77

88
use Magento\Catalog\Model\Product;
99
use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
10-
use Magento\Framework\Setup\UpgradeDataInterface;
11-
use Magento\Framework\Setup\ModuleContextInterface;
12-
use Magento\Framework\Setup\ModuleDataSetupInterface;
1310
use Magento\Eav\Setup\EavSetup;
1411
use Magento\Eav\Setup\EavSetupFactory;
12+
use Magento\Framework\Setup\ModuleContextInterface;
13+
use Magento\Framework\Setup\ModuleDataSetupInterface;
14+
use Magento\Framework\Setup\UpgradeDataInterface;
1515

1616
/**
1717
* Upgrade Data script
@@ -62,6 +62,10 @@ public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface
6262
}
6363
}
6464

65+
if (version_compare($context->getVersion(), '2.2.2', '<')) {
66+
$this->upgradeQuoteItemPrice($setup);
67+
}
68+
6569
$setup->endSetup();
6670
}
6771

@@ -97,4 +101,30 @@ private function updateRelatedProductTypes(string $attributeId, array $relatedPr
97101
implode(',', $relatedProductTypes)
98102
);
99103
}
104+
105+
/**
106+
* Update 'price' value for quote items without price of configurable products subproducts.
107+
*
108+
* @param ModuleDataSetupInterface $setup
109+
*/
110+
private function upgradeQuoteItemPrice(ModuleDataSetupInterface $setup)
111+
{
112+
$connection = $setup->getConnection();
113+
$quoteItemTable = $setup->getTable('quote_item');
114+
$select = $connection->select();
115+
$select->joinLeft(
116+
['qi2' => $quoteItemTable],
117+
'qi1.parent_item_id = qi2.item_id',
118+
['price']
119+
)->where(
120+
'qi1.price = 0'
121+
. ' AND qi1.parent_item_id IS NOT NULL'
122+
. ' AND qi2.product_type = "' . Configurable::TYPE_CODE . '"'
123+
);
124+
$updateQuoteItem = $setup->getConnection()->updateFromSelect(
125+
$select,
126+
['qi1' => $quoteItemTable]
127+
);
128+
$setup->getConnection()->query($updateQuoteItem);
129+
}
100130
}

0 commit comments

Comments
 (0)