ensure cart totals update when items are removed or quantity changed (https://github.com/woocommerce/woocommerce-blocks/pull/1840)
* ensure cart totals update when items are removed (prototype):
- return complete cart object from DELETE cart/items/:key
- use receiveCart on client to update whole cart including total
* move API endpoint for removing cart items to cart controller:
- returns full cart schema so should be part of cart controller
- is now a POST request with param - not strict REST
- fix up client action to use new API
* move API test for removing cart items (API has moved)
* use correct path for remove API in tests (doh!)
* add extra API test for remove_cart_item with bad key => 404 (experiment)
* experiment: delete test_remove_cart_item, does test_remove_bad_cart_item work?
* reinstate test_remove_cart_item with single valid request
* remove unnecessary newline
* tidy comments in PHP api tests, rerun travis?
* remove test_remove_cart_item which may be causing problems
* reinstate troublesome remove cart item api test (experiment):
- see if this works now travis issue is resolved
* whitespace
* show correct total when changing cart item quantity:
- move update cart item quantity API to cart controller
- & return full cart response
- update js action to new API route & receive full cart response
* simplify test_remove_cart_item API test - now just tests a valid remove succeeds
* remove test_update_item (API has moved) +
+ experimentally remove test_remove_bad_cart_item
- testing if cart remove tests interact with each other
* fix tests (🤞) - pass params in body, not as query params
* reinstate test for re-deleting same item
* update API docs - update/delete cart item have moved to /cart
* add response data checks to new cart API tests:
- extra protection against expected 404 "false positives"
* reinstate API test for changing cart item quantity
* fix remove cart item body tests - MIA items return error code, not cart
* fix test - quantity param is int not string
* attempt fix 404ing test_update_item:
- only allow POST, remove trailing `/`
- align array equals for good measure :)
* fix action for update-item - method=POST, now takes body params
* fix response body asserts in test_update_item
* reinstate update_item and delete_item on CartItems controller
* typos + examples in new cart items API docs
* reorder previous cart item docs to minimise diff/churn
* reinstate tabs in docs response example
This commit is contained in:
parent
52feba4f85
commit
5a26d2708e
|
@ -199,13 +199,13 @@ export function* removeItemFromCart( cartItemKey ) {
|
||||||
yield itemQuantityPending( cartItemKey, true );
|
yield itemQuantityPending( cartItemKey, true );
|
||||||
|
|
||||||
try {
|
try {
|
||||||
yield apiFetch( {
|
const cart = yield apiFetch( {
|
||||||
path: `/wc/store/cart/items/${ cartItemKey }`,
|
path: `/wc/store/cart/remove-item/?key=${ cartItemKey }`,
|
||||||
method: 'DELETE',
|
method: 'POST',
|
||||||
cache: 'no-store',
|
cache: 'no-store',
|
||||||
} );
|
} );
|
||||||
|
|
||||||
yield receiveRemovedItem( cartItemKey );
|
yield receiveCart( cart );
|
||||||
} catch ( error ) {
|
} catch ( error ) {
|
||||||
yield receiveError( error );
|
yield receiveError( error );
|
||||||
}
|
}
|
||||||
|
@ -227,15 +227,17 @@ export function* changeCartItemQuantity( cartItemKey, quantity ) {
|
||||||
yield itemQuantityPending( cartItemKey, true );
|
yield itemQuantityPending( cartItemKey, true );
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = yield apiFetch( {
|
const cart = yield apiFetch( {
|
||||||
path: `/wc/store/cart/items/${ cartItemKey }?quantity=${ quantity }`,
|
path: `/wc/store/cart/update-item`,
|
||||||
method: 'PUT',
|
method: 'POST',
|
||||||
|
data: {
|
||||||
|
key: cartItemKey,
|
||||||
|
quantity,
|
||||||
|
},
|
||||||
cache: 'no-store',
|
cache: 'no-store',
|
||||||
} );
|
} );
|
||||||
|
|
||||||
if ( result ) {
|
yield receiveCart( cart );
|
||||||
yield receiveCartItem( result );
|
|
||||||
}
|
|
||||||
} catch ( error ) {
|
} catch ( error ) {
|
||||||
yield receiveError( error );
|
yield receiveError( error );
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,6 +103,44 @@ class Cart extends RestController {
|
||||||
'schema' => [ $this, 'get_public_item_schema' ],
|
'schema' => [ $this, 'get_public_item_schema' ],
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
register_rest_route(
|
||||||
|
$this->namespace,
|
||||||
|
'/' . $this->rest_base . '/remove-item',
|
||||||
|
[
|
||||||
|
[
|
||||||
|
'methods' => 'POST',
|
||||||
|
'callback' => [ $this, 'remove_cart_item' ],
|
||||||
|
'args' => [
|
||||||
|
'key' => [
|
||||||
|
'description' => __( 'Unique identifier (key) for the cart item.', 'woo-gutenberg-products-block' ),
|
||||||
|
'type' => 'string',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'schema' => [ $this, 'get_public_item_schema' ],
|
||||||
|
]
|
||||||
|
);
|
||||||
|
register_rest_route(
|
||||||
|
$this->namespace,
|
||||||
|
'/' . $this->rest_base . '/update-item',
|
||||||
|
[
|
||||||
|
[
|
||||||
|
'methods' => 'POST',
|
||||||
|
'callback' => [ $this, 'update_cart_item' ],
|
||||||
|
'args' => [
|
||||||
|
'key' => [
|
||||||
|
'description' => __( 'Unique identifier (key) for the cart item to update.', 'woo-gutenberg-products-block' ),
|
||||||
|
'type' => 'string',
|
||||||
|
],
|
||||||
|
'quantity' => [
|
||||||
|
'description' => __( 'New quantity of the item in the cart.', 'woo-gutenberg-products-block' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'schema' => [ $this, 'get_public_item_schema' ],
|
||||||
|
]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -193,6 +231,54 @@ class Cart extends RestController {
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a single cart item.
|
||||||
|
*
|
||||||
|
* @param \WP_Rest_Request $request Full data about the request.
|
||||||
|
* @return \WP_Error|\WP_REST_Response Response object on success, or WP_Error object on failure.
|
||||||
|
*/
|
||||||
|
public function remove_cart_item( $request ) {
|
||||||
|
$controller = new CartController();
|
||||||
|
$cart = $controller->get_cart_instance();
|
||||||
|
$cart_item = $controller->get_cart_item( $request['key'] );
|
||||||
|
|
||||||
|
if ( ! $cart_item ) {
|
||||||
|
return new RestError( 'woocommerce_rest_cart_invalid_key', __( 'Cart item does not exist.', 'woo-gutenberg-products-block' ), array( 'status' => 404 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
$cart->remove_cart_item( $request['key'] );
|
||||||
|
|
||||||
|
$data = $this->prepare_item_for_response( $cart, $request );
|
||||||
|
$response = rest_ensure_response( $data );
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change quantity for specified cart item.
|
||||||
|
*
|
||||||
|
* @param \WP_Rest_Request $request Full data about the request.
|
||||||
|
* @return \WP_Error|\WP_REST_Response Response object on success, or WP_Error object on failure.
|
||||||
|
*/
|
||||||
|
public function update_cart_item( $request ) {
|
||||||
|
$controller = new CartController();
|
||||||
|
$cart = $controller->get_cart_instance();
|
||||||
|
$cart_item = $controller->get_cart_item( $request['key'] );
|
||||||
|
|
||||||
|
if ( ! $cart_item ) {
|
||||||
|
return new RestError( 'woocommerce_rest_cart_invalid_key', __( 'Cart item does not exist.', 'woo-gutenberg-products-block' ), array( 'status' => 404 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( isset( $request['quantity'] ) ) {
|
||||||
|
$cart->set_quantity( $request['key'], $request['quantity'] );
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = $this->prepare_item_for_response( $cart, $request );
|
||||||
|
$response = rest_ensure_response( $data );
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cart item schema.
|
* Cart item schema.
|
||||||
*
|
*
|
||||||
|
|
|
@ -308,6 +308,8 @@ Example response:
|
||||||
|
|
||||||
## Cart API
|
## Cart API
|
||||||
|
|
||||||
|
### Get the cart
|
||||||
|
|
||||||
```http
|
```http
|
||||||
GET /cart
|
GET /cart
|
||||||
```
|
```
|
||||||
|
@ -455,6 +457,43 @@ Example response:
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Edit single cart item
|
||||||
|
|
||||||
|
Change the quantity of a cart item.
|
||||||
|
|
||||||
|
```http
|
||||||
|
PUT /cart/update-item/
|
||||||
|
```
|
||||||
|
|
||||||
|
| Attribute | Type | Required | Description |
|
||||||
|
| :--------- | :------ | :------: | :--------------------------------- |
|
||||||
|
| `key` | string | Yes | The key of the cart item to edit. |
|
||||||
|
| `quantity` | integer | Yes | Quantity of this item in the cart. |
|
||||||
|
|
||||||
|
Returns the full cart object (same response as `GET /cart`).
|
||||||
|
|
||||||
|
```http
|
||||||
|
curl --request POST "https://example-store.com/wp-json/wc/store/cart/update-item?key=1ff1de774005f8da13f42943881c655f&quantity=3"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Delete single cart item
|
||||||
|
|
||||||
|
Delete/remove an item from the cart.
|
||||||
|
|
||||||
|
```http
|
||||||
|
POST /cart/remove-item/
|
||||||
|
```
|
||||||
|
|
||||||
|
| Attribute | Type | Required | Description |
|
||||||
|
| :-------- | :----- | :------: | :-------------------------------- |
|
||||||
|
| `key` | string | Yes | The key of the cart item to edit. |
|
||||||
|
|
||||||
|
Returns the full cart object (same response as `GET /cart`).
|
||||||
|
|
||||||
|
```http
|
||||||
|
curl --request POST "https://example-store.com/wp-json/wc/store/cart/remove-item?key=1ff1de774005f8da13f42943881c655f"
|
||||||
|
```
|
||||||
|
|
||||||
## Cart items API
|
## Cart items API
|
||||||
|
|
||||||
### List cart items
|
### List cart items
|
||||||
|
|
|
@ -85,6 +85,72 @@ class Cart extends TestCase {
|
||||||
$this->assertEquals( '2900', $data['totals']->total_price );
|
$this->assertEquals( '2900', $data['totals']->total_price );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test removing a nonexistent cart item.
|
||||||
|
*/
|
||||||
|
public function test_remove_bad_cart_item() {
|
||||||
|
// Test removing a bad cart item - should return 404.
|
||||||
|
$request = new WP_REST_Request( 'POST', '/wc/store/cart/remove-item' );
|
||||||
|
$request->set_body_params(
|
||||||
|
array(
|
||||||
|
'key' => 'bad_item_key_123',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$response = $this->server->dispatch( $request );
|
||||||
|
$data = $response->get_data();
|
||||||
|
|
||||||
|
$this->assertEquals( 404, $response->get_status() );
|
||||||
|
$this->assertEquals( 'woocommerce_rest_cart_invalid_key', $data['code'] );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test remove cart item.
|
||||||
|
*/
|
||||||
|
public function test_remove_cart_item() {
|
||||||
|
// Test removing a valid cart item - should return updated cart.
|
||||||
|
$request = new WP_REST_Request( 'POST', '/wc/store/cart/remove-item' );
|
||||||
|
$request->set_body_params(
|
||||||
|
array(
|
||||||
|
'key' => $this->keys[0],
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$response = $this->server->dispatch( $request );
|
||||||
|
$data = $response->get_data();
|
||||||
|
|
||||||
|
$this->assertEquals( 200, $response->get_status() );
|
||||||
|
$this->assertEquals( 1, $data['items_count'] );
|
||||||
|
$this->assertEquals( 1, count( $data['items'] ) );
|
||||||
|
$this->assertEquals( '10', $data['items_weight'] );
|
||||||
|
$this->assertEquals( '1000', $data['totals']->total_items );
|
||||||
|
|
||||||
|
// Test removing same item again - should return 404 (item is already removed).
|
||||||
|
$response = $this->server->dispatch( $request );
|
||||||
|
$data = $response->get_data();
|
||||||
|
|
||||||
|
$this->assertEquals( 404, $response->get_status() );
|
||||||
|
$this->assertEquals( 'woocommerce_rest_cart_invalid_key', $data['code'] );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test changing the quantity of a cart item.
|
||||||
|
*/
|
||||||
|
public function test_update_item() {
|
||||||
|
$request = new WP_REST_Request( 'POST', '/wc/store/cart/update-item' );
|
||||||
|
$request->set_body_params(
|
||||||
|
array(
|
||||||
|
'key' => $this->keys[0],
|
||||||
|
'quantity' => 10,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$response = $this->server->dispatch( $request );
|
||||||
|
$data = $response->get_data();
|
||||||
|
|
||||||
|
$this->assertEquals( 200, $response->get_status() );
|
||||||
|
$this->assertEquals( 10, $data['items'][0]['quantity'] );
|
||||||
|
$this->assertEquals( 11, $data['items_count'] );
|
||||||
|
$this->assertEquals( '11000', $data['totals']->total_items );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test applying coupon to cart.
|
* Test applying coupon to cart.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue