540 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			PHP
		
	
	
		
			Executable File
		
	
	
			
		
		
	
	
			540 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			PHP
		
	
	
		
			Executable File
		
	
	
<?php
 | 
						|
/**
 | 
						|
 * Copyright © Magento, Inc. All rights reserved.
 | 
						|
 * See COPYING.txt for license details.
 | 
						|
 */
 | 
						|
declare(strict_types=1);
 | 
						|
 | 
						|
namespace Magento\GraphQl\Quote\Customer;
 | 
						|
 | 
						|
use Magento\Quote\Model\QuoteIdMaskFactory;
 | 
						|
use Magento\Quote\Model\ResourceModel\Quote as QuoteResource;
 | 
						|
use Magento\Customer\Api\CustomerRepositoryInterface;
 | 
						|
use Magento\Framework\Registry;
 | 
						|
use Magento\Quote\Model\ResourceModel\Quote\CollectionFactory as QuoteCollectionFactory;
 | 
						|
use Magento\Sales\Api\OrderRepositoryInterface;
 | 
						|
use Magento\Sales\Model\OrderFactory;
 | 
						|
use Magento\Sales\Model\ResourceModel\Order\CollectionFactory;
 | 
						|
use Magento\TestFramework\Helper\Bootstrap;
 | 
						|
use Magento\TestFramework\TestCase\GraphQlAbstract;
 | 
						|
 | 
						|
/**
 | 
						|
 * End to checkout tests for customer
 | 
						|
 */
 | 
						|
