magento2-docker/dev/tests/integration/testsuite/Magento/Sales/Model/AdminOrder/CreateTest.php

1008 lines
39 KiB
PHP

<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\Sales\Model\AdminOrder;
use Magento\Backend\Model\Session\Quote as SessionQuote;
use Magento\Customer\Api\AddressRepositoryInterface;
use Magento\Customer\Api\CustomerRepositoryInterface;
use Magento\Customer\Model\Customer;
use Magento\Customer\Model\CustomerRegistry;
use Magento\Framework\Message\ManagerInterface;
use Magento\Framework\Registry;
use Magento\Quote\Model\Quote;
use Magento\Sales\Api\Data\OrderAddressExtensionInterface;
use Magento\Sales\Api\Data\OrderAddressExtensionInterfaceFactory;
use Magento\Sales\Api\OrderManagementInterface;
use Magento\Sales\Model\Order;
use Magento\Sales\Model\AdminOrder\EmailSender;
use Magento\TestFramework\Helper\Bootstrap;
use Magento\TestFramework\ObjectManager;
use PHPUnit\Framework\MockObject\MockObject;
use Symfony\Component\HttpFoundation\Response;
/**
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
* @magentoAppArea adminhtml
* @magentoAppIsolation enabled
*/
class CreateTest extends \PHPUnit\Framework\TestCase
{
/**
* @var Create
*/
private $model;
/**
* @var ManagerInterface
*/
private $messageManager;
/**
* @var EmailSender|MockObject
*/
private $emailSenderMock;
/**
* @var ObjectManager
*/
private $objectManager;
protected function setUp(): void
{
$this->objectManager = Bootstrap::getObjectManager();
$this->messageManager = $this->objectManager->get(ManagerInterface::class);
$this->emailSenderMock = $this->getMockBuilder(EmailSender::class)
->disableOriginalConstructor()
->getMock();
$this->model =$this->objectManager->create(
Create::class,
['messageManager' => $this->messageManager, 'emailSender' => $this->emailSenderMock]
);
}
/**
* @magentoDataFixture Magento/Downloadable/_files/product_downloadable.php
* @magentoDataFixture Magento/Downloadable/_files/order_with_downloadable_product.php
* @magentoDbIsolation disabled
*/
public function testInitFromOrderShippingAddressSameAsBillingWhenEmpty()
{
/** @var $order Order */
$order = $this->objectManager->create(Order::class);
$order->loadByIncrementId('100000001');
self::assertNull($order->getShippingAddress());
$this->objectManager->get(Registry::class)->unregister('rule_data');
$this->model->initFromOrder($order);
self::assertNull($order->getShippingAddress());
}
/**
* @magentoDataFixture Magento/Customer/_files/customer.php
* @magentoDataFixture Magento/Downloadable/_files/product_downloadable.php
* @magentoDataFixture Magento/Downloadable/_files/order_with_downloadable_product_with_additional_options.php
* @magentoDbIsolation disabled
* @magentoAppIsolation enabled
*/
public function testInitFromOrderAndCreateOrderFromQuoteWithAdditionalOptions()
{
/** @var $serializer \Magento\Framework\Serialize\Serializer\Json */
$serializer = $this->objectManager->create(\Magento\Framework\Serialize\Serializer\Json::class);
/** @var $order Order */
$order = $this->objectManager->create(Order::class);
$order->loadByIncrementId('100000001');
/** @var $orderCreate \Magento\Sales\Model\AdminOrder\Create */
$orderCreate = $this->model->initFromOrder($order);
$quoteItems = $orderCreate->getQuote()->getItemsCollection();
self::assertEquals(1, $quoteItems->count());
$quoteItem = $quoteItems->getFirstItem();
$quoteItemOptions = $quoteItem->getOptionsByCode();
self::assertEquals(
$serializer->serialize(['additional_option_key' => 'additional_option_value']),
$quoteItemOptions['additional_options']->getValue()
);
$session = $this->objectManager->get(SessionQuote::class);
$session->setCustomerId(1);
$customer = $this->objectManager->create(Customer::class);
$customer->load(1)->setDefaultBilling(null)->setDefaultShipping(null)->save();
$customerMock = $this->getMockedCustomer();
$rate = $this->objectManager->create(Quote\Address\Rate::class);
$rate->setCode('freeshipping_freeshipping');
$this->model->getQuote()->setCustomer($customerMock);
$this->model->getQuote()->getShippingAddress()->addShippingRate($rate);
$this->model->getQuote()->getShippingAddress()->setCountryId('EE');
$this->model->setShippingAsBilling(0);
$this->model->setPaymentData(['method' => 'checkmo']);
$newOrder = $this->model->createOrder();
$newOrderItems = $newOrder->getItemsCollection();
self::assertEquals(1, $newOrderItems->count());
$order->loadByIncrementId('100000001');
$this->assertEquals($newOrder->getRealOrderId(), $order->getRelationChildRealId());
$this->assertEquals($newOrder->getId(), $order->getRelationChildId());
$newOrderItem = $newOrderItems->getFirstItem();
self::assertEquals(
['additional_option_key' => 'additional_option_value'],
$newOrderItem->getProductOptionByCode('additional_options')
);
Response::closeOutputBuffers(1, false);
}
/**
* @magentoDataFixture Magento/Downloadable/_files/product_downloadable.php
* @magentoDataFixture Magento/Downloadable/_files/order_with_downloadable_product.php
* @magentoDataFixture Magento/Sales/_files/order_shipping_address_same_as_billing.php
* @magentoDbIsolation disabled
*/
public function testInitFromOrderShippingAddressSameAsBillingWhenSame()
{
/** @var $order Order */
$order = $this->objectManager->create(Order::class);
$order->loadByIncrementId('100000001');
self::assertNull($order->getShippingAddress()->getSameAsBilling());
/** @var OrderAddressExtensionInterface $shippingExtAttributes */
$shippingExtAttributes = $this->objectManager->get(OrderAddressExtensionInterfaceFactory::class)
->create();
$billingExtAttributes = clone $shippingExtAttributes;
$shippingExtAttributes->setData('tmp', false);
$billingExtAttributes->setData('tmp', true);
$order->getShippingAddress()->setExtensionAttributes($shippingExtAttributes);
$order->getBillingAddress()->setExtensionAttributes($billingExtAttributes);
$this->objectManager->get(Registry::class)->unregister('rule_data');
$this->model->initFromOrder($order);
self::assertTrue($order->getShippingAddress()->getSameAsBilling());
}
/**
* @magentoDataFixture Magento/Downloadable/_files/product_downloadable.php
* @magentoDataFixture Magento/Downloadable/_files/order_with_downloadable_product.php
* @magentoDataFixture Magento/Sales/_files/order_shipping_address_different_to_billing.php
* @magentoDbIsolation disabled
*/
public function testInitFromOrderShippingAddressSameAsBillingWhenDifferent()
{
/** @var $order Order */
$order = $this->objectManager->create(Order::class);
$order->loadByIncrementId('100000002');
self::assertNull($order->getShippingAddress()->getSameAsBilling());
$this->objectManager->get(Registry::class)->unregister('rule_data');
$this->model->initFromOrder($order);
self::assertFalse($order->getShippingAddress()->getSameAsBilling());
}
/**
* @magentoDataFixture Magento/Sales/_files/order_paid_with_payflowpro.php
* @magentoDbIsolation disabled
*/
public function testInitFromOrderCcInformationDeleted()
{
/** @var $order Order */
$order = $this->objectManager->create(Order::class);
$order->loadByIncrementId('100000001');
$payment = $order->getPayment();
self::assertEquals('5', $payment->getCcExpMonth());
self::assertEquals('2016', $payment->getCcExpYear());
self::assertEquals('AE', $payment->getCcType());
self::assertEquals('0005', $payment->getCcLast4());
$this->objectManager->get(Registry::class)->unregister('rule_data');
$payment = $this->model->initFromOrder($order)->getQuote()->getPayment();
self::assertNull($payment->getCcExpMonth());
self::assertNull($payment->getCcExpYear());
self::assertNull($payment->getCcType());
self::assertNull($payment->getCcLast4());
}
/**
* @magentoDataFixture Magento/Sales/_files/order.php
* @magentoDbIsolation disabled
*/
public function testInitFromOrderWithEmptyPaymentDetails()
{
/** @var $order Order */
$order = $this->objectManager->create(Order::class);
$order->loadByIncrementId('100000001');
$this->objectManager->get(Registry::class)
->unregister('rule_data');
$initOrder = $this->model->initFromOrder($order);
$payment = $initOrder->getQuote()->getPayment();
self::assertEquals($initOrder->getQuote()->getId(), $payment->getData('quote_id'));
$payment->unsetData('quote_id');
self::assertEmpty($payment->getMethod());
self::assertEmpty($payment->getAdditionalInformation());
self::assertEmpty($payment->getAdditionalData());
self::assertEmpty($payment->getData());
}
/**
* @magentoAppIsolation enabled
*/
public function testGetCustomerWishlistNoCustomerId()
{
/** @var SessionQuote $session */
$session = $this->objectManager->create(SessionQuote::class);
$session->setCustomerId(null);
self::assertFalse(
$this->model->getCustomerWishlist(true),
'If customer ID is not set to session, false is expected to be returned.'
);
}
/**
* @magentoDataFixture Magento/Customer/_files/customer.php
* @magentoDataFixture Magento/Catalog/_files/product_simple.php
* @magentoAppIsolation enabled
* @magentoDbIsolation disabled
*/
public function testGetCustomerWishlist()
{
$customerIdFromFixture = 1;
$productIdFromFixture = 1;
/** @var SessionQuote $session */
$session = $this->objectManager->create(SessionQuote::class);
$session->setCustomerId($customerIdFromFixture);
/** Test new wishlist creation for the customer specified above */
/** @var \Magento\Wishlist\Model\Wishlist $wishlist */
$wishlist = $this->model->getCustomerWishlist(true);
self::assertInstanceOf(
\Magento\Wishlist\Model\Wishlist::class,
$wishlist,
'New Wish List is expected to be created if existing Customer does not have one yet.'
);
self::assertEquals(0, $wishlist->getItemsCount(), 'New Wish List must be empty just after creation.');
/** Add new item to wishlist and try to get it using getCustomerWishlist once again */
$wishlist->addNewItem($productIdFromFixture)->save();
$updatedWishlist = $this->model->getCustomerWishlist(true);
self::assertEquals(
1,
$updatedWishlist->getItemsCount(),
'Wish List must contain a Product which was added to it earlier.'
);
/** Try to load wishlist from cache in the class after it is deleted from DB */
$wishlist->delete();
self::assertSame(
$updatedWishlist,
$this->model->getCustomerWishlist(false),
'Wish List cached in class variable is expected to be returned.'
);
self::assertNotSame(
$updatedWishlist,
$this->model->getCustomerWishlist(true),
'New Wish List is expected to be created when cache is forced to be refreshed.'
);
}
/**
* @magentoDbIsolation enabled
*/
public function testSetBillingAddress()
{
$addressData = $this->getValidAddressData();
/** Validate data before creating address object */
$this->model->setIsValidate(true)->setBillingAddress($addressData);
self::assertInstanceOf(
Quote\Address::class,
$this->model->getBillingAddress(),
'Billing address object was not created.'
);
$expectedAddressData = array_merge(
$addressData,
[
'address_type' => 'billing',
'quote_id' => $this->model->getQuote()->getId(),
'street' => "Line1\nLine2",
'save_in_address_book' => 0,
'region' => '',
'region_id' => 1,
]
);
$result = $this->model->getBillingAddress()->getData();
foreach ($expectedAddressData as $key => $value) {
self::assertArrayHasKey($key, $result);
self::assertEquals($value, $result[$key]);
}
}
/**
* @magentoDataFixture Magento/Customer/_files/customer.php
* @magentoDbIsolation disabled
*/
public function testSetBillingAddressValidationErrors()
{
$customerIdFromFixture = 1;
/** @var SessionQuote $session */
$session = $this->objectManager->create(SessionQuote::class);
$session->setCustomerId($customerIdFromFixture);
$invalidAddressData = array_merge($this->getValidAddressData(), ['firstname' => '', 'lastname' => '']);
/**
* Note that validation errors are collected during setBillingAddress() call in the internal class variable,
* but they are not set to message manager at this step.
* They are set to message manager only during createOrder() call.
*/
$this->model->setIsValidate(true)->setBillingAddress($invalidAddressData);
try {
$this->model->createOrder();
$this->fail('Validation errors are expected to lead to exception during createOrder() call.');
} catch (\Magento\Framework\Exception\LocalizedException $e) {
/** createOrder is expected to throw exception with empty message when validation error occurs */
}
$errorMessages = [];
/** @var $validationError \Magento\Framework\Message\Error */
foreach ($this->messageManager->getMessages()->getItems() as $validationError) {
$errorMessages[] = $validationError->getText();
}
self::assertTrue(
in_array('Billing Address: "First Name" is a required value.', $errorMessages),
'Expected validation message is absent.'
);
self::assertTrue(
in_array('Billing Address: "Last Name" is a required value.', $errorMessages),
'Expected validation message is absent.'
);
}
/**
* @magentoDataFixture Magento/Catalog/_files/product_simple.php
* @magentoAppIsolation enabled
*/
public function testCreateOrderNewCustomerDifferentAddresses()
{
$productIdFromFixture = 1;
$shippingMethod = 'freeshipping_freeshipping';
$paymentMethod = 'checkmo';
$shippingAddressAsBilling = 0;
$customerEmail = 'new_customer@example.com';
$firstNameForShippingAddress = 'FirstNameForShipping';
$orderData = [
'currency' => 'USD',
'account' => ['group_id' => '1', 'email' => $customerEmail],
'billing_address' => array_merge($this->getValidAddressData(), ['save_in_address_book' => '1']),
'shipping_address' => array_merge(
$this->getValidAddressData(),
['save_in_address_book' => '1', 'firstname' => $firstNameForShippingAddress]
),
'shipping_method' => $shippingMethod,
'comment' => ['customer_note' => ''],
'send_confirmation' => true,
];
$paymentData = ['method' => $paymentMethod];
$this->preparePreconditionsForCreateOrder(
$productIdFromFixture,
$customerEmail,
$shippingMethod,
$shippingAddressAsBilling,
$paymentData,
$orderData,
$paymentMethod
);
$order = $this->model->createOrder();
$newBillAddress = $order->getBillingAddress();
self::assertEquals($this->model->getQuote()->getCustomerFirstname(), $newBillAddress->getFirstname());
self::assertEquals($this->model->getQuote()->getCustomerLastname(), $newBillAddress->getLastname());
self::assertEquals($order->getCustomerFirstname(), $newBillAddress->getFirstname());
self::assertEquals($order->getCustomerLastname(), $newBillAddress->getLastname());
$this->verifyCreatedOrder($order, $shippingMethod);
/** @var Customer $customer */
$customer = $this->objectManager->create(Customer::class);
$customer->load($order->getCustomerId());
self::assertEquals(
$firstNameForShippingAddress,
$customer->getPrimaryShippingAddress()->getFirstname(),
'Shipping address is saved incorrectly.'
);
}
/**
* @magentoDataFixture Magento/Catalog/_files/product_simple_with_decimal_qty.php
* @magentoDbIsolation disabled
* @magentoAppIsolation enabled
*/
public function testCreateOrderNewCustomer()
{
$productIdFromFixture = 1;
$shippingMethod = 'freeshipping_freeshipping';
$paymentMethod = 'checkmo';
$shippingAddressAsBilling = 1;
$customerEmail = 'new_customer@example.com';
$orderData = [
'currency' => 'USD',
'account' => ['group_id' => '1', 'email' => $customerEmail],
'billing_address' => array_merge($this->getValidAddressData(), ['save_in_address_book' => '1']),
'shipping_method' => $shippingMethod,
'comment' => ['customer_note' => ''],
'send_confirmation' => false,
];
$paymentData = ['method' => $paymentMethod];
$this->preparePreconditionsForCreateOrder(
$productIdFromFixture,
$customerEmail,
$shippingMethod,
$shippingAddressAsBilling,
$paymentData,
$orderData,
$paymentMethod
);
$order = $this->model->createOrder();
//Check, order considering decimal qty in product.
foreach ($order->getItems() as $orderItem) {
self::assertTrue($orderItem->getIsQtyDecimal());
}
$this->verifyCreatedOrder($order, $shippingMethod);
}
/**
* Tests order creation with new customer after failed first place order action.
*
* @magentoDataFixture Magento/Catalog/_files/product_simple.php
* @magentoDbIsolation disabled
* @magentoAppIsolation enabled
* @dataProvider createOrderNewCustomerWithFailedFirstPlaceOrderActionDataProvider
* @param string $customerEmailFirstAttempt
* @param string $customerEmailSecondAttempt
*/
public function testCreateOrderNewCustomerWithFailedFirstPlaceOrderAction(
$customerEmailFirstAttempt,
$customerEmailSecondAttempt
) {
$productIdFromFixture = 1;
$shippingMethod = 'freeshipping_freeshipping';
$paymentMethod = 'checkmo';
$shippingAddressAsBilling = 1;
$customerEmail = $customerEmailFirstAttempt;
$orderData = [
'currency' => 'USD',
'account' => ['group_id' => '1', 'email' => $customerEmail],
'billing_address' => array_merge($this->getValidAddressData(), ['save_in_address_book' => '1']),
'shipping_method' => $shippingMethod,
'comment' => ['customer_note' => ''],
'send_confirmation' => false,
];
$paymentData = ['method' => $paymentMethod];
$this->preparePreconditionsForCreateOrder(
$productIdFromFixture,
$customerEmail,
$shippingMethod,
$shippingAddressAsBilling,
$paymentData,
$orderData,
$paymentMethod
);
// Emulates failing place order action
$orderManagement = $this->getMockForAbstractClass(OrderManagementInterface::class);
$orderManagement->method('place')
->willThrowException(new \Exception('Can\'t place order'));
$this->objectManager->addSharedInstance($orderManagement, OrderManagementInterface::class);
try {
$this->model->createOrder();
} catch (\Exception $e) {
$this->objectManager->removeSharedInstance(OrderManagementInterface::class);
}
$customerEmail = $customerEmailSecondAttempt ? :$this->model->getQuote()->getCustomer()->getEmail();
$orderData['account']['email'] = $customerEmailSecondAttempt;
$this->preparePreconditionsForCreateOrder(
$productIdFromFixture,
$customerEmail,
$shippingMethod,
$shippingAddressAsBilling,
$paymentData,
$orderData,
$paymentMethod
);
$order = $this->model->createOrder();
$this->verifyCreatedOrder($order, $shippingMethod);
}
/**
* Email before and after failed first place order action.
*
* @case #1 Is the same.
* @case #2 Changed after failed first place order action.
* @return array
*/
public function createOrderNewCustomerWithFailedFirstPlaceOrderActionDataProvider()
{
return [
1 => ['customer@email.com', 'customer@email.com'],
2 => ['customer@email.com', 'changed_customer@email.com'],
];
}
/**
* @magentoDataFixture Magento/Catalog/_files/product_simple.php
* @magentoDataFixture Magento/Customer/_files/customer.php
* @magentoDbIsolation disabled
* @magentoAppIsolation enabled
*/
public function testCreateOrderExistingCustomerDifferentAddresses()
{
$productIdFromFixture = 1;
$customerIdFromFixture = 1;
$customerEmailFromFixture = 'customer@example.com';
$shippingMethod = 'freeshipping_freeshipping';
$paymentMethod = 'checkmo';
$shippingAddressAsBilling = 0;
$firstNameForShippingAddress = 'FirstNameForShipping';
$orderData = [
'currency' => 'USD',
'billing_address' => array_merge($this->getValidAddressData(), ['save_in_address_book' => '1']),
'shipping_address' => array_merge(
$this->getValidAddressData(),
['save_in_address_book' => '1', 'firstname' => $firstNameForShippingAddress]
),
'shipping_method' => $shippingMethod,
'comment' => ['customer_note' => ''],
'send_confirmation' => false,
];
$paymentData = ['method' => $paymentMethod];
$this->preparePreconditionsForCreateOrder(
$productIdFromFixture,
$customerEmailFromFixture,
$shippingMethod,
$shippingAddressAsBilling,
$paymentData,
$orderData,
$paymentMethod,
$customerIdFromFixture
);
$customerMock = $this->getMockedCustomer();
$this->model->getQuote()->setCustomer($customerMock);
$order = $this->model->createOrder();
$this->verifyCreatedOrder($order, $shippingMethod);
$this->objectManager->get(CustomerRegistry::class)
->remove($order->getCustomerId());
$customer = $this->objectManager->get(CustomerRepositoryInterface::class)
->getById($order->getCustomerId());
$address = $this->objectManager->get(AddressRepositoryInterface::class)
->getById($customer->getDefaultShipping());
self::assertEquals(
$firstNameForShippingAddress,
$address->getFirstname(),
'Shipping address is saved incorrectly.'
);
}
/**
* @magentoDataFixture Magento/Catalog/_files/product_simple.php
* @magentoDataFixture Magento/Customer/_files/customer.php
* @magentoDbIsolation disabled
* @magentoAppIsolation enabled
*/
public function testCreateOrderExistingCustomer()
{
$productIdFromFixture = 1;
$customerIdFromFixture = 1;
$customerEmailFromFixture = 'customer@example.com';
$shippingMethod = 'freeshipping_freeshipping';
$paymentMethod = 'checkmo';
$shippingAddressAsBilling = 1;
$orderData = [
'currency' => 'USD',
'billing_address' => array_merge($this->getValidAddressData(), ['save_in_address_book' => '1']),
'shipping_method' => $shippingMethod,
'comment' => ['customer_note' => ''],
'send_confirmation' => false,
];
$paymentData = ['method' => $paymentMethod];
$this->preparePreconditionsForCreateOrder(
$productIdFromFixture,
$customerEmailFromFixture,
$shippingMethod,
$shippingAddressAsBilling,
$paymentData,
$orderData,
$paymentMethod,
$customerIdFromFixture
);
$customerMock = $this->getMockedCustomer();
$this->model->getQuote()->setCustomer($customerMock);
$order = $this->model->createOrder();
if ($this->model->getSendConfirmation() && !$order->getEmailSent()) {
$this->emailSenderMock->expects($this->once())
->method('send')
->willReturn(true);
} else {
$this->emailSenderMock->expects($this->never())->method('send');
}
$this->verifyCreatedOrder($order, $shippingMethod);
}
/**
* @magentoDataFixture Magento/Sales/_files/quote.php
* @magentoDataFixture Magento/Customer/_files/customer.php
* @magentoAppIsolation enabled
* @magentoDbIsolation disabled
*/
public function testGetCustomerCartExistingCart()
{
$fixtureCustomerId = 1;
/** Preconditions */
/** @var SessionQuote $session */
$session = $this->objectManager->create(SessionQuote::class);
$session->setCustomerId($fixtureCustomerId);
/** @var $quoteFixture Quote */
$quoteFixture = $this->objectManager->create(Quote::class);
$quoteFixture->load('test01', 'reserved_order_id');
$quoteFixture->setCustomerIsGuest(false)->setCustomerId($fixtureCustomerId)->save();
/** SUT execution */
$customerQuote = $this->model->getCustomerCart();
self::assertEquals($quoteFixture->getId(), $customerQuote->getId(), 'Quote ID is invalid.');
/** Try to load quote once again to ensure that caching works correctly */
$customerQuoteFromCache = $this->model->getCustomerCart();
self::assertSame($customerQuote, $customerQuoteFromCache, 'Customer quote caching does not work correctly.');
}
/**
* @magentoDataFixture Magento/Sales/_files/quote.php
* @magentoDataFixture Magento/Customer/_files/customer.php
* @magentoAppIsolation enabled
* @magentoDbIsolation disabled
*/
public function testMoveQuoteItemToCart()
{
$fixtureCustomerId = 1;
/** Preconditions */
/** @var SessionQuote $session */
$session = $this->objectManager->create(SessionQuote::class);
$session->setCustomerId($fixtureCustomerId);
/** @var $quoteFixture Quote */
$quoteFixture = $this->objectManager->create(Quote::class);
$quoteFixture->load('test01', 'reserved_order_id');
$quoteFixture->setCustomerIsGuest(false)->setCustomerId($fixtureCustomerId)->save();
$customerQuote = $this->model->getCustomerCart();
$item = $customerQuote->getAllVisibleItems()[0];
$this->model->moveQuoteItem($item, 'cart', 3);
self::assertEquals(4, $item->getQty(), 'Number of Qty isn\'t correct for Quote item.');
self::assertEquals(3, $item->getQtyToAdd(), 'Number of added qty isn\'t correct for Quote item.');
}
/**
* @magentoAppIsolation enabled
* @magentoDbIsolation disabled
* @magentoDataFixture Magento/Customer/_files/customer.php
*/
public function testGetCustomerCartNewCart()
{
$customerIdFromFixture = 1;
/** Preconditions */
/** @var SessionQuote $session */
$session = $this->objectManager->create(SessionQuote::class);
$session->setCustomerId($customerIdFromFixture);
/** SUT execution */
$customerQuote = $this->model->getCustomerCart();
self::assertInstanceOf(Quote::class, $customerQuote);
self::assertEmpty($customerQuote->getData());
}
/**
* Prepare preconditions for createOrder method invocation.
*
* @param int $productIdFromFixture
* @param string $customerEmail
* @param string $shippingMethod
* @param int $shippingAddressAsBilling
* @param array $paymentData
* @param array $orderData
* @param string $paymentMethod
* @param int|null $customerIdFromFixture
*/
private function preparePreconditionsForCreateOrder(
$productIdFromFixture,
$customerEmail,
$shippingMethod,
$shippingAddressAsBilling,
$paymentData,
$orderData,
$paymentMethod,
$customerIdFromFixture = null
) {
/** Disable product options */
/** @var \Magento\Catalog\Model\Product $product */
$product = $this->objectManager->create(\Magento\Catalog\Model\Product::class);
$product->load($productIdFromFixture)->setHasOptions(false)->save();
/** Set current customer */
/** @var SessionQuote $session */
$session = $this->objectManager->get(SessionQuote::class);
if ($customerIdFromFixture !== null) {
$session->setCustomerId($customerIdFromFixture);
/** Unset fake IDs for default billing and shipping customer addresses */
/** @var Customer $customer */
$customer = $this->objectManager->create(Customer::class);
if (empty($orderData['checkForDefaultStreet'])) {
$customer->load($customerIdFromFixture)->setDefaultBilling(null)->setDefaultShipping(null)->save();
}
} else {
/**
* Customer ID must be set to session to pass \Magento\Sales\Model\AdminOrder\Create::_validate()
* This code emulates order placement via admin panel.
*/
$session->setCustomerId(0);
}
/** Emulate availability of shipping method (all are disabled by default) */
/** @var $rate Quote\Address\Rate */
$rate = $this->objectManager->create(Quote\Address\Rate::class);
$rate->setCode($shippingMethod);
$this->model->getQuote()->getShippingAddress()->addShippingRate($rate);
$this->model->setShippingAsBilling($shippingAddressAsBilling);
$this->model->addProduct($productIdFromFixture, ['qty' => 1]);
$this->model->setPaymentData($paymentData);
$this->model->setIsValidate(true)->importPostData($orderData);
/** Check preconditions */
self::assertEquals(
0,
$this->messageManager->getMessages()->getCount(),
"Precondition failed: Errors occurred before SUT execution."
);
/** Selectively check quote data */
$createOrderData = $this->model->getData();
self::assertEquals(
$shippingMethod,
$createOrderData['shipping_method'],
'Precondition failed: Shipping method specified in create order model is invalid'
);
self::assertEquals(
'FirstName',
$createOrderData['billing_address']['firstname'],
'Precondition failed: Address data is invalid in create order model'
);
self::assertEquals(
'Simple Product',
$this->model->getQuote()->getItemByProduct($product)->getData('name'),
'Precondition failed: Quote items data is invalid in create order model'
);
self::assertEquals(
$customerEmail,
$this->model->getQuote()->getCustomer()->getEmail(),
'Precondition failed: Customer data is invalid in create order model'
);
self::assertEquals(
$paymentMethod,
$this->model->getQuote()->getPayment()->getData('method'),
'Precondition failed: Payment method data is invalid in create order model'
);
}
/**
* Ensure that order is created correctly via createOrder().
*
* @param Order $order
* @param string $shippingMethod
*/
private function verifyCreatedOrder($order, $shippingMethod)
{
/** Selectively check order data */
$orderData = $order->getData();
self::assertNotEmpty($orderData['increment_id'], 'Order increment ID is empty.');
self::assertEquals($this->model->getQuote()->getId(), $orderData['quote_id'], 'Quote ID is invalid.');
self::assertEquals(
$this->model->getQuote()->getCustomer()->getEmail(),
$orderData['customer_email'],
'Customer email is invalid.'
);
self::assertEquals(
$this->model->getQuote()->getCustomer()->getFirstname(),
$orderData['customer_firstname'],
'Customer first name is invalid.'
);
self::assertEquals($shippingMethod, $orderData['shipping_method'], 'Shipping method is invalid.');
}
/**
* Get valid address data for address creation.
*
* @return array
*/
private function getValidAddressData()
{
return [
'prefix' => 'prefix',
'firstname' => 'FirstName',
'middlename' => 'MiddleName',
'lastname' => 'LastName',
'suffix' => 'suffix',
'company' => 'Company Name',
'street' => [0 => 'Line1', 1 => 'Line2'],
'city' => 'City',
'country_id' => 'US',
'region' => [
'region' => '',
'region_id' => '1',
],
'postcode' => '76868',
'telephone' => '+8709273498729384',
'fax' => '',
'vat_id' => ''
];
}
/**
* @magentoDataFixture Magento/Customer/_files/customer.php
* @magentoDataFixture Magento/Customer/_files/customer_address_attribute_update.php
* @magentoDbIsolation disabled
*/
public function testSetBillingAddressStreetValidationErrors()
{
$customerIdFromFixture = 1;
/** @var SessionQuote $session */
$session = $this->objectManager->create(SessionQuote::class);
$session->setCustomerId($customerIdFromFixture);
$invalidAddressData = array_merge($this->getValidAddressData(), ['street' => [0 => 'Whit`e', 1 => 'Lane']]);
/**
* Note that validation errors are collected during setBillingAddress() call in the internal class variable,
* but they are not set to message manager at this step.
* They are set to message manager only during createOrder() call.
*/
$this->model->setIsValidate(true)->setBillingAddress($invalidAddressData);
$this->model->setIsValidate(true)->setShippingAddress($invalidAddressData);
try {
$this->model->createOrder();
$this->fail('Validation errors are expected to lead to exception during createOrder() call.');
} catch (\Magento\Framework\Exception\LocalizedException $e) {
/** createOrder is expected to throw exception with empty message when validation error occurs */
}
$errorMessages = [];
/** @var $validationError \Magento\Framework\Message\Error */
foreach ($this->messageManager->getMessages()->getItems() as $validationError) {
$errorMessages[] = $validationError->getText();
}
self::assertTrue(
in_array(
'Billing Address: "Street Address" contains non-alphabetic or non-numeric characters.',
$errorMessages
),
'Expected validation message is absent.'
);
self::assertTrue(
in_array(
'Shipping Address: "Street Address" contains non-alphabetic or non-numeric characters.',
$errorMessages
),
'Expected validation message is absent.'
);
}
/**
* If the current street address for a customer differs with the default one (saved in customer address book)
* then the updated validation rule (`input_validation`) should applied on current one while placing a new order.
*
* @magentoDataFixture Magento/Customer/_files/customer_address_street_attribute.php
* @magentoDbIsolation disabled
* @magentoAppIsolation enabled
*/
public function testCreateOrderExistingCustomerWhenDefaultAddressDiffersWithNew()
{
$productIdFromFixture = 1;
$customerIdFromFixture = 1;
$customerEmailFromFixture = 'customer@example.com';
$shippingMethod = 'freeshipping_freeshipping';
$paymentMethod = 'checkmo';
$shippingAddressAsBilling = 1;
$invalidAddressData = array_merge($this->getValidAddressData(), ['street' => [0 => 'White', 1 => 'Lane']]);
// Any change in default customer address should be treated as new address by setting up
// `customer_address_id` to `null` in billing and shipping addresses.
$address = array_merge($invalidAddressData, ['save_in_address_book' => '1', 'customer_address_id' => null]);
$orderData = [
'currency' => 'USD',
'billing_address' => $address,
'shipping_method' => $shippingMethod,
'comment' => ['customer_note' => ''],
'send_confirmation' => false,
'checkForDefaultStreet' => true,
];
$paymentData = ['method' => $paymentMethod];
$this->preparePreconditionsForCreateOrder(
$productIdFromFixture,
$customerEmailFromFixture,
$shippingMethod,
$shippingAddressAsBilling,
$paymentData,
$orderData,
$paymentMethod,
$customerIdFromFixture
);
$this->model->setBillingAddress($orderData['billing_address']);
try {
$order =$this->model->createOrder();
$orderData = $order->getData();
self::assertNotEmpty($orderData['increment_id'], 'Order increment ID is empty.');
} catch (\Magento\Framework\Exception\LocalizedException $e) {
/** createOrder is expected to throw exception with empty message when validation error occurs */
self::assertEquals('Validation is failed.', $e->getRawMessage());
}
}
/**
* Get customer mock object.
*
* @return \Magento\Customer\Model\Data\Customer
*/
private function getMockedCustomer()
{
$customerMock = $this->getMockBuilder(\Magento\Customer\Model\Data\Customer::class)
->disableOriginalConstructor()
->setMethods(
[
'getId',
'getGroupId',
'getEmail',
'_getExtensionAttributes'
]
)->getMock();
$customerMock->method('getId')
->willReturn(1);
$customerMock->method('getGroupId')
->willReturn(1);
$customerMock->method('getEmail')
->willReturn('customer@example.com');
$customerMock->method('_getExtensionAttributes')
->willReturn(null);
return $customerMock;
}
}