Skip to content

Commit c3d9b40

Browse files
committed
Merge branch 'github-2.3-develop' into MAGETWO-70681
2 parents cf5d3fe + 5253029 commit c3d9b40

23 files changed

+535
-53
lines changed

app/code/Magento/Catalog/Model/Product/Attribute/Backend/TierPrice/UpdateHandler.php

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@
77

88
namespace Magento\Catalog\Model\Product\Attribute\Backend\TierPrice;
99

10-
use Magento\Framework\EntityManager\Operation\ExtensionInterface;
1110
use Magento\Catalog\Api\Data\ProductInterface;
11+
use Magento\Framework\App\ObjectManager;
12+
use Magento\Framework\Locale\FormatInterface;
1213
use Magento\Store\Model\StoreManagerInterface;
1314
use Magento\Catalog\Api\ProductAttributeRepositoryInterface;
1415
use Magento\Customer\Api\GroupManagementInterface;
@@ -40,26 +41,34 @@ class UpdateHandler extends AbstractHandler
4041
*/
4142
private $tierPriceResource;
4243

44+
/**
45+
* @var FormatInterface
46+
*/
47+
private $localeFormat;
48+
4349
/**
4450
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
4551
* @param \Magento\Catalog\Api\ProductAttributeRepositoryInterface $attributeRepository
4652
* @param \Magento\Customer\Api\GroupManagementInterface $groupManagement
4753
* @param \Magento\Framework\EntityManager\MetadataPool $metadataPool
4854
* @param \Magento\Catalog\Model\ResourceModel\Product\Attribute\Backend\Tierprice $tierPriceResource
55+
* @param FormatInterface|null $localeFormat
4956
*/
5057
public function __construct(
5158
StoreManagerInterface $storeManager,
5259
ProductAttributeRepositoryInterface $attributeRepository,
5360
GroupManagementInterface $groupManagement,
5461
MetadataPool $metadataPool,
55-
Tierprice $tierPriceResource
62+
Tierprice $tierPriceResource,
63+
FormatInterface $localeFormat = null
5664
) {
5765
parent::__construct($groupManagement);
5866

5967
$this->storeManager = $storeManager;
6068
$this->attributeRepository = $attributeRepository;
6169
$this->metadataPoll = $metadataPool;
6270
$this->tierPriceResource = $tierPriceResource;
71+
$this->localeFormat = $localeFormat ?: ObjectManager::getInstance()->get(FormatInterface::class);
6372
}
6473

6574
/**
@@ -125,8 +134,9 @@ private function updateValues(array $valuesToUpdate, array $oldValues): bool
125134
{
126135
$isChanged = false;
127136
foreach ($valuesToUpdate as $key => $value) {
128-
if ((!empty($value['value']) && (float)$oldValues[$key]['price'] !== (float)$value['value'])
129-
|| $this->getPercentage($oldValues[$key]) !== $this->getPercentage($value)
137+
if ((!empty($value['value'])
138+
&& (float)$oldValues[$key]['price'] !== $this->localeFormat->getNumber($value['value'])
139+
) || $this->getPercentage($oldValues[$key]) !== $this->getPercentage($value)
130140
) {
131141
$price = new \Magento\Framework\DataObject(
132142
[

app/code/Magento/Catalog/Test/Mftf/Section/AdminEditProductAttributesSection.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,6 @@
2121
<element name="ProductDataMayBeLostModal" type="button" selector="//aside[contains(@class,'_show')]//header[contains(.,'Product data may be lost')]"/>
2222
<element name="ProductDataMayBeLostConfirmButton" type="button" selector="//aside[contains(@class,'_show')]//button[.='Change Input Type']"/>
2323
<element name="defaultLabel" type="text" selector="//td[contains(text(), '{{attributeName}}')]/following-sibling::td[contains(@class, 'col-frontend_label')]" parameterized="true"/>
24+
<element name="formByStoreId" type="block" selector="//form[contains(@action,'store/{{store_id}}')]" parameterized="true"/>
2425
</section>
2526
</sections>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataProfileSchema.xsd">
11+
<entity name="StockOptionsDisplayOutOfStockProductsEnable">
12+
<data key="path">cataloginventory/options/show_out_of_stock</data>
13+
<data key="scope_id">0</data>
14+
<data key="label">Yes</data>
15+
<data key="value">1</data>
16+
</entity>
17+
<entity name="StockOptionsDisplayOutOfStockProductsDisable">
18+
<data key="path">cataloginventory/options/show_out_of_stock</data>
19+
<data key="scope_id">0</data>
20+
<data key="label">No</data>
21+
<data key="value">0</data>
22+
</entity>
23+
</entities>

app/code/Magento/Customer/Model/AccountManagement.php

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use Magento\Customer\Model\Customer\CredentialsValidator;
2020
use Magento\Customer\Model\Metadata\Validator;
2121
use Magento\Customer\Model\ResourceModel\Visitor\CollectionFactory;
22+
use Magento\Directory\Model\AllowedCountries;
2223
use Magento\Eav\Model\Validator\Attribute\Backend;
2324
use Magento\Framework\Api\ExtensibleDataObjectConverter;
2425
use Magento\Framework\Api\SearchCriteriaBuilder;
@@ -339,6 +340,11 @@ class AccountManagement implements AccountManagementInterface
339340
*/
340341
private $addressRegistry;
341342

