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

Commit 4fcc190

Browse files
authored
Merge pull request #7 from magento/2.2-develop
2.2 develop-update
2 parents 584242c + 32a7c4b commit 4fcc190

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)