Skip to content
This repository was archived by the owner on Apr 29, 2019. It is now read-only.

Commit 75573a9

Browse files
committed
[Cart Operations] Remove item mutation
Partial #37
1 parent 0d0b300 commit 75573a9

File tree

3 files changed

+310
-0
lines changed

3 files changed

+310
-0
lines changed
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
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\NoSuchEntityException;
11+
use Magento\Framework\GraphQl\Config\Element\Field;
12+
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
13+
use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException;
14+
use Magento\Framework\GraphQl\Query\ResolverInterface;
15+
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
16+
use Magento\Quote\Api\GuestCartItemRepositoryInterface;
17+
use Magento\Quote\Api\GuestCartRepositoryInterface;
18+
use Magento\QuoteGraphQl\Model\Cart\ExtractDataFromCart;
19+
20+
/**
21+
* @inheritdoc
22+
*/
23+
class RemoveItemFromCartOutput implements ResolverInterface
24+
{
25+
/**
26+
* @var GuestCartItemRepositoryInterface
27+
*/
28+
private $guestCartItemRepository;
29+
30+
/**
31+
* @var GuestCartRepositoryInterface
32+
*/
33+
private $guestCartRepository;
34+
35+
/**
36+
* @var ExtractDataFromCart
37+
*/
38+
private $extractDataFromCart;
39+
40+
public function __construct(
41+
GuestCartItemRepositoryInterface $guestCartItemRepository,
42+
GuestCartRepositoryInterface $guestCartRepository,
43+
ExtractDataFromCart $extractDataFromCart
44+
) {
45+
$this->guestCartItemRepository = $guestCartItemRepository;
46+
$this->guestCartRepository = $guestCartRepository;
47+
$this->extractDataFromCart = $extractDataFromCart;
48+
}
49+
50+
public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null)
51+
{
52+
if (!isset($args['input']['cart_id'])) {
53+
throw new GraphQlInputException(__('Required parameter "cart_id" is missing'));
54+
}
55+
if (!isset($args['input']['cart_item_id'])) {
56+
throw new GraphQlInputException(__('Required parameter "cart_item_id" is missing'));
57+
}
58+
$maskedCartId = $args['input']['cart_id'];
59+
$itemId = $args['input']['cart_item_id'];
60+
61+
try {
62+
$this->guestCartItemRepository->deleteById($maskedCartId, $itemId);
63+
} catch (NoSuchEntityException $e) {
64+
throw new GraphQlNoSuchEntityException(__($e->getMessage()));
65+
}
66+
67+
$cart = $this->guestCartRepository->get($maskedCartId);
68+
69+
$cartData = $this->extractDataFromCart->execute($cart);
70+
71+
return ['cart' => array_merge(['cart_id' => $maskedCartId], $cartData)];
72+
}
73+
}

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ type Mutation {
1414
setShippingAddressesOnCart(input: SetShippingAddressesOnCartInput): SetShippingAddressesOnCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\SetShippingAddressesOnCart")
1515
setBillingAddressOnCart(input: SetBillingAddressOnCartInput): SetBillingAddressOnCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\SetBillingAddressOnCart")
1616
setShippingMethodsOnCart(input: SetShippingMethodsOnCartInput): SetShippingMethodsOnCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\SetShippingMethodsOnCart")
17+
removeItemFromCart(input: RemoveItemFromCartInput): RemoveItemFromCartOutput @resolver(class: "Magento\\QuoteGraphQl\\Model\\Resolver\\RemoveItemFromCartOutput")
1718
}
1819

