Skip to content

Commit ed0dd32

Browse files
committed
[Checkout coverage] setGuestEmailOnCart mutation
1 parent 4a28abb commit ed0dd32

File tree

7 files changed

+388
-0
lines changed

7 files changed

+388
-0
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\QuoteGraphQl\Model\Resolver;
9+
10+
use Magento\Framework\Exception\LocalizedException;
11+
use Magento\Framework\GraphQl\Config\Element\Field;
12+
use Magento\Framework\GraphQl\Query\ResolverInterface;
13+
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
14+
use Magento\Quote\Model\Quote;
15+
use Magento\QuoteGraphQl\Model\Cart\GetCartForUser;
16+
17+
/**
18+
* @inheritdoc
19+
*/
20+
class GuestEmail implements ResolverInterface
21+
{
22+
/**
23+
* @var GetCartForUser
24+
*/
25+
private $getCartForUser;
26+
27+
/**
28+
* @param GetCartForUser $getCartForUser
29+
*/
30+
public function __construct(
31+
GetCartForUser $getCartForUser
32+
) {
33+
$this->getCartForUser = $getCartForUser;
34+
}
35+
36+
/**
37+
* @inheritdoc
38+
*/
39+
public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null)
40+
{
41+
if (!isset($value['model'])) {
42+
throw new LocalizedException(__('"model" value should be specified'));
43+
}
44+
/** @var Quote $cart */
45+
$cart = $value['model'];
46+
47+
return $cart->getCustomerEmail();
48+
}
49+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\QuoteGraphQl\Model\Resolver;
9+
10+
use Magento\Framework\Exception\CouldNotSaveException;
11+
use Magento\Framework\Exception\LocalizedException;
12+
use Magento\Framework\GraphQl\Config\Element\Field;
13+
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
14+
use Magento\Framework\GraphQl\Query\ResolverInterface;
15+
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
16+
use Magento\Framework\Validator\EmailAddress as EmailAddressValidator;
17+
use Magento\Quote\Api\CartRepositoryInterface;
18+
use Magento\QuoteGraphQl\Model\Cart\GetCartForUser;
19+
20+
/**
21+
* @inheritdoc
22+
*/
23+
class SetGuestEmailOnCart implements ResolverInterface
24+
{
25+
/**
26+
* @var CartRepositoryInterface
27+
*/
28+
private $cartRepository;
29+
30+
/**
31+
* @var GetCartForUser
32+
*/
33+
private $getCartForUser;
34+
35+
/**
36+
* @param GetCartForUser $getCartForUser
37+
* @param CartRepositoryInterface $cartRepository
38+
*/
39+
public function __construct(
40+
GetCartForUser $getCartForUser,
41+
CartRepositoryInterface $cartRepository
42+
) {
43+
$this->getCartForUser = $getCartForUser;
44+
$this->cartRepository = $cartRepository;
45+
}
46+
47+
/**
48+
* @inheritdoc
49+
*/
50+
public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null)
51+
{
52+
if (!isset($args['input']['cart_id']) || empty($args['input']['cart_id'])) {
53+
throw new GraphQlInputException(__('Required parameter "cart_id" is missing'));
54+
}
55+
$maskedCartId = $args['input']['cart_id'];
56+
57+
if (!isset($args['input']['email']) || empty($args['input']['email'])) {
58+
throw new GraphQlInputException(__('Required parameter "email" is missing'));
59+
}
60+
61+
$guestEmail = $args['input']['email'];
62+
63+
if (!\Zend_Validate::is($guestEmail, EmailAddressValidator::class)) {
64+
throw new GraphQlInputException(__('Invalid email format'));
65+
}
66+
67+
$currentUserId = $context->getUserId();
68+
69+
if ($currentUserId !== 0) {
70+
throw new GraphQlInputException(__('The request is not allowed for logged in customers'));
71+
}
72+
73+
$cart = $this->getCartForUser->execute($maskedCartId, $currentUserId);
74+
$cart->setCustomerEmail($guestEmail);
75+
76+
try {
77+
$this->cartRepository->save($cart);
78+
} catch (CouldNotSaveException $e) {
79+
throw new LocalizedException(__($e->getMessage()), $e);
80+
}
81+
82+
return [
83+
'cart' => [
84+
'model' => $cart,
85+
'guest_email' => $guestEmail
86+
],
87+
];
88+
}
89+
}

app/code/Magento/QuoteGraphQl/etc/schema.graphqls

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ type Mutation {
1717
setBillingAddressOnCart(input: SetBillingAddressOnCartInput): SetBillingAddressOnCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\SetBillingAddressOnCart")
1818
setShippingMethodsOnCart(input: SetShippingMethodsOnCartInput): SetShippingMethodsOnCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\SetShippingMethodsOnCart")
1919
setPaymentMethodOnCart(input: SetPaymentMethodOnCartInput): SetPaymentMethodOnCartOutput @resolver(class: "Magento\\QuoteGraphQl\\Model\\Resolver\\SetPaymentMethodOnCart")
20+
setGuestEmailOnCart(input: SetGuestEmailOnCartInput): SetGuestEmailOnCartOutput @resolver(class: "Magento\\QuoteGraphQl\\Model\\Resolver\\SetGuestEmailOnCart")
2021
}
2122

