525 lines
20 KiB
PHP
Executable File
525 lines
20 KiB
PHP
Executable File
<?php
|
|
/**
|
|
* Copyright © Magento, Inc. All rights reserved.
|
|
* See COPYING.txt for license details.
|
|
*/
|
|
declare(strict_types=1);
|
|
|
|
namespace Magento\Customer\Model\Address;
|
|
|
|
use Magento\Customer\Api\AddressRepositoryInterface;
|
|
use Magento\Customer\Api\CustomerRepositoryInterface;
|
|
use Magento\Customer\Api\Data\AddressInterface;
|
|
use Magento\Customer\Api\Data\AddressInterfaceFactory;
|
|
use Magento\Customer\Model\AddressRegistry;
|
|
use Magento\Customer\Model\CustomerRegistry;
|
|
use Magento\Customer\Model\ResourceModel\Address;
|
|
use Magento\Customer\Model\Vat;
|
|
use Magento\Customer\Observer\AfterAddressSaveObserver;
|
|
use Magento\Framework\App\Config\ScopeConfigInterface;
|
|
use Magento\Framework\DataObjectFactory;
|
|
use Magento\Framework\Exception\InputException;
|
|
use Magento\TestFramework\Directory\Model\GetRegionIdByName;
|
|
use Magento\TestFramework\Helper\Bootstrap;
|
|
use Magento\TestFramework\ObjectManager;
|
|
use PHPUnit\Framework\TestCase;
|
|
use Psr\Log\LoggerInterface as PsrLogger;
|
|
|
|
/**
|
|
* Assert that address was created as expected or address create throws expected error.
|
|
*
|
|
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
|
|
*
|
|
* @magentoDbIsolation enabled
|
|
*/
|
|
class CreateAddressTest extends TestCase
|
|
{
|
|
/**
|
|
* Static customer address data.
|
|
*/
|
|
private const STATIC_CUSTOMER_ADDRESS_DATA = [
|
|
AddressInterface::TELEPHONE => 3468676,
|
|
AddressInterface::POSTCODE => 75477,
|
|
AddressInterface::COUNTRY_ID => 'US',
|
|
'custom_region_name' => 'Alabama',
|
|
AddressInterface::CITY => 'CityM',
|
|
AddressInterface::STREET => ['Green str, 67'],
|
|
AddressInterface::LASTNAME => 'Smith',
|
|
AddressInterface::FIRSTNAME => 'John',
|
|
];
|
|
|
|
/**
|
|
* @var ObjectManager
|
|
*/
|
|
protected $objectManager;
|
|
|
|
/**
|
|
* @var AddressInterfaceFactory
|
|
*/
|
|
protected $addressFactory;
|
|
|
|
/**
|
|
* @var CustomerRegistry
|
|
*/
|
|
protected $customerRegistry;
|
|
|
|
/**
|
|
* @var AddressRepositoryInterface
|
|
*/
|
|
protected $addressRepository;
|
|
|
|
/**
|
|
* @var GetRegionIdByName
|
|
*/
|
|
protected $getRegionIdByName;
|
|
|
|
/**
|
|
* @var CustomerRepositoryInterface
|
|
*/
|
|
protected $customerRepository;
|
|
|
|
/**
|
|
* @var AddressRegistry
|
|
*/
|
|
private $addressRegistry;
|
|
|
|
/**
|
|
* @var Address
|
|
*/
|
|
private $addressResource;
|
|
|
|
/**
|
|
* @var int[]
|
|
*/
|
|
private $createdAddressesIds = [];
|
|
|
|
/**
|
|
* @var DataObjectFactory
|
|
*/
|
|
private $dataObjectFactory;
|
|
|
|
/**
|
|
* @inheritdoc
|
|
*/
|
|
protected function setUp(): void
|
|
{
|
|
$this->objectManager = Bootstrap::getObjectManager();
|
|
$this->addressFactory = $this->objectManager->get(AddressInterfaceFactory::class);
|
|
$this->customerRegistry = $this->objectManager->get(CustomerRegistry::class);
|
|
$this->addressRepository = $this->objectManager->get(AddressRepositoryInterface::class);
|
|
$this->getRegionIdByName = $this->objectManager->get(GetRegionIdByName::class);
|
|
$this->customerRepository = $this->objectManager->get(CustomerRepositoryInterface::class);
|
|
$this->addressRegistry = $this->objectManager->get(AddressRegistry::class);
|
|
$this->addressResource = $this->objectManager->get(Address::class);
|
|
$this->dataObjectFactory = $this->objectManager->get(DataObjectFactory::class);
|
|
parent::setUp();
|
|
}
|
|
|
|
/**
|
|
* @inheritdoc
|
|
*/
|
|
protected function tearDown(): void
|
|
{
|
|
foreach ($this->createdAddressesIds as $createdAddressesId) {
|
|
$this->addressRegistry->remove($createdAddressesId);
|
|
}
|
|
$this->objectManager->removeSharedInstance(AfterAddressSaveObserver::class);
|
|
parent::tearDown();
|
|
}
|
|
|
|
/**
|
|
* Assert that default addresses properly created for customer.
|
|
*
|
|
* @magentoDataFixture Magento/Customer/_files/customer_no_address.php
|
|
*
|
|
* @dataProvider createDefaultAddressesDataProvider
|
|
*
|
|
* @param array $addressData
|
|
* @param bool $isShippingDefault
|
|
* @param bool $isBillingDefault
|
|
* @return void
|
|
*/
|
|
public function testCreateDefaultAddress(
|
|
array $addressData,
|
|
bool $isShippingDefault,
|
|
bool $isBillingDefault
|
|
): void {
|
|
$customer = $this->customerRepository->get('customer5@example.com');
|
|
$this->assertNull($customer->getDefaultShipping(), 'Customer already has default shipping address');
|
|
$this->assertNull($customer->getDefaultBilling(), 'Customer already has default billing address');
|
|
$address = $this->createAddress(
|
|
(int)$customer->getId(),
|
|
$addressData,
|
|
$isShippingDefault,
|
|
$isBillingDefault
|
|
);
|
|
$expectedShipping = $isShippingDefault ? $address->getId() : null;
|
|
$expectedBilling = $isBillingDefault ? $address->getId() : null;
|
|
$customer = $this->customerRepository->get('customer5@example.com');
|
|
$this->assertEquals($expectedShipping, $customer->getDefaultShipping());
|
|
$this->assertEquals($expectedBilling, $customer->getDefaultBilling());
|
|
}
|
|
|
|
/**
|
|
* Data provider for create default or not default address.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function createDefaultAddressesDataProvider(): array
|
|
{
|
|
return [
|
|
'any_addresses_are_default' => [self::STATIC_CUSTOMER_ADDRESS_DATA, false, false],
|
|
'shipping_address_is_default' => [self::STATIC_CUSTOMER_ADDRESS_DATA, true, false],
|
|
'billing_address_is_default' => [self::STATIC_CUSTOMER_ADDRESS_DATA, false, true],
|
|
'all_addresses_are_default' => [self::STATIC_CUSTOMER_ADDRESS_DATA, true, true],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Assert that address created successfully.
|
|
*
|
|
* @magentoDataFixture Magento/Customer/_files/customer_no_address.php
|
|
*
|
|
* @dataProvider createAddressesDataProvider
|
|
*
|
|
* @param array $addressData
|
|
* @param array $expectedData
|
|
* @return void
|
|
*/
|
|
public function testAddressCreatedWithProperData(array $addressData, array $expectedData): void
|
|
{
|
|
if (isset($expectedData['custom_region_name'])) {
|
|
$expectedData[AddressInterface::REGION_ID] = $this->getRegionIdByName->execute(
|
|
$expectedData['custom_region_name'],
|
|
$expectedData[AddressInterface::COUNTRY_ID]
|
|
);
|
|
unset($expectedData['custom_region_name']);
|
|
}
|
|
$customer = $this->customerRepository->get('customer5@example.com');
|
|
$createdAddressData = $this->createAddress((int)$customer->getId(), $addressData)->__toArray();
|
|
foreach ($expectedData as $fieldCode => $expectedValue) {
|
|
$this->assertTrue(isset($createdAddressData[$fieldCode]), "Field $fieldCode wasn't found.");
|
|
$this->assertEquals($createdAddressData[$fieldCode], $expectedValue);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Data provider for create address with proper data.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function createAddressesDataProvider(): array
|
|
{
|
|
return [
|
|
'required_fields_valid_data' => [
|
|
self::STATIC_CUSTOMER_ADDRESS_DATA,
|
|
[
|
|
AddressInterface::TELEPHONE => 3468676,
|
|
AddressInterface::COUNTRY_ID => 'US',
|
|
AddressInterface::POSTCODE => 75477,
|
|
'custom_region_name' => 'Alabama',
|
|
AddressInterface::FIRSTNAME => 'John',
|
|
AddressInterface::LASTNAME => 'Smith',
|
|
AddressInterface::STREET => ['Green str, 67'],
|
|
AddressInterface::CITY => 'CityM',
|
|
],
|
|
],
|
|
'required_field_empty_postcode_for_uk' => [
|
|
array_replace(
|
|
self::STATIC_CUSTOMER_ADDRESS_DATA,
|
|
[AddressInterface::POSTCODE => '', AddressInterface::COUNTRY_ID => 'GB']
|
|
),
|
|
[
|
|
AddressInterface::COUNTRY_ID => 'GB',
|
|
AddressInterface::POSTCODE => null,
|
|
],
|
|
],
|
|
'required_field_empty_region_id_for_ua' => [
|
|
array_replace(
|
|
self::STATIC_CUSTOMER_ADDRESS_DATA,
|
|
[AddressInterface::REGION_ID => '', AddressInterface::COUNTRY_ID => 'UA']
|
|
),
|
|
[
|
|
AddressInterface::COUNTRY_ID => 'UA',
|
|
AddressInterface::REGION => [
|
|
'region' => null,
|
|
'region_code' => null,
|
|
'region_id' => 0,
|
|
],
|
|
],
|
|
],
|
|
'required_field_street_as_array' => [
|
|
array_replace(self::STATIC_CUSTOMER_ADDRESS_DATA, [AddressInterface::STREET => ['', 'Green str, 67']]),
|
|
[AddressInterface::STREET => ['Green str, 67']],
|
|
],
|
|
'field_name_prefix' => [
|
|
array_merge(self::STATIC_CUSTOMER_ADDRESS_DATA, [AddressInterface::PREFIX => 'My prefix']),
|
|
[AddressInterface::PREFIX => 'My prefix'],
|
|
],
|
|
'field_middle_name_initial' => [
|
|
array_merge(self::STATIC_CUSTOMER_ADDRESS_DATA, [AddressInterface::MIDDLENAME => 'My middle name']),
|
|
[AddressInterface::MIDDLENAME => 'My middle name'],
|
|
],
|
|
'field_name_suffix' => [
|
|
array_merge(self::STATIC_CUSTOMER_ADDRESS_DATA, [AddressInterface::SUFFIX => 'My suffix']),
|
|
[AddressInterface::SUFFIX => 'My suffix'],
|
|
],
|
|
'field_company_name' => [
|
|
array_merge(self::STATIC_CUSTOMER_ADDRESS_DATA, [AddressInterface::COMPANY => 'My company']),
|
|
[AddressInterface::COMPANY => 'My company'],
|
|
],
|
|
'field_vat_number' => [
|
|
array_merge(self::STATIC_CUSTOMER_ADDRESS_DATA, [AddressInterface::VAT_ID => 'My VAT number']),
|
|
[AddressInterface::VAT_ID => 'My VAT number'],
|
|
],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Assert that proper error message has thrown if address creating with wrong data.
|
|
*
|
|
* @magentoDataFixture Magento/Customer/_files/customer_no_address.php
|
|
*
|
|
* @dataProvider createWrongAddressesDataProvider
|
|
*
|
|
* @param array $addressData
|
|
* @param \Exception $expectException
|
|
* @return void
|
|
*/
|
|
public function testExceptionThrownDuringCreateAddress(array $addressData, \Exception $expectException): void
|
|
{
|
|
$customer = $this->customerRepository->get('customer5@example.com');
|
|
$this->expectExceptionObject($expectException);
|
|
$this->createAddress((int)$customer->getId(), $addressData);
|
|
}
|
|
|
|
/**
|
|
* Data provider for create address with wrong data.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function createWrongAddressesDataProvider(): array
|
|
{
|
|
return [
|
|
'required_field_empty_telephone' => [
|
|
array_replace(self::STATIC_CUSTOMER_ADDRESS_DATA, [AddressInterface::TELEPHONE => '']),
|
|
InputException::requiredField('telephone'),
|
|
],
|
|
'required_field_empty_postcode_for_us' => [
|
|
array_replace(self::STATIC_CUSTOMER_ADDRESS_DATA, [AddressInterface::POSTCODE => '']),
|
|
InputException::requiredField('postcode'),
|
|
],
|
|
// TODO: Uncomment this variation after fix issue https://jira.corp.magento.com/browse/MC-31031
|
|
// 'required_field_empty_region_id_for_us' => [
|
|
// array_replace(self::STATIC_CUSTOMER_ADDRESS_DATA, [AddressInterface::REGION_ID => '']),
|
|
// InputException::requiredField('regionId'),
|
|
// ],
|
|
'required_field_empty_firstname' => [
|
|
array_replace(self::STATIC_CUSTOMER_ADDRESS_DATA, [AddressInterface::FIRSTNAME => '']),
|
|
InputException::requiredField('firstname'),
|
|
],
|
|
'required_field_empty_lastname' => [
|
|
array_replace(self::STATIC_CUSTOMER_ADDRESS_DATA, [AddressInterface::LASTNAME => '']),
|
|
InputException::requiredField('lastname'),
|
|
],
|
|
'required_field_empty_street_as_array' => [
|
|
array_replace(self::STATIC_CUSTOMER_ADDRESS_DATA, [AddressInterface::STREET => []]),
|
|
InputException::requiredField('street'),
|
|
],
|
|
'required_field_empty_city' => [
|
|
array_replace(self::STATIC_CUSTOMER_ADDRESS_DATA, [AddressInterface::CITY => '']),
|
|
InputException::requiredField('city'),
|
|
],
|
|
// TODO: Uncomment this variation after fix issue https://jira.corp.magento.com/browse/MC-31031
|
|
// 'field_invalid_vat_number' => [
|
|
// array_merge(self::STATIC_CUSTOMER_ADDRESS_DATA, [AddressInterface::VAT_ID => '/>.<*']),
|
|
// null// It need to create some error but currently magento doesn't has validation for this field.,
|
|
// ],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Assert that after address creation customer group is Group for Valid VAT ID - Domestic.
|
|
*
|
|
* @magentoAppIsolation enabled
|
|
* @magentoDataFixture Magento/Customer/_files/customer_no_address.php
|
|
* @magentoConfigFixture current_store general/store_information/country_id AT
|
|
* @magentoConfigFixture current_store customer/create_account/auto_group_assign 1
|
|
* @magentoConfigFixture current_store customer/create_account/viv_domestic_group 2
|
|
* @return void
|
|
*/
|
|
public function testAddressCreatedWithGroupAssignByDomesticVatId(): void
|
|
{
|
|
$this->createVatMock(true, true);
|
|
$addressData = array_merge(
|
|
self::STATIC_CUSTOMER_ADDRESS_DATA,
|
|
[AddressInterface::VAT_ID => '111', AddressInterface::COUNTRY_ID => 'AT']
|
|
);
|
|
$customer = $this->customerRepository->get('customer5@example.com');
|
|
$this->createAddress((int)$customer->getId(), $addressData, false, true);
|
|
$this->assertEquals(2, $this->getCustomerGroupId('customer5@example.com'));
|
|
}
|
|
|
|
/**
|
|
* Assert that after address creation customer group is Group for Valid VAT ID - Intra-Union.
|
|
*
|
|
* @magentoAppIsolation enabled
|
|
* @magentoDataFixture Magento/Customer/_files/customer_no_address.php
|
|
* @magentoConfigFixture current_store general/store_information/country_id GR
|
|
* @magentoConfigFixture current_store customer/create_account/auto_group_assign 1
|
|
* @magentoConfigFixture current_store customer/create_account/viv_intra_union_group 2
|
|
* @return void
|
|
*/
|
|
public function testAddressCreatedWithGroupAssignByIntraUnionVatId(): void
|
|
{
|
|
$this->createVatMock(true, true);
|
|
$addressData = array_merge(
|
|
self::STATIC_CUSTOMER_ADDRESS_DATA,
|
|
[AddressInterface::VAT_ID => '111', AddressInterface::COUNTRY_ID => 'AT']
|
|
);
|
|
$customer = $this->customerRepository->get('customer5@example.com');
|
|
$this->createAddress((int)$customer->getId(), $addressData, false, true);
|
|
$this->assertEquals(2, $this->getCustomerGroupId('customer5@example.com'));
|
|
}
|
|
|
|
/**
|
|
* Assert that after address creation customer group is Group for Invalid VAT ID.
|
|
*
|
|
* @magentoAppIsolation enabled
|
|
* @magentoDataFixture Magento/Customer/_files/customer_no_address.php
|
|
* @magentoConfigFixture current_store customer/create_account/auto_group_assign 1
|
|
* @magentoConfigFixture current_store customer/create_account/viv_invalid_group 2
|
|
* @return void
|
|
*/
|
|
public function testAddressCreatedWithGroupAssignByInvalidVatId(): void
|
|
{
|
|
$this->createVatMock(false, true);
|
|
$addressData = array_merge(
|
|
self::STATIC_CUSTOMER_ADDRESS_DATA,
|
|
[AddressInterface::VAT_ID => '111', AddressInterface::COUNTRY_ID => 'AT']
|
|
);
|
|
$customer = $this->customerRepository->get('customer5@example.com');
|
|
$this->createAddress((int)$customer->getId(), $addressData, false, true);
|
|
$this->assertEquals(2, $this->getCustomerGroupId('customer5@example.com'));
|
|
}
|
|
|
|
/**
|
|
* Assert that after address creation customer group is Validation Error Group.
|
|
*
|
|
* @magentoAppIsolation enabled
|
|
* @magentoDataFixture Magento/Customer/_files/customer_no_address.php
|
|
* @magentoConfigFixture current_store customer/create_account/auto_group_assign 1
|
|
* @magentoConfigFixture current_store customer/create_account/viv_error_group 2
|
|
* @return void
|
|
*/
|
|
public function testAddressCreatedWithGroupAssignByVatIdWithError(): void
|
|
{
|
|
$this->createVatMock(false, false);
|
|
$addressData = array_merge(
|
|
self::STATIC_CUSTOMER_ADDRESS_DATA,
|
|
[AddressInterface::VAT_ID => '111', AddressInterface::COUNTRY_ID => 'AT']
|
|
);
|
|
$customer = $this->customerRepository->get('customer5@example.com');
|
|
$this->createAddress((int)$customer->getId(), $addressData, false, true);
|
|
$this->assertEquals(2, $this->getCustomerGroupId('customer5@example.com'));
|
|
}
|
|
|
|
/**
|
|
* @magentoDataFixture Magento/Customer/_files/customer_no_address.php
|
|
* @magentoDataFixture Magento/Store/_files/second_website_with_store_group_and_store.php
|
|
* @magentoConfigFixture default_store general/country/allow BD,BB,AF
|
|
* @magentoConfigFixture fixture_second_store_store general/country/allow AS,BM
|
|
*
|
|
* @return void
|
|
*/
|
|
public function testCreateAvailableAddress(): void
|
|
{
|
|
$countryId = 'BB';
|
|
$addressData = array_merge(self::STATIC_CUSTOMER_ADDRESS_DATA, [AddressInterface::COUNTRY_ID => $countryId]);
|
|
$customer = $this->customerRepository->get('customer5@example.com');
|
|
$address = $this->createAddress((int)$customer->getId(), $addressData);
|
|
$this->assertSame($countryId, $address->getCountryId());
|
|
}
|
|
|
|
/**
|
|
* Create customer address with provided address data.
|
|
*
|
|
* @param int $customerId
|
|
* @param array $addressData
|
|
* @param bool $isDefaultShipping
|
|
* @param bool $isDefaultBilling
|
|
* @return AddressInterface
|
|
*/
|
|
protected function createAddress(
|
|
int $customerId,
|
|
array $addressData,
|
|
bool $isDefaultShipping = false,
|
|
bool $isDefaultBilling = false
|
|
): AddressInterface {
|
|
if (isset($addressData['custom_region_name'])) {
|
|
$addressData[AddressInterface::REGION_ID] = $this->getRegionIdByName->execute(
|
|
$addressData['custom_region_name'],
|
|
$addressData[AddressInterface::COUNTRY_ID]
|
|
);
|
|
unset($addressData['custom_region_name']);
|
|
}
|
|
|
|
$addressData['attribute_set_id'] = $this->addressResource->getEntityType()->getDefaultAttributeSetId();
|
|
$address = $this->addressFactory->create(['data' => $addressData]);
|
|
$address->setCustomerId($customerId);
|
|
$address->setIsDefaultShipping($isDefaultShipping);
|
|
$address->setIsDefaultBilling($isDefaultBilling);
|
|
$address = $this->addressRepository->save($address);
|
|
$this->customerRegistry->remove($customerId);
|
|
$this->addressRegistry->remove($address->getId());
|
|
$this->createdAddressesIds[] = (int)$address->getId();
|
|
|
|
return $address;
|
|
}
|
|
|
|
/**
|
|
* Creates mock for vat id validation.
|
|
*
|
|
* @param bool $isValid
|
|
* @param bool $isRequestSuccess
|
|
* @return void
|
|
*/
|
|
private function createVatMock(bool $isValid = false, bool $isRequestSuccess = false): void
|
|
{
|
|
$gatewayResponse = $this->dataObjectFactory->create(
|
|
[
|
|
'data' => [
|
|
'is_valid' => $isValid,
|
|
'request_date' => '',
|
|
'request_identifier' => '123123123',
|
|
'request_success' => $isRequestSuccess,
|
|
'request_message' => __(''),
|
|
],
|
|
]
|
|
);
|
|
$customerVat = $this->getMockBuilder(Vat::class)
|
|
->setConstructorArgs(
|
|
[
|
|
$this->objectManager->get(ScopeConfigInterface::class),
|
|
$this->objectManager->get(PsrLogger::class)
|
|
]
|
|
)
|
|
->setMethods(['checkVatNumber'])
|
|
->getMock();
|
|
$customerVat->method('checkVatNumber')->willReturn($gatewayResponse);
|
|
$this->objectManager->removeSharedInstance(Vat::class);
|
|
$this->objectManager->addSharedInstance($customerVat, Vat::class);
|
|
}
|
|
|
|
/**
|
|
* Returns customer group id by email.
|
|
*
|
|
* @param string $email
|
|
* @return int
|
|
*/
|
|
private function getCustomerGroupId(string $email): int
|
|
{
|
|
return (int)$this->customerRepository->get($email)->getGroupId();
|
|
}
|
|
}
|