343+
/**
344+
* @var AllowedCountries
345+
*/
346+
private $allowedCountriesReader;
347+
342348
/**
343349
* @param CustomerFactory $customerFactory
344350
* @param ManagerInterface $eventManager
@@ -371,8 +377,10 @@ class AccountManagement implements AccountManagementInterface
371377
* @param CollectionFactory|null $visitorCollectionFactory
372378
* @param SearchCriteriaBuilder|null $searchCriteriaBuilder
373379
* @param AddressRegistry|null $addressRegistry
380+
* @param AllowedCountries|null $allowedCountriesReader
374381
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
375382
* @SuppressWarnings(PHPMD.NPathComplexity)
383+
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
376384
*/
377385
public function __construct(
378386
CustomerFactory $customerFactory,
@@ -405,7 +413,8 @@ public function __construct(
405413
SaveHandlerInterface $saveHandler = null,
406414
CollectionFactory $visitorCollectionFactory = null,
407415
SearchCriteriaBuilder $searchCriteriaBuilder = null,
408-
AddressRegistry $addressRegistry = null
416+
AddressRegistry $addressRegistry = null,
417+
AllowedCountries $allowedCountriesReader = null
409418
) {
410419
$this->customerFactory = $customerFactory;
411420
$this->eventManager = $eventManager;
@@ -445,6 +454,8 @@ public function __construct(
445454
?: ObjectManager::getInstance()->get(SearchCriteriaBuilder::class);
446455
$this->addressRegistry = $addressRegistry
447456
?: ObjectManager::getInstance()->get(AddressRegistry::class);
457+
$this->allowedCountriesReader = $allowedCountriesReader
458+
?: ObjectManager::getInstance()->get(AllowedCountries::class);
448459
}
449460

450461
/**
@@ -554,6 +565,7 @@ public function authenticate($username, $password)
554565
}
555566
try {
556567
$this->getAuthentication()->authenticate($customerId, $password);
568+
// phpcs:disable Magento2.Exceptions.ThrowCatch
557569
} catch (InvalidEmailOrPasswordException $e) {
558570
throw new InvalidEmailOrPasswordException(__('Invalid login or password.'));
559571
}
@@ -894,11 +906,15 @@ public function createAccountWithPasswordHash(CustomerInterface $customer, $hash
894906
throw new InputMismatchException(
895907
__('A customer with the same email address already exists in an associated website.')
896908
);
909+
// phpcs:disable Magento2.Exceptions.ThrowCatch
897910
} catch (LocalizedException $e) {
898911
throw $e;
899912
}
900913
try {
901914
foreach ($customerAddresses as $address) {
915+
if (!$this->isAddressAllowedForWebsite($address, $customer->getStoreId())) {
916+
continue;
917+
}
902918
if ($address->getId()) {
903919
$newAddress = clone $address;
904920
$newAddress->setId(null);
@@ -910,6 +926,7 @@ public function createAccountWithPasswordHash(CustomerInterface $customer, $hash
910926
}
911927
}
912928
$this->customerRegistry->remove($customer->getId());
929+
// phpcs:disable Magento2.Exceptions.ThrowCatch
913930
} catch (InputException $e) {
914931
$this->customerRepository->delete($customer);
915932
throw $e;
@@ -1012,6 +1029,7 @@ private function changePasswordForCustomer($customer, $currentPassword, $newPass
10121029
{
10131030
try {
10141031
$this->getAuthentication()->authenticate($customer->getId(), $currentPassword);
1032+
// phpcs:disable Magento2.Exceptions.ThrowCatch
10151033
} catch (InvalidEmailOrPasswordException $e) {
10161034
throw new InvalidEmailOrPasswordException(
10171035
__("The password doesn't match this account. Verify the password and try again.")
@@ -1071,6 +1089,7 @@ public function validate(CustomerInterface $customer)
10711089
$result = $this->getEavValidator()->isValid($customerModel);
10721090
if ($result === false && is_array($this->getEavValidator()->getMessages())) {
10731091
return $validationResults->setIsValid(false)->setMessages(
1092+
// phpcs:ignore Magento2.Functions.DiscouragedFunction
10741093
call_user_func_array(
10751094
'array_merge',
10761095
$this->getEavValidator()->getMessages()
@@ -1606,4 +1625,18 @@ private function setIgnoreValidationFlag($customer)
16061625
{
16071626
$customer->setData('ignore_validation_flag', true);
16081627
}
1628+
1629+
/**
1630+
* Check is address allowed for store
1631+
*
1632+
* @param AddressInterface $address
1633+
* @param int|null $storeId
1634+
* @return bool
1635+
*/
1636+
private function isAddressAllowedForWebsite(AddressInterface $address, $storeId): bool
1637+
{
1638+
$allowedCountries = $this->allowedCountriesReader->getAllowedCountries(ScopeInterface::SCOPE_STORE, $storeId);
1639+
1640+
return in_array($address->getCountryId(), $allowedCountries);
1641+
}
16091642
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
11+
<actionGroup name="StorefrontRegisterCustomerFromOrderSuccessPage">
12+
<arguments>
13+
<argument name="customer" />
14+
</arguments>
15+
<click selector="{{CheckoutSuccessRegisterSection.createAccountButton}}" stepKey="clickCreateAccountButton"/>
16+
<fillField selector="{{StorefrontCustomerCreateFormSection.passwordField}}" userInput="{{customer.password}}" stepKey="typePassword"/>
17+
<fillField selector="{{StorefrontCustomerCreateFormSection.confirmPasswordField}}" userInput="{{customer.password}}" stepKey="typeConfirmationPassword"/>
18+
<click selector="{{StorefrontCustomerCreateFormSection.createAccountButton}}" stepKey="clickOnCreateAccount"/>
19+
<see selector="{{StorefrontMessagesSection.success}}" userInput="Thank you for registering" stepKey="verifyAccountCreated"/>
20+
</actionGroup>
21+
</actionGroups>

app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use Magento\Customer\Model\AuthenticationInterface;
1313
use Magento\Customer\Model\Data\Customer;
1414
use Magento\Customer\Model\EmailNotificationInterface;
15+
use Magento\Directory\Model\AllowedCountries;
1516
use Magento\Framework\Api\SearchCriteriaBuilder;
1617
use Magento\Framework\App\Area;
1718
use Magento\Framework\Exception\NoSuchEntityException;
@@ -155,6 +156,11 @@ class AccountManagementTest extends \PHPUnit\Framework\TestCase
155156
*/
156157
private $searchCriteriaBuilderMock;
157158

159+
/**
160+
* @var AllowedCountries|\PHPUnit_Framework_MockObject_MockObject
161+
*/
162+
private $allowedCountriesReader;
163+
158164
/**
159165
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
160166
*/
@@ -193,6 +199,7 @@ protected function setUp()
193199
$this->extensibleDataObjectConverter = $this->createMock(
194200
\Magento\Framework\Api\ExtensibleDataObjectConverter::class
195201
);
202+
$this->allowedCountriesReader = $this->createMock(AllowedCountries::class);
196203
$this->authenticationMock = $this->getMockBuilder(AuthenticationInterface::class)
197204
->disableOriginalConstructor()
198205
->getMock();
@@ -256,6 +263,7 @@ protected function setUp()
256263
'visitorCollectionFactory' => $this->visitorCollectionFactory,
257264
'searchCriteriaBuilder' => $this->searchCriteriaBuilderMock,
258265
'addressRegistry' => $this->addressRegistryMock,
266+
'allowedCountriesReader' => $this->allowedCountriesReader,
259267
]
260268
);
261269
$this->objectManagerHelper->setBackwardCompatibleProperty(
@@ -551,7 +559,14 @@ public function testCreateAccountWithPasswordHashWithAddressException()
551559
->expects($this->once())
552560
->method('delete')
553561
->with($customer);
554-
562+
$this->allowedCountriesReader
563+
->expects($this->atLeastOnce())
564+
->method('getAllowedCountries')
565+
->willReturn(['US' => 'US']);
566+
$address
567+
->expects($this->atLeastOnce())
568+
->method('getCountryId')
569+
->willReturn('US');
555570
$this->accountManagement->createAccountWithPasswordHash($customer, $hash);
556571
}
557572

