123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609 |
- <?php
- /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
- declare(strict_types=1);
- namespace Magento\Quote\Model;
- use Magento\Catalog\Api\ProductRepositoryInterface;
- use Magento\Catalog\Model\ProductRepository;
- use Magento\Customer\Api\CustomerRepositoryInterface;
- use Magento\Customer\Api\Data\CustomerInterface;
- use Magento\Customer\Api\Data\CustomerInterfaceFactory;
- use Magento\Customer\Model\Data\Customer;
- use Magento\Framework\Exception\LocalizedException;
- use Magento\TestFramework\Helper\Bootstrap;
- use Magento\TestFramework\ObjectManager;
- use Magento\Framework\Api\SearchCriteriaBuilder;
- use Magento\Quote\Api\CartRepositoryInterface;
- use Magento\Framework\Api\ExtensibleDataInterface;
- /**
- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
- */
- class QuoteTest extends \PHPUnit\Framework\TestCase
- {
- /**
- * @var ObjectManager
- */
- private $objectManager;
- /**
- * @inheritdoc
- */
- protected function setUp()
- {
- $this->objectManager = Bootstrap::getObjectManager();
- }
- /**
- * @param ExtensibleDataInterface $entity
- * @return array
- */
- private function convertToArray(ExtensibleDataInterface $entity): array
- {
- return $this->objectManager
- ->create(\Magento\Framework\Api\ExtensibleDataObjectConverter::class)
- ->toFlatArray($entity);
- }
- /**
- * @magentoDataFixture Magento/Catalog/_files/product_virtual.php
- * @magentoDataFixture Magento/Sales/_files/quote.php
- * @return void
- */
- public function testCollectTotalsWithVirtual(): void
- {
- $quote = $this->objectManager->create(Quote::class);
- $quote->load('test01', 'reserved_order_id');
- $productRepository = $this->objectManager->create(
- ProductRepositoryInterface::class
- );
- $product = $productRepository->get('virtual-product', false, null, true);
- $quote->addProduct($product);
- $quote->collectTotals();
- $this->assertEquals(2, $quote->getItemsQty());
- $this->assertEquals(1, $quote->getVirtualItemsQty());
- $this->assertEquals(20, $quote->getGrandTotal());
- $this->assertEquals(20, $quote->getBaseGrandTotal());
- }
- /**
- * @return void
- */
- public function testSetCustomerData(): void
- {
- /** @var Quote $quote */
- $quote = $this->objectManager->create(Quote::class);
- /** @var CustomerInterfaceFactory $customerFactory */
- $customerFactory = $this->objectManager->create(
- CustomerInterfaceFactory::class
- );
- /** @var \Magento\Framework\Api\DataObjectHelper $dataObjectHelper */
- $dataObjectHelper = $this->objectManager->create(\Magento\Framework\Api\DataObjectHelper::class);
- $expected = $this->_getCustomerDataArray();
- $customer = $customerFactory->create();
- $dataObjectHelper->populateWithArray(
- $customer,
- $expected,
- \Magento\Customer\Api\Data\CustomerInterface::class
- );
- $this->assertEquals($expected, $this->convertToArray($customer));
- $quote->setCustomer($customer);
- $customer = $quote->getCustomer();
- $this->assertEquals($expected, $this->convertToArray($customer));
- $this->assertEquals('qa@example.com', $quote->getCustomerEmail());
- }
- /**
- * @return void
- */
- public function testUpdateCustomerData(): void
- {
- /** @var Quote $quote */
- $quote = $this->objectManager->create(Quote::class);
- $customerFactory = $this->objectManager->create(
- CustomerInterfaceFactory::class
- );
- /** @var \Magento\Framework\Api\DataObjectHelper $dataObjectHelper */
- $dataObjectHelper = $this->objectManager->create(\Magento\Framework\Api\DataObjectHelper::class);
- $expected = $this->_getCustomerDataArray();
- //For save in repository
- $expected = $this->removeIdFromCustomerData($expected);
- $customerDataSet = $customerFactory->create();
- $dataObjectHelper->populateWithArray(
- $customerDataSet,
- $expected,
- \Magento\Customer\Api\Data\CustomerInterface::class
- );
- $this->assertEquals($expected, $this->convertToArray($customerDataSet));
- /**
- * @var \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository
- */
- $customerRepository = $this->objectManager
- ->create(\Magento\Customer\Api\CustomerRepositoryInterface::class);
- $customerRepository->save($customerDataSet);
- $quote->setCustomer($customerDataSet);
- $expected = $this->_getCustomerDataArray();
- $expected = $this->changeEmailInCustomerData('test@example.com', $expected);
- $customerDataUpdated = $customerFactory->create();
- $dataObjectHelper->populateWithArray(
- $customerDataUpdated,
- $expected,
- \Magento\Customer\Api\Data\CustomerInterface::class
- );
- $quote->updateCustomerData($customerDataUpdated);
- $customer = $quote->getCustomer();
- $expected = $this->changeEmailInCustomerData('test@example.com', $expected);
- $actual = $this->convertToArray($customer);
- foreach ($expected as $item) {
- $this->assertContains($item, $actual);
- }
- $this->assertEquals('test@example.com', $quote->getCustomerEmail());
- }
- /**
- * Customer data is set to quote (which contains valid group ID).
- *
- * @return void
- */
- public function testGetCustomerGroupFromCustomer(): void
- {
- /** Preconditions */
- /** @var CustomerInterfaceFactory $customerFactory */
- $customerFactory = $this->objectManager->create(
- CustomerInterfaceFactory::class
- );
- $customerGroupId = 3;
- $customerData = $customerFactory->create()->setId(1)->setGroupId($customerGroupId);
- /** @var Quote $quote */
- $quote = $this->objectManager->create(Quote::class);
- $quote->setCustomer($customerData);
- $quote->unsetData('customer_group_id');
- /** Execute SUT */
- $this->assertEquals($customerGroupId, $quote->getCustomerGroupId(), "Customer group ID is invalid");
- }
- /**
- * @magentoDataFixture Magento/Customer/_files/customer_group.php
- * @return void
- */
- public function testGetCustomerTaxClassId(): void
- {
- /**
- * Preconditions: create quote and assign ID of customer group created in fixture to it.
- */
- $fixtureGroupCode = 'custom_group';
- $fixtureTaxClassId = 3;
- /** @var \Magento\Customer\Model\Group $group */
- $group = $this->objectManager->create(\Magento\Customer\Model\Group::class);
- $fixtureGroupId = $group->load($fixtureGroupCode, 'customer_group_code')->getId();
- /** @var Quote $quote */
- $quote = $this->objectManager->create(Quote::class);
- $quote->setCustomerGroupId($fixtureGroupId);
- /** Execute SUT */
- $this->assertEquals($fixtureTaxClassId, $quote->getCustomerTaxClassId(), 'Customer tax class ID is invalid.');
- }
- /**
- * Billing and shipping address arguments are not passed, customer has default billing and shipping addresses.
- *
- * @magentoDataFixture Magento/Customer/_files/customer.php
- * @magentoDataFixture Magento/Customer/_files/customer_address.php
- * @magentoDataFixture Magento/Customer/_files/customer_two_addresses.php
- * @return void
- */
- public function testAssignCustomerWithAddressChangeAddressesNotSpecified(): void
- {
- /** Preconditions:
- * Customer with two addresses created
- * First address is default billing, second is default shipping.
- */
- /** @var Quote $quote */
- $quote = $this->objectManager->create(Quote::class);
- $customerData = $this->_prepareQuoteForTestAssignCustomerWithAddressChange($quote);
- /** Execute SUT */
- $quote->assignCustomerWithAddressChange($customerData);
- /** Check if SUT caused expected effects */
- $fixtureCustomerId = 1;
- $this->assertEquals($fixtureCustomerId, $quote->getCustomerId(), 'Customer ID in quote is invalid.');
- $expectedBillingAddressData = [
- 'street' => 'Green str, 67',
- 'telephone' => 3468676,
- 'postcode' => 75477,
- 'country_id' => 'US',
- 'city' => 'CityM',
- 'lastname' => 'Smith',
- 'firstname' => 'John',
- 'customer_id' => 1,
- 'customer_address_id' => 1,
- 'region_id' => 1
- ];
- $billingAddress = $quote->getBillingAddress();
- foreach ($expectedBillingAddressData as $field => $value) {
- $this->assertEquals(
- $value,
- $billingAddress->getData($field),
- "'{$field}' value in quote billing address is invalid."
- );
- }
- $expectedShippingAddressData = [
- 'customer_address_id' => 2,
- 'telephone' => 3234676,
- 'postcode' => 47676,
- 'country_id' => 'US',
- 'city' => 'CityX',
- 'street' => 'Black str, 48',
- 'lastname' => 'Smith',
- 'firstname' => 'John',
- 'customer_id' => 1,
- 'region_id' => 1
- ];
- $shippingAddress = $quote->getShippingAddress();
- foreach ($expectedShippingAddressData as $field => $value) {
- $this->assertEquals(
- $value,
- $shippingAddress->getData($field),
- "'{$field}' value in quote shipping address is invalid."
- );
- }
- }
- /**
- * Billing and shipping address arguments are passed, customer has default billing and shipping addresses.
- *
- * @magentoDataFixture Magento/Customer/_files/customer.php
- * @magentoDataFixture Magento/Customer/_files/customer_address.php
- * @magentoDataFixture Magento/Customer/_files/customer_two_addresses.php
- * @return void
- */
- public function testAssignCustomerWithAddressChange(): void
- {
- /** Preconditions:
- * Customer with two addresses created
- * First address is default billing, second is default shipping.
- */
- /** @var Quote $quote */
- $quote = $this->objectManager->create(Quote::class);
- $customerData = $this->_prepareQuoteForTestAssignCustomerWithAddressChange($quote);
- /** @var \Magento\Quote\Model\Quote\Address $quoteBillingAddress */
- $expectedBillingAddressData = [
- 'street' => 'Billing str, 67',
- 'telephone' => 16546757,
- 'postcode' => 2425457,
- 'country_id' => 'US',
- 'city' => 'CityBilling',
- 'lastname' => 'LastBilling',
- 'firstname' => 'FirstBilling',
- 'region_id' => 1
- ];
- $quoteBillingAddress = $this->objectManager->create(\Magento\Quote\Model\Quote\Address::class);
- $quoteBillingAddress->setData($expectedBillingAddressData);
- $expectedShippingAddressData = [
- 'telephone' => 787878787,
- 'postcode' => 117785,
- 'country_id' => 'US',
- 'city' => 'CityShipping',
- 'street' => 'Shipping str, 48',
- 'lastname' => 'LastShipping',
- 'firstname' => 'FirstShipping',
- 'region_id' => 1
- ];
- $quoteShippingAddress = $this->objectManager->create(\Magento\Quote\Model\Quote\Address::class);
- $quoteShippingAddress->setData($expectedShippingAddressData);
- /** Execute SUT */
- $quote->assignCustomerWithAddressChange($customerData, $quoteBillingAddress, $quoteShippingAddress);
- /** Check if SUT caused expected effects */
- $fixtureCustomerId = 1;
- $this->assertEquals($fixtureCustomerId, $quote->getCustomerId(), 'Customer ID in quote is invalid.');
- $billingAddress = $quote->getBillingAddress();
- foreach ($expectedBillingAddressData as $field => $value) {
- $this->assertEquals(
- $value,
- $billingAddress->getData($field),
- "'{$field}' value in quote billing address is invalid."
- );
- }
- $shippingAddress = $quote->getShippingAddress();
- foreach ($expectedShippingAddressData as $field => $value) {
- $this->assertEquals(
- $value,
- $shippingAddress->getData($field),
- "'{$field}' value in quote shipping address is invalid."
- );
- }
- }
- /**
- * @magentoDataFixture Magento/Catalog/_files/product_simple_duplicated.php
- * @return void
- */
- public function testAddProductUpdateItem(): void
- {
- /** @var Quote $quote */
- $quote = $this->objectManager->create(Quote::class);
- $quote->load('test01', 'reserved_order_id');
- $productStockQty = 100;
- $productRepository = $this->objectManager->create(
- ProductRepositoryInterface::class
- );
- $product = $productRepository->get('simple-1', false, null, true);
- $quote->addProduct($product, 50);
- $quote->setTotalsCollectedFlag(false)->collectTotals();
- $this->assertEquals(50, $quote->getItemsQty());
- $quote->addProduct($product, 50);
- $quote->setTotalsCollectedFlag(false)->collectTotals();
- $this->assertEquals(100, $quote->getItemsQty());
- $params = [
- 'related_product' => '',
- 'product' => $product->getId(),
- 'qty' => 1,
- 'id' => 0
- ];
- $updateParams = new \Magento\Framework\DataObject($params);
- $quote->updateItem($updateParams['id'], $updateParams);
- $quote->setTotalsCollectedFlag(false)->collectTotals();
- $this->assertEquals(1, $quote->getItemsQty());
- $this->expectException(\Magento\Framework\Exception\LocalizedException::class);
- // TODO: fix test or implementation as described in https://github.com/magento-engcom/msi/issues/1037
- // $this->expectExceptionMessage('The requested qty is not available');
- $updateParams['qty'] = $productStockQty + 1;
- $quote->updateItem($updateParams['id'], $updateParams);
- }
- /**
- * Prepare quote for testing assignCustomerWithAddressChange method.
- *
- * Customer with two addresses created. First address is default billing, second is default shipping.
- *
- * @param Quote $quote
- * @return CustomerInterface
- */
- protected function _prepareQuoteForTestAssignCustomerWithAddressChange(Quote $quote): CustomerInterface
- {
- $customerRepository = $this->objectManager->create(
- CustomerRepositoryInterface::class
- );
- $fixtureCustomerId = 1;
- /** @var \Magento\Customer\Model\Customer $customer */
- $customer = $this->objectManager->create(\Magento\Customer\Model\Customer::class);
- $fixtureSecondAddressId = 2;
- $customer->load($fixtureCustomerId)->setDefaultShipping($fixtureSecondAddressId)->save();
- $customerData = $customerRepository->getById($fixtureCustomerId);
- $this->assertEmpty(
- $quote->getBillingAddress()->getId(),
- "Precondition failed: billing address should be empty."
- );
- $this->assertEmpty(
- $quote->getShippingAddress()->getId(),
- "Precondition failed: shipping address should be empty."
- );
- return $customerData;
- }
- /**
- * @param string $email
- * @param array $customerData
- * @return array
- */
- protected function changeEmailInCustomerData(string $email, array $customerData): array
- {
- $customerData[\Magento\Customer\Model\Data\Customer::EMAIL] = $email;
- return $customerData;
- }
- /**
- * @param array $customerData
- * @return array
- */
- protected function removeIdFromCustomerData(array $customerData): array
- {
- unset($customerData[\Magento\Customer\Model\Data\Customer::ID]);
- return $customerData;
- }
- /**
- * @return array
- */
- protected function _getCustomerDataArray(): array
- {
- return [
- Customer::CONFIRMATION => 'test',
- Customer::CREATED_AT => '2/3/2014',
- Customer::CREATED_IN => 'Default',
- Customer::DEFAULT_BILLING => 'test',
- Customer::DEFAULT_SHIPPING => 'test',
- Customer::DOB => '2014-02-03 00:00:00',
- Customer::EMAIL => 'qa@example.com',
- Customer::FIRSTNAME => 'Joe',
- Customer::GENDER => 0,
- Customer::GROUP_ID => \Magento\Customer\Model\GroupManagement::NOT_LOGGED_IN_ID,
- Customer::ID => 1,
- Customer::LASTNAME => 'Dou',
- Customer::MIDDLENAME => 'Ivan',
- Customer::PREFIX => 'Dr.',
- Customer::STORE_ID => 1,
- Customer::SUFFIX => 'Jr.',
- Customer::TAXVAT => 1,
- Customer::WEBSITE_ID => 1
- ];
- }
- /**
- * Test to verify that reserved_order_id will be changed if it already in used
- *
- * @magentoDataFixture Magento/Sales/_files/order.php
- * @magentoDataFixture Magento/Quote/_files/empty_quote.php
- * @return void
- */
- public function testReserveOrderId(): void
- {
- /** @var Quote $quote */
- $quote = $this->objectManager->create(Quote::class);
- $quote->load('reserved_order_id', 'reserved_order_id');
- $quote->reserveOrderId();
- $this->assertEquals('reserved_order_id', $quote->getReservedOrderId());
- $quote->setReservedOrderId('100000001');
- $quote->reserveOrderId();
- $this->assertNotEquals('100000001', $quote->getReservedOrderId());
- }
- /**
- * Test to verify that disabled product cannot be added to cart
- * @magentoDataFixture Magento/Quote/_files/is_not_salable_product.php
- * @return void
- */
- public function testAddedProductToQuoteIsSalable(): void
- {
- $productId = 99;
- /** @var ProductRepository $productRepository */
- $productRepository = $this->objectManager->get(ProductRepository::class);
- /** @var Quote $quote */
- $product = $productRepository->getById($productId, false, null, true);
- $this->expectException(LocalizedException::class);
- $this->expectExceptionMessage('Product that you are trying to add is not available.');
- $quote = $this->objectManager->create(Quote::class);
- $quote->addProduct($product);
- }
- /**
- * @magentoDataFixture Magento/Sales/_files/quote.php
- * @magentoDataFixture Magento/Catalog/_files/product_simple.php
- * @return void
- */
- public function testGetItemById(): void
- {
- $quote = $this->objectManager->create(Quote::class);
- $quote->load('test01', 'reserved_order_id');
- $quoteItem = $this->objectManager->create(\Magento\Quote\Model\Quote\Item::class);
- $productRepository = $this->objectManager->create(ProductRepositoryInterface::class);
- $product = $productRepository->get('simple');
- $quoteItem->setProduct($product);
- $quote->addItem($quoteItem);
- $quote->save();
- $this->assertInstanceOf(\Magento\Quote\Model\Quote\Item::class, $quote->getItemById($quoteItem->getId()));
- $this->assertEquals($quoteItem->getId(), $quote->getItemById($quoteItem->getId())->getId());
- }
- /**
- * Tests of quotes merging.
- *
- * @param int|null $guestItemGiftMessageId
- * @param int|null $customerItemGiftMessageId
- * @param int|null $guestOrderGiftMessageId
- * @param int|null $customerOrderGiftMessageId
- * @param int|null $expectedItemGiftMessageId
- * @param int|null $expectedOrderGiftMessageId
- *
- * @magentoDataFixture Magento/Sales/_files/quote.php
- * @dataProvider giftMessageDataProvider
- * @throws LocalizedException
- * @return void
- */
- public function testMerge(
- $guestItemGiftMessageId,
- $customerItemGiftMessageId,
- $guestOrderGiftMessageId,
- $customerOrderGiftMessageId,
- $expectedItemGiftMessageId,
- $expectedOrderGiftMessageId
- ): void {
- $productRepository = $this->objectManager->create(ProductRepositoryInterface::class);
- $product = $productRepository->get('simple', false, null, true);
- /** @var Quote $quote */
- $guestQuote = $this->getQuote('test01');
- $guestQuote->setGiftMessageId($guestOrderGiftMessageId);
- /** @var Quote $customerQuote */
- $customerQuote = $this->objectManager->create(Quote::class);
- $customerQuote->setReservedOrderId('test02')
- ->setStoreId($guestQuote->getStoreId())
- ->addProduct($product);
- $customerQuote->setGiftMessageId($customerOrderGiftMessageId);
- $guestItem = $guestQuote->getItemByProduct($product);
- $guestItem->setGiftMessageId($guestItemGiftMessageId);
- $customerItem = $customerQuote->getItemByProduct($product);
- $customerItem->setGiftMessageId($customerItemGiftMessageId);
- $customerQuote->merge($guestQuote);
- $mergedItemItem = $customerQuote->getItemByProduct($product);
- self::assertEquals($expectedOrderGiftMessageId, $customerQuote->getGiftMessageId());
- self::assertEquals($expectedItemGiftMessageId, $mergedItemItem->getGiftMessageId());
- }
- /**
- * Provides order- and item-level gift message Id.
- *
- * @return array
- */
- public function giftMessageDataProvider(): array
- {
- return [
- [
- 'guestItemId' => null,
- 'customerItemId' => 1,
- 'guestOrderId' => null,
- 'customerOrderId' => 11,
- 'expectedItemId' => 1,
- 'expectedOrderId' => 11
- ],
- [
- 'guestItemId' => 1,
- 'customerItemId' => 2,
- 'guestOrderId' => 11,
- 'customerOrderId' => 22,
- 'expectedItemId' => 1,
- 'expectedOrderId' => 11
- ]
- ];
- }
- /**
- * Gets quote by reserved order id.
- *
- * @param string $reservedOrderId
- * @return Quote
- */
- private function getQuote(string $reservedOrderId): Quote
- {
- /** @var SearchCriteriaBuilder $searchCriteriaBuilder */
- $searchCriteriaBuilder = $this->objectManager->get(SearchCriteriaBuilder::class);
- $searchCriteria = $searchCriteriaBuilder->addFilter('reserved_order_id', $reservedOrderId)
- ->create();
- /** @var CartRepositoryInterface $quoteRepository */
- $quoteRepository = $this->objectManager->get(CartRepositoryInterface::class);
- $items = $quoteRepository->getList($searchCriteria)->getItems();
- return array_pop($items);
- }
- }
|