Skip to content

Commit 4e10da6

Browse files
committed
graphQl-470: Creating/getting Cart queries should support Store context
1 parent 0e8428c commit 4e10da6

File tree

7 files changed

+227
-1
lines changed

7 files changed

+227
-1
lines changed

app/code/Magento/QuoteGraphQl/Model/Cart/GetCartForUser.php

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use Magento\Quote\Api\CartRepositoryInterface;
1414
use Magento\Quote\Model\MaskedQuoteIdToQuoteIdInterface;
1515
use Magento\Quote\Model\Quote;
16+
use Magento\Store\Model\StoreManagerInterface;
1617

1718
/**
1819
* Get cart
@@ -29,16 +30,24 @@ class GetCartForUser
2930
*/
3031
private $cartRepository;
3132

33+
/**
34+
* @var StoreManagerInterface
35+
*/
36+
private $storeManager;
37+
3238
/**
3339
* @param MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId
3440
* @param CartRepositoryInterface $cartRepository
41+
* @param StoreManagerInterface $storeManager
3542
*/
3643
public function __construct(
3744
MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId,
38-
CartRepositoryInterface $cartRepository
45+
CartRepositoryInterface $cartRepository,
46+
StoreManagerInterface $storeManager
3947
) {
4048
$this->maskedQuoteIdToQuoteId = $maskedQuoteIdToQuoteId;
4149
$this->cartRepository = $cartRepository;
50+
$this->storeManager = $storeManager;
4251
}
4352

4453
/**
@@ -75,6 +84,15 @@ public function execute(string $cartHash, ?int $customerId): Quote
7584
);
7685
}
7786

87+
if ((int)$cart->getStoreId() !== (int)$this->storeManager->getStore()->getId()) {
88+
throw new GraphQlAuthorizationException(
89+
__(
90+
'Wrong store code specified for cart "%masked_cart_id"',
91+
['masked_cart_id' => $cartHash]
92+
)
93+
);
94+
}
95+
7896
$cartCustomerId = (int)$cart->getCustomerId();
7997

8098
/* Guest cart, allow operations */

dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/CreateEmptyCartTest.php

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
namespace Magento\GraphQl\Quote\Customer;
99

10+
use Magento\Framework\App\ResourceConnection;
1011
use Magento\Integration\Api\CustomerTokenServiceInterface;
1112
use Magento\TestFramework\Helper\Bootstrap;
1213
use Magento\TestFramework\TestCase\GraphQlAbstract;
@@ -27,11 +28,17 @@ class CreateEmptyCartTest extends GraphQlAbstract
2728
*/
2829
private $customerTokenService;
2930

31+
/**
32+
* @var ResourceConnection
33+
*/
34+
private $resourceConnection;
35+
3036
protected function setUp()
3137
{
3238
$objectManager = Bootstrap::getObjectManager();
3339
$this->guestCartRepository = $objectManager->get(GuestCartRepositoryInterface::class);
3440
$this->customerTokenService = $objectManager->get(CustomerTokenServiceInterface::class);
41+
$this->resourceConnection = $objectManager->get(ResourceConnection::class);
3542
}
3643