1920
input AddSimpleProductsToCartInput {
@@ -206,6 +207,15 @@ type AddVirtualProductsToCartOutput {
206207
cart: Cart!
207208
}
208209

210+
input RemoveItemFromCartInput {
211+
cart_id: String!
212+
cart_item_id: String!
213+
}
214+
215+
type RemoveItemFromCartOutput {
216+
cart: Cart!
217+
}
218+
209219
type SimpleCartItem implements CartItemInterface @doc(description: "Simple Cart Item") {
210220
customizable_options: [SelectedCustomizableOption] @resolver(class: "Magento\\QuoteGraphQl\\Model\\Resolver\\CustomizableOptions")
211221
}
Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
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;
9+
10+
use Magento\Catalog\Api\ProductRepositoryInterface;
11+
use Magento\Integration\Api\CustomerTokenServiceInterface;
12+
use Magento\Quote\Api\Data\CartInterface;
13+
use Magento\Quote\Api\GuestCartRepositoryInterface;
14+
use Magento\Quote\Model\Quote;
15+
use Magento\Quote\Model\QuoteIdToMaskedQuoteIdInterface;
16+
use Magento\Quote\Model\ResourceModel\Quote as QuoteResource;
17+
use Magento\TestFramework\Helper\Bootstrap;
18+
use Magento\TestFramework\TestCase\GraphQlAbstract;
19+
use Magento\TestFramework\ObjectManager;
20+
21+
/**
22+
* Test for empty cart creation mutation
23+
*/
24+
class RemoveItemFromCartTest extends GraphQlAbstract
25+
{
26+
/**
27+
* @var QuoteResource
28+
*/
29+
private $quoteResource;
30+
31+
/**
32+
* @var Quote
33+
*/
34+
private $quote;
35+
36+
/**
37+
* @var QuoteIdToMaskedQuoteIdInterface
38+
*/
39+
private $quoteIdToMaskedId;
40+
41+
/**
42+
* @var ProductRepositoryInterface
43+
*/
44+
private $productRepository;
45+
46+
/**
47+
* @var GuestCartRepositoryInterface
48+
*/
49+
private $guestCartRepository;
50+
51+
protected function setUp()
52+
{
53+
$objectManager = Bootstrap::getObjectManager();
54+
$this->quoteResource = $objectManager->create(QuoteResource::class);
55+
$this->quote = $objectManager->create(Quote::class);
56+
$this->quoteIdToMaskedId = $objectManager->create(QuoteIdToMaskedQuoteIdInterface::class);
57+
$this->productRepository = $objectManager->create(ProductRepositoryInterface::class);
58+
$this->guestCartRepository = $objectManager->create(GuestCartRepositoryInterface::class);
59+
}
60+
61+
/**
62+
* @magentoApiDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php
63+
*/
64+
public function testGuestRemoveItemFromCart()
65+
{
66+
$this->quoteResource->load(
67+
$this->quote,
68+
'test_order_with_simple_product_without_address',
69+
'reserved_order_id'
70+
);
71+
$maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId());
72+
$itemId = $this->quote->getItemByProduct($this->productRepository->get('simple'))->getId();
73+
74+
$query = <<<QUERY
75+
mutation {
76+
removeItemFromCart(
77+
input: {
78+
cart_id: "$maskedQuoteId"
79+
cart_item_id: "$itemId"
80+
}
81+
) {
82+
cart {
83+
cart_id
84+
items {
85+
id
86+
qty
87+
}
88+
}
89+
}
90+
}
91+
QUERY;
92+
$response = $this->graphQlQuery($query);
93+
94+
$this->assertArrayHasKey('removeItemFromCart', $response);
95+
$this->assertArrayHasKey('cart', $response['removeItemFromCart']);
96+
97+
$responseCart = $response['removeItemFromCart']['cart'];
98+
99+
$this->assertCount(0, $responseCart['items']);
100+
}
101+
102+
/**
103+
* @magentoApiDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php
104+
* @magentoApiDataFixture Magento/Customer/_files/customer.php
105+
*/
106+
public function testRemoveItemFromCart()
107+
{
108+
$this->quoteResource->load(
109+
$this->quote,
110+
'test_order_with_simple_product_without_address',
111+
'reserved_order_id'
112+
);
113+
$maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId());
114+
$itemId = $this->quote->getItemByProduct($this->productRepository->get('simple'))->getId();
115+
116+
$this->quote->setCustomerId(1);
117+
$this->quoteResource->save($this->quote);
118+
119+
$headerMap = $this->getHeaderMap();
120+
121+
$query = <<<QUERY
122+
mutation {
123+
removeItemFromCart(
124+
input: {
125+
cart_id: "$maskedQuoteId"
126+
cart_item_id: "$itemId"
127+
}
128+
) {
129+
cart {
130+
cart_id
131+
items {
132+
id
133+
qty
134+
}
135+
}
136+
}
137+
}
138+
QUERY;
139+
140+
$response = $this->graphQlQuery($query, [], '', $headerMap);
141+
142+
$this->assertArrayHasKey('removeItemFromCart', $response);
143+
$this->assertArrayHasKey('cart', $response['removeItemFromCart']);
144+
145+
$responseCart = $response['removeItemFromCart']['cart'];
146+
147+
$this->assertCount(0, $responseCart['items']);
148+
}
149+
150+
public function testRemoveItemFromCartNoSuchCartIdException()
151+
{
152+
$maskedCartId = 'nada';
153+
154+
$this->expectExceptionMessage('No such entity with cartId');
155+
156+
$query = <<<QUERY
157+
mutation {
158+
removeItemFromCart(
159+
input: {
160+
cart_id: "$maskedCartId"
161+
cart_item_id: "nononono"
162+
}
163+
) {
164+
cart {
165+
cart_id
166+
items {
167+
id
168+
qty
169+
}
170+
}
171+
}
172+
}
173+
QUERY;
174+
$this->graphQlQuery($query);
175+
}
176+
177+
/**
178+
* @magentoApiDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php
179+
*/
180+
public function testRemoveItemFromCartNoSuchCartItem()
181+
{
182+
$this->quoteResource->load(
183+
$this->quote,
184+
'test_order_with_simple_product_without_address',
185+
'reserved_order_id'
186+
);
187+
$maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId());
188+
$itemId = 'nononono';
189+
190+
$this->expectExceptionMessage(sprintf('Cart doesn\'t contain the %s item.', $itemId));
191+
192+
$query = <<<QUERY
193+
mutation {
194+
removeItemFromCart(
195+
input: {
196+
cart_id: "$maskedQuoteId"
197+
cart_item_id: "$itemId"
198+
}
199+
) {
200+
cart {
201+
cart_id
202+
items {
203+
id
204+
qty
205+
}
206+
}
207+
}
208+
}
209+
QUERY;
210+
$this->graphQlQuery($query);
211+
}
212+
213+
/**
214+
* @param string $username
215+
* @return array
216+
*/
217+
private function getHeaderMap(string $username = '[email protected]'): array
218+
{
219+
$password = 'password';
220+
/** @var CustomerTokenServiceInterface $customerTokenService */
221+
$customerTokenService = ObjectManager::getInstance()
222+
->get(CustomerTokenServiceInterface::class);
223+
$customerToken = $customerTokenService->createCustomerAccessToken($username, $password);
224+
$headerMap = ['Authorization' => 'Bearer ' . $customerToken];
225+
return $headerMap;
226+
}
227+
}

0 commit comments

Comments
 (0)