From f1412702f5fdd4fc5c7658c9a9c05be0d01fc4a7 Mon Sep 17 00:00:00 2001 From: Seghir Nadir Date: Thu, 27 Oct 2022 15:29:27 +0100 Subject: [PATCH] Calculate cart totals after running extensions (#7490) * calculate cart totals afer running extensions * update totlas call in CartUpdateCustomer * test that cart is recalcing --- src/StoreApi/Routes/V1/AbstractCartRoute.php | 12 +--- src/StoreApi/Routes/V1/CartUpdateCustomer.php | 2 +- .../Schemas/V1/CartExtensionsSchema.php | 8 ++- src/StoreApi/Utilities/CartController.php | 11 ++++ tests/php/StoreApi/Routes/CartExtensions.php | 58 ++++++++++++++++++- 5 files changed, 76 insertions(+), 15 deletions(-) diff --git a/src/StoreApi/Routes/V1/AbstractCartRoute.php b/src/StoreApi/Routes/V1/AbstractCartRoute.php index 7815996cc93..9fb10a3f0d5 100644 --- a/src/StoreApi/Routes/V1/AbstractCartRoute.php +++ b/src/StoreApi/Routes/V1/AbstractCartRoute.php @@ -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 ); @@ -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. * diff --git a/src/StoreApi/Routes/V1/CartUpdateCustomer.php b/src/StoreApi/Routes/V1/CartUpdateCustomer.php index 98ca25d289e..19fe455f880 100644 --- a/src/StoreApi/Routes/V1/CartUpdateCustomer.php +++ b/src/StoreApi/Routes/V1/CartUpdateCustomer.php @@ -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 ) ); } diff --git a/src/StoreApi/Schemas/V1/CartExtensionsSchema.php b/src/StoreApi/Schemas/V1/CartExtensionsSchema.php index 1890ac6a911..c9f3dfc788f 100644 --- a/src/StoreApi/Schemas/V1/CartExtensionsSchema.php +++ b/src/StoreApi/Schemas/V1/CartExtensionsSchema.php @@ -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 ) ); } diff --git a/src/StoreApi/Utilities/CartController.php b/src/StoreApi/Utilities/CartController.php index 8912dbdb970..c97698dfd43 100644 --- a/src/StoreApi/Utilities/CartController.php +++ b/src/StoreApi/Utilities/CartController.php @@ -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. * diff --git a/tests/php/StoreApi/Routes/CartExtensions.php b/tests/php/StoreApi/Routes/CartExtensions.php index 6f97ca842d8..3275073b06d 100644 --- a/tests/php/StoreApi/Routes/CartExtensions.php +++ b/tests/php/StoreApi/Routes/CartExtensions.php @@ -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' ); + } + ); + }, + ) + ); + } /** * 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( @@ -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', + ), + ) + ); + } }