3744
/**
@@ -57,5 +64,51 @@ public function testCreateEmptyCart()
5764

5865
self::assertNotNull($guestCart->getId());
5966
self::assertEquals(1, $guestCart->getCustomer()->getId());
67+
self::assertSame('default', $guestCart->getStore()->getCode());
68+
69+
$this->deleteCreatedQuote($guestCart->getId());
70+
}
71+
72+
/**
73+
* @magentoApiDataFixture Magento/Store/_files/second_store.php
74+
* @magentoApiDataFixture Magento/Customer/_files/customer.php
75+
*/
76+
public function testCreateEmptyCartWithNotDefaultStore()
77+
{
78+
$query = <<<QUERY
79+
mutation {
80+
createEmptyCart
81+
}
82+
QUERY;
83+
84+
$customerToken = $this->customerTokenService->createCustomerAccessToken('[email protected]', 'password');
85+
$headerMap = ['Authorization' => 'Bearer ' . $customerToken, 'Store' => 'fixture_second_store'];
86+
87+
$response = $this->graphQlQuery($query, [], '', $headerMap);
88+
89+
self::assertArrayHasKey('createEmptyCart', $response);
90+
91+
$maskedCartId = $response['createEmptyCart'];
92+
/* guestCartRepository is used for registered customer to get the cart hash */
93+
$guestCart = $this->guestCartRepository->get($maskedCartId);
94+
95+
self::assertNotNull($guestCart->getId());
96+
self::assertEquals(1, $guestCart->getCustomer()->getId());
97+
self::assertSame('fixture_second_store', $guestCart->getStore()->getCode());
98+
99+
$this->deleteCreatedQuote($guestCart->getId());
100+
}
101+
102+
/**
103+
* Delete active quote for customer by customer id.
104+
* This is needed to have ability to create new quote for another store and not return the active one.
105+
* @see QuoteManagement::createCustomerCart
106+
*
107+
* @param $quoteId
108+
*/
109+
private function deleteCreatedQuote($quoteId)
110+
{
111+
$connection = $this->resourceConnection->getConnection();
112+
$connection->query('DELETE FROM quote WHERE entity_id = ' . $quoteId);
60113
}
61114
}

dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/GetCartTest.php

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,58 @@ public function testGetInactiveCart()
134134
$this->graphQlQuery($query, [], '', $this->getHeaderMap());
135135
}
136136

137+
/**
138+
* @magentoApiDataFixture Magento/Checkout/_files/active_quote_not_default_store.php
139+
*/
140+
public function testGetCartWithNotDefaultStore()
141+
{
142+
$maskedQuoteId = $this->getMaskedQuoteIdByReversedQuoteId('test_order_1_not_default_store');
143+
$query = $this->getCartQuery($maskedQuoteId);
144+
145+
$headerMap = $this->getHeaderMap();
146+
$headerMap['Store'] = 'fixture_second_store';
147+
148+
$response = $this->graphQlQuery($query, [], '', $headerMap);
149+
150+
self::assertArrayHasKey('cart', $response);
151+
self::assertArrayHasKey('items', $response['cart']);
152+
}
153+
154+
/**
155+
* @magentoApiDataFixture Magento/Checkout/_files/active_quote.php
156+
* @magentoApiDataFixture Magento/Store/_files/second_store.php
157+
*
158+
* @expectedException \Exception
159+
* @expectedExceptionMessage Wrong store code specified for cart
160+
*/
161+
public function testGetCartWithWrongStore()
162+
{
163+
$maskedQuoteId = $this->getMaskedQuoteIdByReversedQuoteId('test_order_1');
164+
$query = $this->getCartQuery($maskedQuoteId);
165+
166+
$headerMap = $this->getHeaderMap();
167+
$headerMap['Store'] = 'fixture_second_store';
168+
169+
$this->graphQlQuery($query, [], '', $headerMap);
170+
}
171+
172+
/**
173+
* @magentoApiDataFixture Magento/Checkout/_files/active_quote_not_default_store.php
174+
*
175+
* @expectedException \Exception
176+
* @expectedExceptionMessage Store code not_existing_store does not exist
177+
*/
178+
public function testGetCartWithNotExistingStore()
179+
{
180+
$maskedQuoteId = $this->getMaskedQuoteIdByReversedQuoteId('test_order_1_not_default_store');
181+
$query = $this->getCartQuery($maskedQuoteId);
182+
183+
$headerMap = $this->getHeaderMap();
184+
$headerMap['Store'] = 'not_existing_store';
185+
186+
$this->graphQlQuery($query, [], '', $headerMap);
187+
}
188+
137189
/**
138190
* @param string $maskedQuoteId
139191
* @return string

dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/CreateEmptyCartTest.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,28 @@ public function testCreateEmptyCart()
4444
self::assertNotNull($guestCart->getId());
4545
self::assertNull($guestCart->getCustomer()->getId());
4646
}
47+
48+
/**
49+
* @magentoApiDataFixture Magento/Store/_files/second_store.php
50+
*/
51+
public function testCreateEmptyCartWithNotDefaultStore()
52+
{
53+
$query = <<<QUERY
54+
mutation {
55+
createEmptyCart
56+
}
57+
QUERY;
58+
$headerMap = ['Store' => 'fixture_second_store'];
59+
60+
$response = $this->graphQlQuery($query, [], '', $headerMap);
61+
62+
self::assertArrayHasKey('createEmptyCart', $response);
63+
64+
$maskedCartId = $response['createEmptyCart'];
65+
$guestCart = $this->guestCartRepository->get($maskedCartId);
66+
67+
self::assertNotNull($guestCart->getId());
68+
self::assertNull($guestCart->getCustomer()->getId());
69+
self::assertSame('fixture_second_store', $guestCart->getStore()->getCode());
70+
}
4771
}

dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/GetCartTest.php

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,54 @@ public function testGetInactiveCart()
115115
$this->graphQlQuery($query);
116116
}
117117

118+
/**
119+
* @magentoApiDataFixture Magento/Checkout/_files/active_quote_not_default_store.php
120+
*/
121+
public function testGetCartWithNotDefaultStore()
122+
{
123+
$maskedQuoteId = $this->getMaskedQuoteIdByReversedQuoteId('test_order_1_not_default_store');
124+
$query = $this->getCartQuery($maskedQuoteId);
125+
126+
$headerMap = ['Store' => 'fixture_second_store'];
127+
$response = $this->graphQlQuery($query, [], '', $headerMap);
128+
129+
self::assertArrayHasKey('cart', $response);
130+
self::assertArrayHasKey('items', $response['cart']);
131+
}
132+
133+
/**
134+
* @magentoApiDataFixture Magento/Checkout/_files/active_quote.php
135+
* @magentoApiDataFixture Magento/Store/_files/second_store.php
136+
*
137+
* @expectedException \Exception
138+
* @expectedExceptionMessage Wrong store code specified for cart
139+
*/
140+
public function testGetCartWithWrongStore()
141+
{
142+
$maskedQuoteId = $this->getMaskedQuoteIdByReversedQuoteId('test_order_1');
143+
$query = $this->getCartQuery($maskedQuoteId);
144+
145+
$headerMap = ['Store' => 'fixture_second_store'];
146+
$this->graphQlQuery($query, [], '', $headerMap);
147+
}
148+
149+
/**
150+
* @magentoApiDataFixture Magento/Customer/_files/customer.php
151+
* @magentoApiDataFixture Magento/Checkout/_files/active_quote_not_default_store.php
152+
*
153+
* @expectedException \Exception
154+
* @expectedExceptionMessage Store code not_existing_store does not exist
155+
*/
156+
public function testGetCartWithNotExistingStore()
157+
{
158+
$maskedQuoteId = $this->getMaskedQuoteIdByReversedQuoteId('test_order_1_not_default_store');
159+
160+
$headerMap['Store'] = 'not_existing_store';
161+
$query = $this->getCartQuery($maskedQuoteId);
162+
163+
$this->graphQlQuery($query, [], '', $headerMap);
164+
}
165+
118166
/**
119167
* @param string $maskedQuoteId
120168
* @return string
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
include 'testsuite/Magento/Store/_files/second_store.php';
7+
include 'testsuite/Magento/Customer/_files/customer.php';
8+
9+
$quote = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Quote\Model\Quote::class);
10+
$quote->setStoreId($store->getId())
11+
->setIsActive(true)
12+
->setIsMultiShipping(false)
13+
->setReservedOrderId('test_order_1_not_default_store')
14+
->setCustomerId($customer->getId())
15+
->save();
16+
17+
/** @var \Magento\Quote\Model\QuoteIdMask $quoteIdMask */
18+
$quoteIdMask = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
19+
->create(\Magento\Quote\Model\QuoteIdMaskFactory::class)
20+
->create();
21+
$quoteIdMask->setQuoteId($quote->getId());
22+
$quoteIdMask->setDataChanges(true);
23+
$quoteIdMask->save();
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
7+
$quote = $objectManager->create(\Magento\Quote\Model\Quote::class);
8+
$quote->load('test_order_1_not_default_store', 'reserved_order_id')->delete();

0 commit comments

Comments
 (0)