diff --git a/includes/admin/class-wc-admin-post-types.php b/includes/admin/class-wc-admin-post-types.php index 32253445884..fb81e543eca 100644 --- a/includes/admin/class-wc-admin-post-types.php +++ b/includes/admin/class-wc-admin-post-types.php @@ -959,11 +959,12 @@ class WC_Admin_Post_Types { if ( 'sale' !== $price_type ) { break; } + $regular_price = $product->get_regular_price(); if ( $is_percentage ) { $percent = $price / 100; - $new_price = max( 0, $product->regular_price - ( round( $product->regular_price * $percent, wc_get_price_decimals() ) ) ); + $new_price = max( 0, $regular_price - ( round( $regular_price * $percent, wc_get_price_decimals() ) ) ); } else { - $new_price = max( 0, $product->regular_price - $price ); + $new_price = max( 0, $regular_price - $price ); } break; diff --git a/tests/unit-tests/admin/class-wc-tests-admin-post-types.php b/tests/unit-tests/admin/class-wc-tests-admin-post-types.php index aa201ff2eaf..433b58c0a81 100644 --- a/tests/unit-tests/admin/class-wc-tests-admin-post-types.php +++ b/tests/unit-tests/admin/class-wc-tests-admin-post-types.php @@ -12,10 +12,27 @@ */ class WC_Tests_Admin_Post_Types extends WC_Unit_Test_Case { + /** + * Get a new SUT (System Under Test) instance and configure the specified fake request data. + * + * @param array $request_data Fake request data to configure. + * @return WC_Admin_Post_Types + */ + private function get_sut_with_request_data( $request_data ) { + $sut = $this + ->getMockBuilder( WC_Admin_Post_Types::class ) + ->setMethods( array( 'request_data' ) ) + ->getMock(); + + $sut->method( 'request_data' )->willReturn( $request_data ); + + return $sut; + } + /** * Data for bulk_and_quick_edit_stock_status_for_variable_product test. * - * @return string[][] + * @return array */ public function data_provider_bulk_and_quick_edit_stock_status_for_variable_product() { return array( @@ -55,12 +72,7 @@ class WC_Tests_Admin_Post_Types extends WC_Unit_Test_Case { 'woocommerce_quick_edit_nonce' => wp_create_nonce( 'woocommerce_quick_edit_nonce' ), ); - $sut = $this - ->getMockBuilder( WC_Admin_Post_Types::class ) - ->setMethods( array( 'request_data' ) ) - ->getMock(); - - $sut->method( 'request_data' )->willReturn( $request_data ); + $sut = $this->get_sut_with_request_data( $request_data ); $sut->bulk_and_quick_edit_save_post( $product->get_id(), get_post( $product->get_id() ) ); @@ -69,4 +81,72 @@ class WC_Tests_Admin_Post_Types extends WC_Unit_Test_Case { $this->assertEquals( $expected_new_stock_status, $child->get_stock_status() ); } } + + /** + * Data for bulk_change_price test. + * + * @return array + */ + public function data_provider_bulk_change_price() { + $dataset = array(); + + // phpcs:ignore Squiz.PHP.CommentedOutCode.Found + // $type_of_price, $initial_price, $type_of_change, $change_amount, $expected_new_price + foreach ( array( 'regular', 'sale' ) as $type ) { + array_push( $dataset, array( $type, '10.33', '1', '5.339', 5.34 ) ); + array_push( $dataset, array( $type, '10.33', '2', '5.3333', 15.66 ) ); + array_push( $dataset, array( $type, '10.33', '2', '15.555%', 11.94 ) ); + array_push( $dataset, array( $type, '10.33', '3', '5.339', 4.99 ) ); + array_push( $dataset, array( $type, '10.33', '3', '15.555%', 8.72 ) ); + } + + array_push( $dataset, array( 'regular', '10.33', '4', '5.339', 10.33 ) ); + array_push( $dataset, array( 'regular', '10.33', '4', '15.555%', 10.33 ) ); + + array_push( $dataset, array( 'sale', '10.33', '4', '5.339', 97.96 ) ); + array_push( $dataset, array( 'sale', '10.33', '4', '15.555%', 87.23 ) ); + + return $dataset; + } + + /** + * @test + * @testdox Prices should change appropriately when a price change is requested via bulk edit. + * @dataProvider data_provider_bulk_change_price + * + * @param string $type_of_price 'regular' or 'sale'. + * @param string $initial_price Initial value for the price. + * @param string $type_of_change 1=absolute, 2=increase, 3=decrease, 4=regular minus (for sale price only). + * @param string $change_amount The amount to change, ending with '%' if it's a percent. + * @param string $expected_new_price Expected value of the product price after the save operation. + */ + public function bulk_change_price( $type_of_price, $initial_price, $type_of_change, $change_amount, $expected_new_price ) { + if ( 'regular' === $type_of_price ) { + $props = array( 'regular_price' => $initial_price ); + } else { + $props = array( + 'regular_price' => $initial_price * 10, + 'sale_price' => $initial_price, + ); + } + + $product = WC_Helper_Product::create_simple_product( true, $props ); + + $this->login_as_administrator(); + + $request_data = array( + 'woocommerce_bulk_edit' => '1', + 'woocommerce_quick_edit_nonce' => wp_create_nonce( 'woocommerce_quick_edit_nonce' ), + "change_{$type_of_price}_price" => $type_of_change, + "_{$type_of_price}_price" => $change_amount, + ); + + $sut = $this->get_sut_with_request_data( $request_data ); + + $sut->bulk_and_quick_edit_save_post( $product->get_id(), get_post( $product->get_id() ) ); + + $product = wc_get_product( $product->get_id() ); + $actual = $product->{"get_{$type_of_price}_price"}(); + $this->assertEquals( $expected_new_price, $actual ); + } }