Skip to content

Commit a4f09a1

Browse files
committed
MC-34298: Introduce separate POST and PUT API for carts/mine/items
1 parent b1081e7 commit a4f09a1

18 files changed

+1377
-930
lines changed

app/code/Magento/Quote/Api/AddCartItemInterface.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
namespace Magento\Quote\Api;
99

10+
use Magento\Quote\Api\Data\CartItemInterface;
11+
1012
/**
1113
* Interface AddCartItemInterface
1214
* @api
@@ -16,11 +18,11 @@ interface AddCartItemInterface
1618
/**
1719
* Add the specified cart item.
1820
*
19-
* @param \Magento\Quote\Api\Data\CartItemInterface $cartItem The item.
20-
* @return \Magento\Quote\Api\Data\CartItemInterface Item.
21+
* @param CartItemInterface $cartItem The item.
22+
* @return CartItemInterface Item.
2123
* @throws \Magento\Framework\Exception\NoSuchEntityException The specified cart does not exist.
2224
* @throws \Magento\Framework\Exception\CouldNotSaveException The specified item could not be saved to the cart.
2325
* @throws \Magento\Framework\Exception\InputException The specified item or cart is not valid.
2426
*/
25-
public function execute(\Magento\Quote\Api\Data\CartItemInterface $cartItem);
27+
public function execute(CartItemInterface $cartItem): CartItemInterface;
2628
}

app/code/Magento/Quote/Api/UpdateCartItemInterface.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
namespace Magento\Quote\Api;
99

10+
use Magento\Quote\Api\Data\CartItemInterface;
11+
1012
/**
1113
* Interface AddCartItemInterface
1214
* @api
@@ -16,11 +18,11 @@ interface UpdateCartItemInterface
1618
/**
1719
* Update the specified cart item.
1820
*
19-
* @param \Magento\Quote\Api\Data\CartItemInterface $cartItem The item.
20-
* @return \Magento\Quote\Api\Data\CartItemInterface Item.
21+
* @param CartItemInterface $cartItem The item.
22+
* @return CartItemInterface Item.
2123
* @throws \Magento\Framework\Exception\NoSuchEntityException The specified cart does not exist.
2224
* @throws \Magento\Framework\Exception\CouldNotSaveException The specified item could not be saved to the cart.
2325
* @throws \Magento\Framework\Exception\InputException The specified item or cart is not valid.
2426
*/
25-
public function execute(\Magento\Quote\Api\Data\CartItemInterface $cartItem);
27+
public function execute(CartItemInterface $cartItem): CartItemInterface;
2628
}

