1008 lines
39 KiB
PHP
Executable File
1008 lines
39 KiB
PHP
Executable File
<?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;
|
|
}
|
|
}
|