Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Calculate cart totals after running extensions #7490

Merged
merged 3 commits into from
Oct 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 1 addition & 11 deletions src/StoreApi/Routes/V1/AbstractCartRoute.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public function __construct( SchemaController $schema_controller, AbstractSchema
*/
public function get_response( \WP_REST_Request $request ) {
$this->load_cart_session( $request );
$this->calculate_totals();
$this->cart_controller->calculate_totals();

if ( $this->requires_nonce( $request ) ) {
$nonce_check = $this->check_nonce( $request );
Expand Down Expand Up @@ -229,16 +229,6 @@ protected function cart_updated( \WP_REST_Request $request ) {
}
}

/**
* Ensures the cart totals are calculated before an API response is generated.
*/
protected function calculate_totals() {
wc()->cart->get_cart();
wc()->cart->calculate_fees();
wc()->cart->calculate_shipping();
wc()->cart->calculate_totals();
}

/**
* For non-GET endpoints, require and validate a nonce to prevent CSRF attacks.
*
Expand Down
2 changes: 1 addition & 1 deletion src/StoreApi/Routes/V1/CartUpdateCustomer.php
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ protected function get_route_post_response( \WP_REST_Request $request ) {

$customer->save();

$this->calculate_totals();
$this->cart_controller->calculate_totals();

return rest_ensure_response( $this->schema->get_item_response( $cart ) );
}
Expand Down
8 changes: 6 additions & 2 deletions src/StoreApi/Schemas/V1/CartExtensionsSchema.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,16 @@ public function get_item_response( $request = null ) {
400
);
}

$controller = new CartController();

if ( is_callable( $callback ) ) {
$callback( $request['data'] );
// We recalculate the cart if we had something to run.
$controller->calculate_totals();
}

$controller = new CartController();
$cart = $controller->get_cart_instance();
$cart = $controller->get_cart_instance();

return rest_ensure_response( $this->cart_schema->get_item_response( $cart ) );
}
Expand Down
11 changes: 11 additions & 0 deletions src/StoreApi/Utilities/CartController.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,17 @@ public function load_cart() {
}
}

/**
* Recalculates the cart totals.
*/
public function calculate_totals() {
$cart = $this->get_cart_instance();
$cart->get_cart();
$cart->calculate_fees();
$cart->calculate_shipping();
$cart->calculate_totals();
}

/**
* Based on the core cart class but returns errors rather than rendering notices directly.
*
Expand Down
58 changes: 57 additions & 1 deletion tests/php/StoreApi/Routes/CartExtensions.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,50 @@
namespace Automattic\WooCommerce\Blocks\Tests\StoreApi\Routes;

use Automattic\WooCommerce\Blocks\Tests\StoreApi\Routes\ControllerTestCase;
use Automattic\WooCommerce\Blocks\Tests\Helpers\FixtureData;

/**
* Cart Controller Tests.
*/
class CartExtensions extends ControllerTestCase {

/**
* Setup test products data. Called before every test.
*/
public function setUp() {
parent::setUp();

$fixtures = new FixtureData();

$this->product = $fixtures->get_simple_product(
array(
'name' => 'Test Product 1',
'regular_price' => 10,
)
);

wc_empty_cart();

wc()->cart->add_to_cart( $this->product->get_id(), 1 );

woocommerce_store_api_register_update_callback(
array(
'namespace' => 'valid-test-plugin',
'callback' => function() {
add_action(
'woocommerce_cart_calculate_fees',
function() {
wc()->cart->add_fee( 'Surcharge', 10, true, 'standard' );
}
);
Comment on lines +39 to +44
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're using fees here because they're the only core cart method that doesn't trigger its own recalc, however, they only work if you add them within this action.

},
)
);
}
/**
* Test getting cart with invalid namespace.
*/
public function test_post() {
public function test_invalid_namespace() {
$request = new \WP_REST_Request( 'POST', '/wc/store/v1/cart/extensions' );
$request->set_header( 'Nonce', wp_create_nonce( 'wc_store_api' ) );
$request->set_body_params(
Expand All @@ -28,4 +62,26 @@ public function test_post() {
400
);
}

/**
* Test getting cart with invalid namespace.
*/
public function test_cart_being_updated() {
$request = new \WP_REST_Request( 'POST', '/wc/store/v1/cart/extensions' );
$request->set_header( 'Nonce', wp_create_nonce( 'wc_store_api' ) );
$request->set_body_params(
array(
'namespace' => 'valid-test-plugin',
)
);
$this->assertAPIResponse(
$request,
200,
array(
'totals' => array(
'total_fees' => '1000',
),
)
);
}
}