class CheckoutEndToEndTest extends GraphQlAbstract
 | 
						|
{
 | 
						|
    /**
 | 
						|
     * @var Registry
 | 
						|
     */
 | 
						|
    private $registry;
 | 
						|
 | 
						|
    /**
 | 
						|
     * @var QuoteCollectionFactory
 | 
						|
     */
 | 
						|
    private $quoteCollectionFactory;
 | 
						|
 | 
						|
    /**
 | 
						|
     * @var QuoteResource
 | 
						|
     */
 | 
						|
    private $quoteResource;
 | 
						|
 | 
						|
    /**
 | 
						|
     * @var QuoteIdMaskFactory
 | 
						|
     */
 | 
						|
    private $quoteIdMaskFactory;
 | 
						|
 | 
						|
    /**
 | 
						|
     * @var CustomerRepositoryInterface
 | 
						|
     */
 | 
						|
    private $customerRepository;
 | 
						|
 | 
						|
    /**
 | 
						|
     * @var CollectionFactory
 | 
						|
     */
 | 
						|
    private $orderCollectionFactory;
 | 
						|
 | 
						|
    /**
 | 
						|
     * @var OrderRepositoryInterface
 | 
						|
     */
 | 
						|
    private $orderRepository;
 | 
						|
 | 
						|
    /**
 | 
						|
     * @var OrderFactory
 | 
						|
     */
 | 
						|
    private $orderFactory;
 | 
						|
 | 
						|
    /**
 | 
						|
     * @var array
 | 
						|
     */
 | 
						|
    private $headers = [];
 | 
						|
 | 
						|
    /**
 | 
						|
     * @inheritdoc
 | 
						|
     */
 | 
						|
    protected function setUp(): void
 | 
						|
    {
 | 
						|
        $objectManager = Bootstrap::getObjectManager();
 | 
						|
 | 
						|
        $this->registry = $objectManager->get(Registry::class);
 | 
						|
        $this->quoteCollectionFactory = $objectManager->get(QuoteCollectionFactory::class);
 | 
						|
        $this->quoteResource = $objectManager->get(QuoteResource::class);
 | 
						|
        $this->quoteIdMaskFactory = $objectManager->get(QuoteIdMaskFactory::class);
 | 
						|
        $this->customerRepository = $objectManager->get(CustomerRepositoryInterface::class);
 | 
						|
        $this->orderCollectionFactory = $objectManager->get(CollectionFactory::class);
 | 
						|
        $this->orderRepository = $objectManager->get(OrderRepositoryInterface::class);
 | 
						|
        $this->orderFactory = $objectManager->get(OrderFactory::class);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * @magentoApiDataFixture Magento/Catalog/_files/products_with_layered_navigation_attribute.php
 | 
						|
     */
 | 
						|
    public function testCheckoutWorkflow()
 | 
						|
    {
 | 
						|
        $quantity = 2;
 | 
						|
 | 
						|
        $this->createCustomer();
 | 
						|
        $token = $this->loginCustomer();
 | 
						|
        $this->headers = ['Authorization' => 'Bearer ' . $token];
 | 
						|
 | 
						|
        $sku = $this->findProduct();
 | 
						|
        $cartId = $this->createEmptyCart();
 | 
						|
        $this->addProductToCart($cartId, $quantity, $sku);
 | 
						|
 | 
						|
        $this->setBillingAddress($cartId);
 | 
						|
        $shippingMethod = $this->setShippingAddress($cartId);
 | 
						|
 | 
						|
        $paymentMethod = $this->setShippingMethod($cartId, $shippingMethod);
 | 
						|
        $this->setPaymentMethod($cartId, $paymentMethod);
 | 
						|
 | 
						|
        $orderIncrementId = $this->placeOrder($cartId);
 | 
						|
 | 
						|
        $order = $this->orderFactory->create();
 | 
						|
        $order->loadByIncrementId($orderIncrementId);
 | 
						|
 | 
						|
        $this->checkOrderInHistory($orderIncrementId);
 | 
						|
        $this->assertNotEmpty($order->getEmailSent());
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * @return void
 | 
						|
     */
 | 
						|
    private function createCustomer(): void
 | 
						|
    {
 | 
						|
        $query = <<<QUERY
 | 
						|
mutation {
 | 
						|
  createCustomer(
 | 
						|
    input: {
 | 
						|
      firstname: "endto"
 | 
						|
      lastname: "endtester"
 | 
						|
      email: "customer@example.com"
 | 
						|
      password: "123123Qa"
 | 
						|
    }
 | 
						|
  ) {
 | 
						|
    customer {
 | 
						|
      id
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
QUERY;
 | 
						|
        $this->graphQlMutation($query);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * @return string
 | 
						|
     */
 | 
						|
    private function loginCustomer(): string
 | 
						|
    {
 | 
						|
        $query = <<<QUERY
 | 
						|
mutation {
 | 
						|
  generateCustomerToken(
 | 
						|
    email: "customer@example.com"
 | 
						|
    password: "123123Qa"
 | 
						|
  ) {
 | 
						|
    token
 | 
						|
  }
 | 
						|
}
 | 
						|
QUERY;
 | 
						|
        $response = $this->graphQlMutation($query);
 | 
						|
        self::assertArrayHasKey('generateCustomerToken', $response);
 | 
						|
        self::assertArrayHasKey('token', $response['generateCustomerToken']);
 | 
						|
        self::assertNotEmpty($response['generateCustomerToken']['token']);
 | 
						|
 | 
						|
        return $response['generateCustomerToken']['token'];
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * @return string
 | 
						|
     */
 | 
						|
    private function findProduct(): string
 | 
						|
    {
 | 
						|
        $query = <<<QUERY
 | 
						|
{
 | 
						|
  products (
 | 
						|
    filter: {
 | 
						|
      sku: {
 | 
						|
        eq:"simple1"
 | 
						|
      }
 | 
						|
    }
 | 
						|
    pageSize: 1
 | 
						|
    currentPage: 1
 | 
						|
  ) {
 | 
						|
    items {
 | 
						|
      sku
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
QUERY;
 | 
						|
        $response = $this->graphQlQuery($query);
 | 
						|
        self::assertArrayHasKey('products', $response);
 | 
						|
        self::assertArrayHasKey('items', $response['products']);
 | 
						|
        self::assertCount(1, $response['products']['items']);
 | 
						|
 | 
						|
        $product = current($response['products']['items']);
 | 
						|
        self::assertArrayHasKey('sku', $product);
 | 
						|
        self::assertNotEmpty($product['sku']);
 | 
						|
 | 
						|
        return $product['sku'];
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * @return string
 | 
						|
     */
 | 
						|
    private function createEmptyCart(): string
 | 
						|
    {
 | 
						|
        $query = <<<QUERY
 | 
						|
mutation {
 | 
						|
  createEmptyCart
 | 
						|
}
 | 
						|
QUERY;
 | 
						|
        $response = $this->graphQlMutation($query, [], '', $this->headers);
 | 
						|
        self::assertArrayHasKey('createEmptyCart', $response);
 | 
						|
        self::assertNotEmpty($response['createEmptyCart']);
 | 
						|
 | 
						|
        return $response['createEmptyCart'];
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * @param string $cartId
 | 
						|
     * @param float $qty
 | 
						|
     * @param string $sku
 | 
						|
     * @return void
 | 
						|
     */
 | 
						|
    private function addProductToCart(string $cartId, float $qty, string $sku): void
 | 
						|
    {
 | 
						|
        $query = <<<QUERY
 | 
						|
mutation {
 | 
						|
  addSimpleProductsToCart(
 | 
						|
    input: {
 | 
						|
      cart_id: "{$cartId}"
 | 
						|
      cart_items: [
 | 
						|
        {
 | 
						|
          data: {
 | 
						|
            quantity: {$qty}
 | 
						|
            sku: "{$sku}"
 | 
						|
          }
 | 
						|
        }
 | 
						|
      ]
 | 
						|
    }
 | 
						|
  ) {
 | 
						|
    cart {
 | 
						|
      items {
 | 
						|
        quantity
 | 
						|
        product {
 | 
						|
          sku
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
QUERY;
 | 
						|
        $this->graphQlMutation($query, [], '', $this->headers);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * @param string $cartId
 | 
						|
     * @param array $auth
 | 
						|
     * @return array
 | 
						|
     */
 | 
						|
    private function setBillingAddress(string $cartId): void
 | 
						|
    {
 | 
						|
        $query = <<<QUERY
 | 
						|
mutation {
 | 
						|
  setBillingAddressOnCart(
 | 
						|
    input: {
 | 
						|
      cart_id: "{$cartId}"
 | 
						|
      billing_address: {
 | 
						|
         address: {
 | 
						|
          firstname: "test firstname"
 | 
						|
          lastname: "test lastname"
 | 
						|
          company: "test company"
 | 
						|
          street: ["test street 1", "test street 2"]
 | 
						|
          city: "test city"
 | 
						|
          postcode: "887766"
 | 
						|
          telephone: "88776655"
 | 
						|
          region: "TX"
 | 
						|
          country_code: "US"
 | 
						|
         }
 | 
						|
      }
 | 
						|
    }
 | 
						|
  ) {
 | 
						|
    cart {
 | 
						|
      billing_address {
 | 
						|
        __typename
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
QUERY;
 | 
						|
        $this->graphQlMutation($query, [], '', $this->headers);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * @param string $cartId
 | 
						|
     * @return array
 | 
						|
     */
 | 
						|
    private function setShippingAddress(string $cartId): array
 | 
						|
    {
 | 
						|
        $query = <<<QUERY
 | 
						|
mutation {
 | 
						|
  setShippingAddressesOnCart(
 | 
						|
    input: {
 | 
						|
      cart_id: "$cartId"
 | 
						|
      shipping_addresses: [
 | 
						|
        {
 | 
						|
          address: {
 | 
						|
            firstname: "test firstname"
 | 
						|
            lastname: "test lastname"
 | 
						|
            company: "test company"
 | 
						|
            street: ["test street 1", "test street 2"]
 | 
						|
            city: "test city"
 | 
						|
            region: "TX"
 | 
						|
            postcode: "887766"
 | 
						|
            country_code: "US"
 | 
						|
            telephone: "88776655"
 | 
						|
          }
 | 
						|
        }
 | 
						|
      ]
 | 
						|
    }
 | 
						|
  ) {
 | 
						|
    cart {
 | 
						|
      shipping_addresses {
 | 
						|
        available_shipping_methods {
 | 
						|
          carrier_code
 | 
						|
          method_code
 | 
						|
          amount {
 | 
						|
            value
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
QUERY;
 | 
						|
        $response = $this->graphQlMutation($query, [], '', $this->headers);
 | 
						|
        self::assertArrayHasKey('setShippingAddressesOnCart', $response);
 | 
						|
        self::assertArrayHasKey('cart', $response['setShippingAddressesOnCart']);
 | 
						|
        self::assertArrayHasKey('shipping_addresses', $response['setShippingAddressesOnCart']['cart']);
 | 
						|
        self::assertCount(1, $response['setShippingAddressesOnCart']['cart']['shipping_addresses']);
 | 
						|
 | 
						|
        $shippingAddress = current($response['setShippingAddressesOnCart']['cart']['shipping_addresses']);
 | 
						|
        self::assertArrayHasKey('available_shipping_methods', $shippingAddress);
 | 
						|
        self::assertCount(1, $shippingAddress['available_shipping_methods']);
 | 
						|
 | 
						|
        $availableShippingMethod = current($shippingAddress['available_shipping_methods']);
 | 
						|
        self::assertArrayHasKey('carrier_code', $availableShippingMethod);
 | 
						|
        self::assertNotEmpty($availableShippingMethod['carrier_code']);
 | 
						|
 | 
						|
        self::assertArrayHasKey('method_code', $availableShippingMethod);
 | 
						|
        self::assertNotEmpty($availableShippingMethod['method_code']);
 | 
						|
 | 
						|
        self::assertArrayHasKey('amount', $availableShippingMethod);
 | 
						|
        self::assertArrayHasKey('value', $availableShippingMethod['amount']);
 | 
						|
        self::assertNotEmpty($availableShippingMethod['amount']['value']);
 | 
						|
 | 
						|
        return $availableShippingMethod;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * @param string $cartId
 | 
						|
     * @param array $method
 | 
						|
     * @return array
 | 
						|
     */
 | 
						|
    private function setShippingMethod(string $cartId, array $method): array
 | 
						|
    {
 | 
						|
        $query = <<<QUERY
 | 
						|
mutation {
 | 
						|
  setShippingMethodsOnCart(input:  {
 | 
						|
    cart_id: "{$cartId}",
 | 
						|
    shipping_methods: [
 | 
						|
      {
 | 
						|
         carrier_code: "{$method['carrier_code']}"
 | 
						|
         method_code: "{$method['method_code']}"
 | 
						|
      }
 | 
						|
    ]
 | 
						|
  }) {
 | 
						|
    cart {
 | 
						|
      available_payment_methods {
 | 
						|
        code
 | 
						|
        title
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
QUERY;
 | 
						|
        $response = $this->graphQlMutation($query, [], '', $this->headers);
 | 
						|
        self::assertArrayHasKey('setShippingMethodsOnCart', $response);
 | 
						|
        self::assertArrayHasKey('cart', $response['setShippingMethodsOnCart']);
 | 
						|
        self::assertArrayHasKey('available_payment_methods', $response['setShippingMethodsOnCart']['cart']);
 | 
						|
        self::assertCount(1, $response['setShippingMethodsOnCart']['cart']['available_payment_methods']);
 | 
						|
 | 
						|
        $availablePaymentMethod = current($response['setShippingMethodsOnCart']['cart']['available_payment_methods']);
 | 
						|
        self::assertArrayHasKey('code', $availablePaymentMethod);
 | 
						|
        self::assertNotEmpty($availablePaymentMethod['code']);
 | 
						|
        self::assertArrayHasKey('title', $availablePaymentMethod);
 | 
						|
        self::assertNotEmpty($availablePaymentMethod['title']);
 | 
						|
 | 
						|
        return $availablePaymentMethod;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * @param string $cartId
 | 
						|
     * @param array $method
 | 
						|
     * @return void
 | 
						|
     */
 | 
						|
    private function setPaymentMethod(string $cartId, array $method): void
 | 
						|
    {
 | 
						|
        $query = <<<QUERY
 | 
						|
mutation {
 | 
						|
  setPaymentMethodOnCart(
 | 
						|
    input: {
 | 
						|
      cart_id: "{$cartId}"
 | 
						|
      payment_method: {
 | 
						|
        code: "{$method['code']}"
 | 
						|
      }
 | 
						|
    }
 | 
						|
  ) {
 | 
						|
    cart {
 | 
						|
      selected_payment_method {
 | 
						|
        code
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
QUERY;
 | 
						|
        $this->graphQlMutation($query, [], '', $this->headers);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * @param string $cartId
 | 
						|
     * @return string
 | 
						|
     */
 | 
						|
    private function placeOrder(string $cartId): string
 | 
						|
    {
 | 
						|
        $query = <<<QUERY
 | 
						|
mutation {
 | 
						|
  placeOrder(
 | 
						|
    input: {
 | 
						|
      cart_id: "{$cartId}"
 | 
						|
    }
 | 
						|
  ) {
 | 
						|
    order {
 | 
						|
      order_number
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
QUERY;
 | 
						|
        $response = $this->graphQlMutation($query, [], '', $this->headers);
 | 
						|
        self::assertArrayHasKey('placeOrder', $response);
 | 
						|
        self::assertArrayHasKey('order', $response['placeOrder']);
 | 
						|
        self::assertArrayHasKey('order_number', $response['placeOrder']['order']);
 | 
						|
        self::assertNotEmpty($response['placeOrder']['order']['order_number']);
 | 
						|
 | 
						|
        return $response['placeOrder']['order']['order_number'];
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * @param string $orderId
 | 
						|
     * @return void
 | 
						|
     */
 | 
						|
    private function checkOrderInHistory(string $orderId): void
 | 
						|
    {
 | 
						|
        $query = <<<QUERY
 | 
						|
{
 | 
						|
  customerOrders {
 | 
						|
    items {
 | 
						|
      increment_id
 | 
						|
      grand_total
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
QUERY;
 | 
						|
        $response = $this->graphQlQuery($query, [], '', $this->headers);
 | 
						|
        self::assertArrayHasKey('customerOrders', $response);
 | 
						|
        self::assertArrayHasKey('items', $response['customerOrders']);
 | 
						|
        self::assertCount(1, $response['customerOrders']['items']);
 | 
						|
 | 
						|
        $order = current($response['customerOrders']['items']);
 | 
						|
        self::assertArrayHasKey('increment_id', $order);
 | 
						|
        self::assertEquals($orderId, $order['increment_id']);
 | 
						|
 | 
						|
        self::assertArrayHasKey('grand_total', $order);
 | 
						|
    }
 | 
						|
 | 
						|
    protected function tearDown(): void
 | 
						|
    {
 | 
						|
        $this->deleteCustomer();
 | 
						|
        $this->deleteQuote();
 | 
						|
        $this->deleteOrder();
 | 
						|
        parent::tearDown();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * @return void
 | 
						|
     */
 | 
						|
    private function deleteCustomer(): void
 | 
						|
    {
 | 
						|
        $email = 'customer@example.com';
 | 
						|
        try {
 | 
						|
            $customer = $this->customerRepository->get($email);
 | 
						|
        } catch (\Exception $exception) {
 | 
						|
            return;
 | 
						|
        }
 | 
						|
        $this->registry->unregister('isSecureArea');
 | 
						|
        $this->registry->register('isSecureArea', true);
 | 
						|
        $this->customerRepository->delete($customer);
 | 
						|
        $this->registry->unregister('isSecureArea');
 | 
						|
        $this->registry->register('isSecureArea', false);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * @return void
 | 
						|
     */
 | 
						|
    private function deleteQuote(): void
 | 
						|
    {
 | 
						|
        $quoteCollection = $this->quoteCollectionFactory->create();
 | 
						|
        foreach ($quoteCollection as $quote) {
 | 
						|
            $this->quoteResource->delete($quote);
 | 
						|
 | 
						|
            $quoteIdMask = $this->quoteIdMaskFactory->create();
 | 
						|
            $quoteIdMask->setQuoteId($quote->getId())
 | 
						|
                ->delete();
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * @return void
 | 
						|
     */
 | 
						|
    private function deleteOrder()
 | 
						|
    {
 | 
						|
        $this->registry->unregister('isSecureArea');
 | 
						|
        $this->registry->register('isSecureArea', true);
 | 
						|
 | 
						|
        $orderCollection = $this->orderCollectionFactory->create();
 | 
						|
        foreach ($orderCollection as $order) {
 | 
						|
            $this->orderRepository->delete($order);
 | 
						|
        }
 | 
						|
        $this->registry->unregister('isSecureArea');
 | 
						|
        $this->registry->register('isSecureArea', false);
 | 
						|
    }
 | 
						|
}
 |