app/code/Magento/Quote/Model/Quote/Item/AddCartItem.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public function __construct(Repository $quoteItemRepository)
3131
/**
3232
* @inheritDoc
3333
*/
34-
public function execute(CartItemInterface $cartItem)
34+
public function execute(CartItemInterface $cartItem): CartItemInterface
3535
{
3636
if (isset($cartItem[CartItemInterface::KEY_ITEM_ID])) {
3737
unset($cartItem[CartItemInterface::KEY_ITEM_ID]);

app/code/Magento/Quote/Model/Quote/Item/UpdateCartItem.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public function __construct(Repository $quoteItemRepository)
3131
/**
3232
* @inheritDoc
3333
*/
34-
public function execute(CartItemInterface $cartItem)
34+
public function execute(CartItemInterface $cartItem): CartItemInterface
3535
{
3636
return $this->quoteItemRepository->save($cartItem);
3737
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
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\Bundle\Api;
9+
10+
use Magento\Catalog\Model\Product;
11+
use Magento\Framework\Webapi\Rest\Request;
12+
use Magento\Quote\Model\Quote;
13+
use Magento\TestFramework\Helper\Bootstrap;
14+
use Magento\TestFramework\ObjectManager;
15+
use Magento\TestFramework\TestCase\WebapiAbstract;
16+
17+
/**
18+
* API test for add cart item with bundle product.
19+
*/
20+
class CartItemAddTest extends WebapiAbstract
21+
{
22+
const SERVICE_VERSION = 'V1';
23+
const SERVICE_NAME = 'quoteAddCartItemV1';
24+
const RESOURCE_PATH = '/V1/carts/';
25+
26+
/**
27+
* @var ObjectManager
28+
*/
29+
protected $objectManager;
30+
31+
/**
32+
* @inheritDoc
33+
*/
34+
protected function setUp(): void
35+
{
36+
$this->objectManager = Bootstrap::getObjectManager();
37+
}
38+
39+
/**
40+
* @magentoApiDataFixture Magento/Checkout/_files/quote_with_items_saved.php
41+
* @magentoApiDataFixture Magento/Bundle/_files/product.php
42+
*/
43+
public function testAddItem(): void
44+
{
45+
/** @var Product $product */
46+
$product = $this->objectManager->create(Product::class)->load(3);
47+
$quote = $this->objectManager->create(Quote::class)->load(
48+
'test_order_item_with_items',
49+
'reserved_order_id'
50+
);
51+
52+
$itemQty = 1;
53+
$bundleProductOptions = $product->getExtensionAttributes()->getBundleProductOptions();
54+
$bundleOptionId = $bundleProductOptions[0]->getId();
55+
$optionSelections = $bundleProductOptions[0]->getProductLinks()[0]->getId();
56+
$buyRequest = [
57+
'bundle_option' => [$bundleOptionId => [$optionSelections]],
58+
'bundle_option_qty' => [$bundleOptionId => 1],
59+
'qty' => $itemQty,
60+
'original_qty' => $itemQty
61+
];
62+
63+
$productSku = $product->getSku();
64+
$productId = $product->getId();
65+
/** @var Quote $quote */
66+
67+
$cartId = $quote->getId();
68+
69+
$serviceInfo = [
70+
'rest' => [
71+
'resourcePath' => self::RESOURCE_PATH . $cartId . '/items',
72+
'httpMethod' => Request::HTTP_METHOD_POST,
73+
],
74+
'soap' => [
75+
'service' => self::SERVICE_NAME,
76+
'serviceVersion' => self::SERVICE_VERSION,
77+
'operation' => self::SERVICE_NAME . 'Execute',
78+
],
79+
];
80+
81+
$requestData = [
82+
"cartItem" => [
83+
"sku" => $productSku,
84+
"qty" => $itemQty,
85+
"quote_id" => $cartId,
86+
"product_option" => [
87+
"extension_attributes" => [
88+
"bundle_options" => [
89+
[
90+
"option_id" => (int)$bundleOptionId,
91+
"option_qty" => $itemQty,
92+
"option_selections" => [(int)$optionSelections]
93+
]
94+
]
95+
]
96+
]
97+
]
98+
];
99+
$response = $this->_webApiCall($serviceInfo, $requestData);
100+
$this->assertTrue($quote->hasProductId($productId));
101+
$this->assertEquals($buyRequest, $quote->getItemById($response['item_id'])->getBuyRequest()->getData());
102+
}
103+
}

dev/tests/api-functional/testsuite/Magento/Bundle/Api/CartItemRepositoryTest.php

Lines changed: 18 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -3,33 +3,45 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
declare(strict_types=1);
7+
68
namespace Magento\Bundle\Api;
79

10+
use Magento\Framework\Webapi\Rest\Request;
11+
use Magento\Quote\Model\Quote;
12+
use Magento\TestFramework\Helper\Bootstrap;
13+
use Magento\TestFramework\ObjectManager;
814
use Magento\TestFramework\TestCase\WebapiAbstract;
915

16+
/**
17+
* API test for cart item repository with bundle product.
18+
*/
1019
class CartItemRepositoryTest extends WebapiAbstract
1120
{
1221
const SERVICE_VERSION = 'V1';
1322
const SERVICE_NAME = 'quoteCartItemRepositoryV1';
1423
const RESOURCE_PATH = '/V1/carts/';
1524

1625
/**
17-
* @var \Magento\TestFramework\ObjectManager
26+
* @var ObjectManager
1827
*/
1928
protected $objectManager;
2029

30+
/**
31+
* @inheritDoc
32+
*/
2133
protected function setUp(): void
2234
{
23-
$this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
35+
$this->objectManager = Bootstrap::getObjectManager();
2436
}
2537

2638
/**
2739
* @magentoApiDataFixture Magento/Checkout/_files/quote_with_bundle_and_options.php
2840
*/
29-
public function testGetAll()
41+
public function testGetAll(): void
3042
{
31-
/** @var $quote \Magento\Quote\Model\Quote */
32-
$quote = $this->objectManager->create(\Magento\Quote\Model\Quote::class)->load(
43+
/** @var $quote Quote */
44+
$quote = $this->objectManager->create(Quote::class)->load(
3345
'test_order_bundle',
3446
'reserved_order_id'
3547
);
@@ -38,7 +50,7 @@ public function testGetAll()
3850
$serviceInfo = [
3951
'rest' => [
4052
'resourcePath' => self::RESOURCE_PATH . $quoteId . '/items',
41-
'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET,
53+
'httpMethod' => Request::HTTP_METHOD_GET,
4254
],
4355
'soap' => [
4456
'service' => self::SERVICE_NAME,
@@ -61,146 +73,4 @@ public function testGetAll()
6173
$this->assertEquals($expectedSelections, $option['option_selections']);
6274
}
6375
}
64-
65-
/**
66-
* @magentoApiDataFixture Magento/Checkout/_files/quote_with_items_saved.php
67-
* @magentoApiDataFixture Magento/Bundle/_files/product.php
68-
*/
69-
public function testAddItem()
70-
{
71-
/** @var \Magento\Catalog\Model\Product $product */
72-
$product = $this->objectManager->create(\Magento\Catalog\Model\Product::class)->load(3);
73-
$quote = $this->objectManager->create(\Magento\Quote\Model\Quote::class)->load(
74-
'test_order_item_with_items',
75-
'reserved_order_id'
76-
);
77-
78-
$itemQty = 1;
79-
$bundleProductOptions = $product->getExtensionAttributes()->getBundleProductOptions();
80-
$bundleOptionId = $bundleProductOptions[0]->getId();
81-
$optionSelections = $bundleProductOptions[0]->getProductLinks()[0]->getId();
82-
$buyRequest = [
83-
'bundle_option' => [$bundleOptionId => [$optionSelections]],
84-
'bundle_option_qty' => [$bundleOptionId => 1],
85-
'qty' => $itemQty,
86-
'original_qty' => $itemQty
87-
];
88-
89-
$productSku = $product->getSku();
90-
$productId = $product->getId();
91-
/** @var \Magento\Quote\Model\Quote $quote */
92-
93-
$cartId = $quote->getId();
94-
95-
$serviceInfo = [
96-
'rest' => [
97-
'resourcePath' => self::RESOURCE_PATH . $cartId . '/items',
98-
'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST,
99-
],
100-
'soap' => [
101-
'service' => self::SERVICE_NAME,
102-
'serviceVersion' => self::SERVICE_VERSION,
103-
'operation' => self::SERVICE_NAME . 'Save',
104-
],
105-
];
106-
107-
$requestData = [
108-
"cartItem" => [
109-
"sku" => $productSku,
110-
"qty" => $itemQty,
111-
"quote_id" => $cartId,
112-
"product_option" => [
113-
"extension_attributes" => [
114-
"bundle_options" => [
115-
[
116-
"option_id" => (int)$bundleOptionId,
117-
"option_qty" => $itemQty,
118-
"option_selections" => [(int)$optionSelections]
119-
]
120-
]
121-
]
122-
]
123-
]
124-
];
125-
$response = $this->_webApiCall($serviceInfo, $requestData);
126-
$this->assertTrue($quote->hasProductId($productId));
127-
$this->assertEquals($buyRequest, $quote->getItemById($response['item_id'])->getBuyRequest()->getData());
128-
}
129-
130-
/**
131-
* @magentoApiDataFixture Magento/Checkout/_files/quote_with_bundle_and_options.php
132-
*/
133-
public function testUpdate()
134-
{
135-
/** @var \Magento\Quote\Model\Quote $quote */
136-
$quote = $this->objectManager->create(\Magento\Quote\Model\Quote::class)->load(
137-
'test_order_bundle',
138-
'reserved_order_id'
139-
);
140-
$cartId = $quote->getId();
141-
$cartItem = $quote->getAllVisibleItems()[0];
142-
$itemSku = $cartItem->getSku();
143-
$itemId = $cartItem->getId();
144-
145-
$product = $cartItem->getProduct();
146-
/** @var $typeInstance \Magento\Bundle\Model\Product\Type */
147-
$typeInstance = $product->getTypeInstance();
148-
$typeInstance->setStoreFilter($product->getStoreId(), $product);
149-
$optionCollection = $typeInstance->getOptionsCollection($product);
150-
$bundleOptions = [];
151-
/** @var $option \Magento\Bundle\Model\Option */
152-
foreach ($optionCollection as $option) {
153-
if (!$option->getRequired()) {
154-
continue;
155-
}
156-
$selectionsCollection = $typeInstance->getSelectionsCollection([$option->getId()], $product);
157-
$option = ['option_id' => $option->getId(), 'option_qty' => 1];
158-
$option['option_selections'] = [$selectionsCollection->getLastItem()->getSelectionId()];
159-
$bundleOptions[] = $option;
160-
}
161-
162-
$serviceInfo = [
163-
'rest' => [
164-
'resourcePath' => self::RESOURCE_PATH . $cartId . '/items/' . $itemId,
165-
'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_PUT,
166-
],
167-
'soap' => [
168-
'service' => self::SERVICE_NAME,
169-
'serviceVersion' => self::SERVICE_VERSION,
170-
'operation' => self::SERVICE_NAME . 'Save',
171-
],
172-
];
173-
$requestData = [
174-
"cartItem" => [
175-
"sku" => $itemSku,
176-
"qty" => 2,
177-
"quote_id" => $cartId,
178-
"item_id" => $itemId,
179-
"product_option" => [
180-
"extension_attributes" => [
181-
"bundle_options" => $bundleOptions
182-
]
183-
]
184-
]
185-
];
186-
$this->_webApiCall($serviceInfo, $requestData);
187-
188-
$quoteUpdated = $this->objectManager->create(\Magento\Quote\Model\Quote::class)->load(
189-
'test_order_bundle',
190-
'reserved_order_id'
191-
);
192-
$cartItems = $quoteUpdated->getAllVisibleItems();
193-
$buyRequest = $cartItems[0]->getBuyRequest()->toArray();
194-
195-
$this->assertCount(1, $cartItems);
196-
$this->assertEquals(count($buyRequest['bundle_option']), count($bundleOptions));
197-
foreach ($bundleOptions as $option) {
198-
$optionId = $option['option_id'];
199-
$optionQty = $option['option_qty'];
200-
$optionSelections = $option['option_selections'];
201-
$this->assertArrayHasKey($optionId, $buyRequest['bundle_option']);
202-
$this->assertEquals($optionQty, $buyRequest['bundle_option_qty'][$optionId]);
203-
$this->assertEquals($optionSelections, $buyRequest['bundle_option'][$optionId]);
204-
}
205-
}
20676
}

0 commit comments

Comments
 (0)