Skip to content

Commit a490f5d

Browse files
ACQE-8324: Using rest api update guest cart of configurable product
- Created a new file for updating the guest cart items
1 parent aad7d94 commit a490f5d

File tree

2 files changed

+270
-135
lines changed

2 files changed

+270
-135
lines changed
Lines changed: 268 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
1+
<?php
2+
/**
3+
* Copyright 2025 Adobe
4+
* All Rights Reserved.
5+
*/
6+
namespace Magento\Quote\Api;
7+
8+
use Magento\Catalog\Api\ProductRepositoryInterface;
9+
use Magento\Framework\Webapi\Rest\Request;
10+
use Magento\Integration\Api\AdminTokenServiceInterface;
11+
use Magento\Integration\Model\AdminTokenService;
12+
use Magento\Integration\Model\Oauth\Token as TokenModel;
13+
use Magento\TestFramework\Bootstrap as TestBootstrap;
14+
use Magento\TestFramework\Helper\Bootstrap;
15+
use Magento\TestFramework\TestCase\WebapiAbstract;
16+
use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
17+
use Magento\User\Model\User;
18+
use Magento\User\Model\User as UserModel;
19+
20+
/**
21+
* Test for Magento\Quote\Api\GuestCartConfigurableItemRepositoryTest.
22+
*/
23+
class GuestCartConfigurableItemRepositoryTest extends WebapiAbstract
24+
{
25+
private const RESOURCE_PATH_ADMIN_TOKEN = "/V1/integration/admin/token";
26+
27+
private const RESOURCE_PATH_GUEST_CART = '/V1/guest-carts/';
28+
29+
private const SERVICE_VERSION_GUEST_CART = 'V1';
30+
31+
private const SERVICE_NAME_GUEST_CART = 'quoteGuestCartManagementV1';
32+
33+
/**
34+
* @var AdminTokenServiceInterface
35+
*/
36+
private $tokenService;
37+
38+
/**
39+
* @var TokenModel
40+
*/
41+
private $tokenModel;
42+
43+
/**
44+
* @var UserModel
45+
*/
46+
private $userModel;
47+
48+
/**
49+
* @var array
50+
*/
51+
private $simpleProductSkus=[];
52+
53+
/**
54+
* @inheritdoc
55+
*/
56+
protected function setUp(): void
57+
{
58+
parent::setUp();
59+
$this->tokenService = Bootstrap::getObjectManager()->get(AdminTokenService::class);
60+
$this->tokenModel = Bootstrap::getObjectManager()->get(TokenModel::class);
61+
$this->userModel = Bootstrap::getObjectManager()->get(User::class);
62+
}
63+
64+
/**
65+
* @magentoApiDataFixture Magento/Webapi/_files/webapi_user.php
66+
* @magentoApiDataFixture Magento/ConfigurableProduct/_files/product_configurable.php
67+
*/
68+
public function testGuestCartUpdateConfigurableItem()
69+
{
70+
$adminToken = $this->createAdminAccessToken();
71+
$guestCartId = $this->createGuestCart($adminToken);
72+
$response = $this->addConfigurableProductToCart($guestCartId, $adminToken);
73+
$this->updateConfigurableProductInCart($guestCartId, $adminToken, $response['item_id']);
74+
$this->verifyCartItems($guestCartId, $adminToken, $response['item_id']);
75+
}
76+
77+
private function createAdminAccessToken()
78+
{
79+
$adminUser = 'webapi_user';
80+
81+
$serviceInfo = [
82+
'rest' => [
83+
'resourcePath' => self::RESOURCE_PATH_ADMIN_TOKEN,
84+
'httpMethod' => Request::HTTP_METHOD_POST,
85+
],
86+
];
87+
$requestData = [
88+
'username' => $adminUser,
89+
'password' => TestBootstrap::ADMIN_PASSWORD,
90+
];
91+
$accessToken = $this->_webApiCall($serviceInfo, $requestData);
92+
$this->assertNotNull($accessToken);
93+
return $accessToken;
94+
}
95+
96+
private function createGuestCart(string $adminToken)
97+
{
98+
$serviceInfo = [
99+
'rest' => [
100+
'resourcePath' => self::RESOURCE_PATH_GUEST_CART,
101+
'httpMethod' => Request::HTTP_METHOD_POST,
102+
'headers' => [
103+
'Authorization' => 'Bearer ' . $adminToken
104+
]
105+
],
106+
'soap' => [
107+
'service' => self::SERVICE_NAME_GUEST_CART,
108+
'serviceVersion' => self::SERVICE_VERSION_GUEST_CART,
109+
'operation' => self::SERVICE_NAME_GUEST_CART . 'CreateEmptyCart',
110+
],
111+
];
112+
113+
$requestData = ['storeId' => 1];
114+
$quoteId = $this->_webApiCall($serviceInfo, $requestData);
115+
$this->assertTrue(strlen($quoteId) >= 32);
116+
return $quoteId;
117+
}
118+
119+
private function addConfigurableProductToCart(string $guestCartId, string $adminToken)
120+
{
121+
$configurableProduct = $this->getConfigurableProduct('configurable');
122+
$optionData = $this->getConfigurableOptionData($configurableProduct);
123+
124+
$requestData = $this->buildCartItemRequestData(
125+
$guestCartId,
126+
$configurableProduct->getSku(),
127+
$optionData['attribute_id'],
128+
$optionData['option_id']
129+
);
130+
131+
$serviceInfo = $this->getCartServiceInfo($guestCartId, $adminToken, 'add');
132+
133+
$response = $this->_webApiCall($serviceInfo, $requestData);
134+
$this->assertNotNull($response['item_id']);
135+
$this->assertEquals(Configurable::TYPE_CODE, $response['product_type']);
136+
$this->assertEquals($requestData['cartItem']['qty'], $response['qty']);
137+
$this->assertContains($response['sku'], $this->simpleProductSkus);
138+
$this->assertEquals(
139+
$response['product_option']['extension_attributes']['configurable_item_options'][0],
140+
$requestData['cartItem']['product_option']['extension_attributes']['configurable_item_options'][0]
141+
);
142+
return $response;
143+
}
144+
145+
private function verifyCartItems(string $guestCartId, string $adminToken, int $expectedItemId)
146+
{
147+
$serviceInfo = $this->getCartServiceInfo($guestCartId, $adminToken,'get');
148+
149+
$response = $this->_webApiCall($serviceInfo, []);
150+
151+
$this->assertIsArray($response);
152+
$this->assertGreaterThan(0, count($response), 'Cart should contain at least one item');
153+
154+
$foundItem = false;
155+
foreach ($response as $item) {
156+
if ($item['item_id'] == $expectedItemId) {
157+
$foundItem = true;
158+
$this->assertEquals(Configurable::TYPE_CODE, $item['product_type']);
159+
$this->assertEquals(1, $item['qty']);
160+
$this->assertArrayHasKey('product_option', $item);
161+
$this->assertContains($item['sku'], $this->simpleProductSkus);
162+
$this->assertArrayHasKey('extension_attributes', $item['product_option']);
163+
$this->assertArrayHasKey('configurable_item_options', $item['product_option']['extension_attributes']);
164+
break;
165+
}
166+
}
167+
168+
$this->assertTrue($foundItem, 'Expected cart item not found in cart items list');
169+
}
170+
171+
private function updateConfigurableProductInCart(string $guestCartId, string $adminToken, int $itemId)
172+
{
173+
$configurableProduct = $this->getConfigurableProduct('configurable');
174+
$optionData = $this->getConfigurableOptionData($configurableProduct);
175+
$requestData = $this->buildCartItemRequestData(
176+
$guestCartId,
177+
$configurableProduct->getSku(),
178+
$optionData['attribute_id'],
179+
$optionData['option_id']
180+
);
181+
$requestData['cartItem']['item_id'] = $itemId;
182+
$serviceInfo = $this->getCartServiceInfo($guestCartId, $adminToken, 'update', $itemId);
183+
$response = $this->_webApiCall($serviceInfo, $requestData);
184+
$this->assertNotNull($response['item_id']);
185+
$this->assertEquals(Configurable::TYPE_CODE, $response['product_type']);
186+
$this->assertEquals($requestData['cartItem']['qty'], $response['qty']);
187+
$this->assertContains($response['sku'], $this->simpleProductSkus);
188+
$this->assertEquals(
189+
$response['product_option']['extension_attributes']['configurable_item_options'][0],
190+
$requestData['cartItem']['product_option']['extension_attributes']['configurable_item_options'][0]
191+
);
192+
}
193+
194+
private function getConfigurableProduct(string $sku)
195+
{
196+
$productRepository = Bootstrap::getObjectManager()->get(ProductRepositoryInterface::class);
197+
$configurableProduct = $productRepository->get($sku);
198+
$simpleProducts = $configurableProduct->getTypeInstance()->getUsedProducts($configurableProduct);
199+
foreach ($simpleProducts as $simpleProduct) {
200+
$this->simpleProductSkus[] = $simpleProduct->getSku();
201+
}
202+
return $configurableProduct;
203+
}
204+
205+
private function getConfigurableOptionData($configurableProduct, $selectedOption = null)
206+
{
207+
$configOptions = $configurableProduct->getExtensionAttributes()->getconfigOptions();
208+
209+
$options = $configOptions[0]->getOptions();
210+
$optionKey = (isset($selectedOption) && isset($options[$selectedOption])) ? $selectedOption : 0;
211+
212+
return [
213+
'attribute_id' => $configOptions[0]->getAttributeId(),
214+
'option_id' => $options[$optionKey]['value_index']
215+
];
216+
}
217+
218+
private function buildCartItemRequestData(string $cartId, string $sku, int $attributeId, int $optionId): array
219+
{
220+
return [
221+
'cartItem' => [
222+
'sku' => $sku,
223+
'qty' => 1,
224+
'quote_id' => $cartId,
225+
'product_option' => [
226+
'extension_attributes' => [
227+
'configurable_item_options' => [
228+
[
229+
'option_id' => $attributeId,
230+
'option_value' => $optionId,
231+
]
232+
]
233+
]
234+
]
235+
],
236+
];
237+
}
238+
239+
private function getCartServiceInfo(string $cartId, string $adminToken, string $action = 'add', int $itemId = null): array
240+
{
241+
$resourcePath = self::RESOURCE_PATH_GUEST_CART . $cartId . '/items';
242+
if ($action === 'update' && $itemId !== null) {
243+
$resourcePath .= '/' . $itemId;
244+
}
245+
246+
$httpMethod = Request::HTTP_METHOD_POST;
247+
if ($action === 'update') {
248+
$httpMethod = Request::HTTP_METHOD_PUT;
249+
} elseif ($action === 'get') {
250+
$httpMethod = Request::HTTP_METHOD_GET;
251+
}
252+
253+
return [
254+
'rest' => [
255+
'resourcePath' => $resourcePath,
256+
'httpMethod' => $httpMethod,
257+
'headers' => [
258+
'Authorization' => 'Bearer ' . $adminToken
259+
]
260+
],
261+
'soap' => [
262+
'service' => self::SERVICE_NAME_GUEST_CART,
263+
'serviceVersion' => self::SERVICE_VERSION_GUEST_CART,
264+
'operation' => self::SERVICE_NAME_GUEST_CART . 'Save',
265+
],
266+
];
267+
}
268+
}

0 commit comments

Comments
 (0)