2223
input AddSimpleProductsToCartInput {
@@ -124,6 +125,11 @@ input PaymentMethodInput {
124125
purchase_order_number: String @doc(description:"Purchase order number")
125126
}
126127

128+
input SetGuestEmailOnCartInput {
129+
cart_id: String!
130+
email: String!
131+
}
132+
127133
type SetPaymentMethodOnCartOutput {
128134
cart: Cart!
129135
}
@@ -147,6 +153,7 @@ type ApplyCouponToCartOutput {
147153
type Cart {
148154
items: [CartItemInterface] @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\CartItems")
149155
applied_coupon: AppliedCoupon @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\AppliedCoupon")
156+
guest_email: String @resolver (class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\GuestEmail")
150157
shipping_addresses: [CartAddress]! @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\ShippingAddresses")
151158
billing_address: CartAddress! @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\BillingAddress")
152159
available_payment_methods: [AvailablePaymentMethod] @resolver(class: "Magento\\QuoteGraphQl\\Model\\Resolver\\AvailablePaymentMethods") @doc(description: "Available payment methods")
@@ -249,6 +256,10 @@ type RemoveItemFromCartOutput {
249256
cart: Cart!
250257
}
251258

259+
type SetGuestEmailOnCartOutput {
260+
cart: Cart!
261+
}
262+
252263
type SimpleCartItem implements CartItemInterface @doc(description: "Simple Cart Item") {
253264
customizable_options: [SelectedCustomizableOption] @resolver(class: "Magento\\QuoteGraphQl\\Model\\Resolver\\CustomizableOptions")
254265
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\GraphQl\Quote\Customer;
9+
10+
use Magento\GraphQl\Quote\GetMaskedQuoteIdByReservedOrderId;
11+
use Magento\Integration\Api\CustomerTokenServiceInterface;
12+
use Magento\TestFramework\Helper\Bootstrap;
13+
use Magento\TestFramework\TestCase\GraphQlAbstract;
14+
15+
/**
16+
* Test for setGuestEmailOnCart mutation
17+
*/
18+
class SetGuestEmailOnCartTest extends GraphQlAbstract
19+
{
20+
/**
21+
* @var CustomerTokenServiceInterface
22+
*/
23+
private $customerTokenService;
24+
25+
/**
26+
* @var GetMaskedQuoteIdByReservedOrderId
27+
*/
28+
private $getMaskedQuoteIdByReservedOrderId;
29+
30+
protected function setUp()
31+
{
32+
$objectManager = Bootstrap::getObjectManager();
33+
$this->getMaskedQuoteIdByReservedOrderId = $objectManager->get(GetMaskedQuoteIdByReservedOrderId::class);
34+
$this->customerTokenService = $objectManager->get(CustomerTokenServiceInterface::class);
35+
}
36+
37+
/**
38+
* @magentoApiDataFixture Magento/Checkout/_files/quote_with_address_saved.php
39+
*/
40+
public function testSetGuestEmailOnCartForLoggedInCustomer()
41+
{
42+
$reservedOrderId = 'test_order_1';
43+
$email = '[email protected]';
44+
$maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute($reservedOrderId);
45+
46+
$query = $this->getSetGuestEmailOnCartMutation($maskedQuoteId, $email);
47+
$this->expectExceptionMessage('The request is not allowed for logged in customers');
48+
$this->graphQlQuery($query, [], '', $this->getHeaderMap());
49+
}
50+
51+
/**
52+
* Returns GraphQl mutation query for setting email address for a guest
53+
*
54+
* @param string $maskedQuoteId
55+
* @param string $email
56+
* @return string
57+
*/
58+
private function getSetGuestEmailOnCartMutation(string $maskedQuoteId, string $email): string
59+
{
60+
return <<<QUERY
61+
mutation {
62+
setGuestEmailOnCart(input: {
63+
cart_id:"$maskedQuoteId"
64+
email: "$email"
65+
}) {
66+
cart {
67+
guest_email
68+
}
69+
}
70+
}
71+
QUERY;
72+
}
73+
74+
/**
75+
* @param string $username
76+
* @param string $password
77+
* @return array
78+
*/
79+
private function getHeaderMap(string $username = '[email protected]', string $password = 'password'): array
80+
{
81+
$customerToken = $this->customerTokenService->createCustomerAccessToken($username, $password);
82+
$headerMap = ['Authorization' => 'Bearer ' . $customerToken];
83+
return $headerMap;
84+
}
85+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\GraphQl\Quote\Guest;
9+
10+
use Magento\GraphQl\Quote\GetMaskedQuoteIdByReservedOrderId;
11+
use Magento\TestFramework\Helper\Bootstrap;
12+
use Magento\TestFramework\TestCase\GraphQlAbstract;
13+
14+
/**
15+
* Test for getting guest email from cart
16+
*/
17+
class CartGuestEmailTest extends GraphQlAbstract
18+
{
19+
/**
20+
* @var GetMaskedQuoteIdByReservedOrderId
21+
*/
22+
private $getMaskedQuoteIdByReservedOrderId;
23+
24+
protected function setUp()
25+
{
26+
$objectManager = Bootstrap::getObjectManager();
27+
$this->getMaskedQuoteIdByReservedOrderId = $objectManager->get(GetMaskedQuoteIdByReservedOrderId::class);
28+
}
29+
30+
/**
31+
* @magentoApiDataFixture Magento/Checkout/_files/quote_with_virtual_product_saved.php
32+
*/
33+
public function testGetCartGuestEmail()
34+
{
35+
$email = '[email protected]';
36+
$maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute(
37+
'test_order_with_virtual_product_without_address'
38+
);
39+
40+
$query = <<<QUERY
41+
{
42+
cart(cart_id:"$maskedQuoteId") {
43+
guest_email
44+
}
45+
}
46+
QUERY;
47+
48+
$response = $this->graphQlQuery($query);
49+
$this->assertArrayHasKey('cart', $response);
50+
$this->assertEquals($email, $response['cart']['guest_email']);
51+
}
52+
}

0 commit comments

Comments
 (0)