From 972c07e2c381eefcfcecaa6bd044fdd96459b0f4 Mon Sep 17 00:00:00 2001 From: Jesse Pearson Date: Wed, 4 Oct 2023 10:03:38 -0300 Subject: [PATCH] Update Name Your Price compatibility to use new Compatibility methods (#7269) --- changelog/fix-7172-nyp-cart-editing | 4 + .../WooCommerceNameYourPrice.php | 56 ++++++-- ...test-class-woocommerce-name-your-price.php | 132 ++++++++++++++++-- 3 files changed, 172 insertions(+), 20 deletions(-) create mode 100644 changelog/fix-7172-nyp-cart-editing diff --git a/changelog/fix-7172-nyp-cart-editing b/changelog/fix-7172-nyp-cart-editing new file mode 100644 index 00000000000..8c13ebfa01e --- /dev/null +++ b/changelog/fix-7172-nyp-cart-editing @@ -0,0 +1,4 @@ +Significance: minor +Type: update + +Update Name Your Price compatibility to use new Compatibility methods. diff --git a/includes/multi-currency/Compatibility/WooCommerceNameYourPrice.php b/includes/multi-currency/Compatibility/WooCommerceNameYourPrice.php index 3ddf98206c0..c716e985acc 100644 --- a/includes/multi-currency/Compatibility/WooCommerceNameYourPrice.php +++ b/includes/multi-currency/Compatibility/WooCommerceNameYourPrice.php @@ -33,6 +33,10 @@ protected function init() { add_action( 'woocommerce_add_cart_item_data', [ $this, 'add_initial_currency' ], 20, 3 ); add_filter( 'woocommerce_get_cart_item_from_session', [ $this, 'convert_cart_currency' ], 20, 2 ); add_filter( MultiCurrency::FILTER_PREFIX . 'should_convert_product_price', [ $this, 'should_convert_product_price' ], 50, 2 ); + + // Convert cart editing price. + add_filter( 'wc_nyp_edit_in_cart_args', [ $this, 'edit_in_cart_args' ], 10, 2 ); + add_filter( 'wc_nyp_get_initial_price', [ $this, 'get_initial_price' ], 10, 3 ); } } @@ -92,20 +96,13 @@ public function convert_cart_currency( $cart_item, $values ) { $cart_item['nyp'] = $cart_item['nyp_original']; } else { - $nyp_currency = $this->multi_currency->get_enabled_currencies()[ $cart_item['nyp_currency'] ] ?? null; - - // Convert entered price back to default currency. - $converted_price = ( (float) $cart_item['nyp_original'] ) / $nyp_currency->get_rate(); + $from_currency = $cart_item['nyp_currency']; + $raw_price = $cart_item['nyp_original']; - if ( ! $selected_currency->get_is_default() ) { - $converted_price = $this->multi_currency->get_price( $converted_price, 'product' ); - } - - $cart_item['nyp'] = $converted_price; + $cart_item['nyp'] = $this->multi_currency->get_raw_conversion( $raw_price, $selected_currency->get_code(), $from_currency ); } $cart_item = WC_Name_Your_Price()->cart->set_cart_item( $cart_item ); - } return $cart_item; @@ -140,4 +137,43 @@ public function should_convert_product_price( bool $return, $product ): bool { return $return; } + + /** + * Add currency to cart edit link. + * + * @param array $args The cart args. + * @param array $cart_item The current cart item. + * + * @return array + */ + public function edit_in_cart_args( $args, $cart_item ) { + $args['nyp_currency'] = $this->multi_currency->get_selected_currency()->get_code(); + return $args; + } + + /** + * Maybe convert any prices being edited from the cart + * + * @param string $initial_price The initial price. + * @param mixed $product The product being queried. + * @param string $suffix The suffix needed for composites and bundles. + * + * @return float|string + */ + public function get_initial_price( $initial_price, $product, $suffix ) { + + if ( isset( $_REQUEST[ 'nyp_raw' . $suffix ] ) && isset( $_REQUEST['nyp_currency'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended + + $from_currency = wc_clean( wp_unslash( $_REQUEST['nyp_currency'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended + $raw_price = (float) wc_clean( wp_unslash( $_REQUEST[ 'nyp_raw' . $suffix ] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended + + $selected_currency = $this->multi_currency->get_selected_currency(); + + if ( $from_currency !== $selected_currency->get_code() ) { + $initial_price = $this->multi_currency->get_raw_conversion( $raw_price, $selected_currency->get_code(), $from_currency ); + } + } + + return $initial_price; + } } diff --git a/tests/unit/multi-currency/compatibility/test-class-woocommerce-name-your-price.php b/tests/unit/multi-currency/compatibility/test-class-woocommerce-name-your-price.php index 9e2d4fffa8e..bb563f80b60 100644 --- a/tests/unit/multi-currency/compatibility/test-class-woocommerce-name-your-price.php +++ b/tests/unit/multi-currency/compatibility/test-class-woocommerce-name-your-price.php @@ -197,13 +197,8 @@ public function test_convert_cart_currency_returns_cart_item_with_converted_valu $this->mock_multi_currency ->expects( $this->once() ) - ->method( 'get_enabled_currencies' ) - ->willReturn( [ $item_currency->get_code() => $item_currency ] ); - - $this->mock_multi_currency - ->expects( $this->once() ) - ->method( 'get_price' ) - ->with( $nyp_value / $item_currency->get_rate() ) + ->method( 'get_raw_conversion' ) + ->with( $nyp_value, $selected_currency->get_code(), $item_currency->get_code() ) ->willReturn( $expected_value ); // Act: Attempt to convert the cart item amount. @@ -242,8 +237,9 @@ public function test_convert_cart_currency_returns_cart_item_with_converted_valu $this->mock_multi_currency ->expects( $this->once() ) - ->method( 'get_enabled_currencies' ) - ->willReturn( [ $item_currency->get_code() => $item_currency ] ); + ->method( 'get_raw_conversion' ) + ->with( $nyp_value, $selected_currency->get_code(), $item_currency->get_code() ) + ->willReturn( $expected_value ); // Act: Attempt to convert the cart item amount. $cart_item = $this->woocommerce_nyp->convert_cart_currency( $cart_item, null ); @@ -253,7 +249,6 @@ public function test_convert_cart_currency_returns_cart_item_with_converted_valu // Assert: Confirm the cart_item value matches the expected value. $this->assertEquals( $expected_value, $cart_item['nyp'] ); - } // If the method is passed false it should return false. @@ -322,6 +317,123 @@ public function test_should_convert_product_price_returns_true_when_no_matches() $this->assertTrue( $this->woocommerce_nyp->should_convert_product_price( true, $product ) ); } + public function test_edit_in_cart_args() { + // Arrange: Set up the currency used for the test. + $selected_currency = new Currency( 'EUR', 2.0 ); + + // Arrange: Set up the mock_multi_currency method mock. + $this->mock_multi_currency + ->expects( $this->once() ) + ->method( 'get_selected_currency' ) + ->willReturn( $selected_currency ); + + // Act: Edit the in cart args. + $result = $this->woocommerce_nyp->edit_in_cart_args( [], [] ); + + // Assert: Confirm that the currency code was added to the arg array. + $this->assertSame( $selected_currency->get_code(), $result['nyp_currency'] ); + } + + /** + * Runs through all the checks in the method returning the initial price until the last one passes all the checks. + * + * @dataProvider provider_get_initial_price + */ + public function test_get_initial_price( $initial_price, $suffix, $request, $get_selected_currency, $get_raw_conversion ) { + // Arrange: Set the initial expected price and the currencies that may be used. + $expected_price = $initial_price; + $selected_currency = new Currency( 'EUR', 2.0 ); + $store_currency = new Currency( 'USD', 1 ); + + // Arrange: Set expectations for calls to get_selected_currency method. + if ( $get_selected_currency ) { + $this->mock_multi_currency + ->expects( $this->once() ) + ->method( 'get_selected_currency' ) + ->willReturn( $selected_currency ); + } else { + $this->mock_multi_currency + ->expects( $this->never() ) + ->method( 'get_selected_currency' ); + } + + // Arrange: Set expectations for calls to get_raw_conversion method and update expected price. + if ( $get_raw_conversion ) { + $expected_price = $initial_price * ( $selected_currency->get_rate() / $store_currency->get_rate() ); + + $this->mock_multi_currency + ->expects( $this->once() ) + ->method( 'get_raw_conversion' ) + ->with( $initial_price, $selected_currency->get_code(), $store_currency->get_code() ) + ->willReturn( $expected_price ); + } else { + $this->mock_multi_currency + ->expects( $this->never() ) + ->method( 'get_raw_conversion' ); + } + + // Arrange: Manually set the request prarameters. + foreach ( $request as $key => $value ) { + $_REQUEST[ $key ] = $value; + } + + // Act: Get the initial price. + $result = $this->woocommerce_nyp->get_initial_price( $initial_price, '', $suffix ); + + // Assert: Confirm the initial price is returned. + $this->assertSame( $expected_price, $result ); + } + + public function provider_get_initial_price() { + return [ + 'Both requests false - return initial_price' => [ + 'initial_price' => 10.00, + 'suffix' => '', + 'request' => [], + 'get_selected_currency' => false, + 'get_raw_conversion' => false, + ], + 'First request true - return initial_price' => [ + 'initial_price' => 10.00, + 'suffix' => '_suffix', + 'request' => [ + 'nyp_raw_suffix' => 'test', + ], + 'get_selected_currency' => false, + 'get_raw_conversion' => false, + ], + 'Second request true - return initial_price' => [ + 'initial_price' => 10.00, + 'suffix' => '_suffix', + 'request' => [ + 'nyp_currency' => 'test', + ], + 'get_selected_currency' => false, + 'get_raw_conversion' => false, + ], + 'Both requests true - return initial_price' => [ + 'initial_price' => 10.00, + 'suffix' => '_suffix', + 'request' => [ + 'nyp_raw_suffix' => 10.00, + 'nyp_currency' => 'EUR', + ], + 'get_selected_currency' => true, + 'get_raw_conversion' => false, + ], + 'Both requests true - return converted price' => [ + 'initial_price' => 10.00, + 'suffix' => '_suffix', + 'request' => [ + 'nyp_raw_suffix' => 10.00, + 'nyp_currency' => 'USD', + ], + 'get_selected_currency' => true, + 'get_raw_conversion' => true, + ], + ]; + } + /** * Sets up `is_nyp` to return true or false for a test. */