magento2-docker/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/CheckoutEndToEndTest.php

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);
}
}