@@ -725,6 +740,14 @@ public function testCreateAccountWithoutPassword()
725740
$this->emailNotificationMock->expects($this->once())
726741
->method('newAccount')
727742
->willReturnSelf();
743+
$this->allowedCountriesReader
744+
->expects($this->atLeastOnce())
745+
->method('getAllowedCountries')
746+
->willReturn(['US' => 'US']);
747+
$address
748+
->expects($this->atLeastOnce())
749+
->method('getCountryId')
750+
->willReturn('US');
728751

729752
$this->accountManagement->createAccount($customer);
730753
}
@@ -970,6 +993,14 @@ public function testCreateAccountWithPassword()
970993
$this->emailNotificationMock->expects($this->once())
971994
->method('newAccount')
972995
->willReturnSelf();
996+
$this->allowedCountriesReader
997+
->expects($this->atLeastOnce())
998+
->method('getAllowedCountries')
999+
->willReturn(['US' => 'US']);
1000+
$address
1001+
->expects($this->atLeastOnce())
1002+
->method('getCountryId')
1003+
->willReturn('US');
9731004

9741005
$this->accountManagement->createAccount($customer, $password);
9751006
}
@@ -1951,6 +1982,14 @@ public function testCreateAccountWithPasswordHashWithCustomerAddresses()
19511982
->method('getWebsite')
19521983
->with($websiteId)
19531984
->willReturn($website);
1985+
$this->allowedCountriesReader
1986+
->expects($this->atLeastOnce())
1987+
->method('getAllowedCountries')
1988+
->willReturn(['US' => 'US']);
1989+
$existingAddress
1990+
->expects($this->atLeastOnce())
1991+
->method('getCountryId')
1992+
->willReturn('US');
19541993

19551994
$this->assertSame($customer, $this->accountManagement->createAccountWithPasswordHash($customer, $hash));
19561995
}
@@ -2078,7 +2117,9 @@ public function testCreateAccountUnexpectedValueException(): void
20782117
->method('newAccount')
20792118
->willThrowException($exception);
20802119
$this->logger->expects($this->once())->method('error')->with($exception);
2081-
2120+
$this->allowedCountriesReader->expects($this->atLeastOnce())
2121+
->method('getAllowedCountries')->willReturn(['US' => 'US']);
2122+
$address->expects($this->atLeastOnce())->method('getCountryId')->willReturn('US');
20822123
$this->accountManagement->createAccount($customer);
20832124
}
20842125

0 commit comments

Comments
 (0)