From 42bec43486729ebd645329d90a40ec7b5fd58664 Mon Sep 17 00:00:00 2001
From: Bohdan Shevchenko <1408sheva@gmail.com>
Date: Wed, 4 Nov 2020 09:52:41 +0200
Subject: [PATCH 01/14] MC-37507: Create automated test for "Invoice Sales
Archive"
---
...sertNumberOfRecordsInUiGridActionGroup.xml | 20 +++++++++++++++++++
.../AdminGridHeadersSection.xml | 1 +
2 files changed, 21 insertions(+)
create mode 100644 app/code/Magento/Ui/Test/Mftf/ActionGroup/AdminAssertNumberOfRecordsInUiGridActionGroup.xml
diff --git a/app/code/Magento/Ui/Test/Mftf/ActionGroup/AdminAssertNumberOfRecordsInUiGridActionGroup.xml b/app/code/Magento/Ui/Test/Mftf/ActionGroup/AdminAssertNumberOfRecordsInUiGridActionGroup.xml
new file mode 100644
index 0000000000000..5928833bf4794
--- /dev/null
+++ b/app/code/Magento/Ui/Test/Mftf/ActionGroup/AdminAssertNumberOfRecordsInUiGridActionGroup.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+ Validates that the Number of Records listed on the Ui grid page is present and correct.
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Ui/Test/Mftf/Section/AdminGridControlsSection/AdminGridHeadersSection.xml b/app/code/Magento/Ui/Test/Mftf/Section/AdminGridControlsSection/AdminGridHeadersSection.xml
index 89831359657bf..c7aa7604d7ade 100644
--- a/app/code/Magento/Ui/Test/Mftf/Section/AdminGridControlsSection/AdminGridHeadersSection.xml
+++ b/app/code/Magento/Ui/Test/Mftf/Section/AdminGridControlsSection/AdminGridHeadersSection.xml
@@ -11,5 +11,6 @@
+
From 40fe02b46e2df4e49012c13a81e7f5b17a82f622 Mon Sep 17 00:00:00 2001
From: Serhii Bohomaz
Date: Fri, 6 Nov 2020 13:39:54 +0200
Subject: [PATCH 02/14] MC-37099: Create automated test for "Update Customer
Address, with Alphanumeric Zip Code"
---
.../ResourceModel/AddressRepositoryTest.php | 344 +++++++++++-------
1 file changed, 211 insertions(+), 133 deletions(-)
diff --git a/dev/tests/integration/testsuite/Magento/Customer/Model/ResourceModel/AddressRepositoryTest.php b/dev/tests/integration/testsuite/Magento/Customer/Model/ResourceModel/AddressRepositoryTest.php
index f80d960be2942..692252ffe3206 100644
--- a/dev/tests/integration/testsuite/Magento/Customer/Model/ResourceModel/AddressRepositoryTest.php
+++ b/dev/tests/integration/testsuite/Magento/Customer/Model/ResourceModel/AddressRepositoryTest.php
@@ -3,18 +3,28 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+declare(strict_types=1);
namespace Magento\Customer\Model\ResourceModel;
use Magento\Customer\Api\AddressRepositoryInterface;
use Magento\Customer\Api\CustomerRepositoryInterface;
-use Magento\Customer\Api\Data\CustomerInterface;
+use Magento\Customer\Api\Data\AddressInterface;
+use Magento\Customer\Api\Data\AddressInterfaceFactory;
use Magento\Customer\Api\Data\RegionInterfaceFactory;
+use Magento\Customer\Model\CustomerRegistry;
+use Magento\Framework\Api\DataObjectHelper;
+use Magento\Framework\Api\Filter;
+use Magento\Framework\Api\FilterBuilder;
+use Magento\Framework\Api\SearchCriteriaBuilder;
use Magento\Framework\Api\SortOrder;
+use Magento\Framework\Api\SortOrderBuilder;
+use Magento\Framework\Config\CacheInterface;
use Magento\Framework\Exception\InputException;
use Magento\Framework\Exception\NoSuchEntityException;
-use Magento\Store\Api\Data\WebsiteInterface;
-use Magento\Store\Api\WebsiteRepositoryInterface;
+use Magento\Store\Model\StoreManagerInterface;
+use Magento\TestFramework\Helper\Bootstrap;
+use PHPUnit\Framework\TestCase;
/**
* Class with integration tests for AddressRepository.
@@ -23,7 +33,7 @@
* @SuppressWarnings(PHPMD.ExcessivePublicCount)
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
-class AddressRepositoryTest extends \PHPUnit\Framework\TestCase
+class AddressRepositoryTest extends TestCase
{
/** @var AddressRepositoryInterface */
private $repository;
@@ -34,34 +44,41 @@ class AddressRepositoryTest extends \PHPUnit\Framework\TestCase
/** @var \Magento\Customer\Model\Data\Address[] */
private $expectedAddresses;
- /** @var \Magento\Customer\Api\Data\AddressInterfaceFactory */
+ /** @var AddressInterfaceFactory */
private $addressFactory;
- /** @var \Magento\Framework\Api\DataObjectHelper */
+ /** @var DataObjectHelper */
private $dataObjectHelper;
+ /** @var CustomerRegistry */
private $customerRegistry;
+ /** @var StoreManagerInterface */
+ private $storeManager;
+
+ /** @var RegionInterfaceFactory */
+ private $regionFactory;
+
+ /** @var CustomerRepositoryInterface */
+ private $customerRepository;
+
/**
- * Set up.
+ * @inheritdoc
*/
protected function setUp(): void
{
- $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
-
- /* @var \Magento\Framework\Config\CacheInterface $cache */
- $cache = $this->objectManager->create(\Magento\Framework\Config\CacheInterface::class);
+ $this->objectManager = Bootstrap::getObjectManager();
+ /* @var CacheInterface $cache */
+ $cache = $this->objectManager->get(CacheInterface::class);
$cache->remove('extension_attributes_config');
-
- $this->repository = $this->objectManager->create(\Magento\Customer\Api\AddressRepositoryInterface::class);
- $this->addressFactory = $this->objectManager->create(
- \Magento\Customer\Api\Data\AddressInterfaceFactory::class
- );
- $this->dataObjectHelper = $this->objectManager->create(\Magento\Framework\Api\DataObjectHelper::class);
- $this->customerRegistry = $this->objectManager->get(\Magento\Customer\Model\CustomerRegistry::class);
-
- $regionFactory = $this->objectManager->get(RegionInterfaceFactory::class);
- $region = $regionFactory->create()
+ $this->repository = $this->objectManager->get(AddressRepositoryInterface::class);
+ $this->addressFactory = $this->objectManager->get(AddressInterfaceFactory::class);
+ $this->dataObjectHelper = $this->objectManager->get(DataObjectHelper::class);
+ $this->customerRegistry = $this->objectManager->get(CustomerRegistry::class);
+ $this->storeManager = $this->objectManager->get(StoreManagerInterface::class);
+ $this->regionFactory = $this->objectManager->get(RegionInterfaceFactory::class);
+ $this->customerRepository = $this->objectManager->get(CustomerRepositoryInterface::class);
+ $region = $this->regionFactory->create()
->setRegionCode('AL')
->setRegion('Alabama')
->setRegionId(1);
@@ -90,12 +107,11 @@ protected function setUp(): void
->setTelephone('3234676')
->setFirstname('John')
->setLastname('Smith');
-
$this->expectedAddresses = [$address, $address2];
}
/**
- * Tear down.
+ * @inheritdoc
*/
protected function tearDown(): void
{
@@ -109,8 +125,9 @@ protected function tearDown(): void
* @magentoDataFixture Magento/Customer/_files/customer_address.php
* @magentoDataFixture Magento/Customer/_files/customer_two_addresses.php
* @magentoAppIsolation enabled
+ * @return void
*/
- public function testSaveAddressChanges()
+ public function testSaveAddressChanges(): void
{
$address = $this->repository->getById(2);
@@ -132,11 +149,19 @@ public function testSaveAddressChanges()
* @magentoDataFixture Magento/Customer/_files/customer_address.php
* @magentoDataFixture Magento/Customer/_files/customer_two_addresses.php
* @magentoAppIsolation enabled
+ * @return void
*/
- public function testSaveAddressesIdSetButNotAlreadyExisting()
+ public function testSaveAddressesIdSetButNotAlreadyExisting(): void
{
- $this->expectException(\Magento\Framework\Exception\NoSuchEntityException::class);
- $this->expectExceptionMessage('No such entity with addressId = 4200');
+ $message = (string)__(
+ 'No such entity with %fieldName = %fieldValue',
+ [
+ 'fieldName' => 'addressId',
+ 'fieldValue' => 4200
+ ]
+ );
+ $this->expectException(NoSuchEntityException::class);
+ $this->expectExceptionMessage($message);
$proposedAddress = $this->_createSecondAddress()->setId(4200);
$this->repository->save($proposedAddress);
@@ -149,8 +174,9 @@ public function testSaveAddressesIdSetButNotAlreadyExisting()
* @magentoDataFixture Magento/Customer/_files/customer_address.php
* @magentoDataFixture Magento/Customer/_files/customer_two_addresses.php
* @magentoAppIsolation enabled
+ * @return void
*/
- public function testGetAddressById()
+ public function testGetAddressById(): void
{
$addressId = 2;
$address = $this->repository->getById($addressId);
@@ -161,11 +187,19 @@ public function testGetAddressById()
* Test for method get address by id with incorrect id.
*
* @magentoDataFixture Magento/Customer/_files/customer.php
+ * @return void
*/
- public function testGetAddressByIdBadAddressId()
+ public function testGetAddressByIdBadAddressId(): void
{
- $this->expectException(\Magento\Framework\Exception\NoSuchEntityException::class);
- $this->expectExceptionMessage('No such entity with addressId = 12345');
+ $message = (string)__(
+ 'No such entity with %fieldName = %fieldValue',
+ [
+ 'fieldName' => 'addressId',
+ 'fieldValue' => 12345
+ ]
+ );
+ $this->expectException(NoSuchEntityException::class);
+ $this->expectExceptionMessage($message);
$this->repository->getById(12345);
}
@@ -176,8 +210,9 @@ public function testGetAddressByIdBadAddressId()
* @magentoDataFixture Magento/Customer/_files/customer.php
* @magentoDataFixture Magento/Customer/_files/customer_address.php
* @magentoAppIsolation enabled
+ * @return void
*/
- public function testSaveNewAddress()
+ public function testSaveNewAddress(): void
{
$proposedAddress = $this->_createSecondAddress()->setCustomerId(1);
@@ -204,8 +239,9 @@ public function testSaveNewAddress()
* @magentoDataFixture Magento/Customer/_files/customer.php
* @magentoDataFixture Magento/Customer/_files/customer_address.php
* @magentoAppIsolation enabled
+ * @return void
*/
- public function testSaveNewAddressWithAttributes()
+ public function testSaveNewAddressWithAttributes(): void
{
$proposedAddress = $this->_createFirstAddress()
->setCustomAttribute('firstname', 'Jane')
@@ -231,8 +267,9 @@ public function testSaveNewAddressWithAttributes()
* @magentoDataFixture Magento/Customer/_files/customer.php
* @magentoDataFixture Magento/Customer/_files/customer_address.php
* @magentoAppIsolation enabled
+ * @return void
*/
- public function testSaveNewInvalidAddress()
+ public function testSaveNewInvalidAddress(): void
{
$address = $this->_createFirstAddress()
->setCustomAttribute('firstname', null)
@@ -256,15 +293,19 @@ public function testSaveNewInvalidAddress()
*
* @return void
*/
- public function testSaveAddressesCustomerIdNotExist()
+ public function testSaveAddressesCustomerIdNotExist(): void
{
+ $message = (string)__(
+ 'No such entity with %fieldName = %fieldValue',
+ [
+ 'fieldName' => 'customerId',
+ 'fieldValue' => 4200
+ ]
+ );
+ $this->expectException(NoSuchEntityException::class);
+ $this->expectExceptionMessage($message);
$proposedAddress = $this->_createSecondAddress()->setCustomerId(4200);
- try {
- $this->repository->save($proposedAddress);
- $this->fail('Expected exception not thrown');
- } catch (NoSuchEntityException $nsee) {
- $this->assertEquals('No such entity with customerId = 4200', $nsee->getMessage());
- }
+ $this->repository->save($proposedAddress);
}
/**
@@ -272,15 +313,19 @@ public function testSaveAddressesCustomerIdNotExist()
*
* @return void
*/
- public function testSaveAddressesCustomerIdInvalid()
+ public function testSaveAddressesCustomerIdInvalid(): void
{
+ $message = (string)__(
+ 'No such entity with %fieldName = %fieldValue',
+ [
+ 'fieldName' => 'customerId',
+ 'fieldValue' => 'this_is_not_a_valid_id'
+ ]
+ );
+ $this->expectException(NoSuchEntityException::class);
+ $this->expectExceptionMessage($message);
$proposedAddress = $this->_createSecondAddress()->setCustomerId('this_is_not_a_valid_id');
- try {
- $this->repository->save($proposedAddress);
- $this->fail('Expected exception not thrown');
- } catch (NoSuchEntityException $nsee) {
- $this->assertEquals('No such entity with customerId = this_is_not_a_valid_id', $nsee->getMessage());
- }
+ $this->repository->save($proposedAddress);
}
/**
@@ -288,24 +333,26 @@ public function testSaveAddressesCustomerIdInvalid()
*
* @magentoDataFixture Magento/Customer/_files/customer.php
* @magentoDataFixture Magento/Customer/_files/customer_address.php
+ * @return void
*/
- public function testDeleteAddress()
+ public function testDeleteAddress(): void
{
$addressId = 1;
// See that customer already has an address with expected addressId
$addressDataObject = $this->repository->getById($addressId);
$this->assertEquals($addressDataObject->getId(), $addressId);
-
// Delete the address from the customer
$this->repository->delete($addressDataObject);
-
- // See that address is deleted
- try {
- $addressDataObject = $this->repository->getById($addressId);
- $this->fail("Expected NoSuchEntityException not caught");
- } catch (NoSuchEntityException $exception) {
- $this->assertEquals('No such entity with addressId = 1', $exception->getMessage());
- }
+ $message = (string)__(
+ 'No such entity with %fieldName = %fieldValue',
+ [
+ 'fieldName' => 'addressId',
+ 'fieldValue' => 1
+ ]
+ );
+ $this->expectException(NoSuchEntityException::class);
+ $this->expectExceptionMessage($message);
+ $this->repository->getById($addressId);
}
/**
@@ -313,8 +360,9 @@ public function testDeleteAddress()
*
* @magentoDataFixture Magento/Customer/_files/customer.php
* @magentoDataFixture Magento/Customer/_files/customer_address.php
+ * @return void
*/
- public function testDeleteAddressById()
+ public function testDeleteAddressById(): void
{
$addressId = 1;
// See that customer already has an address with expected addressId
@@ -323,50 +371,63 @@ public function testDeleteAddressById()
// Delete the address from the customer
$this->repository->deleteById($addressId);
-
- // See that address is deleted
- try {
- $addressDataObject = $this->repository->getById($addressId);
- $this->fail("Expected NoSuchEntityException not caught");
- } catch (NoSuchEntityException $exception) {
- $this->assertEquals('No such entity with addressId = 1', $exception->getMessage());
- }
+ $message = (string)__(
+ 'No such entity with %fieldName = %fieldValue',
+ [
+ 'fieldName' => 'addressId',
+ 'fieldValue' => 1
+ ]
+ );
+ $this->expectException(NoSuchEntityException::class);
+ $this->expectExceptionMessage($message);
+ $this->repository->getById($addressId);
}
/**
* Test delete address from customer with incorrect address id.
*
* @magentoDataFixture Magento/Customer/_files/customer.php
+ * @return void
*/
- public function testDeleteAddressFromCustomerBadAddressId()
+ public function testDeleteAddressFromCustomerBadAddressId(): void
{
- try {
- $this->repository->deleteById(12345);
- $this->fail("Expected NoSuchEntityException not caught");
- } catch (NoSuchEntityException $exception) {
- $this->assertEquals('No such entity with addressId = 12345', $exception->getMessage());
- }
+ $message = (string)__(
+ 'No such entity with %fieldName = %fieldValue',
+ [
+ 'fieldName' => 'addressId',
+ 'fieldValue' => 12345
+ ]
+ );
+ $this->expectException(NoSuchEntityException::class);
+ $this->expectExceptionMessage($message);
+ $this->repository->deleteById(12345);
}
/**
* Test for searching addressed.
*
- * @param \Magento\Framework\Api\Filter[] $filters
- * @param \Magento\Framework\Api\Filter[] $filterGroup
- * @param \Magento\Framework\Api\SortOrder[] $filterOrders
+ * @param Filter[] $filters
+ * @param Filter[] $filterGroup
+ * @param SortOrder[] $filterOrders
* @param array $expectedResult array of expected results indexed by ID
* @param int $currentPage current page for search criteria
*
+ * @return void
* @dataProvider searchAddressDataProvider
*
* @magentoDataFixture Magento/Customer/_files/customer.php
* @magentoDataFixture Magento/Customer/_files/customer_two_addresses.php
* @magentoAppIsolation enabled
*/
- public function testSearchAddresses($filters, $filterGroup, $filterOrders, $expectedResult, $currentPage)
- {
- /** @var \Magento\Framework\Api\SearchCriteriaBuilder $searchBuilder */
- $searchBuilder = $this->objectManager->create(\Magento\Framework\Api\SearchCriteriaBuilder::class);
+ public function testSearchAddresses(
+ $filters,
+ $filterGroup,
+ $filterOrders,
+ array $expectedResult,
+ int $currentPage
+ ): void {
+ /** @var SearchCriteriaBuilder $searchBuilder */
+ $searchBuilder = $this->objectManager->create(SearchCriteriaBuilder::class);
foreach ($filters as $filter) {
$searchBuilder->addFilters([$filter]);
}
@@ -403,18 +464,18 @@ public function testSearchAddresses($filters, $filterGroup, $filterOrders, $expe
*
* @return array
*/
- public function searchAddressDataProvider()
+ public function searchAddressDataProvider(): array
{
/**
- * @var \Magento\Framework\Api\FilterBuilder $filterBuilder
+ * @var FilterBuilder $filterBuilder
*/
- $filterBuilder = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
- ->create(\Magento\Framework\Api\FilterBuilder::class);
+ $filterBuilder = Bootstrap::getObjectManager()
+ ->create(FilterBuilder::class);
/**
- * @var \Magento\Framework\Api\SortOrderBuilder $orderBuilder
+ * @var SortOrderBuilder $orderBuilder
*/
- $orderBuilder = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
- ->create(\Magento\Framework\Api\SortOrderBuilder::class);
+ $orderBuilder = Bootstrap::getObjectManager()
+ ->create(SortOrderBuilder::class);
return [
'Address with postcode 75477' => [
[$filterBuilder->setField('postcode')->setValue('75477')->create()],
@@ -482,13 +543,13 @@ public function searchAddressDataProvider()
* Test for save addresses with restricted countries.
*
* @magentoDataFixture Magento/Customer/Fixtures/customer_sec_website.php
+ * @return void
*/
- public function testSaveAddressWithRestrictedCountries()
+ public function testSaveAddressWithRestrictedCountries(): void
{
- $website = $this->getWebsite('test');
- $customer = $this->getCustomer('customer.web@example.com', (int)$website->getId());
- $regionFactory = $this->objectManager->get(RegionInterfaceFactory::class);
- $region = $regionFactory->create()
+ $website = $this->storeManager->getWebsite('test');
+ $customer = $this->customerRepository->get('customer.web@example.com', (int)$website->getId());
+ $region = $this->regionFactory->create()
->setRegionCode('CA')
->setRegion('California')
->setRegionId(12);
@@ -513,8 +574,9 @@ public function testSaveAddressWithRestrictedCountries()
*
* @magentoDataFixture Magento/Customer/_files/customer.php
* @magentoDataFixture Magento/Customer/_files/customer_address.php
+ * @return void
*/
- public function testSaveNewAddressWithExtraSpacesInPhone()
+ public function testSaveNewAddressWithExtraSpacesInPhone(): void
{
$proposedAddress = $this->_createSecondAddress()
->setCustomerId(1)
@@ -528,8 +590,9 @@ public function testSaveNewAddressWithExtraSpacesInPhone()
* Scenario for customer's default shipping and billing address saving and rollback.
*
* @magentoDataFixture Magento/Customer/_files/customer_without_addresses.php
+ * @return void
*/
- public function testCustomerAddressRelationSynchronisation()
+ public function testCustomerAddressRelationSynchronisation(): void
{
/**
* Creating new address which is default shipping and billing for existing customer.
@@ -544,7 +607,7 @@ public function testCustomerAddressRelationSynchronisation()
/**
* Customer registry should be updated with default shipping and billing addresses.
*/
- $customer = $this->getCustomer('customer@example.com', 1);
+ $customer = $this->customerRepository->get('customer@example.com', 1);
$this->assertEquals($savedAddress->getId(), $customer->getDefaultShipping());
$this->assertEquals($savedAddress->getId(), $customer->getDefaultBilling());
@@ -557,21 +620,66 @@ public function testCustomerAddressRelationSynchronisation()
/**
* Customer's default shipping and billing addresses should be updated.
*/
- $customer = $this->getCustomer('customer@example.com', 1);
+ $customer = $this->customerRepository->get('customer@example.com', 1);
$this->assertNull($customer->getDefaultShipping());
$this->assertNull($customer->getDefaultBilling());
}
+ /**
+ * Update Customer Address, with Alphanumeric Zip Code
+ *
+ * @magentoDataFixture Magento/Customer/_files/customer_one_address.php
+ * @return void
+ */
+ public function testUpdateWithAlphanumericZipCode(): void
+ {
+ $region = $this->regionFactory->create()
+ ->setRegionCode('PH')
+ ->setRegion('Pinminnoch')
+ ->setRegionId(1);
+ $websiteId = (int)$this->storeManager->getWebsite('base')->getId();
+ $customer = $this->customerRepository->get('customer_one_address@test.com', $websiteId);
+ $defaultBillingAddress = $customer->getDefaultBilling();
+ $addressData = [
+ AddressInterface::FIRSTNAME => 'Doe',
+ AddressInterface::LASTNAME => 'Doe',
+ AddressInterface::MIDDLENAME => 'Middle Name',
+ AddressInterface::SUFFIX => '_Suffix',
+ AddressInterface::PREFIX => 'Prefix',
+ AddressInterface::COMPANY => 'Company',
+ AddressInterface::STREET => ['Northgate Street, 39'],
+ AddressInterface::CITY => 'BICKTON',
+ AddressInterface::COUNTRY_ID => 'GB',
+ AddressInterface::REGION => $region,
+ AddressInterface::POSTCODE => 'KA26 1PF',
+ AddressInterface::TELEPHONE => '999-777-111-2345',
+ AddressInterface::VAT_ID => '987654321'
+ ];
+ $customerAddress = $this->repository->getById((int)$defaultBillingAddress);
+ foreach ($addressData as $key => $value) {
+ $customerAddress->setData($key, $value);
+ }
+ $savedAddress = $this->repository->save($customerAddress);
+ $customerData = $savedAddress->__toArray();
+ foreach ($addressData as $key => $value) {
+ if ($key === 'region') {
+ $this->assertEquals('Pinminnoch', $value->getRegion());
+ } else {
+ $this->assertEquals($value, $customerData[$key]);
+ }
+ }
+ }
+
/**
* Helper function that returns an Address Data Object that matches the data from customer_address fixture
*
- * @return \Magento\Customer\Api\Data\AddressInterface
+ * @return AddressInterface
*/
- private function _createFirstAddress()
+ private function _createFirstAddress(): AddressInterface
{
$address = $this->addressFactory->create();
$this->dataObjectHelper->mergeDataObjects(
- \Magento\Customer\Api\Data\AddressInterface::class,
+ AddressInterface::class,
$address,
$this->expectedAddresses[0]
);
@@ -583,13 +691,13 @@ private function _createFirstAddress()
/**
* Helper function that returns an Address Data Object that matches the data from customer_two_address fixture
*
- * @return \Magento\Customer\Api\Data\AddressInterface
+ * @return AddressInterface
*/
- private function _createSecondAddress()
+ private function _createSecondAddress(): AddressInterface
{
$address = $this->addressFactory->create();
$this->dataObjectHelper->mergeDataObjects(
- \Magento\Customer\Api\Data\AddressInterface::class,
+ AddressInterface::class,
$address,
$this->expectedAddresses[1]
);
@@ -597,34 +705,4 @@ private function _createSecondAddress()
$address->setRegion($this->expectedAddresses[1]->getRegion());
return $address;
}
-
- /**
- * Gets customer entity.
- *
- * @param string $email
- * @param int $websiteId
- * @return CustomerInterface
- * @throws NoSuchEntityException
- * @throws \Magento\Framework\Exception\LocalizedException
- */
- private function getCustomer(string $email, int $websiteId): CustomerInterface
- {
- /** @var CustomerRepositoryInterface $repository */
- $repository = $this->objectManager->get(CustomerRepositoryInterface::class);
- return $repository->get($email, $websiteId);
- }
-
- /**
- * Gets website entity.
- *
- * @param string $code
- * @return WebsiteInterface
- * @throws NoSuchEntityException
- */
- private function getWebsite(string $code): WebsiteInterface
- {
- /** @var WebsiteRepositoryInterface $repository */
- $repository = $this->objectManager->get(WebsiteRepositoryInterface::class);
- return $repository->get($code);
- }
}
From c287f03ffcab71b06109de6bf0ee335de05a6045 Mon Sep 17 00:00:00 2001
From: Serhii Bohomaz
Date: Fri, 6 Nov 2020 16:07:21 +0200
Subject: [PATCH 03/14] MC-37099: Create automated test for "Update Customer
Address, with Alphanumeric Zip Code"
---
.../ResourceModel/AddressRepositoryTest.php | 34 +++++++++----------
1 file changed, 17 insertions(+), 17 deletions(-)
diff --git a/dev/tests/integration/testsuite/Magento/Customer/Model/ResourceModel/AddressRepositoryTest.php b/dev/tests/integration/testsuite/Magento/Customer/Model/ResourceModel/AddressRepositoryTest.php
index 692252ffe3206..4aefde9bf9fdb 100644
--- a/dev/tests/integration/testsuite/Magento/Customer/Model/ResourceModel/AddressRepositoryTest.php
+++ b/dev/tests/integration/testsuite/Magento/Customer/Model/ResourceModel/AddressRepositoryTest.php
@@ -157,7 +157,7 @@ public function testSaveAddressesIdSetButNotAlreadyExisting(): void
'No such entity with %fieldName = %fieldValue',
[
'fieldName' => 'addressId',
- 'fieldValue' => 4200
+ 'fieldValue' => 4200,
]
);
$this->expectException(NoSuchEntityException::class);
@@ -195,7 +195,7 @@ public function testGetAddressByIdBadAddressId(): void
'No such entity with %fieldName = %fieldValue',
[
'fieldName' => 'addressId',
- 'fieldValue' => 12345
+ 'fieldValue' => 12345,
]
);
$this->expectException(NoSuchEntityException::class);
@@ -299,7 +299,7 @@ public function testSaveAddressesCustomerIdNotExist(): void
'No such entity with %fieldName = %fieldValue',
[
'fieldName' => 'customerId',
- 'fieldValue' => 4200
+ 'fieldValue' => 4200,
]
);
$this->expectException(NoSuchEntityException::class);
@@ -319,7 +319,7 @@ public function testSaveAddressesCustomerIdInvalid(): void
'No such entity with %fieldName = %fieldValue',
[
'fieldName' => 'customerId',
- 'fieldValue' => 'this_is_not_a_valid_id'
+ 'fieldValue' => 'this_is_not_a_valid_id',
]
);
$this->expectException(NoSuchEntityException::class);
@@ -347,7 +347,7 @@ public function testDeleteAddress(): void
'No such entity with %fieldName = %fieldValue',
[
'fieldName' => 'addressId',
- 'fieldValue' => 1
+ 'fieldValue' => 1,
]
);
$this->expectException(NoSuchEntityException::class);
@@ -375,7 +375,7 @@ public function testDeleteAddressById(): void
'No such entity with %fieldName = %fieldValue',
[
'fieldName' => 'addressId',
- 'fieldValue' => 1
+ 'fieldValue' => 1,
]
);
$this->expectException(NoSuchEntityException::class);
@@ -395,7 +395,7 @@ public function testDeleteAddressFromCustomerBadAddressId(): void
'No such entity with %fieldName = %fieldValue',
[
'fieldName' => 'addressId',
- 'fieldValue' => 12345
+ 'fieldValue' => 12345,
]
);
$this->expectException(NoSuchEntityException::class);
@@ -482,7 +482,7 @@ public function searchAddressDataProvider(): array
null,
null,
[
- ['id' => 1, 'city' => 'CityM', 'postcode' => 75477, 'firstname' => 'John'],
+ ['id' => 1, 'city' => 'CityM', 'postcode' => 75477, 'firstname' => 'John',],
],
1
],
@@ -491,7 +491,7 @@ public function searchAddressDataProvider(): array
null,
null,
[
- ['id' => 1, 'city' => 'CityM', 'postcode' => 75477, 'firstname' => 'John'],
+ ['id' => 1, 'city' => 'CityM', 'postcode' => 75477, 'firstname' => 'John',],
],
1
],
@@ -503,8 +503,8 @@ public function searchAddressDataProvider(): array
$orderBuilder->setField('city')->setDirection(SortOrder::SORT_ASC)->create(),
],
[
- ['id' => 1, 'city' => 'CityM', 'postcode' => 75477, 'firstname' => 'John'],
- ['id' => 2, 'city' => 'CityX', 'postcode' => 47676, 'firstname' => 'John'],
+ ['id' => 1, 'city' => 'CityM', 'postcode' => 75477, 'firstname' => 'John',],
+ ['id' => 2, 'city' => 'CityX', 'postcode' => 47676, 'firstname' => 'John',],
],
2
],
@@ -518,8 +518,8 @@ public function searchAddressDataProvider(): array
$orderBuilder->setField('city')->setDirection(SortOrder::SORT_DESC)->create(),
],
[
- ['id' => 2, 'city' => 'CityX', 'postcode' => 47676, 'firstname' => 'John'],
- ['id' => 1, 'city' => 'CityM', 'postcode' => 75477, 'firstname' => 'John'],
+ ['id' => 2, 'city' => 'CityX', 'postcode' => 47676, 'firstname' => 'John',],
+ ['id' => 1, 'city' => 'CityM', 'postcode' => 75477, 'firstname' => 'John',],
],
2
],
@@ -531,8 +531,8 @@ public function searchAddressDataProvider(): array
$orderBuilder->setField('postcode')->setDirection(SortOrder::SORT_ASC)->create(),
],
[
- ['id' => 2, 'city' => 'CityX', 'postcode' => 47676, 'firstname' => 'John'],
- ['id' => 1, 'city' => 'CityM', 'postcode' => 75477, 'firstname' => 'John'],
+ ['id' => 2, 'city' => 'CityX', 'postcode' => 47676, 'firstname' => 'John',],
+ ['id' => 1, 'city' => 'CityM', 'postcode' => 75477, 'firstname' => 'John',],
],
2
],
@@ -662,8 +662,8 @@ public function testUpdateWithAlphanumericZipCode(): void
$savedAddress = $this->repository->save($customerAddress);
$customerData = $savedAddress->__toArray();
foreach ($addressData as $key => $value) {
- if ($key === 'region') {
- $this->assertEquals('Pinminnoch', $value->getRegion());
+ if ($key === AddressInterface::REGION) {
+ $this->assertEquals($customerData[$key][AddressInterface::REGION], $value->getRegion());
} else {
$this->assertEquals($value, $customerData[$key]);
}
From a1cc18525c022361216f21917478a41e1806ac14 Mon Sep 17 00:00:00 2001
From: Serhii Bohomaz
Date: Fri, 6 Nov 2020 17:18:55 +0200
Subject: [PATCH 04/14] MC-37099: Create automated test for "Update Customer
Address, with Alphanumeric Zip Code"
---
.../ResourceModel/AddressRepositoryTest.php | 20 +++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/dev/tests/integration/testsuite/Magento/Customer/Model/ResourceModel/AddressRepositoryTest.php b/dev/tests/integration/testsuite/Magento/Customer/Model/ResourceModel/AddressRepositoryTest.php
index 4aefde9bf9fdb..3e7b59500b574 100644
--- a/dev/tests/integration/testsuite/Magento/Customer/Model/ResourceModel/AddressRepositoryTest.php
+++ b/dev/tests/integration/testsuite/Magento/Customer/Model/ResourceModel/AddressRepositoryTest.php
@@ -482,7 +482,7 @@ public function searchAddressDataProvider(): array
null,
null,
[
- ['id' => 1, 'city' => 'CityM', 'postcode' => 75477, 'firstname' => 'John',],
+ ['id' => 1, 'city' => 'CityM', 'postcode' => 75477, 'firstname' => 'John'],
],
1
],
@@ -491,7 +491,7 @@ public function searchAddressDataProvider(): array
null,
null,
[
- ['id' => 1, 'city' => 'CityM', 'postcode' => 75477, 'firstname' => 'John',],
+ ['id' => 1, 'city' => 'CityM', 'postcode' => 75477, 'firstname' => 'John'],
],
1
],
@@ -503,8 +503,8 @@ public function searchAddressDataProvider(): array
$orderBuilder->setField('city')->setDirection(SortOrder::SORT_ASC)->create(),
],
[
- ['id' => 1, 'city' => 'CityM', 'postcode' => 75477, 'firstname' => 'John',],
- ['id' => 2, 'city' => 'CityX', 'postcode' => 47676, 'firstname' => 'John',],
+ ['id' => 1, 'city' => 'CityM', 'postcode' => 75477, 'firstname' => 'John'],
+ ['id' => 2, 'city' => 'CityX', 'postcode' => 47676, 'firstname' => 'John'],
],
2
],
@@ -518,8 +518,8 @@ public function searchAddressDataProvider(): array
$orderBuilder->setField('city')->setDirection(SortOrder::SORT_DESC)->create(),
],
[
- ['id' => 2, 'city' => 'CityX', 'postcode' => 47676, 'firstname' => 'John',],
- ['id' => 1, 'city' => 'CityM', 'postcode' => 75477, 'firstname' => 'John',],
+ ['id' => 2, 'city' => 'CityX', 'postcode' => 47676, 'firstname' => 'John'],
+ ['id' => 1, 'city' => 'CityM', 'postcode' => 75477, 'firstname' => 'John'],
],
2
],
@@ -531,8 +531,8 @@ public function searchAddressDataProvider(): array
$orderBuilder->setField('postcode')->setDirection(SortOrder::SORT_ASC)->create(),
],
[
- ['id' => 2, 'city' => 'CityX', 'postcode' => 47676, 'firstname' => 'John',],
- ['id' => 1, 'city' => 'CityM', 'postcode' => 75477, 'firstname' => 'John',],
+ ['id' => 2, 'city' => 'CityX', 'postcode' => 47676, 'firstname' => 'John'],
+ ['id' => 1, 'city' => 'CityM', 'postcode' => 75477, 'firstname' => 'John'],
],
2
],
@@ -562,7 +562,7 @@ public function testSaveAddressWithRestrictedCountries(): void
'country_id' => 'US',
'region' => $region,
'postcode' => 90230,
- 'telephone' => '555655431'
+ 'telephone' => '555655431',
];
$address = $this->addressFactory->create(['data' => $addressData]);
$saved = $this->repository->save($address);
@@ -653,7 +653,7 @@ public function testUpdateWithAlphanumericZipCode(): void
AddressInterface::REGION => $region,
AddressInterface::POSTCODE => 'KA26 1PF',
AddressInterface::TELEPHONE => '999-777-111-2345',
- AddressInterface::VAT_ID => '987654321'
+ AddressInterface::VAT_ID => '987654321',
];
$customerAddress = $this->repository->getById((int)$defaultBillingAddress);
foreach ($addressData as $key => $value) {
From 537fc27f50be999897602bf34d2db6efd3d93856 Mon Sep 17 00:00:00 2001
From: Bohdan Shevchenko <1408sheva@gmail.com>
Date: Tue, 10 Nov 2020 13:56:17 +0200
Subject: [PATCH 05/14] MC-38960: Fix and unskip test for "Admin should be able
to create a Date product attribute"
---
.../CreateProductAttributeEntityDateTest.xml | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/CreateProductAttributeEntityTest/CreateProductAttributeEntityDateTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/CreateProductAttributeEntityTest/CreateProductAttributeEntityDateTest.xml
index 26ff1bc45be9d..d1f7adb8a902c 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/CreateProductAttributeEntityTest/CreateProductAttributeEntityDateTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/CreateProductAttributeEntityTest/CreateProductAttributeEntityDateTest.xml
@@ -16,9 +16,6 @@
-
-
-
@@ -35,8 +32,9 @@
-
+
+
@@ -57,7 +55,7 @@
-
+
From 9fb7eb2fefc4d1ad4e13dc2078b71ffc271d20f0 Mon Sep 17 00:00:00 2001
From: engcom-Echo
Date: Tue, 10 Nov 2020 16:00:31 +0200
Subject: [PATCH 06/14] MC-38105: Unable to set native session handler that is
different from the one define in php.ini
---
.../Framework/Session/SessionManagerTest.php | 40 ++++++++++++++-----
.../Framework/Session/SessionManager.php | 4 +-
2 files changed, 33 insertions(+), 11 deletions(-)
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Session/SessionManagerTest.php b/dev/tests/integration/testsuite/Magento/Framework/Session/SessionManagerTest.php
index d35d875ff8006..21321b49f2610 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/Session/SessionManagerTest.php
+++ b/dev/tests/integration/testsuite/Magento/Framework/Session/SessionManagerTest.php
@@ -115,6 +115,9 @@ class SessionManagerTest extends \PHPUnit\Framework\TestCase
*/
private $appState;
+ /**
+ * @inheritdoc
+ */
protected function setUp(): void
{
$this->sessionName = 'frontEndSession';
@@ -250,8 +253,6 @@ public function testIsValidForHost()
$this->model->destroy();
}
- /**
- */
public function testStartAreaNotSet()
{
$this->expectException(\Magento\Framework\Exception\SessionException::class);
@@ -283,17 +284,23 @@ public function testStartAreaNotSet()
$this->model->start();
}
- public function testConstructor()
+ /**
+ * @param string $saveMethod
+ * @dataProvider dataConstructor
+ *
+ * @return void
+ */
+ public function testConstructor(string $saveMethod): void
{
global $mockPHPFunctions;
$mockPHPFunctions = true;
$deploymentConfigMock = $this->createMock(DeploymentConfig::class);
$deploymentConfigMock->method('get')
- ->willReturnCallback(function ($configPath) {
+ ->willReturnCallback(function ($configPath) use ($saveMethod) {
switch ($configPath) {
case Config::PARAM_SESSION_SAVE_METHOD:
- return 'db';
+ return $saveMethod;
case Config::PARAM_SESSION_CACHE_LIMITER:
return 'private_no_expire';
case Config::PARAM_SESSION_SAVE_PATH:
@@ -313,22 +320,35 @@ public function testConstructor()
'sessionConfig' => $sessionConfig,
]
);
- $this->assertEquals('db', $sessionConfig->getOption('session.save_handler'));
+ $this->assertEquals($saveMethod, $sessionConfig->getOption('session.save_handler'));
$this->assertEquals('private_no_expire', $sessionConfig->getOption('session.cache_limiter'));
$this->assertEquals('explicit_save_path', $sessionConfig->getOption('session.save_path'));
$this->assertArrayHasKey('session.use_only_cookies', self::$isIniSetInvoked);
$this->assertEquals('1', self::$isIniSetInvoked['session.use_only_cookies']);
foreach ($sessionConfig->getOptions() as $option => $value) {
- if ($option=='session.save_handler') {
- $this->assertArrayNotHasKey('session.save_handler', self::$isIniSetInvoked);
+ if ($option == 'session.save_handler' && $value == 'user') {
+ $this->assertArrayNotHasKey('session.save_handler', self::$isIniSetInvoked);
} else {
- $this->assertArrayHasKey($option, self::$isIniSetInvoked);
- $this->assertEquals($value, self::$isIniSetInvoked[$option]);
+ $this->assertArrayHasKey($option, self::$isIniSetInvoked);
+ $this->assertEquals($value, self::$isIniSetInvoked[$option]);
}
}
$this->assertTrue(self::$isSessionSetSaveHandlerInvoked);
}
+ /**
+ * @return array
+ */
+ public function dataConstructor(): array
+ {
+ return [
+ [Config::PARAM_SESSION_SAVE_METHOD =>'db'],
+ [Config::PARAM_SESSION_SAVE_METHOD =>'redis'],
+ [Config::PARAM_SESSION_SAVE_METHOD =>'memcached'],
+ [Config::PARAM_SESSION_SAVE_METHOD =>'user'],
+ ];
+ }
+
private function initializeModel(): void
{
$this->model = $this->objectManager->create(
diff --git a/lib/internal/Magento/Framework/Session/SessionManager.php b/lib/internal/Magento/Framework/Session/SessionManager.php
index 7e43a9f2d99c0..039caf202e60e 100644
--- a/lib/internal/Magento/Framework/Session/SessionManager.php
+++ b/lib/internal/Magento/Framework/Session/SessionManager.php
@@ -619,7 +619,9 @@ private function initIniOptions()
}
foreach ($this->sessionConfig->getOptions() as $option => $value) {
- if ($option=='session.save_handler') {
+ // It is now explicitly forbidden to set the module name to "user".
+ // Formerly, this has been silently ignored.
+ if ($option === 'session.save_handler' && $value === 'user') {
continue;
} else {
$result = ini_set($option, $value);
From 41c17e7ed402f9aebda96d284e5a62bd7f72f663 Mon Sep 17 00:00:00 2001
From: Yurii Sapiha
Date: Wed, 11 Nov 2020 12:59:32 +0200
Subject: [PATCH 07/14] MC-37901: Create automated test for "Widgets with
different themes is presented in grid/filter"
---
.../Block/Adminhtml/Widget/InstanceTest.php | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/dev/tests/integration/testsuite/Magento/Widget/Block/Adminhtml/Widget/InstanceTest.php b/dev/tests/integration/testsuite/Magento/Widget/Block/Adminhtml/Widget/InstanceTest.php
index 57d4322ded9a3..9088dbfea6f85 100644
--- a/dev/tests/integration/testsuite/Magento/Widget/Block/Adminhtml/Widget/InstanceTest.php
+++ b/dev/tests/integration/testsuite/Magento/Widget/Block/Adminhtml/Widget/InstanceTest.php
@@ -118,13 +118,23 @@ public function gridFiltersDataProvider(): array
'filter' => base64_encode('sort_order=1'),
],
'expected_widgets' => [
- 'recently compared products'
+ 'recently compared products',
+ ],
+ ],
+ 'filter_by_title_and_luma_theme' => [
+ 'filter' => [
+ 'filter' => base64_encode(
+ 'title=cms page widget title&theme_id=' . $this->loadThemeIdByCode('Magento/luma')
+ ),
+ ],
+ 'expected_widgets' => [
+ 'cms page widget title',
],
],
- 'filter_by_multiple_filters' => [
+ 'filter_by_title_and_blank_theme' => [
'filter' => [
'filter' => base64_encode(
- 'type=Magento%5CCatalog%5CBlock%5CWidget%5CRecentlyCompared&sort_order=1'
+ 'title=recently compared products&theme_id=' . $this->loadThemeIdByCode('Magento/blank')
),
],
'expected_widgets' => [
@@ -270,7 +280,7 @@ private function assertWidgets($expectedWidgets, AbstractCollection $collection)
$this->assertCount(count($expectedWidgets), $collection);
foreach ($expectedWidgets as $widgetTitle) {
$item = $collection->getItemByColumnValue('title', $widgetTitle);
- $this->assertNotNull($item);
+ $this->assertNotNull($item, sprintf('Expected widget %s is not present in grid', $widgetTitle));
}
}
From b5d053387bff1a53efebec96cf1afc7fb7bf5c25 Mon Sep 17 00:00:00 2001
From: SmVladyslav
Date: Thu, 12 Nov 2020 11:33:49 +0200
Subject: [PATCH 08/14] MC-38460: Setting custom price on bundle product causes
wrong prices on attached simple products when reordering.
---
.../Quote/Model/Quote/Item/Processor.php | 5 +-
.../Model/Sales/AdminOrder/ReorderTest.php | 89 +++++++++++++++++++
.../order_item_with_bundle_and_options.php | 10 ++-
.../Model/Sales/AdminOrder/ReorderTest.php | 89 +++++++++++++++++++
...der_item_with_configurable_and_options.php | 18 +++-
5 files changed, 204 insertions(+), 7 deletions(-)
create mode 100644 dev/tests/integration/testsuite/Magento/Bundle/Model/Sales/AdminOrder/ReorderTest.php
create mode 100644 dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/Sales/AdminOrder/ReorderTest.php
diff --git a/app/code/Magento/Quote/Model/Quote/Item/Processor.php b/app/code/Magento/Quote/Model/Quote/Item/Processor.php
index c6bef1cc80bfb..477a6f2254d52 100644
--- a/app/code/Magento/Quote/Model/Quote/Item/Processor.php
+++ b/app/code/Magento/Quote/Model/Quote/Item/Processor.php
@@ -96,11 +96,12 @@ public function prepare(Item $item, DataObject $request, Product $candidate): vo
}
$item->addQty($candidate->getCartQty());
- $customPrice = $request->getCustomPrice();
if (!$item->getParentItem() || $item->getParentItem()->isChildrenCalculated()) {
$item->setPrice($candidate->getFinalPrice());
}
- if (!empty($customPrice)) {
+
+ $customPrice = $request->getCustomPrice();
+ if (!empty($customPrice) && !$candidate->getParentProductId()) {
$item->setCustomPrice($customPrice);
$item->setOriginalCustomPrice($customPrice);
}
diff --git a/dev/tests/integration/testsuite/Magento/Bundle/Model/Sales/AdminOrder/ReorderTest.php b/dev/tests/integration/testsuite/Magento/Bundle/Model/Sales/AdminOrder/ReorderTest.php
new file mode 100644
index 0000000000000..6ca5ec22f5e14
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Bundle/Model/Sales/AdminOrder/ReorderTest.php
@@ -0,0 +1,89 @@
+objectManager = Bootstrap::getObjectManager();
+ $this->model =$this->objectManager->get(Create::class);
+ }
+
+ /**
+ * Check Custom Price after reordering with Bundle product.
+ *
+ * @return void
+ * @magentoDataFixture Magento/Bundle/_files/order_item_with_bundle_and_options.php
+ */
+ public function testReorderBundleProductWithCustomPrice(): void
+ {
+ $customPrice = 300;
+ /** @var $order Order */
+ $order = $this->objectManager->create(Order::class);
+ $order->loadByIncrementId('100000001');
+ $this->model->initFromOrder($order);
+
+ /** @var QuoteItem[] $quoteItems */
+ $quoteItems = $this->model->getQuote()->getAllItems();
+ $firstQuoteItem = array_shift($quoteItems);
+ self::assertNull($firstQuoteItem->getParentItemId());
+ self::assertEquals($customPrice, (int)$firstQuoteItem->getCustomPrice());
+ foreach ($quoteItems as $quoteItem) {
+ self::assertEquals($firstQuoteItem->getId(), $quoteItem->getParentItemId());
+ self::assertEquals(0, (int)$quoteItem->getCustomPrice());
+ }
+
+ $shippingMethod = 'freeshipping_freeshipping';
+ /** @var Rate $rate */
+ $rate = $this->objectManager->create(Rate::class);
+ $rate->setCode($shippingMethod);
+ $this->model->getQuote()->getShippingAddress()->addShippingRate($rate);
+ $this->model->setPaymentData(['method' => 'checkmo']);
+ $this->model->setIsValidate(true)->importPostData(['shipping_method' => $shippingMethod]);
+ $newOrder = $this->model->createOrder();
+
+ /** @var OrderItem[] $orderItems */
+ $orderItems = $newOrder->getAllItems();
+ $firstOrderItem = array_shift($orderItems);
+ self::assertNull($firstOrderItem->getParentItemId());
+ self::assertEquals($customPrice, (int)$firstOrderItem->getPrice());
+ foreach ($orderItems as $orderItem) {
+ self::assertEquals($firstOrderItem->getId(), $orderItem->getParentItemId());
+ self::assertEquals(0, (int)$orderItem->getPrice());
+ }
+ }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Bundle/_files/order_item_with_bundle_and_options.php b/dev/tests/integration/testsuite/Magento/Bundle/_files/order_item_with_bundle_and_options.php
index ae85671a684d8..e20bf232c70e1 100644
--- a/dev/tests/integration/testsuite/Magento/Bundle/_files/order_item_with_bundle_and_options.php
+++ b/dev/tests/integration/testsuite/Magento/Bundle/_files/order_item_with_bundle_and_options.php
@@ -48,6 +48,7 @@
'bundle_option' => $bundleOptions,
'bundle_option_qty' => $bundleOptionsQty,
'qty' => 1,
+ 'custom_price' => 300,
];
/** @var \Magento\Sales\Model\Order\Item $orderItem */
@@ -58,7 +59,14 @@
$orderItem->setPrice($product->getPrice());
$orderItem->setRowTotal($product->getPrice());
$orderItem->setProductType($product->getTypeId());
-$orderItem->setProductOptions(['info_buyRequest' => $requestInfo]);
+$orderItem->setProductOptions([
+ 'info_buyRequest' => $requestInfo,
+ 'bundle_options' => [
+ [
+ 'value' => [['title' => $product->getName()]]
+ ]
+ ]
+]);
/** @var \Magento\Sales\Model\Order $order */
$order = $objectManager->create(\Magento\Sales\Model\Order::class);
diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/Sales/AdminOrder/ReorderTest.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/Sales/AdminOrder/ReorderTest.php
new file mode 100644
index 0000000000000..9a02830ad74cf
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/Sales/AdminOrder/ReorderTest.php
@@ -0,0 +1,89 @@
+objectManager = Bootstrap::getObjectManager();
+ $this->model =$this->objectManager->get(Create::class);
+ }
+
+ /**
+ * Check Custom Price after reordering with Configurable product.
+ *
+ * @return void
+ * @magentoDataFixture Magento/ConfigurableProduct/_files/order_item_with_configurable_and_options.php
+ */
+ public function testReorderConfigurableProductWithCustomPrice(): void
+ {
+ $customPrice = 300;
+ /** @var $order Order */
+ $order = $this->objectManager->create(Order::class);
+ $order->loadByIncrementId('100000001');
+ $this->model->initFromOrder($order);
+
+ /** @var QuoteItem[] $quoteItems */
+ $quoteItems = $this->model->getQuote()->getAllItems();
+ $firstQuoteItem = array_shift($quoteItems);
+ self::assertNull($firstQuoteItem->getParentItemId());
+ self::assertEquals($customPrice, (int)$firstQuoteItem->getCustomPrice());
+ foreach ($quoteItems as $quoteItem) {
+ self::assertEquals($firstQuoteItem->getId(), $quoteItem->getParentItemId());
+ self::assertEquals(0, (int)$quoteItem->getCustomPrice());
+ }
+
+ $shippingMethod = 'freeshipping_freeshipping';
+ /** @var Rate $rate */
+ $rate = $this->objectManager->create(Rate::class);
+ $rate->setCode($shippingMethod);
+ $this->model->getQuote()->getShippingAddress()->addShippingRate($rate);
+ $this->model->setPaymentData(['method' => 'checkmo']);
+ $this->model->setIsValidate(true)->importPostData(['shipping_method' => $shippingMethod]);
+ $newOrder = $this->model->createOrder();
+
+ /** @var OrderItem[] $orderItems */
+ $orderItems = $newOrder->getAllItems();
+ $firstOrderItem = array_shift($orderItems);
+ self::assertNull($firstOrderItem->getParentItemId());
+ self::assertEquals($customPrice, (int)$firstOrderItem->getPrice());
+ foreach ($orderItems as $orderItem) {
+ self::assertEquals($firstOrderItem->getId(), $orderItem->getParentItemId());
+ self::assertEquals(0, (int)$orderItem->getPrice());
+ }
+ }
+}
diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/order_item_with_configurable_and_options.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/order_item_with_configurable_and_options.php
index 47d86b34fc05e..d0956e460f709 100644
--- a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/order_item_with_configurable_and_options.php
+++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/order_item_with_configurable_and_options.php
@@ -3,6 +3,9 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+
+use Magento\Catalog\Api\Data\ProductInterface;
+use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\TestFramework\Workaround\Override\Fixture\Resolver;
Resolver::getInstance()->requireDataFixture('Magento/ConfigurableProduct/_files/product_configurable.php');
@@ -20,9 +23,11 @@
$payment = $objectManager->create(\Magento\Sales\Model\Order\Payment::class);
$payment->setMethod('checkmo');
-/** @var $product \Magento\Catalog\Model\Product */
-$product = $objectManager->create(\Magento\Catalog\Model\Product::class);
-$product->load(1);
+/** @var ProductRepositoryInterface $productRepository */
+$productRepository = $objectManager->get(ProductRepositoryInterface::class);
+$product = $productRepository->get('configurable');
+/** @var ProductInterface $firstChildProduct */
+$firstChildProduct = current($product->getTypeInstance()->getUsedProducts($product));
/** @var $attribute \Magento\Catalog\Model\ResourceModel\Eav\Attribute */
$eavConfig = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Eav\Model\Config::class);
@@ -38,6 +43,7 @@
'super_attribute' => [
$attribute->getId() => $option->getId(),
],
+ 'custom_price' => 300,
];
/** @var \Magento\Sales\Model\Order $order */
$order = $objectManager->create(\Magento\Sales\Model\Order::class);
@@ -54,7 +60,11 @@
$orderItem->setPrice($product->getPrice());
$orderItem->setRowTotal($product->getPrice());
$orderItem->setProductType($product->getTypeId());
-$orderItem->setProductOptions(['info_buyRequest' => $requestInfo]);
+$orderItem->setProductOptions([
+ 'info_buyRequest' => $requestInfo,
+ 'simple_sku' => $firstChildProduct->getSku(),
+ 'simple_name' => $firstChildProduct->getName(),
+]);
/** @var \Magento\Sales\Model\Order $order */
$order = $objectManager->create(\Magento\Sales\Model\Order::class);
From 667e1dce09b0c9e79232a0aed7bc4cb6856882c7 Mon Sep 17 00:00:00 2001
From: engcom-Echo
Date: Thu, 12 Nov 2020 14:00:19 +0200
Subject: [PATCH 09/14] MC-38105: Unable to set native session handler that is
different from the one define in php.ini
---
.../Magento/Framework/Session/SessionManagerTest.php | 2 +-
lib/internal/Magento/Framework/Session/SessionManager.php | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Session/SessionManagerTest.php b/dev/tests/integration/testsuite/Magento/Framework/Session/SessionManagerTest.php
index 21321b49f2610..310e2c9d7b6ae 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/Session/SessionManagerTest.php
+++ b/dev/tests/integration/testsuite/Magento/Framework/Session/SessionManagerTest.php
@@ -326,7 +326,7 @@ public function testConstructor(string $saveMethod): void
$this->assertArrayHasKey('session.use_only_cookies', self::$isIniSetInvoked);
$this->assertEquals('1', self::$isIniSetInvoked['session.use_only_cookies']);
foreach ($sessionConfig->getOptions() as $option => $value) {
- if ($option == 'session.save_handler' && $value == 'user') {
+ if ($option === 'session.save_handler' && !$value === 'memcached') {
$this->assertArrayNotHasKey('session.save_handler', self::$isIniSetInvoked);
} else {
$this->assertArrayHasKey($option, self::$isIniSetInvoked);
diff --git a/lib/internal/Magento/Framework/Session/SessionManager.php b/lib/internal/Magento/Framework/Session/SessionManager.php
index 039caf202e60e..73ece8277f327 100644
--- a/lib/internal/Magento/Framework/Session/SessionManager.php
+++ b/lib/internal/Magento/Framework/Session/SessionManager.php
@@ -619,9 +619,9 @@ private function initIniOptions()
}
foreach ($this->sessionConfig->getOptions() as $option => $value) {
- // It is now explicitly forbidden to set the module name to "user".
- // Formerly, this has been silently ignored.
- if ($option === 'session.save_handler' && $value === 'user') {
+ // Since PHP 7.2 it is explicitly forbidden to set the module name to "user".
+ // Need to skip all handlers except memcached. Redis and Db have implements SessionHandlerInterface.
+ if ($option === 'session.save_handler' && !$value === 'memcached') {
continue;
} else {
$result = ini_set($option, $value);
From 2c8b332a4c61de9ad48e0018bfff46244d67c9cd Mon Sep 17 00:00:00 2001
From: engcom-Kilo
Date: Wed, 11 Nov 2020 13:23:40 +0200
Subject: [PATCH 10/14] MC-37364: Unit Test and JSUnit Test fails to start on
Magento composer 2.4.0
---
.../Test/Unit/Model/Export/ProductTest.php | 3 +-
.../ShippingInformationManagementTest.php | 25 ++++++--
.../Checkout/Plugin/GuestValidationTest.php | 21 ++++++-
.../Model/Checkout/Plugin/ValidationTest.php | 21 ++++++-
.../Test/Unit/Model/Renderer/RegionTest.php | 3 +-
.../Unit/Model/Link/UpdateHandlerTest.php | 20 ++++++-
.../Quote/Item/CartItemProcessorTest.php | 29 ++++++---
.../Unit/Model/Sample/UpdateHandlerTest.php | 20 ++++++-
.../IsAllowedGuestCheckoutObserverTest.php | 6 +-
.../Test/Unit/Model/Plugin/OrderGetTest.php | 42 +++++++++++--
.../Test/Unit/Model/Plugin/OrderSaveTest.php | 42 +++++++++++--
.../Unit/Model/DisableMultishippingTest.php | 26 ++++++--
.../Test/Unit/Model/QuoteManagerTest.php | 27 +++++++--
.../Media/ExternalVideoEntryConverterTest.php | 34 ++++++++---
.../Model/ShippingAddressAssignmentTest.php | 21 ++++++-
.../Test/Unit/Model/OrderRepositoryTest.php | 59 ++++++++++---------
dev/tests/integration/phpunit.xml.dist | 6 +-
.../testsuite/Magento/IntegrationTest.php | 7 ++-
dev/tests/unit/phpunit.xml.dist | 1 +
19 files changed, 320 insertions(+), 93 deletions(-)
diff --git a/app/code/Magento/CatalogImportExport/Test/Unit/Model/Export/ProductTest.php b/app/code/Magento/CatalogImportExport/Test/Unit/Model/Export/ProductTest.php
index 1ad82497119ba..a71d995f78a8c 100644
--- a/app/code/Magento/CatalogImportExport/Test/Unit/Model/Export/ProductTest.php
+++ b/app/code/Magento/CatalogImportExport/Test/Unit/Model/Export/ProductTest.php
@@ -172,7 +172,8 @@ protected function setUp(): void
$this->productFactory = $this->getMockBuilder(
\Magento\Catalog\Model\ResourceModel\ProductFactory::class
- )->addMethods(['getTypeId'])
+ )->disableOriginalConstructor()
+ ->addMethods(['getTypeId'])
->onlyMethods(['create'])
->getMock();
diff --git a/app/code/Magento/Checkout/Test/Unit/Model/ShippingInformationManagementTest.php b/app/code/Magento/Checkout/Test/Unit/Model/ShippingInformationManagementTest.php
index 8618626642421..8bb017f4b212c 100644
--- a/app/code/Magento/Checkout/Test/Unit/Model/ShippingInformationManagementTest.php
+++ b/app/code/Magento/Checkout/Test/Unit/Model/ShippingInformationManagementTest.php
@@ -148,7 +148,7 @@ protected function setUp(): void
'importCustomerAddressData',
'save',
'getShippingRateByCode',
- 'getShippingMethod'
+ 'getShippingMethod',
]
)
->disableOriginalConstructor()
@@ -167,7 +167,7 @@ protected function setUp(): void
'collectTotals',
'getExtensionAttributes',
'setExtensionAttributes',
- 'setBillingAddress'
+ 'setBillingAddress',
]
)
->disableOriginalConstructor()
@@ -238,9 +238,7 @@ private function setShippingAssignmentsMocks($shippingMethod): void
->willReturn(null);
$this->shippingAddressMock->expects($this->once())
->method('setLimitCarrier');
- $this->cartExtensionMock = $this->getMockBuilder(CartExtension::class)
- ->addMethods(['getShippingAssignments', 'setShippingAssignments'])
- ->getMock();
+ $this->cartExtensionMock = $this->getCartExtensionMock();
$this->cartExtensionFactoryMock->expects($this->once())
->method('create')
->willReturn($this->cartExtensionMock);
@@ -622,4 +620,21 @@ public function testSaveAddressInformation(): void
$this->model->saveAddressInformation($cartId, $addressInformationMock)
);
}
+
+ /**
+ * Build cart extension mock.
+ *
+ * @return MockObject
+ */
+ private function getCartExtensionMock(): MockObject
+ {
+ $mockBuilder = $this->getMockBuilder(CartExtension::class);
+ try {
+ $mockBuilder->addMethods(['getShippingAssignments', 'setShippingAssignments']);
+ } catch (\RuntimeException $e) {
+ // CartExtension already generated.
+ }
+
+ return $mockBuilder->getMock();
+ }
}
diff --git a/app/code/Magento/CheckoutAgreements/Test/Unit/Model/Checkout/Plugin/GuestValidationTest.php b/app/code/Magento/CheckoutAgreements/Test/Unit/Model/Checkout/Plugin/GuestValidationTest.php
index 01e4480956180..845d71f6e2f17 100644
--- a/app/code/Magento/CheckoutAgreements/Test/Unit/Model/Checkout/Plugin/GuestValidationTest.php
+++ b/app/code/Magento/CheckoutAgreements/Test/Unit/Model/Checkout/Plugin/GuestValidationTest.php
@@ -78,9 +78,7 @@ protected function setUp(): void
$this->subjectMock = $this->getMockForAbstractClass(GuestPaymentInformationManagementInterface::class);
$this->paymentMock = $this->getMockForAbstractClass(PaymentInterface::class);
$this->addressMock = $this->getMockForAbstractClass(AddressInterface::class);
- $this->extensionAttributesMock = $this->getMockBuilder(PaymentExtension::class)
- ->addMethods(['getAgreementIds'])
- ->getMock();
+ $this->extensionAttributesMock = $this->getPaymentExtension();
$this->scopeConfigMock = $this->getMockForAbstractClass(ScopeConfigInterface::class);
$this->checkoutAgreementsListMock = $this->createMock(
CheckoutAgreementsListInterface::class
@@ -165,4 +163,21 @@ public function testBeforeSavePaymentInformationAndPlaceOrderIfAgreementsNotVali
"The order wasn't placed. First, agree to the terms and conditions, then try placing your order again."
);
}
+
+ /**
+ * Build payment extension mock.
+ *
+ * @return MockObject
+ */
+ private function getPaymentExtension(): MockObject
+ {
+ $mockBuilder = $this->getMockBuilder(PaymentExtension::class);
+ try {
+ $mockBuilder->addMethods(['getAgreementIds']);
+ } catch (\RuntimeException $e) {
+ // Payment extension already generated.
+ }
+
+ return $mockBuilder->getMock();
+ }
}
diff --git a/app/code/Magento/CheckoutAgreements/Test/Unit/Model/Checkout/Plugin/ValidationTest.php b/app/code/Magento/CheckoutAgreements/Test/Unit/Model/Checkout/Plugin/ValidationTest.php
index 7dea366506d66..ebe4c2c1c7b05 100644
--- a/app/code/Magento/CheckoutAgreements/Test/Unit/Model/Checkout/Plugin/ValidationTest.php
+++ b/app/code/Magento/CheckoutAgreements/Test/Unit/Model/Checkout/Plugin/ValidationTest.php
@@ -96,9 +96,7 @@ protected function setUp(): void
->disableOriginalConstructor()
->getMock();
$this->quoteRepositoryMock = $this->getMockForAbstractClass(CartRepositoryInterface::class);
- $this->extensionAttributesMock = $this->getMockBuilder(PaymentExtension::class)
- ->addMethods(['getAgreementIds'])
- ->getMock();
+ $this->extensionAttributesMock = $this->getPaymentExtension();
$this->scopeConfigMock = $this->getMockForAbstractClass(ScopeConfigInterface::class);
$this->checkoutAgreementsListMock = $this->createMock(
CheckoutAgreementsListInterface::class
@@ -232,4 +230,21 @@ public function testBeforeSavePaymentInformation()
->willReturn($this->extensionAttributesMock);
$this->model->beforeSavePaymentInformation($this->subjectMock, $cartId, $this->paymentMock, $this->addressMock);
}
+
+ /**
+ * Build payment extension mock.
+ *
+ * @return MockObject
+ */
+ private function getPaymentExtension(): MockObject
+ {
+ $mockBuilder = $this->getMockBuilder(PaymentExtension::class);
+ try {
+ $mockBuilder->addMethods(['getAgreementIds']);
+ } catch (\RuntimeException $e) {
+ // Payment extension already generated.
+ }
+
+ return $mockBuilder->getMock();
+ }
}
diff --git a/app/code/Magento/Customer/Test/Unit/Model/Renderer/RegionTest.php b/app/code/Magento/Customer/Test/Unit/Model/Renderer/RegionTest.php
index ae48926f12612..37e89c63c8957 100644
--- a/app/code/Magento/Customer/Test/Unit/Model/Renderer/RegionTest.php
+++ b/app/code/Magento/Customer/Test/Unit/Model/Renderer/RegionTest.php
@@ -66,7 +66,8 @@ function (array $attributes) use ($elementMock): string {
}
);
$countryMock = $this->getMockBuilder(AbstractElement::class)
- ->addMethods(['getValue', 'serialize'])
+ ->onlyMethods(['serialize'])
+ ->addMethods(['getValue'])
->disableOriginalConstructor()
->getMockForAbstractClass();
$countryMock->method('serialize')->willReturnCallback(
diff --git a/app/code/Magento/Downloadable/Test/Unit/Model/Link/UpdateHandlerTest.php b/app/code/Magento/Downloadable/Test/Unit/Model/Link/UpdateHandlerTest.php
index 22cf4b9abf7ca..af4d785955600 100644
--- a/app/code/Magento/Downloadable/Test/Unit/Model/Link/UpdateHandlerTest.php
+++ b/app/code/Magento/Downloadable/Test/Unit/Model/Link/UpdateHandlerTest.php
@@ -56,7 +56,7 @@ protected function setUp(): void
->getMockForAbstractClass();
$this->linkMock = $this->getMockBuilder(LinkInterface::class)
->getMock();
- $this->productExtensionMock = $this->createMock(ProductExtensionInterface::class);
+ $this->productExtensionMock = $this->getProductExtensionMock();
$this->productExtensionMock->expects($this->once())
->method('getDownloadableProductLinks')
->willReturn([$this->linkMock]);
@@ -145,4 +145,22 @@ public function testExecuteNonDownloadable(): void
$this->assertEquals($this->entityMock, $this->model->execute($this->entityMock));
}
+
+ /**
+ * Build product extension mock.
+ *
+ * @return MockObject
+ */
+ private function getProductExtensionMock(): MockObject
+ {
+ $mockBuilder = $this->getMockBuilder(ProductExtensionInterface::class)
+ ->disableOriginalConstructor();
+ try {
+ $mockBuilder->addMethods(['getDownloadableProductLinks']);
+ } catch (\RuntimeException $e) {
+ // ProductExtension already generated.
+ }
+
+ return $mockBuilder->getMockForAbstractClass();
+ }
}
diff --git a/app/code/Magento/Downloadable/Test/Unit/Model/Quote/Item/CartItemProcessorTest.php b/app/code/Magento/Downloadable/Test/Unit/Model/Quote/Item/CartItemProcessorTest.php
index c177b117f19d0..46ded7b3c456b 100644
--- a/app/code/Magento/Downloadable/Test/Unit/Model/Quote/Item/CartItemProcessorTest.php
+++ b/app/code/Magento/Downloadable/Test/Unit/Model/Quote/Item/CartItemProcessorTest.php
@@ -170,14 +170,12 @@ public function testProcessProductOptions()
$this->optionFactoryMock->expects($this->once())->method('create')->willReturn($productOptionMock);
$productOptionMock->expects($this->once())->method('getExtensionAttributes')->willReturn(null);
- $extAttributeMock = $this->getMockBuilder(ProductOptionExtension::class)
- ->addMethods(['setDownloadableOption'])
- ->getMock();
+ $extAttributeMock = $this->getProductOptionExtensionMock();
$this->objectHelperMock->expects($this->once())->method('populateWithArray')->with(
$downloadableOptionMock,
[
- 'downloadable_links' => $downloadableLinks
+ 'downloadable_links' => $downloadableLinks,
],
DownloadableOptionInterface::class
);
@@ -206,9 +204,7 @@ public function testProcessProductOptionsWhenItemDoesNotHaveDownloadableLinks()
->method('getOptionByCode')
->with('downloadable_link_ids');
- $extAttributeMock = $this->getMockBuilder(ProductOptionExtension::class)
- ->addMethods(['setDownloadableOption'])
- ->getMock();
+ $extAttributeMock = $this->getProductOptionExtensionMock();
$productOptionMock = $this->getMockForAbstractClass(ProductOptionInterface::class);
$productOptionMock->expects($this->any())
->method('getExtensionAttributes')
@@ -228,7 +224,7 @@ public function testProcessProductOptionsWhenItemDoesNotHaveDownloadableLinks()
$this->objectHelperMock->expects($this->once())->method('populateWithArray')->with(
$downloadableOptionMock,
[
- 'downloadable_links' => $downloadableLinks
+ 'downloadable_links' => $downloadableLinks,
],
DownloadableOptionInterface::class
);
@@ -243,4 +239,21 @@ public function testProcessProductOptionsWhenItemDoesNotHaveDownloadableLinks()
$this->assertEquals($cartItemMock, $this->model->processOptions($cartItemMock));
}
+
+ /**
+ * Build product option extension mock.
+ *
+ * @return MockObject
+ */
+ private function getProductOptionExtensionMock(): MockObject
+ {
+ $mockBuilder = $this->getMockBuilder(ProductOptionExtension::class);
+ try {
+ $mockBuilder->addMethods(['setDownloadableOption']);
+ } catch (\RuntimeException $e) {
+ // ProductOptionExtension already generated.
+ }
+
+ return $mockBuilder->getMock();
+ }
}
diff --git a/app/code/Magento/Downloadable/Test/Unit/Model/Sample/UpdateHandlerTest.php b/app/code/Magento/Downloadable/Test/Unit/Model/Sample/UpdateHandlerTest.php
index 0f8fe92e467ce..d826cde3cd78a 100644
--- a/app/code/Magento/Downloadable/Test/Unit/Model/Sample/UpdateHandlerTest.php
+++ b/app/code/Magento/Downloadable/Test/Unit/Model/Sample/UpdateHandlerTest.php
@@ -56,7 +56,7 @@ protected function setUp(): void
->getMockForAbstractClass();
$this->sampleMock = $this->getMockBuilder(SampleInterface::class)
->getMock();
- $this->productExtensionMock = $this->createMock(ProductExtensionInterface::class);
+ $this->productExtensionMock = $this->getProductExtensionMock();
$this->productExtensionMock//->expects($this->once())
->method('getDownloadableProductSamples')
->willReturn([$this->sampleMock]);
@@ -145,4 +145,22 @@ public function testExecuteNonDownloadable(): void
$this->assertEquals($this->entityMock, $this->model->execute($this->entityMock));
}
+
+ /**
+ * Build product extension mock.
+ *
+ * @return MockObject
+ */
+ private function getProductExtensionMock(): MockObject
+ {
+ $mockBuilder = $this->getMockBuilder(ProductExtensionInterface::class)
+ ->disableOriginalConstructor();
+ try {
+ $mockBuilder->addMethods(['getDownloadableProductSamples']);
+ } catch (\RuntimeException $e) {
+ // Product extension already generated.
+ }
+
+ return $mockBuilder->getMockForAbstractClass();
+ }
}
diff --git a/app/code/Magento/Downloadable/Test/Unit/Observer/IsAllowedGuestCheckoutObserverTest.php b/app/code/Magento/Downloadable/Test/Unit/Observer/IsAllowedGuestCheckoutObserverTest.php
index 6040b301a60a8..ea4a2769a117b 100644
--- a/app/code/Magento/Downloadable/Test/Unit/Observer/IsAllowedGuestCheckoutObserverTest.php
+++ b/app/code/Magento/Downloadable/Test/Unit/Observer/IsAllowedGuestCheckoutObserverTest.php
@@ -91,13 +91,13 @@ protected function setUp(): void
->getMock();
$this->storeMock = $this->getMockBuilder(DataObject::class)
+ ->addMethods(['getId'])
->disableOriginalConstructor()
->getMock();
$this->storeManagerMock = $this->getMockForAbstractClass(StoreManagerInterface::class);
- $this->storeManagerMock
- ->method('getStore')
- ->with(self::STUB_STORE_ID)
+ $this->storeManagerMock->method('getStore')
+ ->with($this->storeMock)
->willReturn($this->storeMock);
$this->isAllowedGuestCheckoutObserver = (new ObjectManagerHelper($this))
diff --git a/app/code/Magento/GiftMessage/Test/Unit/Model/Plugin/OrderGetTest.php b/app/code/Magento/GiftMessage/Test/Unit/Model/Plugin/OrderGetTest.php
index 15c0e1b408ded..d9389f43843a3 100644
--- a/app/code/Magento/GiftMessage/Test/Unit/Model/Plugin/OrderGetTest.php
+++ b/app/code/Magento/GiftMessage/Test/Unit/Model/Plugin/OrderGetTest.php
@@ -106,18 +106,14 @@ protected function setUp(): void
$this->orderMock = $this->createMock(
OrderInterface::class
);
- $this->orderExtensionMock = $this->getMockBuilder(OrderExtension::class)
- ->addMethods(['getGiftMessage', 'setGiftMessage'])
- ->getMock();
+ $this->orderExtensionMock = $this->getOrderExtensionMock();
$this->giftMessageMock = $this->createMock(
MessageInterface::class
);
$this->orderItemMock = $this->createMock(
OrderItemInterface::class
);
- $this->orderItemExtensionMock = $this->getMockBuilder(OrderItemExtension::class)
- ->addMethods(['setGiftMessage', 'getGiftMessage'])
- ->getMock();
+ $this->orderItemExtensionMock = $this->getOrderItemExtensionMock();
$this->orderRepositoryMock = $this->createMock(
\Magento\Sales\Api\OrderRepositoryInterface::class
);
@@ -272,4 +268,38 @@ public function testAfterGetList()
$this->collectionMock->expects($this->once())->method('getItems')->willReturn([$this->orderMock]);
$this->plugin->afterGetList($this->orderRepositoryMock, $this->collectionMock);
}
+
+ /**
+ * Build order extension mock.
+ *
+ * @return MockObject
+ */
+ private function getOrderExtensionMock(): MockObject
+ {
+ $mockObject = $this->getMockBuilder(OrderExtension::class);
+ try {
+ $mockObject->addMethods(['getGiftMessage', 'setGiftMessage']);
+ } catch (\RuntimeException $e) {
+ // Order extension already generated.
+ }
+
+ return $mockObject->getMock();
+ }
+
+ /**
+ * Build order item extension mock.
+ *
+ * @return MockObject
+ */
+ private function getOrderItemExtensionMock(): MockObject
+ {
+ $mockObject = $this->getMockBuilder(OrderItemExtension::class);
+ try {
+ $mockObject->addMethods(['getGiftMessage', 'setGiftMessage']);
+ } catch (\RuntimeException $e) {
+ // Order extension already generated.
+ }
+
+ return $mockObject->getMock();
+ }
}
diff --git a/app/code/Magento/GiftMessage/Test/Unit/Model/Plugin/OrderSaveTest.php b/app/code/Magento/GiftMessage/Test/Unit/Model/Plugin/OrderSaveTest.php
index f6eaa02d9eaab..11491754e3bcb 100644
--- a/app/code/Magento/GiftMessage/Test/Unit/Model/Plugin/OrderSaveTest.php
+++ b/app/code/Magento/GiftMessage/Test/Unit/Model/Plugin/OrderSaveTest.php
@@ -76,18 +76,14 @@ protected function setUp(): void
$this->orderMock = $this->createMock(
OrderInterface::class
);
- $this->orderExtensionMock = $this->getMockBuilder(OrderExtension::class)
- ->addMethods(['getGiftMessage', 'setGiftMessage'])
- ->getMock();
+ $this->orderExtensionMock = $this->getOrderExtensionMock();
$this->giftMessageMock = $this->createMock(
MessageInterface::class
);
$this->orderItemMock = $this->createMock(
OrderItemInterface::class
);
- $this->orderItemExtensionMock = $this->getMockBuilder(OrderItemExtension::class)
- ->addMethods(['setGiftMessage', 'getGiftMessage'])
- ->getMock();
+ $this->orderItemExtensionMock = $this->getOrderItemExtensionMock();
$this->orderRepositoryMock = $this->createMock(
\Magento\Sales\Api\OrderRepositoryInterface::class
);
@@ -192,4 +188,38 @@ public function testAfterSaveIfItemGiftMessagesNotExist()
->willThrowException(new \Exception('Test message'));
$this->plugin->afterSave($this->orderRepositoryMock, $this->orderMock);
}
+
+ /**
+ * Build order extension mock.
+ *
+ * @return MockObject
+ */
+ private function getOrderExtensionMock(): MockObject
+ {
+ $mockBuilder = $this->getMockBuilder(OrderExtension::class);
+ try {
+ $mockBuilder->addMethods(['getGiftMessage', 'setGiftMessage']);
+ } catch (\RuntimeException $e) {
+ // OrderExtension already generated.
+ }
+
+ return $mockBuilder->getMock();
+ }
+
+ /**
+ * Build order item extension mock.
+ *
+ * @return MockObject
+ */
+ private function getOrderItemExtensionMock(): MockObject
+ {
+ $mockBuilder = $this->getMockBuilder(OrderItemExtension::class);
+ try {
+ $mockBuilder->addMethods(['getGiftMessage', 'setGiftMessage']);
+ } catch (\RuntimeException $e) {
+ // OrderItemExtension already generated.
+ }
+
+ return $mockBuilder->getMock();
+ }
}
diff --git a/app/code/Magento/Multishipping/Test/Unit/Model/DisableMultishippingTest.php b/app/code/Magento/Multishipping/Test/Unit/Model/DisableMultishippingTest.php
index 9882f8d1441aa..075fc4ac347b0 100644
--- a/app/code/Magento/Multishipping/Test/Unit/Model/DisableMultishippingTest.php
+++ b/app/code/Magento/Multishipping/Test/Unit/Model/DisableMultishippingTest.php
@@ -59,11 +59,7 @@ public function testExecuteWithMultishippingModeEnabled(bool $hasShippingAssignm
->method('setIsMultiShipping')
->with(0);
- /** @var CartExtensionInterface|MockObject $extensionAttributesMock */
- $extensionAttributesMock = $this->getMockBuilder(CartExtensionInterface::class)
- ->addMethods(['getShippingAssignments', 'setShippingAssignments'])
- ->disableOriginalConstructor()
- ->getMockForAbstractClass();
+ $extensionAttributesMock = $this->getCartExtensionMock();
$extensionAttributesMock->expects($this->once())
->method('getShippingAssignments')
@@ -90,7 +86,7 @@ public function executeWithMultishippingModeEnabledDataProvider(): array
{
return [
'check_with_shipping_assignments' => [true],
- 'check_without_shipping_assignments' => [false]
+ 'check_without_shipping_assignments' => [false],
];
}
@@ -113,4 +109,22 @@ public function testExecuteWithMultishippingModeDisabled(): void
$this->assertFalse($this->disableMultishippingModel->execute($this->quoteMock));
}
+
+ /**
+ * Build cart extension mock.
+ *
+ * @return MockObject
+ */
+ private function getCartExtensionMock(): MockObject
+ {
+ $mockBuilder = $this->getMockBuilder(CartExtensionInterface::class)
+ ->disableOriginalConstructor();
+ try {
+ $mockBuilder->addMethods(['getShippingAssignments', 'setShippingAssignments']);
+ } catch (\RuntimeException $e) {
+ // CartExtension already generated.
+ }
+
+ return $mockBuilder->getMockForAbstractClass();
+ }
}
diff --git a/app/code/Magento/Persistent/Test/Unit/Model/QuoteManagerTest.php b/app/code/Magento/Persistent/Test/Unit/Model/QuoteManagerTest.php
index 03d6ab02beb3c..d6d80ab7de229 100644
--- a/app/code/Magento/Persistent/Test/Unit/Model/QuoteManagerTest.php
+++ b/app/code/Magento/Persistent/Test/Unit/Model/QuoteManagerTest.php
@@ -23,6 +23,7 @@
use Magento\Quote\Model\Quote\Address;
use Magento\Quote\Model\Quote\ShippingAssignment\ShippingAssignmentProcessor;
use PHPUnit\Framework\MockObject\MockObject;
+use PHPUnit\Framework\MockObject\RuntimeException;
use PHPUnit\Framework\TestCase;
/**
@@ -94,7 +95,7 @@ protected function setUp(): void
'setCustomerData',
'clearQuote',
'clearStorage',
- 'getQuote'
+ 'getQuote',
])
->onlyMethods(['removePersistentCookie'])
->disableOriginalConstructor()
@@ -115,7 +116,7 @@ protected function setUp(): void
'setCustomerLastname',
'setCustomerGroupId',
'setIsPersistent',
- 'getCustomerId'
+ 'getCustomerId',
])
->onlyMethods([
'getId',
@@ -132,7 +133,7 @@ protected function setUp(): void
'getExtensionAttributes',
'setExtensionAttributes',
'__wakeup',
- 'setCustomer'
+ 'setCustomer',
])
->disableOriginalConstructor()
->getMock();
@@ -240,8 +241,7 @@ public function testSetGuest()
->method('removePersistentCookie')->willReturn($this->sessionMock);
$this->quoteMock->expects($this->once())->method('isVirtual')->willReturn(false);
$this->quoteMock->expects($this->once())->method('getItemsQty')->willReturn(1);
- $extensionAttributes = $this->getMockBuilder(CartExtensionInterface::class)
- ->getMockForAbstractClass();
+ $extensionAttributes = $this->getExtensionAttributesMock();
$shippingAssignment = $this->createMock(ShippingAssignmentInterface::class);
$extensionAttributes->expects($this->once())
->method('setShippingAssignments')
@@ -381,4 +381,21 @@ public function testConvertCustomerCartToGuestWithEmptyQuoteId()
$this->quoteMock->expects($this->once())->method('getId')->willReturn(1);
$this->model->convertCustomerCartToGuest();
}
+
+ /**
+ * Build CartExtensionInterface mock.
+ *
+ * @return MockObject
+ */
+ private function getExtensionAttributesMock(): MockObject
+ {
+ $extensionMockBuilder = $this->getMockBuilder(CartExtensionInterface::class);
+ try {
+ $extensionMockBuilder->addMethods(['setShippingAssignments']);
+ } catch (\RuntimeException $e) {
+ // do nothing as CartExtensionInterface already generated and has 'setShippingAssignments' method.
+ }
+
+ return $extensionMockBuilder->getMockForAbstractClass();
+ }
}
diff --git a/app/code/Magento/ProductVideo/Test/Unit/Model/Product/Attribute/Media/ExternalVideoEntryConverterTest.php b/app/code/Magento/ProductVideo/Test/Unit/Model/Product/Attribute/Media/ExternalVideoEntryConverterTest.php
index a921bff76c8d6..fd96ca7fb7ebf 100644
--- a/app/code/Magento/ProductVideo/Test/Unit/Model/Product/Attribute/Media/ExternalVideoEntryConverterTest.php
+++ b/app/code/Magento/ProductVideo/Test/Unit/Model/Product/Attribute/Media/ExternalVideoEntryConverterTest.php
@@ -81,7 +81,7 @@ protected function setUp(): void
'getContent',
'setContent',
'getExtensionAttributes',
- 'setExtensionAttributes'
+ 'setExtensionAttributes',
]
);
@@ -104,11 +104,7 @@ protected function setUp(): void
['create']
);
- $this->mediaGalleryEntryExtensionMock = $this->getMockBuilder(ProductAttributeMediaGalleryEntryExtension::class)
- ->addMethods(['getVideoProvider'])
- ->onlyMethods(['setVideoContent', 'getVideoContent'])
- ->disableOriginalConstructor()
- ->getMock();
+ $this->mediaGalleryEntryExtensionMock = $this->getProductAttributeMediaGalleryEntryExtensionMock();
$this->mediaGalleryEntryExtensionMock->expects($this->any())->method('setVideoContent')->willReturn(null);
$this->mediaGalleryEntryExtensionFactoryMock->expects($this->any())->method('create')->willReturn(
@@ -123,7 +119,7 @@ protected function setUp(): void
'mediaGalleryEntryFactory' => $this->mediaGalleryEntryFactoryMock,
'dataObjectHelper' => $this->dataObjectHelperMock,
'videoEntryFactory' => $this->videoEntryFactoryMock,
- 'mediaGalleryEntryExtensionFactory' => $this->mediaGalleryEntryExtensionFactoryMock
+ 'mediaGalleryEntryExtensionFactory' => $this->mediaGalleryEntryExtensionFactoryMock,
]
);
}
@@ -218,4 +214,28 @@ public function testConvertFrom()
$result = $this->modelObject->convertFrom($this->mediaGalleryEntryMock);
$this->assertEquals($expectedResult, $result);
}
+
+ /**
+ * Build ProductAttributeMediaGalleryEntryExtension mock.
+ *
+ * @return MockObject
+ */
+ private function getProductAttributeMediaGalleryEntryExtensionMock(): MockObject
+ {
+ $mockBuilder = $this->getMockBuilder(ProductAttributeMediaGalleryEntryExtension::class)
+ ->disableOriginalConstructor();
+ try {
+ $mockBuilder->addMethods(
+ [
+ 'getVideoProvider',
+ 'setVideoContent',
+ 'getVideoContent',
+ ]
+ );
+ } catch (\Exception $e) {
+ // ProductAttributeMediaGalleryEntryExtension already generated and has all necessary methods.
+ }
+
+ return $mockBuilder->getMock();
+ }
}
diff --git a/app/code/Magento/Quote/Test/Unit/Model/ShippingAddressAssignmentTest.php b/app/code/Magento/Quote/Test/Unit/Model/ShippingAddressAssignmentTest.php
index 00cb1d48e8889..75f3af2643722 100644
--- a/app/code/Magento/Quote/Test/Unit/Model/ShippingAddressAssignmentTest.php
+++ b/app/code/Magento/Quote/Test/Unit/Model/ShippingAddressAssignmentTest.php
@@ -66,9 +66,7 @@ protected function setUp(): void
);
$this->quoteMock = $this->createMock(Quote::class);
$this->addressMock = $this->createMock(Address::class);
- $this->extensionAttributeMock = $this->getMockBuilder(CartExtension::class)
- ->addMethods(['setShippingAssignments'])
- ->getMock();
+ $this->extensionAttributeMock = $this->getCartExtensionMock();
$this->shippingAssignmentMock = $this->getMockForAbstractClass(ShippingAssignmentInterface::class);
//shipping assignment processing
@@ -113,4 +111,21 @@ public function testSetAddressUseForShippingFalse()
$this->quoteMock->expects($this->once())->method('setShippingAddress')->with($addressMock);
$this->model->setAddress($this->quoteMock, $this->addressMock, false);
}
+
+ /**
+ * Build cart extension mock.
+ *
+ * @return MockObject
+ */
+ private function getCartExtensionMock(): MockObject
+ {
+ $mockBuilder = $this->getMockBuilder(CartExtension::class);
+ try {
+ $mockBuilder->addMethods(['setShippingAssignments']);
+ } catch (\RuntimeException $e) {
+ // CartExtension already generated.
+ }
+
+ return $mockBuilder->getMock();
+ }
}
diff --git a/app/code/Magento/Sales/Test/Unit/Model/OrderRepositoryTest.php b/app/code/Magento/Sales/Test/Unit/Model/OrderRepositoryTest.php
index 2e51bd8d75b89..d242268649a5e 100644
--- a/app/code/Magento/Sales/Test/Unit/Model/OrderRepositoryTest.php
+++ b/app/code/Magento/Sales/Test/Unit/Model/OrderRepositoryTest.php
@@ -13,8 +13,8 @@
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
use Magento\Payment\Api\Data\PaymentAdditionalInfoInterface;
use Magento\Payment\Api\Data\PaymentAdditionalInfoInterfaceFactory;
-use Magento\Sales\Api\Data\OrderExtension;
use Magento\Sales\Api\Data\OrderExtensionFactory;
+use Magento\Sales\Api\Data\OrderExtensionInterface;
use Magento\Sales\Api\Data\OrderInterface;
use Magento\Sales\Api\Data\OrderPaymentInterface;
use Magento\Sales\Api\Data\OrderSearchResultInterfaceFactory as SearchResultFactory;
@@ -111,7 +111,7 @@ protected function setUp(): void
'collectionProcessor' => $this->collectionProcessor,
'orderExtensionFactory' => $this->orderExtensionFactoryMock,
'orderTaxManagement' => $this->orderTaxManagementMock,
- 'paymentAdditionalInfoFactory' => $this->paymentAdditionalInfoFactory
+ 'paymentAdditionalInfoFactory' => $this->paymentAdditionalInfoFactory,
]
);
}
@@ -138,18 +138,7 @@ public function testGetList()
->disableOriginalConstructor()
->setMethods(['setKey', 'setValue'])->getMockForAbstractClass();
- $extensionAttributes = $this->getMockBuilder(OrderExtension::class)
- ->addMethods(
- [
- 'getShippingAssignments',
- 'setShippingAssignments',
- 'setConvertingFromQuote',
- 'setAppliedTaxes',
- 'setItemAppliedTaxes',
- 'setPaymentAdditionalInfo'
- ]
- )
- ->getMock();
+ $extensionAttributes = $this->getOrderExtensionMock();
$shippingAssignmentBuilder = $this->createMock(
ShippingAssignmentBuilder::class
);
@@ -188,9 +177,7 @@ public function testSave()
->disableOriginalConstructor()
->getMock();
$orderEntity = $this->createMock(Order::class);
- $extensionAttributes = $this->getMockBuilder(OrderExtension::class)
- ->addMethods(['getShippingAssignments'])
- ->getMock();
+ $extensionAttributes = $this->getOrderExtensionMock();
$shippingAssignment = $this->getMockBuilder(ShippingAssignment::class)
->disableOriginalConstructor()
->setMethods(['getShipping'])
@@ -230,18 +217,7 @@ public function testGet()
$paymentMock = $this->getMockBuilder(OrderPaymentInterface::class)
->disableOriginalConstructor()->getMockForAbstractClass();
$paymentMock->expects($this->once())->method('getAdditionalInformation')->willReturn($paymentInfo);
- $orderExtension = $this->getMockBuilder(OrderExtension::class)
- ->setMethods(
- [
- 'getShippingAssignments',
- 'setAppliedTaxes',
- 'setConvertingFromQuote',
- 'setItemAppliedTaxes',
- 'setPaymentAdditionalInfo'
- ]
- )
- ->disableOriginalConstructor()
- ->getMockForAbstractClass();
+ $orderExtension = $this->getOrderExtensionMock();
$orderExtension->expects($this->once())->method('getShippingAssignments')->willReturn(true);
$orderExtension->expects($this->once())->method('setAppliedTaxes')->with($appliedTaxes);
$orderExtension->expects($this->once())->method('setConvertingFromQuote')->with(true);
@@ -266,4 +242,29 @@ public function testGet()
$this->orderRepository->get($orderId);
}
+
+ /**
+ * Buld order extension mock.
+ *
+ * @return MockObject
+ */
+ private function getOrderExtensionMock(): MockObject
+ {
+ $mockBuilder = $this->getMockBuilder(OrderExtensionInterface::class)->disableOriginalConstructor();
+ try {
+ $mockBuilder->addMethods(
+ [
+ 'getShippingAssignments',
+ 'setAppliedTaxes',
+ 'setConvertingFromQuote',
+ 'setItemAppliedTaxes',
+ 'setPaymentAdditionalInfo',
+ ]
+ );
+ } catch (\RuntimeException $e) {
+ // Order extension already generated.
+ }
+
+ return $mockBuilder->getMockForAbstractClass();
+ }
}
diff --git a/dev/tests/integration/phpunit.xml.dist b/dev/tests/integration/phpunit.xml.dist
index 92dd1e11f613b..d57e6809da7e9 100644
--- a/dev/tests/integration/phpunit.xml.dist
+++ b/dev/tests/integration/phpunit.xml.dist
@@ -17,14 +17,14 @@
>
-
+
testsuite/Magento/IntegrationTest.php
-
+
testsuite/Magento/MemoryUsageTest.php
-
+
testsuite
../../../app/code/*/*/Test/Integration
testsuite/Magento/MemoryUsageTest.php
diff --git a/dev/tests/integration/testsuite/Magento/IntegrationTest.php b/dev/tests/integration/testsuite/Magento/IntegrationTest.php
index 4626a10884290..39d383fb86354 100644
--- a/dev/tests/integration/testsuite/Magento/IntegrationTest.php
+++ b/dev/tests/integration/testsuite/Magento/IntegrationTest.php
@@ -41,7 +41,7 @@ public static function suite($className)
$suitesConfig = $configuration->testSuite();
$suite = new TestSuite();
foreach ($suitesConfig as $suiteConfig) {
- if ($suiteConfig->name() === 'Magento Integration Tests') {
+ if ($suiteConfig->name() === 'Magento_Integration_Tests') {
continue;
}
$suites = self::getSuites($suiteConfig);
@@ -73,7 +73,10 @@ public static function suite($className)
private static function getConfigurationFile(): string
{
$params = getopt('c:', ['configuration:']);
- $longConfig = $params['configuration'] ?? '';
+ $defaultConfigFile = file_exists(__DIR__ . '../../phpunit.xml')
+ ? __DIR__ . '/../../phpunit.xml'
+ : __DIR__ . '/../../phpunit.xml.dist';
+ $longConfig = $params['configuration'] ?? $defaultConfigFile;
$shortConfig = $params['c'] ?? '';
return $shortConfig ? $shortConfig : $longConfig;
diff --git a/dev/tests/unit/phpunit.xml.dist b/dev/tests/unit/phpunit.xml.dist
index 1793b0f698310..709bb7c1ea95b 100644
--- a/dev/tests/unit/phpunit.xml.dist
+++ b/dev/tests/unit/phpunit.xml.dist
@@ -15,6 +15,7 @@
../../../app/code/*/*/Test/Unit
+ ../../../vendor/magento/module-*/Test/Unit
../../../lib/internal/*/*/Test/Unit
From caefb4e63f0c726c996118c2707afaf63ed3c665 Mon Sep 17 00:00:00 2001
From: engcom-Echo
Date: Thu, 12 Nov 2020 14:21:04 +0200
Subject: [PATCH 11/14] MC-38105: Unable to set native session handler that is
different from the one define in php.ini
---
.../Magento/Framework/Session/SessionManagerTest.php | 8 ++++----
lib/internal/Magento/Framework/Session/SessionManager.php | 4 ++--
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Session/SessionManagerTest.php b/dev/tests/integration/testsuite/Magento/Framework/Session/SessionManagerTest.php
index 310e2c9d7b6ae..6a461c3007ca7 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/Session/SessionManagerTest.php
+++ b/dev/tests/integration/testsuite/Magento/Framework/Session/SessionManagerTest.php
@@ -326,11 +326,11 @@ public function testConstructor(string $saveMethod): void
$this->assertArrayHasKey('session.use_only_cookies', self::$isIniSetInvoked);
$this->assertEquals('1', self::$isIniSetInvoked['session.use_only_cookies']);
foreach ($sessionConfig->getOptions() as $option => $value) {
- if ($option === 'session.save_handler' && !$value === 'memcached') {
- $this->assertArrayNotHasKey('session.save_handler', self::$isIniSetInvoked);
+ if ($option === 'session.save_handler' && $value !== 'memcached') {
+ $this->assertArrayNotHasKey('session.save_handler', self::$isIniSetInvoked);
} else {
- $this->assertArrayHasKey($option, self::$isIniSetInvoked);
- $this->assertEquals($value, self::$isIniSetInvoked[$option]);
+ $this->assertArrayHasKey($option, self::$isIniSetInvoked);
+ $this->assertEquals($value, self::$isIniSetInvoked[$option]);
}
}
$this->assertTrue(self::$isSessionSetSaveHandlerInvoked);
diff --git a/lib/internal/Magento/Framework/Session/SessionManager.php b/lib/internal/Magento/Framework/Session/SessionManager.php
index 73ece8277f327..90b49a32a7851 100644
--- a/lib/internal/Magento/Framework/Session/SessionManager.php
+++ b/lib/internal/Magento/Framework/Session/SessionManager.php
@@ -620,8 +620,8 @@ private function initIniOptions()
foreach ($this->sessionConfig->getOptions() as $option => $value) {
// Since PHP 7.2 it is explicitly forbidden to set the module name to "user".
- // Need to skip all handlers except memcached. Redis and Db have implements SessionHandlerInterface.
- if ($option === 'session.save_handler' && !$value === 'memcached') {
+ // https://bugs.php.net/bug.php?id=77384
+ if ($option === 'session.save_handler' && $value !== 'memcached') {
continue;
} else {
$result = ini_set($option, $value);
From 8285894e91aa5ee57119ee7cdbe8006ed85d2b59 Mon Sep 17 00:00:00 2001
From: Viktor Kopin
Date: Fri, 13 Nov 2020 15:15:39 +0200
Subject: [PATCH 12/14] MC-30348: Rest salesShipOrderV1 API w/ Bundles error:
"You can't create a shipment without products"
---
.../Shipment/BundleShipmentTypeValidator.php | 51 ++++
app/code/Magento/Bundle/etc/di.xml | 7 +
app/code/Magento/Bundle/i18n/en_US.csv | 3 +
.../Order/Shipment/ShipmentItemsValidator.php | 62 +++++
.../ShipmentItemsValidatorInterface.php | 27 ++
.../Model/Order/Validation/ShipOrder.php | 69 +++++-
.../Magento/Sales/Model/ValidatorResult.php | 16 +-
app/code/Magento/Sales/etc/di.xml | 1 +
.../Sales/Service/V1/ShipOrderTest.php | 136 +++++++++-
.../order_with_bundle_shipped_separately.php | 123 ++++++----
.../order_with_bundle_shipped_together.php | 232 ++++++++++++++++++
..._with_bundle_shipped_together_rollback.php | 11 +
12 files changed, 666 insertions(+), 72 deletions(-)
create mode 100644 app/code/Magento/Bundle/Model/Sales/Order/Shipment/BundleShipmentTypeValidator.php
create mode 100644 app/code/Magento/Sales/Model/Order/Shipment/ShipmentItemsValidator.php
create mode 100644 app/code/Magento/Sales/Model/Order/Shipment/ShipmentItemsValidatorInterface.php
create mode 100644 dev/tests/integration/testsuite/Magento/Bundle/_files/order_with_bundle_shipped_together.php
create mode 100644 dev/tests/integration/testsuite/Magento/Bundle/_files/order_with_bundle_shipped_together_rollback.php
diff --git a/app/code/Magento/Bundle/Model/Sales/Order/Shipment/BundleShipmentTypeValidator.php b/app/code/Magento/Bundle/Model/Sales/Order/Shipment/BundleShipmentTypeValidator.php
new file mode 100644
index 0000000000000..396f19e739347
--- /dev/null
+++ b/app/code/Magento/Bundle/Model/Sales/Order/Shipment/BundleShipmentTypeValidator.php
@@ -0,0 +1,51 @@
+isDummy(true)) {
+ return $result;
+ }
+
+ $message = 'Cannot create shipment as bundle product "%1" has shipment type "%2". ' .
+ '%3 should be shipped instead.';
+
+ if ($item->getHasChildren() && $item->getProductType() === Type::TYPE_BUNDLE) {
+ $result[] = __(
+ $message,
+ $item->getSku(),
+ __('Separately'),
+ __('Bundle product options'),
+ );
+ }
+
+ if ($item->getParentItem() && $item->getParentItem()->getProductType() === Type::TYPE_BUNDLE) {
+ $result[] = __(
+ $message,
+ $item->getParentItem()->getSku(),
+ __('Together'),
+ __('Bundle product itself'),
+ );
+ }
+
+ return $result;
+ }
+}
diff --git a/app/code/Magento/Bundle/etc/di.xml b/app/code/Magento/Bundle/etc/di.xml
index 6c1a5ab2e7257..9bfa450175ecc 100644
--- a/app/code/Magento/Bundle/etc/di.xml
+++ b/app/code/Magento/Bundle/etc/di.xml
@@ -234,4 +234,11 @@
+
+
+
+ - Magento\Bundle\Model\Sales\Order\Shipment\BundleShipmentTypeValidator
+
+
+
diff --git a/app/code/Magento/Bundle/i18n/en_US.csv b/app/code/Magento/Bundle/i18n/en_US.csv
index ad9fad974e38f..99ef117fffadb 100644
--- a/app/code/Magento/Bundle/i18n/en_US.csv
+++ b/app/code/Magento/Bundle/i18n/en_US.csv
@@ -105,3 +105,6 @@ Select...,Select...
Status,Status
Thumbnail,Thumbnail
Type,Type
+"Cannot create shipment as bundle product ""%1"" has shipment type ""%2"". %3 should be shipped instead.","Cannot create shipment as bundle product ""%1"" has shipment type ""%2"". %3 should be shipped instead."
+"Bundle product itself","Bundle product itself"
+"Bundle product options","Bundle product options"
diff --git a/app/code/Magento/Sales/Model/Order/Shipment/ShipmentItemsValidator.php b/app/code/Magento/Sales/Model/Order/Shipment/ShipmentItemsValidator.php
new file mode 100644
index 0000000000000..2112ef6066bd3
--- /dev/null
+++ b/app/code/Magento/Sales/Model/Order/Shipment/ShipmentItemsValidator.php
@@ -0,0 +1,62 @@
+validatorResultFactory = $validatorResult;
+ $this->validators = $validators;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function validate(array $items): ValidatorResultInterface
+ {
+ $messages = [];
+ foreach ($this->validators as $validator) {
+ if (!$validator instanceof ValidatorInterface) {
+ throw new ConfigurationMismatchException(
+ __(
+ 'The "%1" validator is not an instance of the general validator interface.',
+ get_class($validator)
+ )
+ );
+ }
+ foreach ($items as $item) {
+ $messages[] = $validator->validate($item);
+ }
+ }
+
+ return $this->validatorResultFactory->create(['messages' => array_merge([], ...$messages)]);
+ }
+}
diff --git a/app/code/Magento/Sales/Model/Order/Shipment/ShipmentItemsValidatorInterface.php b/app/code/Magento/Sales/Model/Order/Shipment/ShipmentItemsValidatorInterface.php
new file mode 100644
index 0000000000000..557feacb2de48
--- /dev/null
+++ b/app/code/Magento/Sales/Model/Order/Shipment/ShipmentItemsValidatorInterface.php
@@ -0,0 +1,27 @@
+orderValidator = $orderValidator;
$this->shipmentValidator = $shipmentValidator;
$this->validatorResultMerger = $validatorResultMerger;
+ $this->itemsValidator = $itemsValidator
+ ?? ObjectManager::getInstance()->get(ShipmentItemsValidatorInterface::class);
}
/**
+ * Order shipment validate
+ *
* @param OrderInterface $order
* @param ShipmentInterface $shipment
* @param array $items
* @param bool $notify
* @param bool $appendComment
- * @param \Magento\Sales\Api\Data\ShipmentCommentCreationInterface|null $comment
+ * @param ShipmentCommentCreationInterface|null $comment
* @param array $tracks
* @param array $packages
- * @param \Magento\Sales\Api\Data\ShipmentCreationArgumentsInterface|null $arguments
- * @return \Magento\Sales\Model\ValidatorResultInterface
+ * @param ShipmentCreationArgumentsInterface|null $arguments
+ * @return ValidatorResultInterface
*/
public function validate(
$order,
@@ -68,10 +84,10 @@ public function validate(
array $items = [],
$notify = false,
$appendComment = false,
- \Magento\Sales\Api\Data\ShipmentCommentCreationInterface $comment = null,
+ ShipmentCommentCreationInterface $comment = null,
array $tracks = [],
array $packages = [],
- \Magento\Sales\Api\Data\ShipmentCreationArgumentsInterface $arguments = null
+ ShipmentCreationArgumentsInterface $arguments = null
) {
$orderValidationResult = $this->orderValidator->validate(
$order,
@@ -87,6 +103,39 @@ public function validate(
]
);
- return $this->validatorResultMerger->merge($orderValidationResult, $shipmentValidationResult);
+ $orderItems = $this->getRequestedOrderItems($items, $order);
+ $itemsValidationResult = $this->itemsValidator->validate($orderItems);
+
+ return $this->validatorResultMerger->merge(
+ $orderValidationResult,
+ $shipmentValidationResult,
+ $itemsValidationResult->getMessages()
+ );
+ }
+
+ /**
+ * Return requested order items
+ *
+ * @param OrderItemInterface[] $items
+ * @param OrderInterface $order
+ * @return OrderItemInterface[]
+ */
+ private function getRequestedOrderItems(array $items, OrderInterface $order): array
+ {
+ $requestedItemIds = array_reduce(
+ $items,
+ function (array $result, ShipmentItemCreationInterface $item): array {
+ $result[] = $item->getOrderItemId();
+ return $result;
+ },
+ []
+ );
+
+ return array_filter(
+ $order->getAllItems(),
+ function (OrderItemInterface $orderItem) use ($requestedItemIds): bool {
+ return in_array($orderItem->getId(), $requestedItemIds);
+ }
+ );
}
}
diff --git a/app/code/Magento/Sales/Model/ValidatorResult.php b/app/code/Magento/Sales/Model/ValidatorResult.php
index b326ebb4b8b37..feb93c02d5aae 100644
--- a/app/code/Magento/Sales/Model/ValidatorResult.php
+++ b/app/code/Magento/Sales/Model/ValidatorResult.php
@@ -6,14 +6,22 @@
namespace Magento\Sales\Model;
/**
- * Class ValidatorResult
+ * Validation result messages class
*/
class ValidatorResult implements ValidatorResultInterface
{
/**
* @var \string[]
*/
- private $messages = [];
+ private $messages;
+
+ /**
+ * @param array $messages
+ */
+ public function __construct(array $messages = [])
+ {
+ $this->messages = $messages;
+ }
/**
* @inheritdoc
@@ -24,7 +32,7 @@ public function addMessage($message)
}
/**
- * @return bool
+ * @inheritdoc
*/
public function hasMessages()
{
@@ -32,7 +40,7 @@ public function hasMessages()
}
/**
- * @return \string[]
+ * @inheritdoc
*/
public function getMessages()
{
diff --git a/app/code/Magento/Sales/etc/di.xml b/app/code/Magento/Sales/etc/di.xml
index b4dadfa944a5b..55c3988cb4ac5 100644
--- a/app/code/Magento/Sales/etc/di.xml
+++ b/app/code/Magento/Sales/etc/di.xml
@@ -117,6 +117,7 @@
+
diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipOrderTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipOrderTest.php
index 64fc612120332..173e817c94c4a 100644
--- a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipOrderTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipOrderTest.php
@@ -3,9 +3,12 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+declare(strict_types=1);
+
namespace Magento\Sales\Service\V1;
use Magento\Catalog\Api\ProductRepositoryInterface;
+use Magento\Catalog\Model\Product\Type;
use Magento\Framework\ObjectManagerInterface;
use Magento\Sales\Api\Data\OrderItemInterface;
use Magento\Sales\Api\ShipmentRepositoryInterface;
@@ -105,7 +108,7 @@ public function testShipOrderStatusPreserve()
$this->assertEquals($orderStatus, $order->getStatus());
$requestData = [
- 'orderId' => $order->getId()
+ 'orderId' => $order->getId(),
];
/** @var OrderItemInterface $item */
foreach ($order->getAllItems() as $item) {
@@ -145,9 +148,9 @@ public function testShipOrder()
[
'track_number' => 'TEST_TRACK_0001',
'title' => 'Simple shipment track',
- 'carrier_code' => 'UPS'
- ]
- ]
+ 'carrier_code' => 'UPS',
+ ],
+ ],
];
/** @var OrderItemInterface $item */
@@ -205,9 +208,9 @@ public function testShipOrderWithoutTrackingNumberReturnsError()
'tracks' => [
[
'title' => 'Simple shipment track',
- 'carrier_code' => 'UPS'
- ]
- ]
+ 'carrier_code' => 'UPS',
+ ],
+ ],
];
$this->_webApiCall($this->getServiceInfo($existingOrder), $requestData);
@@ -231,9 +234,9 @@ public function testPartialShipOrderWithBundleShippedSeparately()
[
'track_number' => 'TEST_TRACK_0001',
'title' => 'Simple shipment track',
- 'carrier_code' => 'UPS'
- ]
- ]
+ 'carrier_code' => 'UPS',
+ ],
+ ],
];
$shippedItemId = null;
@@ -267,8 +270,9 @@ public function testPartialShipOrderWithBundleShippedSeparately()
if ($item->getItemId() == $shippedItemId) {
$this->assertEquals(1, $item->getQtyShipped());
continue;
+ } elseif ($item->getParentItem()) {
+ $this->assertEquals(0, $item->getQtyShipped());
}
- $this->assertEquals(0, $item->getQtyShipped());
}
}
@@ -336,6 +340,116 @@ public function testPartialShipOrderWithTwoBundleShippedSeparatelyContainsSameSi
}
}
+ /**
+ * @magentoApiDataFixture Magento/Bundle/_files/order_with_bundle_shipped_separately.php
+ */
+ public function testValidationShipTogetherWithBundleShippedSeparate()
+ {
+ $order = $this->getOrder('100000001');
+
+ $requestData = [
+ 'orderId' => $order->getId(),
+ 'items' => [],
+ 'comment' => [
+ 'comment' => 'Test Comment',
+ 'is_visible_on_front' => 1,
+ ],
+ 'tracks' => [],
+ ];
+
+ foreach ($order->getAllItems() as $item) {
+ if ($item->getProductType() === Type::TYPE_BUNDLE) {
+ $requestData['items'][] = [
+ 'order_item_id' => $item->getItemId(),
+ 'qty' => $item->getQtyOrdered(),
+ ];
+ break;
+ }
+ }
+
+ try {
+ $this->_webApiCall($this->getServiceInfo($order), $requestData);
+ $this->fail('Expected exception was not raised');
+ } catch (\Exception $exception) {
+ $this->assertExceptionMessage(
+ $exception,
+ 'Shipment Document Validation Error(s): '
+ . 'You can\'t create a shipment without products. '
+ . 'Cannot create shipment as bundle product "bundle-product" has shipment type "Separately". '
+ . 'Bundle product options should be shipped instead.'
+ );
+ }
+
+ foreach ($order->getAllItems() as $item) {
+ if ($item->getProductType() === Type::TYPE_SIMPLE) {
+ $requestData['items'] = [
+ [
+ 'order_item_id' => $item->getItemId(),
+ 'qty' => $item->getQtyOrdered(),
+ ],
+ ];
+ break;
+ }
+ }
+
+ $this->_webApiCall($this->getServiceInfo($order), $requestData);
+ }
+
+ /**
+ * @magentoApiDataFixture Magento/Bundle/_files/order_with_bundle_shipped_together.php
+ */
+ public function testValidationShipTogetherWithBundleShippedTogether()
+ {
+ $order = $this->getOrder('100000001');
+
+ $requestData = [
+ 'orderId' => $order->getId(),
+ 'items' => [],
+ 'comment' => [
+ 'comment' => 'Test Comment',
+ 'is_visible_on_front' => 1,
+ ],
+ 'tracks' => [],
+ ];
+
+ foreach ($order->getAllItems() as $item) {
+ if ($item->getProductType() === Type::TYPE_SIMPLE) {
+ $requestData['items'][] = [
+ 'order_item_id' => $item->getItemId(),
+ 'qty' => $item->getQtyOrdered(),
+ ];
+ break;
+ }
+ }
+
+ try {
+ $this->_webApiCall($this->getServiceInfo($order), $requestData);
+ $this->fail('Expected exception was not raised');
+ } catch (\Exception $exception) {
+ $this->assertExceptionMessage(
+ $exception,
+ 'Shipment Document Validation Error(s): '
+ . 'You can\'t create a shipment without products. '
+ . 'Cannot create shipment as bundle product "bundle-product" has shipment type "Together". '
+ . 'Bundle product itself should be shipped instead.'
+ );
+ }
+
+ foreach ($order->getAllItems() as $item) {
+ if ($item->getProductType() === Type::TYPE_BUNDLE) {
+ $requestData['items'] = [
+ [
+ 'order_item_id' => $item->getItemId(),
+ 'qty' => $item->getQtyOrdered(),
+ ],
+ ];
+ break;
+ }
+ }
+
+ $this->_webApiCall($this->getServiceInfo($order), $requestData);
+ }
+
/**
* @param Order $order
* @return array
diff --git a/dev/tests/integration/testsuite/Magento/Bundle/_files/order_with_bundle_shipped_separately.php b/dev/tests/integration/testsuite/Magento/Bundle/_files/order_with_bundle_shipped_separately.php
index b91d479cdf1ef..7d214e8ab45a7 100644
--- a/dev/tests/integration/testsuite/Magento/Bundle/_files/order_with_bundle_shipped_separately.php
+++ b/dev/tests/integration/testsuite/Magento/Bundle/_files/order_with_bundle_shipped_separately.php
@@ -3,32 +3,56 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-
+declare(strict_types=1);
+
+use Magento\Bundle\Api\Data\LinkInterface;
+use Magento\Bundle\Api\Data\LinkInterfaceFactory;
+use Magento\Bundle\Api\Data\OptionInterfaceFactory;
+use Magento\Bundle\Model\Option;
+use Magento\Bundle\Model\Product\Price;
+use Magento\Bundle\Model\Product\Type;
+use Magento\Catalog\Api\ProductRepositoryInterface;
+use Magento\Catalog\Model\Product;
+use Magento\Catalog\Model\Product\Attribute\Source\Status;
+use Magento\Catalog\Model\Product\Type\AbstractType;
+use Magento\Catalog\Model\Product\Visibility;
+use Magento\Catalog\Model\ProductFactory;
+use Magento\Framework\ObjectManagerInterface;
+use Magento\Sales\Api\OrderPaymentRepositoryInterface as PaymentFactory;
+use Magento\Sales\Model\Order;
+use Magento\Sales\Model\Order\Address;
+use Magento\Sales\Model\Order\Item;
+use Magento\Sales\Model\Order\ItemFactory;
+use Magento\Sales\Model\OrderFactory;
+use Magento\Sales\Model\OrderRepository;
+use Magento\Store\Model\StoreManagerInterface;
+use Magento\TestFramework\Helper\Bootstrap;
use Magento\TestFramework\Workaround\Override\Fixture\Resolver;
Resolver::getInstance()->requireDataFixture('Magento/Catalog/_files/products.php');
-/** @var $objectManager \Magento\TestFramework\ObjectManager */
-$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
-/** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */
-$productRepository = $objectManager->create(\Magento\Catalog\Api\ProductRepositoryInterface::class);
+/** @var ObjectManagerInterface $objectManager */
+$objectManager = Bootstrap::getObjectManager();
+/** @var ProductRepositoryInterface $productRepository */
+$productRepository = $objectManager->get(ProductRepositoryInterface::class);
$sampleProduct = $productRepository->get('simple');
$secondSampleProduct = $productRepository->get('custom-design-simple-product');
+$productFactory = $objectManager->get(ProductFactory::class);
-/** @var $product \Magento\Catalog\Model\Product */
-$product = $objectManager->create(\Magento\Catalog\Model\Product::class);
-$product->setTypeId('bundle')
+/** @var $product Product */
+$product = $productFactory->create();
+$product->setTypeId(Type::TYPE_CODE)
->setId(3)
- ->setAttributeSetId(4)
+ ->setAttributeSetId($product->getDefaultAttributeSetId())
->setWebsiteIds([1])
->setName('Bundle Product')
->setSku('bundle-product')
- ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH)
- ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED)
+ ->setVisibility(Visibility::VISIBILITY_BOTH)
+ ->setStatus(Status::STATUS_ENABLED)
->setStockData(['use_config_manage_stock' => 1, 'qty' => 100, 'is_qty_decimal' => 0, 'is_in_stock' => 1])
->setPriceView(1)
- ->setPriceType(1)
- ->setShipmentType(1)
+ ->setPriceType(Price::PRICE_TYPE_FIXED)
+ ->setShipmentType(AbstractType::SHIPMENT_SEPARATELY)
->setPrice(10.0)
->setBundleOptionsData(
[
@@ -46,7 +70,7 @@
'required' => 1,
'delete' => '',
],
- ]
+ ],
)
->setBundleSelectionsData(
[
@@ -65,16 +89,15 @@
'selection_can_change_qty' => 1,
'delete' => '',
],
- ]
- ]
+ ],
+ ],
);
if ($product->getBundleOptionsData()) {
$options = [];
foreach ($product->getBundleOptionsData() as $key => $optionData) {
if (!(bool)$optionData['delete']) {
- $option = $objectManager->create(\Magento\Bundle\Api\Data\OptionInterfaceFactory::class)
- ->create(['data' => $optionData]);
+ $option = $objectManager->get(OptionInterfaceFactory::class)->create(['data' => $optionData]);
$option->setSku($product->getSku());
$option->setOptionId(null);
@@ -83,9 +106,8 @@
if (!empty($bundleLinks[$key])) {
foreach ($bundleLinks[$key] as $linkData) {
if (!(bool)$linkData['delete']) {
- /** @var \Magento\Bundle\Api\Data\LinkInterface$link */
- $link = $objectManager->create(\Magento\Bundle\Api\Data\LinkInterfaceFactory::class)
- ->create(['data' => $linkData]);
+ /** @var LinkInterface $link */
+ $link = $objectManager->get(LinkInterfaceFactory::class)->create(['data' => $linkData]);
$linkProduct = $productRepository->getById($linkData['product_id']);
$link->setSku($linkProduct->getSku());
$link->setQty($linkData['selection_qty']);
@@ -104,26 +126,22 @@
$extension->setBundleProductOptions($options);
$product->setExtensionAttributes($extension);
}
-$product->save();
-
-$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+$productRepository->save($product);
$addressData = include __DIR__ . '/../../../Magento/Sales/_files/address_data.php';
-$billingAddress = $objectManager->create(\Magento\Sales\Model\Order\Address::class, ['data' => $addressData]);
+$billingAddress = $objectManager->create(Address::class, ['data' => $addressData]);
$billingAddress->setAddressType('billing');
$shippingAddress = clone $billingAddress;
$shippingAddress->setId(null)->setAddressType('shipping');
-$payment = $objectManager->create(\Magento\Sales\Model\Order\Payment::class);
-$payment->setMethod('checkmo');
+$paymentFactory = $objectManager->get(PaymentFactory::class);
+$payment = $paymentFactory->create()->setMethod('checkmo');
-/** @var $product \Magento\Catalog\Model\Product */
-$product = $objectManager->create(\Magento\Catalog\Model\Product::class);
-$product->load(3);
+$product = $productRepository->getById(3);
-/** @var $typeInstance \Magento\Bundle\Model\Product\Type */
+/** @var $typeInstance Type */
$typeInstance = $product->getTypeInstance();
$typeInstance->setStoreFilter($product->getStoreId(), $product);
$optionCollection = $typeInstance->getOptionsCollection($product);
@@ -132,7 +150,7 @@
$bundleOptionsQty = [];
$optionsData = [];
foreach ($optionCollection as $option) {
- /** @var $option \Magento\Bundle\Model\Option */
+ /** @var $option Option */
$selectionsCollection = $typeInstance->getSelectionsCollection([$option->getId()], $product);
if ($option->isMultiSelection()) {
$optionsData[$option->getId()] = array_column($selectionsCollection->toArray(), 'product_id');
@@ -151,41 +169,52 @@
'qty' => 1,
];
+$orderItemFactory = $objectManager->get(ItemFactory::class);
$orderItems = [];
-/** @var \Magento\Sales\Model\Order\Item $orderItem */
-$orderItem = $objectManager->create(\Magento\Sales\Model\Order\Item::class);
+/** @var Item $orderItem */
+$orderItem = $orderItemFactory->create();
$orderItem->setProductId($product->getId());
$orderItem->setQtyOrdered(1);
$orderItem->setBasePrice($product->getPrice());
$orderItem->setPrice($product->getPrice());
$orderItem->setRowTotal($product->getPrice());
$orderItem->setProductType($product->getTypeId());
-$orderItem->setProductOptions(['info_buyRequest' => $requestInfo]);
+$orderItem->setSku($product->getSku());
+$orderItem->setProductOptions([
+ 'info_buyRequest' => $requestInfo,
+ 'shipment_type' => AbstractType::SHIPMENT_SEPARATELY
+]);
$orderItems[] = $orderItem;
foreach ($optionsData as $optionId => $productId) {
- /** @var $selectedProduct \Magento\Catalog\Model\Product */
- $selectedProduct = $objectManager->create(\Magento\Catalog\Model\Product::class);
- $selectedProduct->load($productId);
+ /** @var $selectedProduct Product */
+ $selectedProduct = $productRepository->getById($productId);
- /** @var \Magento\Sales\Model\Order\Item $orderItem */
- $orderItem = $objectManager->create(\Magento\Sales\Model\Order\Item::class);
+ /** @var Item $orderItem */
+ $orderItem = $orderItemFactory->create();
$orderItem->setProductId($productId);
$orderItem->setQtyOrdered(1);
$orderItem->setBasePrice($selectedProduct->getPrice());
$orderItem->setPrice($selectedProduct->getPrice());
$orderItem->setRowTotal($selectedProduct->getPrice());
$orderItem->setProductType($selectedProduct->getTypeId());
- $orderItem->setProductOptions(['info_buyRequest' => $requestInfo]);
+ $orderItem->setSku($selectedProduct->getSku());
+ $orderItem->setProductOptions([
+ 'info_buyRequest' => $requestInfo,
+ 'shipment_type' => AbstractType::SHIPMENT_SEPARATELY
+ ]);
+ $orderItem->setParentItem($orderItems[0]);
$orderItems[] = $orderItem;
}
-/** @var \Magento\Sales\Model\Order $order */
-$order = $objectManager->create(\Magento\Sales\Model\Order::class);
+$orderFactory = $objectManager->get(OrderFactory::class);
+$orderRepository = $objectManager->get(OrderRepository::class);
+/** @var Order $order */
+$order = $orderFactory->create();
$order->setIncrementId('100000001');
-$order->setState(\Magento\Sales\Model\Order::STATE_NEW);
-$order->setStatus($order->getConfig()->getStateDefaultStatus(\Magento\Sales\Model\Order::STATE_NEW));
+$order->setState(Order::STATE_NEW);
+$order->setStatus($order->getConfig()->getStateDefaultStatus(Order::STATE_NEW));
$order->setCustomerIsGuest(true);
$order->setCustomerEmail('customer@null.com');
$order->setCustomerFirstname('firstname');
@@ -199,8 +228,8 @@
$order->addItem($item);
}
-$order->setStoreId($objectManager->get(\Magento\Store\Model\StoreManagerInterface::class)->getStore()->getId());
+$order->setStoreId($objectManager->get(StoreManagerInterface::class)->getStore()->getId());
$order->setSubtotal(100);
$order->setBaseSubtotal(100);
$order->setBaseGrandTotal(100);
-$order->save();
+$orderRepository->save($order);
diff --git a/dev/tests/integration/testsuite/Magento/Bundle/_files/order_with_bundle_shipped_together.php b/dev/tests/integration/testsuite/Magento/Bundle/_files/order_with_bundle_shipped_together.php
new file mode 100644
index 0000000000000..4cc8c96ae9697
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Bundle/_files/order_with_bundle_shipped_together.php
@@ -0,0 +1,232 @@
+requireDataFixture('Magento/Catalog/_files/products.php');
+
+/** @var ObjectManagerInterface $objectManager */
+$objectManager = Bootstrap::getObjectManager();
+/** @var ProductRepositoryInterface $productRepository */
+$productRepository = $objectManager->get(ProductRepositoryInterface::class);
+$sampleProduct = $productRepository->get('simple');
+$secondSampleProduct = $productRepository->get('custom-design-simple-product');
+$productFactory = $objectManager->get(ProductFactory::class);
+
+/** @var $product Product */
+$product = $productFactory->create();
+$product->setTypeId(Type::TYPE_CODE)
+ ->setId(3)
+ ->setAttributeSetId($product->getDefaultAttributeSetId())
+ ->setWebsiteIds([1])
+ ->setName('Bundle Product')
+ ->setSku('bundle-product')
+ ->setVisibility(Visibility::VISIBILITY_BOTH)
+ ->setStatus(Status::STATUS_ENABLED)
+ ->setStockData(['use_config_manage_stock' => 1, 'qty' => 100, 'is_qty_decimal' => 0, 'is_in_stock' => 1])
+ ->setPriceView(1)
+ ->setPriceType(Price::PRICE_TYPE_FIXED)
+ ->setShipmentType(AbstractType::SHIPMENT_TOGETHER)
+ ->setPrice(10.0)
+ ->setBundleOptionsData(
+ [
+ [
+ 'title' => 'Bundle Product Items',
+ 'default_title' => 'Bundle Product Items',
+ 'type' => 'select',
+ 'required' => 1,
+ 'delete' => '',
+ ],
+ [
+ 'title' => 'Bundle Product Items Option 2',
+ 'default_title' => 'Bundle Product Items Option 2',
+ 'type' => 'select',
+ 'required' => 1,
+ 'delete' => '',
+ ],
+ ],
+ )
+ ->setBundleSelectionsData(
+ [
+ [
+ [
+ 'product_id' => $sampleProduct->getId(),
+ 'selection_qty' => 1,
+ 'selection_can_change_qty' => 1,
+ 'delete' => '',
+ ],
+ ],
+ [
+ [
+ 'product_id' => $secondSampleProduct->getId(),
+ 'selection_qty' => 1,
+ 'selection_can_change_qty' => 1,
+ 'delete' => '',
+ ],
+ ],
+ ],
+ );
+
+if ($product->getBundleOptionsData()) {
+ $options = [];
+ foreach ($product->getBundleOptionsData() as $key => $optionData) {
+ if (!(bool)$optionData['delete']) {
+ $option = $objectManager->get(OptionInterfaceFactory::class)->create(['data' => $optionData]);
+ $option->setSku($product->getSku());
+ $option->setOptionId(null);
+
+ $links = [];
+ $bundleLinks = $product->getBundleSelectionsData();
+ if (!empty($bundleLinks[$key])) {
+ foreach ($bundleLinks[$key] as $linkData) {
+ if (!(bool)$linkData['delete']) {
+ /** @var LinkInterface $link */
+ $link = $objectManager->get(LinkInterfaceFactory::class)->create(['data' => $linkData]);
+ $linkProduct = $productRepository->getById($linkData['product_id']);
+ $link->setSku($linkProduct->getSku());
+ $link->setQty($linkData['selection_qty']);
+ if (isset($linkData['selection_can_change_qty'])) {
+ $link->setCanChangeQuantity($linkData['selection_can_change_qty']);
+ }
+ $links[] = $link;
+ }
+ }
+ $option->setProductLinks($links);
+ $options[] = $option;
+ }
+ }
+ }
+ $extension = $product->getExtensionAttributes();
+ $extension->setBundleProductOptions($options);
+ $product->setExtensionAttributes($extension);
+}
+$productRepository->save($product);
+
+$addressData = include __DIR__ . '/../../../Magento/Sales/_files/address_data.php';
+
+$billingAddress = $objectManager->create(Address::class, ['data' => $addressData]);
+$billingAddress->setAddressType('billing');
+
+$shippingAddress = clone $billingAddress;
+$shippingAddress->setId(null)->setAddressType('shipping');
+
+$paymentFactory = $objectManager->get(PaymentFactory::class);
+$payment = $paymentFactory->create()->setMethod('checkmo');
+
+$product = $productRepository->getById(3);
+
+/** @var $typeInstance Type */
+$typeInstance = $product->getTypeInstance();
+$typeInstance->setStoreFilter($product->getStoreId(), $product);
+$optionCollection = $typeInstance->getOptionsCollection($product);
+
+$bundleOptions = [];
+$bundleOptionsQty = [];
+$optionsData = [];
+foreach ($optionCollection as $option) {
+ /** @var $option Option */
+ $selectionsCollection = $typeInstance->getSelectionsCollection([$option->getId()], $product);
+ if ($option->isMultiSelection()) {
+ $optionsData[$option->getId()] = array_column($selectionsCollection->toArray(), 'product_id');
+ $bundleOptions[$option->getId()] = array_column($selectionsCollection->toArray(), 'selection_id');
+ } else {
+ $bundleOptions[$option->getId()] = $selectionsCollection->getFirstItem()->getSelectionId();
+ $optionsData[$option->getId()] = $selectionsCollection->getFirstItem()->getProductId();
+ }
+ $bundleOptionsQty[$option->getId()] = 1;
+}
+
+$requestInfo = [
+ 'product' => $product->getId(),
+ 'bundle_option' => $bundleOptions,
+ 'bundle_option_qty' => $bundleOptionsQty,
+ 'qty' => 1,
+];
+
+$orderItemFactory = $objectManager->get(ItemFactory::class);
+$orderItems = [];
+/** @var Item $orderItem */
+$orderItem = $orderItemFactory->create();
+$orderItem->setProductId($product->getId());
+$orderItem->setQtyOrdered(1);
+$orderItem->setBasePrice($product->getPrice());
+$orderItem->setPrice($product->getPrice());
+$orderItem->setRowTotal($product->getPrice());
+$orderItem->setProductType($product->getTypeId());
+$orderItem->setSku($product->getSku());
+$orderItem->setProductOptions([
+ 'info_buyRequest' => $requestInfo,
+ 'bundle_options' => [['value' => [['title' => $sampleProduct->getSku()]]]],
+]);
+
+$orderItems[] = $orderItem;
+
+foreach ($optionsData as $optionId => $productId) {
+ /** @var $selectedProduct Product */
+ $selectedProduct = $productRepository->getById($productId);
+
+ /** @var Item $orderItem */
+ $orderItem = $orderItemFactory->create();
+ $orderItem->setProductId($productId);
+ $orderItem->setQtyOrdered(1);
+ $orderItem->setBasePrice($selectedProduct->getPrice());
+ $orderItem->setPrice($selectedProduct->getPrice());
+ $orderItem->setRowTotal($selectedProduct->getPrice());
+ $orderItem->setProductType($selectedProduct->getTypeId());
+ $orderItem->setSku($selectedProduct->getSku());
+ $orderItem->setProductOptions(['info_buyRequest' => $requestInfo]);
+ $orderItem->setParentItem($orderItems[0]);
+ $orderItems[] = $orderItem;
+}
+
+$orderFactory = $objectManager->get(OrderFactory::class);
+$orderRepository = $objectManager->get(OrderRepository::class);
+/** @var Order $order */
+$order = $orderFactory->create();
+$order->setIncrementId('100000001');
+$order->setState(Order::STATE_NEW);
+$order->setStatus($order->getConfig()->getStateDefaultStatus(Order::STATE_NEW));
+$order->setCustomerIsGuest(true);
+$order->setCustomerEmail('customer@null.com');
+$order->setCustomerFirstname('firstname');
+$order->setCustomerLastname('lastname');
+$order->setBillingAddress($billingAddress);
+$order->setShippingAddress($shippingAddress);
+$order->setAddresses([$billingAddress, $shippingAddress]);
+$order->setPayment($payment);
+
+foreach ($orderItems as $item) {
+ $order->addItem($item);
+}
+
+$order->setStoreId($objectManager->get(StoreManagerInterface::class)->getStore()->getId());
+$order->setSubtotal(100);
+$order->setBaseSubtotal(100);
+$order->setBaseGrandTotal(100);
+$orderRepository->save($order);
diff --git a/dev/tests/integration/testsuite/Magento/Bundle/_files/order_with_bundle_shipped_together_rollback.php b/dev/tests/integration/testsuite/Magento/Bundle/_files/order_with_bundle_shipped_together_rollback.php
new file mode 100644
index 0000000000000..4b113164d4ef2
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Bundle/_files/order_with_bundle_shipped_together_rollback.php
@@ -0,0 +1,11 @@
+requireDataFixture('Magento/Bundle/_files/product_rollback.php');
+Resolver::getInstance()->requireDataFixture('Magento/Sales/_files/default_rollback.php');
From 1bf65baa12383fd83f1cb3ad33569271bcbd2692 Mon Sep 17 00:00:00 2001
From: Viktor Kopin
Date: Mon, 16 Nov 2020 15:54:16 +0200
Subject: [PATCH 13/14] MC-38788: setup:upgrade not possible in after
installing Sample Data Magento
---
.../Model/Adapter/Elasticsearch.php | 92 ++++++---
.../Model/Adapter/ElasticsearchTest.php | 194 ++++++++++++++++++
2 files changed, 252 insertions(+), 34 deletions(-)
create mode 100644 dev/tests/integration/testsuite/Magento/Elasticsearch/Model/Adapter/ElasticsearchTest.php
diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/Elasticsearch.php b/app/code/Magento/Elasticsearch/Model/Adapter/Elasticsearch.php
index 261f8d84b5baa..1b4b7ec322f3c 100644
--- a/app/code/Magento/Elasticsearch/Model/Adapter/Elasticsearch.php
+++ b/app/code/Magento/Elasticsearch/Model/Adapter/Elasticsearch.php
@@ -6,11 +6,18 @@
namespace Magento\Elasticsearch\Model\Adapter;
-use Magento\Catalog\Api\Data\ProductAttributeInterface;
+use Elasticsearch\Common\Exceptions\Missing404Exception;
+use Magento\AdvancedSearch\Model\Client\ClientInterface;
use Magento\Catalog\Api\ProductAttributeRepositoryInterface;
use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\StaticField;
+use Magento\Elasticsearch\Model\Adapter\Index\BuilderInterface;
+use Magento\Elasticsearch\Model\Adapter\Index\IndexNameResolver;
+use Magento\Elasticsearch\Model\Config;
+use Magento\Elasticsearch\SearchAdapter\ConnectionManager;
use Magento\Framework\App\ObjectManager;
+use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Stdlib\ArrayManager;
+use Psr\Log\LoggerInterface;
/**
* Elasticsearch adapter
@@ -36,7 +43,7 @@ class Elasticsearch
protected $connectionManager;
/**
- * @var \Magento\Elasticsearch\Model\Adapter\Index\IndexNameResolver
+ * @var IndexNameResolver
*/
protected $indexNameResolver;
@@ -46,22 +53,22 @@ class Elasticsearch
protected $fieldMapper;
/**
- * @var \Magento\Elasticsearch\Model\Config
+ * @var Config
*/
protected $clientConfig;
/**
- * @var \Magento\AdvancedSearch\Model\Client\ClientInterface
+ * @var ClientInterface
*/
protected $client;
/**
- * @var \Magento\Elasticsearch\Model\Adapter\Index\BuilderInterface
+ * @var BuilderInterface
*/
protected $indexBuilder;
/**
- * @var \Psr\Log\LoggerInterface
+ * @var LoggerInterface
*/
protected $logger;
@@ -101,27 +108,27 @@ class Elasticsearch
private $arrayManager;
/**
- * @param \Magento\Elasticsearch\SearchAdapter\ConnectionManager $connectionManager
+ * @param ConnectionManager $connectionManager
* @param FieldMapperInterface $fieldMapper
- * @param \Magento\Elasticsearch\Model\Config $clientConfig
+ * @param Config $clientConfig
* @param Index\BuilderInterface $indexBuilder
- * @param \Psr\Log\LoggerInterface $logger
+ * @param LoggerInterface $logger
* @param Index\IndexNameResolver $indexNameResolver
* @param BatchDataMapperInterface $batchDocumentDataMapper
* @param array $options
* @param ProductAttributeRepositoryInterface|null $productAttributeRepository
* @param StaticField|null $staticFieldProvider
* @param ArrayManager|null $arrayManager
- * @throws \Magento\Framework\Exception\LocalizedException
+ * @throws LocalizedException
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function __construct(
- \Magento\Elasticsearch\SearchAdapter\ConnectionManager $connectionManager,
+ ConnectionManager $connectionManager,
FieldMapperInterface $fieldMapper,
- \Magento\Elasticsearch\Model\Config $clientConfig,
- \Magento\Elasticsearch\Model\Adapter\Index\BuilderInterface $indexBuilder,
- \Psr\Log\LoggerInterface $logger,
- \Magento\Elasticsearch\Model\Adapter\Index\IndexNameResolver $indexNameResolver,
+ Config $clientConfig,
+ BuilderInterface $indexBuilder,
+ LoggerInterface $logger,
+ IndexNameResolver $indexNameResolver,
BatchDataMapperInterface $batchDocumentDataMapper,
$options = [],
ProductAttributeRepositoryInterface $productAttributeRepository = null,
@@ -146,7 +153,7 @@ public function __construct(
$this->client = $this->connectionManager->getConnection($options);
} catch (\Exception $e) {
$this->logger->critical($e);
- throw new \Magento\Framework\Exception\LocalizedException(
+ throw new LocalizedException(
__('The search failed because of a search engine misconfiguration.')
);
}
@@ -156,14 +163,14 @@ public function __construct(
* Retrieve Elasticsearch server status
*
* @return bool
- * @throws \Magento\Framework\Exception\LocalizedException
+ * @throws LocalizedException
*/
public function ping()
{
try {
$response = $this->client->ping();
} catch (\Exception $e) {
- throw new \Magento\Framework\Exception\LocalizedException(
+ throw new LocalizedException(
__('Could not ping search engine: %1', $e->getMessage())
);
}
@@ -387,22 +394,12 @@ public function updateIndexMapping(int $storeId, string $mappedIndexerId, string
return $this;
}
- $attribute = $this->productAttributeRepository->get($attributeCode);
- $newAttributeMapping = $this->staticFieldProvider->getField($attribute);
- $mappedAttributes = $this->getMappedAttributes($indexName);
-
- $attrToUpdate = array_diff_key($newAttributeMapping, $mappedAttributes);
- if (!empty($attrToUpdate)) {
- $settings['index']['mapping']['total_fields']['limit'] = $this
- ->getMappingTotalFieldsLimit(array_merge($mappedAttributes, $attrToUpdate));
- $this->client->putIndexSettings($indexName, ['settings' => $settings]);
-
- $this->client->addFieldsMapping(
- $attrToUpdate,
- $indexName,
- $this->clientConfig->getEntityType()
- );
- $this->setMappedAttributes($indexName, $attrToUpdate);
+ try {
+ $this->updateMapping($attributeCode, $indexName);
+ } catch (Missing404Exception $e) {
+ unset($this->indexByCode[$mappedIndexerId . '_' . $storeId]);
+ $indexName = $this->getIndexFromAlias($storeId, $mappedIndexerId);
+ $this->updateMapping($attributeCode, $indexName);
}
return $this;
@@ -505,4 +502,31 @@ private function getMappingTotalFieldsLimit(array $allAttributeTypes): int
}
return $count + self::MAPPING_TOTAL_FIELDS_BUFFER_LIMIT;
}
+
+ /**
+ * Perform index mapping update
+ *
+ * @param string $attributeCode
+ * @param string $indexName
+ * @return void
+ */
+ private function updateMapping(string $attributeCode, string $indexName): void
+ {
+ $attribute = $this->productAttributeRepository->get($attributeCode);
+ $newAttributeMapping = $this->staticFieldProvider->getField($attribute);
+ $mappedAttributes = $this->getMappedAttributes($indexName);
+ $attrToUpdate = array_diff_key($newAttributeMapping, $mappedAttributes);
+ if (!empty($attrToUpdate)) {
+ $settings['index']['mapping']['total_fields']['limit'] = $this
+ ->getMappingTotalFieldsLimit(array_merge($mappedAttributes, $attrToUpdate));
+ $this->client->putIndexSettings($indexName, ['settings' => $settings]);
+
+ $this->client->addFieldsMapping(
+ $attrToUpdate,
+ $indexName,
+ $this->clientConfig->getEntityType()
+ );
+ $this->setMappedAttributes($indexName, $attrToUpdate);
+ }
+ }
}
diff --git a/dev/tests/integration/testsuite/Magento/Elasticsearch/Model/Adapter/ElasticsearchTest.php b/dev/tests/integration/testsuite/Magento/Elasticsearch/Model/Adapter/ElasticsearchTest.php
new file mode 100644
index 0000000000000..986d98f0f2f14
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Elasticsearch/Model/Adapter/ElasticsearchTest.php
@@ -0,0 +1,194 @@
+objectManager = Bootstrap::getObjectManager();
+ $this->indexNameResolver = $this->objectManager->get(IndexNameResolver::class);
+ $this->adapter = $this->objectManager->get(Elasticsearch::class);
+ $this->storeManager = $this->objectManager->create(StoreManagerInterface::class);
+ $connectionManager = $this->objectManager->create(ConnectionManager::class);
+ $this->client = $connectionManager->getConnection();
+ $this->indexBuilder = $this->objectManager->get(BuilderInterface::class);
+ $this->arrayManager = $this->objectManager->get(ArrayManager::class);
+ $indexer = $this->objectManager->create(Indexer::class);
+ $indexer->load('catalogsearch_fulltext');
+ $indexer->reindexAll();
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function tearDown(): void
+ {
+ $this->deleteIndex($this->newIndex);
+ }
+
+ /**
+ * Tests possibility to create mapping if adapter has obsolete index name in cache
+ *
+ * @magentoDataFixture Magento/Elasticsearch/_files/select_attribute.php
+ * @return void
+ */
+ public function testRetryOnIndexNotFoundException(): void
+ {
+ $this->updateElasticsearchIndex();
+ $this->createNewAttribute();
+ $mapping = $this->client->getMapping(['index' => $this->newIndex]);
+ $pathField = $this->arrayManager->findPath('properties', $mapping);
+ $attributes = $this->arrayManager->get($pathField, $mapping, []);
+ $this->assertArrayHasKey('multiselect_attribute', $attributes);
+ }
+
+ /**
+ * Prepare and save new attribute
+ *
+ * @return void
+ */
+ public function createNewAttribute(): void
+ {
+ /** @var CategorySetup $installer */
+ $installer = $this->objectManager->get(CategorySetup::class);
+ /** @var Attribute $attribute */
+ $multiselectAttribute = $this->objectManager->get(Attribute::class);
+ $multiselectAttribute->setData(
+ [
+ 'attribute_code' => 'multiselect_attribute',
+ 'entity_type_id' => $installer->getEntityTypeId('catalog_product'),
+ 'is_global' => 1,
+ 'is_user_defined' => 1,
+ 'frontend_input' => 'multiselect',
+ 'is_unique' => 0,
+ 'is_required' => 0,
+ 'is_searchable' => 1,
+ 'is_visible_in_advanced_search' => 0,
+ 'is_comparable' => 0,
+ 'is_filterable' => 1,
+ 'is_filterable_in_search' => 0,
+ 'is_used_for_promo_rules' => 0,
+ 'is_html_allowed_on_front' => 1,
+ 'is_visible_on_front' => 0,
+ 'used_in_product_listing' => 0,
+ 'used_for_sort_by' => 0,
+ 'frontend_label' => ['Multiselect Attribute'],
+ 'backend_type' => 'varchar',
+ 'backend_model' => ArrayBackend::class,
+ 'option' => [
+ 'value' => [
+ 'dog' => ['Dog'],
+ 'cat' => ['Cat'],
+ ],
+ 'order' => [
+ 'dog' => 1,
+ 'cat' => 2,
+ ],
+ ],
+ ]
+ );
+ $multiselectAttribute->save();
+ }
+
+ /**
+ * Prepare new index and delete old. Keep cache alive.
+ *
+ * @return void
+ */
+ private function updateElasticsearchIndex(): void
+ {
+ $storeId = (int)$this->storeManager->getDefaultStoreView()->getId();
+ $mappedIndexerId = 'product';
+ $this->adapter->updateIndexMapping($storeId, $mappedIndexerId, 'select_attribute');
+ $oldIndex = $this->indexNameResolver->getIndexFromAlias($storeId, $mappedIndexerId);
+ $this->newIndex = $oldIndex . '1';
+ $this->deleteIndex($this->newIndex);
+ $this->indexBuilder->setStoreId($storeId);
+ $this->client->createIndex($this->newIndex, ['settings' => $this->indexBuilder->build()]);
+ $this->client->updateAlias(
+ $this->indexNameResolver->getIndexNameForAlias($storeId, $mappedIndexerId),
+ $this->newIndex,
+ $oldIndex
+ );
+ $this->client->deleteIndex($oldIndex);
+ }
+
+ /**
+ * Delete index by name if exists
+ *
+ * @param $newIndex
+ */
+ private function deleteIndex($newIndex): void
+ {
+ if ($this->client->indexExists($newIndex)) {
+ $this->client->deleteIndex($newIndex);
+ }
+ }
+}
From 16629107cda62af80e601be6009a5f671e0107a1 Mon Sep 17 00:00:00 2001
From: engcom-Kilo
Date: Tue, 17 Nov 2020 18:27:13 +0200
Subject: [PATCH 14/14] MC-37364: Unit Test and JSUnit Test fails to start on
Magento composer 2.4.0. Revert integration tests suites. Add correct
exception class to unit tests.
---
.../Test/Unit/Model/ShippingInformationManagementTest.php | 3 ++-
.../Test/Unit/Model/Checkout/Plugin/GuestValidationTest.php | 3 ++-
.../Test/Unit/Model/Checkout/Plugin/ValidationTest.php | 3 ++-
.../Downloadable/Test/Unit/Model/Link/UpdateHandlerTest.php | 3 ++-
.../Test/Unit/Model/Quote/Item/CartItemProcessorTest.php | 3 ++-
.../Test/Unit/Model/Sample/UpdateHandlerTest.php | 3 ++-
.../GiftMessage/Test/Unit/Model/Plugin/OrderGetTest.php | 5 +++--
.../GiftMessage/Test/Unit/Model/Plugin/OrderSaveTest.php | 5 +++--
.../Test/Unit/Model/DisableMultishippingTest.php | 3 ++-
.../Magento/Persistent/Test/Unit/Model/QuoteManagerTest.php | 2 +-
.../Attribute/Media/ExternalVideoEntryConverterTest.php | 3 ++-
.../Quote/Test/Unit/Model/ShippingAddressAssignmentTest.php | 3 ++-
.../Magento/Sales/Test/Unit/Model/OrderRepositoryTest.php | 3 ++-
dev/tests/integration/phpunit.xml.dist | 6 +++---
dev/tests/integration/testsuite/Magento/IntegrationTest.php | 2 +-
15 files changed, 31 insertions(+), 19 deletions(-)
diff --git a/app/code/Magento/Checkout/Test/Unit/Model/ShippingInformationManagementTest.php b/app/code/Magento/Checkout/Test/Unit/Model/ShippingInformationManagementTest.php
index 8bb017f4b212c..6ff782d94e4eb 100644
--- a/app/code/Magento/Checkout/Test/Unit/Model/ShippingInformationManagementTest.php
+++ b/app/code/Magento/Checkout/Test/Unit/Model/ShippingInformationManagementTest.php
@@ -32,6 +32,7 @@
use Magento\Quote\Model\ShippingAssignmentFactory;
use Magento\Quote\Model\ShippingFactory;
use PHPUnit\Framework\MockObject\MockObject;
+use PHPUnit\Framework\MockObject\RuntimeException;
use PHPUnit\Framework\TestCase;
/**
@@ -631,7 +632,7 @@ private function getCartExtensionMock(): MockObject
$mockBuilder = $this->getMockBuilder(CartExtension::class);
try {
$mockBuilder->addMethods(['getShippingAssignments', 'setShippingAssignments']);
- } catch (\RuntimeException $e) {
+ } catch (RuntimeException $e) {
// CartExtension already generated.
}
diff --git a/app/code/Magento/CheckoutAgreements/Test/Unit/Model/Checkout/Plugin/GuestValidationTest.php b/app/code/Magento/CheckoutAgreements/Test/Unit/Model/Checkout/Plugin/GuestValidationTest.php
index 845d71f6e2f17..bb05d5636677c 100644
--- a/app/code/Magento/CheckoutAgreements/Test/Unit/Model/Checkout/Plugin/GuestValidationTest.php
+++ b/app/code/Magento/CheckoutAgreements/Test/Unit/Model/Checkout/Plugin/GuestValidationTest.php
@@ -20,6 +20,7 @@
use Magento\Quote\Api\Data\PaymentInterface;
use Magento\Store\Model\ScopeInterface;
use PHPUnit\Framework\MockObject\MockObject;
+use PHPUnit\Framework\MockObject\RuntimeException;
use PHPUnit\Framework\TestCase;
/**
@@ -174,7 +175,7 @@ private function getPaymentExtension(): MockObject
$mockBuilder = $this->getMockBuilder(PaymentExtension::class);
try {
$mockBuilder->addMethods(['getAgreementIds']);
- } catch (\RuntimeException $e) {
+ } catch (RuntimeException $e) {
// Payment extension already generated.
}
diff --git a/app/code/Magento/CheckoutAgreements/Test/Unit/Model/Checkout/Plugin/ValidationTest.php b/app/code/Magento/CheckoutAgreements/Test/Unit/Model/Checkout/Plugin/ValidationTest.php
index ebe4c2c1c7b05..b7e5127df1f8b 100644
--- a/app/code/Magento/CheckoutAgreements/Test/Unit/Model/Checkout/Plugin/ValidationTest.php
+++ b/app/code/Magento/CheckoutAgreements/Test/Unit/Model/Checkout/Plugin/ValidationTest.php
@@ -22,6 +22,7 @@
use Magento\Quote\Model\Quote;
use Magento\Store\Model\ScopeInterface;
use PHPUnit\Framework\MockObject\MockObject;
+use PHPUnit\Framework\MockObject\RuntimeException;
use PHPUnit\Framework\TestCase;
/**
@@ -241,7 +242,7 @@ private function getPaymentExtension(): MockObject
$mockBuilder = $this->getMockBuilder(PaymentExtension::class);
try {
$mockBuilder->addMethods(['getAgreementIds']);
- } catch (\RuntimeException $e) {
+ } catch (RuntimeException $e) {
// Payment extension already generated.
}
diff --git a/app/code/Magento/Downloadable/Test/Unit/Model/Link/UpdateHandlerTest.php b/app/code/Magento/Downloadable/Test/Unit/Model/Link/UpdateHandlerTest.php
index af4d785955600..16b698adf57f0 100644
--- a/app/code/Magento/Downloadable/Test/Unit/Model/Link/UpdateHandlerTest.php
+++ b/app/code/Magento/Downloadable/Test/Unit/Model/Link/UpdateHandlerTest.php
@@ -15,6 +15,7 @@
use Magento\Downloadable\Model\Link\UpdateHandler;
use Magento\Downloadable\Model\Product\Type;
use PHPUnit\Framework\MockObject\MockObject;
+use PHPUnit\Framework\MockObject\RuntimeException;
use PHPUnit\Framework\TestCase;
/**
@@ -157,7 +158,7 @@ private function getProductExtensionMock(): MockObject
->disableOriginalConstructor();
try {
$mockBuilder->addMethods(['getDownloadableProductLinks']);
- } catch (\RuntimeException $e) {
+ } catch (RuntimeException $e) {
// ProductExtension already generated.
}
diff --git a/app/code/Magento/Downloadable/Test/Unit/Model/Quote/Item/CartItemProcessorTest.php b/app/code/Magento/Downloadable/Test/Unit/Model/Quote/Item/CartItemProcessorTest.php
index 46ded7b3c456b..8eaed8eebc05a 100644
--- a/app/code/Magento/Downloadable/Test/Unit/Model/Quote/Item/CartItemProcessorTest.php
+++ b/app/code/Magento/Downloadable/Test/Unit/Model/Quote/Item/CartItemProcessorTest.php
@@ -21,6 +21,7 @@
use Magento\Quote\Model\Quote\Item;
use Magento\Quote\Model\Quote\ProductOptionFactory;
use PHPUnit\Framework\MockObject\MockObject;
+use PHPUnit\Framework\MockObject\RuntimeException;
use PHPUnit\Framework\TestCase;
/**
@@ -250,7 +251,7 @@ private function getProductOptionExtensionMock(): MockObject
$mockBuilder = $this->getMockBuilder(ProductOptionExtension::class);
try {
$mockBuilder->addMethods(['setDownloadableOption']);
- } catch (\RuntimeException $e) {
+ } catch (RuntimeException $e) {
// ProductOptionExtension already generated.
}
diff --git a/app/code/Magento/Downloadable/Test/Unit/Model/Sample/UpdateHandlerTest.php b/app/code/Magento/Downloadable/Test/Unit/Model/Sample/UpdateHandlerTest.php
index d826cde3cd78a..cc0427808ebc0 100644
--- a/app/code/Magento/Downloadable/Test/Unit/Model/Sample/UpdateHandlerTest.php
+++ b/app/code/Magento/Downloadable/Test/Unit/Model/Sample/UpdateHandlerTest.php
@@ -15,6 +15,7 @@
use Magento\Downloadable\Model\Product\Type;
use Magento\Downloadable\Model\Sample\UpdateHandler;
use PHPUnit\Framework\MockObject\MockObject;
+use PHPUnit\Framework\MockObject\RuntimeException;
use PHPUnit\Framework\TestCase;
/**
@@ -157,7 +158,7 @@ private function getProductExtensionMock(): MockObject
->disableOriginalConstructor();
try {
$mockBuilder->addMethods(['getDownloadableProductSamples']);
- } catch (\RuntimeException $e) {
+ } catch (RuntimeException $e) {
// Product extension already generated.
}
diff --git a/app/code/Magento/GiftMessage/Test/Unit/Model/Plugin/OrderGetTest.php b/app/code/Magento/GiftMessage/Test/Unit/Model/Plugin/OrderGetTest.php
index d9389f43843a3..85bae4a42a8df 100644
--- a/app/code/Magento/GiftMessage/Test/Unit/Model/Plugin/OrderGetTest.php
+++ b/app/code/Magento/GiftMessage/Test/Unit/Model/Plugin/OrderGetTest.php
@@ -20,6 +20,7 @@
use Magento\Sales\Api\Data\OrderItemInterface;
use Magento\Sales\Model\ResourceModel\Order\Collection;
use PHPUnit\Framework\MockObject\MockObject;
+use PHPUnit\Framework\MockObject\RuntimeException;
use PHPUnit\Framework\TestCase;
/**
@@ -279,7 +280,7 @@ private function getOrderExtensionMock(): MockObject
$mockObject = $this->getMockBuilder(OrderExtension::class);
try {
$mockObject->addMethods(['getGiftMessage', 'setGiftMessage']);
- } catch (\RuntimeException $e) {
+ } catch (RuntimeException $e) {
// Order extension already generated.
}
@@ -296,7 +297,7 @@ private function getOrderItemExtensionMock(): MockObject
$mockObject = $this->getMockBuilder(OrderItemExtension::class);
try {
$mockObject->addMethods(['getGiftMessage', 'setGiftMessage']);
- } catch (\RuntimeException $e) {
+ } catch (RuntimeException $e) {
// Order extension already generated.
}
diff --git a/app/code/Magento/GiftMessage/Test/Unit/Model/Plugin/OrderSaveTest.php b/app/code/Magento/GiftMessage/Test/Unit/Model/Plugin/OrderSaveTest.php
index 11491754e3bcb..51702f4349003 100644
--- a/app/code/Magento/GiftMessage/Test/Unit/Model/Plugin/OrderSaveTest.php
+++ b/app/code/Magento/GiftMessage/Test/Unit/Model/Plugin/OrderSaveTest.php
@@ -16,6 +16,7 @@
use Magento\Sales\Api\Data\OrderItemExtension;
use Magento\Sales\Api\Data\OrderItemInterface;
use PHPUnit\Framework\MockObject\MockObject;
+use PHPUnit\Framework\MockObject\RuntimeException;
use PHPUnit\Framework\TestCase;
class OrderSaveTest extends TestCase
@@ -199,7 +200,7 @@ private function getOrderExtensionMock(): MockObject
$mockBuilder = $this->getMockBuilder(OrderExtension::class);
try {
$mockBuilder->addMethods(['getGiftMessage', 'setGiftMessage']);
- } catch (\RuntimeException $e) {
+ } catch (RuntimeException $e) {
// OrderExtension already generated.
}
@@ -216,7 +217,7 @@ private function getOrderItemExtensionMock(): MockObject
$mockBuilder = $this->getMockBuilder(OrderItemExtension::class);
try {
$mockBuilder->addMethods(['getGiftMessage', 'setGiftMessage']);
- } catch (\RuntimeException $e) {
+ } catch (RuntimeException $e) {
// OrderItemExtension already generated.
}
diff --git a/app/code/Magento/Multishipping/Test/Unit/Model/DisableMultishippingTest.php b/app/code/Magento/Multishipping/Test/Unit/Model/DisableMultishippingTest.php
index 075fc4ac347b0..8d4013dd54e2c 100644
--- a/app/code/Magento/Multishipping/Test/Unit/Model/DisableMultishippingTest.php
+++ b/app/code/Magento/Multishipping/Test/Unit/Model/DisableMultishippingTest.php
@@ -11,6 +11,7 @@
use Magento\Quote\Api\Data\CartExtensionInterface;
use Magento\Quote\Api\Data\CartInterface;
use PHPUnit\Framework\MockObject\MockObject;
+use PHPUnit\Framework\MockObject\RuntimeException;
use PHPUnit\Framework\TestCase;
/**
@@ -121,7 +122,7 @@ private function getCartExtensionMock(): MockObject
->disableOriginalConstructor();
try {
$mockBuilder->addMethods(['getShippingAssignments', 'setShippingAssignments']);
- } catch (\RuntimeException $e) {
+ } catch (RuntimeException $e) {
// CartExtension already generated.
}
diff --git a/app/code/Magento/Persistent/Test/Unit/Model/QuoteManagerTest.php b/app/code/Magento/Persistent/Test/Unit/Model/QuoteManagerTest.php
index d6d80ab7de229..ece36673c1e82 100644
--- a/app/code/Magento/Persistent/Test/Unit/Model/QuoteManagerTest.php
+++ b/app/code/Magento/Persistent/Test/Unit/Model/QuoteManagerTest.php
@@ -392,7 +392,7 @@ private function getExtensionAttributesMock(): MockObject
$extensionMockBuilder = $this->getMockBuilder(CartExtensionInterface::class);
try {
$extensionMockBuilder->addMethods(['setShippingAssignments']);
- } catch (\RuntimeException $e) {
+ } catch (RuntimeException $e) {
// do nothing as CartExtensionInterface already generated and has 'setShippingAssignments' method.
}
diff --git a/app/code/Magento/ProductVideo/Test/Unit/Model/Product/Attribute/Media/ExternalVideoEntryConverterTest.php b/app/code/Magento/ProductVideo/Test/Unit/Model/Product/Attribute/Media/ExternalVideoEntryConverterTest.php
index fd96ca7fb7ebf..a55416da4b532 100644
--- a/app/code/Magento/ProductVideo/Test/Unit/Model/Product/Attribute/Media/ExternalVideoEntryConverterTest.php
+++ b/app/code/Magento/ProductVideo/Test/Unit/Model/Product/Attribute/Media/ExternalVideoEntryConverterTest.php
@@ -20,6 +20,7 @@
use Magento\ProductVideo\Model\Product\Attribute\Media\ExternalVideoEntryConverter;
use Magento\ProductVideo\Model\Product\Attribute\Media\VideoEntry;
use PHPUnit\Framework\MockObject\MockObject;
+use PHPUnit\Framework\MockObject\RuntimeException;
use PHPUnit\Framework\TestCase;
/**
@@ -232,7 +233,7 @@ private function getProductAttributeMediaGalleryEntryExtensionMock(): MockObject
'getVideoContent',
]
);
- } catch (\Exception $e) {
+ } catch (RuntimeException $e) {
// ProductAttributeMediaGalleryEntryExtension already generated and has all necessary methods.
}
diff --git a/app/code/Magento/Quote/Test/Unit/Model/ShippingAddressAssignmentTest.php b/app/code/Magento/Quote/Test/Unit/Model/ShippingAddressAssignmentTest.php
index 75f3af2643722..868188c97b1fa 100644
--- a/app/code/Magento/Quote/Test/Unit/Model/ShippingAddressAssignmentTest.php
+++ b/app/code/Magento/Quote/Test/Unit/Model/ShippingAddressAssignmentTest.php
@@ -16,6 +16,7 @@
use Magento\Quote\Model\Quote\ShippingAssignment\ShippingAssignmentProcessor;
use Magento\Quote\Model\ShippingAddressAssignment;
use PHPUnit\Framework\MockObject\MockObject;
+use PHPUnit\Framework\MockObject\RuntimeException;
use PHPUnit\Framework\TestCase;
class ShippingAddressAssignmentTest extends TestCase
@@ -122,7 +123,7 @@ private function getCartExtensionMock(): MockObject
$mockBuilder = $this->getMockBuilder(CartExtension::class);
try {
$mockBuilder->addMethods(['setShippingAssignments']);
- } catch (\RuntimeException $e) {
+ } catch (RuntimeException $e) {
// CartExtension already generated.
}
diff --git a/app/code/Magento/Sales/Test/Unit/Model/OrderRepositoryTest.php b/app/code/Magento/Sales/Test/Unit/Model/OrderRepositoryTest.php
index d242268649a5e..41c92da1cde5d 100644
--- a/app/code/Magento/Sales/Test/Unit/Model/OrderRepositoryTest.php
+++ b/app/code/Magento/Sales/Test/Unit/Model/OrderRepositoryTest.php
@@ -29,6 +29,7 @@
use Magento\Tax\Api\Data\OrderTaxDetailsInterface;
use Magento\Tax\Api\OrderTaxManagementInterface;
use PHPUnit\Framework\MockObject\MockObject;
+use PHPUnit\Framework\MockObject\RuntimeException;
use PHPUnit\Framework\TestCase;
/**
@@ -261,7 +262,7 @@ private function getOrderExtensionMock(): MockObject
'setPaymentAdditionalInfo',
]
);
- } catch (\RuntimeException $e) {
+ } catch (RuntimeException $e) {
// Order extension already generated.
}
diff --git a/dev/tests/integration/phpunit.xml.dist b/dev/tests/integration/phpunit.xml.dist
index d57e6809da7e9..92dd1e11f613b 100644
--- a/dev/tests/integration/phpunit.xml.dist
+++ b/dev/tests/integration/phpunit.xml.dist
@@ -17,14 +17,14 @@
>
-
+
testsuite/Magento/IntegrationTest.php
-
+
testsuite/Magento/MemoryUsageTest.php
-
+
testsuite
../../../app/code/*/*/Test/Integration
testsuite/Magento/MemoryUsageTest.php
diff --git a/dev/tests/integration/testsuite/Magento/IntegrationTest.php b/dev/tests/integration/testsuite/Magento/IntegrationTest.php
index 39d383fb86354..26dec49c83b52 100644
--- a/dev/tests/integration/testsuite/Magento/IntegrationTest.php
+++ b/dev/tests/integration/testsuite/Magento/IntegrationTest.php
@@ -41,7 +41,7 @@ public static function suite($className)
$suitesConfig = $configuration->testSuite();
$suite = new TestSuite();
foreach ($suitesConfig as $suiteConfig) {
- if ($suiteConfig->name() === 'Magento_Integration_Tests') {
+ if ($suiteConfig->name() === 'Magento Integration Tests') {
continue;
}
$suites = self::getSuites($suiteConfig);