Skip to content

Commit

Permalink
Show ECE buttons on products w/o shipping tax included in price, and …
Browse files Browse the repository at this point in the history
…improve tests (#9954)

Co-authored-by: Timur Karimov <timur@Timurs-MacBook-Pro.local>
Co-authored-by: Mike Moore <michael.moore@automattic.com>
  • Loading branch information
3 people authored Dec 19, 2024
1 parent 863519d commit 2176d63
Show file tree
Hide file tree
Showing 4 changed files with 185 additions and 75 deletions.
4 changes: 4 additions & 0 deletions changelog/fix-ece-button-for-price-including-tax
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: fix

Show express checkout for products w/o shipping but where tax is included into price.
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ public function should_show_express_checkout_button() {
return true;
}

// Non-shipping product and billing is calculated based on shopper billing addres. Excludes Pay for Order page.
// Non-shipping product and tax is calculated based on shopper billing address. Excludes Pay for Order page.
if (
// If the product doesn't needs shipping.
(
Expand All @@ -426,8 +426,10 @@ public function should_show_express_checkout_button() {
( ( $this->is_cart() || $this->is_checkout() ) && ! WC()->cart->needs_shipping() )
)

// ...and billing is calculated based on billing address.
&& wc_tax_enabled() && 'billing' === get_option( 'woocommerce_tax_based_on' )
// ...and tax is calculated based on billing address.
&& wc_tax_enabled()
&& 'billing' === get_option( 'woocommerce_tax_based_on' )
&& 'yes' !== get_option( 'woocommerce_prices_include_tax' )
) {
return false;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
<?php
/**
* Class WC_Payments_Express_Checkout_Button_Handler_Test
*
* @package WooCommerce\Payments\Tests
*/

use PHPUnit\Framework\MockObject\MockObject;

/**
* WC_Payments_Express_Checkout_Button_Handler unit tests.
*/
class WC_Payments_Express_Checkout_Button_Handler_Test extends WCPAY_UnitTestCase {
/**
* System under test.
*
* @var WC_Payments_Express_Checkout_Button_Handler
*/
private $system_under_test;

/**
* Mock WC_Payments_Account.
*
* @var WC_Payments_Account|MockObject
*/
private $mock_wcpay_account;

/**
* Mock WC_Payment_Gateway_WCPay.
*
* @var WC_Payment_Gateway_WCPay|MockObject
*/
private $mock_wcpay_gateway;

/**
* Mock Express Checkout Button Helper.
*
* @var WC_Payments_Express_Checkout_Button_Helper|MockObject
*/
private $mock_ece_button_helper;

/**
* Mock Express Checkout Ajax Handler.
*
* @var WC_Payments_Express_Checkout_Ajax_Handler|MockObject
*/
private $mock_express_checkout_ajax_handler;



/**
* Shipping zone.
*
* @var WC_Shipping_Zone
*/
private $zone;

/**
* Flat rate shipping method ID.
*
* @var int
*/
private $flat_rate_id;

/**
* Local pickup shipping method ID.
*
* @var int
*/
private $local_pickup_id;

/**
* Pre-test setup
*/
public function set_up() {
parent::set_up();

WC()->shipping()->unregister_shipping_methods();

$this->mock_wcpay_account = $this->createMock( WC_Payments_Account::class );
$this->mock_wcpay_gateway = $this->createMock( WC_Payment_Gateway_WCPay::class );
$this->mock_ece_button_helper = $this->createMock( WC_Payments_Express_Checkout_Button_Helper::class );
$this->mock_express_checkout_ajax_handler = $this->createMock( WC_Payments_Express_Checkout_Ajax_Handler::class );

$this->system_under_test = new WC_Payments_Express_Checkout_Button_Handler(
$this->mock_wcpay_account,
$this->mock_wcpay_gateway,
$this->mock_ece_button_helper,
$this->mock_express_checkout_ajax_handler
);

// Set up shipping zones and methods.
$this->zone = new WC_Shipping_Zone();
$this->zone->set_zone_name( 'Worldwide' );
$this->zone->set_zone_order( 1 );
$this->zone->save();

$flat_rate = $this->zone->add_shipping_method( 'flat_rate' );
$this->flat_rate_id = $flat_rate;

$local_pickup = $this->zone->add_shipping_method( 'local_pickup' );
$this->local_pickup_id = $local_pickup;
}

public function tear_down() {
parent::tear_down();

// Clean up shipping zones and methods.
$this->zone->delete();
}

public function test_filter_cart_needs_shipping_address_regular_products() {
$this->assertEquals(
true,
$this->system_under_test->filter_cart_needs_shipping_address( true ),
'Should not modify shipping address requirement for regular products'
);
}


public function test_filter_cart_needs_shipping_address_subscription_products() {
WC_Subscriptions_Cart::set_cart_contains_subscription( true );
$this->mock_ece_button_helper->method( 'is_checkout' )->willReturn( true );

$this->zone->delete_shipping_method( $this->flat_rate_id );
$this->zone->delete_shipping_method( $this->local_pickup_id );

$this->assertFalse(
$this->system_under_test->filter_cart_needs_shipping_address( true ),
'Should not require shipping address for subscription without shipping methods'
);

remove_filter( 'woocommerce_shipping_method_count', '__return_zero' );
WC_Subscriptions_Cart::set_cart_contains_subscription( false );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,6 @@ class WC_Payments_Express_Checkout_Button_Helper_Test extends WCPAY_UnitTestCase
*/
private $mock_wcpay_account;

/**
* Express Checkout Helper instance.
*
* @var WC_Payments_Express_Checkout_Button_Helper
*/
private $express_checkout_helper;

/**
* Test shipping zone.
*
Expand All @@ -61,21 +54,7 @@ class WC_Payments_Express_Checkout_Button_Helper_Test extends WCPAY_UnitTestCase
*
* @var WC_Payments_Express_Checkout_Button_Helper
*/
private $mock_express_checkout_helper;

/**
* Express Checkout Ajax Handler instance.
*
* @var WC_Payments_Express_Checkout_Ajax_Handler
*/
private $mock_express_checkout_ajax_handler;

/**
* Express Checkout ECE Button Handler instance.
*
* @var WC_Payments_Express_Checkout_Button_Handler
*/
private $mock_express_checkout_ece_button_handler;
private $system_under_test;

/**
* Test product to add to the cart
Expand All @@ -92,23 +71,7 @@ public function set_up() {
$this->mock_wcpay_account = $this->createMock( WC_Payments_Account::class );
$this->mock_wcpay_gateway = $this->make_wcpay_gateway();

$this->mock_express_checkout_helper = new WC_Payments_Express_Checkout_Button_Helper( $this->mock_wcpay_gateway, $this->mock_wcpay_account );
$this->mock_express_checkout_ajax_handler = $this->getMockBuilder( WC_Payments_Express_Checkout_Ajax_Handler::class )
->setConstructorArgs(
[
$this->mock_express_checkout_helper,
]
)
->getMock();

$this->mock_ece_button_helper = $this->getMockBuilder( WC_Payments_Express_Checkout_Button_Helper::class )
->setConstructorArgs(
[
$this->mock_wcpay_gateway,
$this->mock_wcpay_account,
]
)
->getMock();
$this->system_under_test = new WC_Payments_Express_Checkout_Button_Helper( $this->mock_wcpay_gateway, $this->mock_wcpay_account );

WC_Helper_Shipping::delete_simple_flat_rate();
$zone = new WC_Shipping_Zone();
Expand All @@ -128,7 +91,7 @@ public function set_up() {

WC()->session->init();
WC()->cart->add_to_cart( $this->simple_product->get_id(), 1 );
$this->mock_express_checkout_helper->update_shipping_method( [ self::get_shipping_option_rate_id( $this->flat_rate_id ) ] );
$this->system_under_test->update_shipping_method( [ self::get_shipping_option_rate_id( $this->flat_rate_id ) ] );
WC()->cart->calculate_totals();
}

Expand Down Expand Up @@ -195,34 +158,34 @@ public function test_common_get_button_settings() {
'height' => '48',
'radius' => '',
],
$this->mock_express_checkout_helper->get_common_button_settings()
$this->system_under_test->get_common_button_settings()
);
}

public function test_cart_prices_include_tax_with_tax_disabled() {
add_filter( 'wc_tax_enabled', '__return_false' );
$this->assertTrue( $this->mock_express_checkout_helper->cart_prices_include_tax() );
$this->assertTrue( $this->system_under_test->cart_prices_include_tax() );
}

public function test_cart_prices_include_tax_with_tax_enabled_and_display_incl() {
add_filter( 'wc_tax_enabled', '__return_true' ); // reset in tear_down.
add_filter( 'pre_option_woocommerce_tax_display_cart', [ $this, '__return_incl' ] ); // reset in tear_down.

$this->assertTrue( $this->mock_express_checkout_helper->cart_prices_include_tax() );
$this->assertTrue( $this->system_under_test->cart_prices_include_tax() );
}

public function test_cart_prices_include_tax_with_tax_enabled_and_display_excl() {
add_filter( 'wc_tax_enabled', '__return_true' ); // reset in tear_down.
add_filter( 'pre_option_woocommerce_tax_display_cart', [ $this, '__return_excl' ] ); // reset in tear_down.

$this->assertFalse( $this->mock_express_checkout_helper->cart_prices_include_tax() );
$this->assertFalse( $this->system_under_test->cart_prices_include_tax() );
}

public function test_get_total_label() {
$this->mock_wcpay_account->method( 'get_statement_descriptor' )
->willReturn( 'Google Pay' );

$result = $this->mock_express_checkout_helper->get_total_label();
$result = $this->system_under_test->get_total_label();

$this->assertEquals( 'Google Pay (via WooCommerce)', $result );
}
Expand All @@ -238,49 +201,54 @@ function () {
}
);

$result = $this->mock_express_checkout_helper->get_total_label();
$result = $this->system_under_test->get_total_label();

$this->assertEquals( 'Google Pay (via WooPayments)', $result );

remove_all_filters( 'wcpay_payment_request_total_label_suffix' );
}

public function test_filter_cart_needs_shipping_address_returns_false() {
sleep( 1 );
$this->zone->delete_shipping_method( $this->flat_rate_id );
$this->zone->delete_shipping_method( $this->local_pickup_id );
public function test_should_show_express_checkout_button_for_non_shipping_but_price_includes_tax() {
$this->mock_wcpay_account
->method( 'is_stripe_connected' )
->willReturn( true );

WC_Subscriptions_Cart::set_cart_contains_subscription( true );
WC_Payments::mode()->dev();

$this->mock_ece_button_helper
->method( 'is_product' )
->willReturn( true );
add_filter( 'woocommerce_is_checkout', '__return_true' );
add_filter( 'wc_shipping_enabled', '__return_false' );
add_filter( 'wc_tax_enabled', '__return_true' );

$this->mock_express_checkout_ece_button_handler = new WC_Payments_Express_Checkout_Button_Handler(
$this->mock_wcpay_account,
$this->mock_wcpay_gateway,
$this->mock_ece_button_helper,
$this->mock_express_checkout_ajax_handler
);
update_option( 'woocommerce_tax_based_on', 'billing' );
update_option( 'woocommerce_prices_include_tax', 'yes' );

$this->assertFalse( $this->mock_express_checkout_ece_button_handler->filter_cart_needs_shipping_address( true ) );
$this->assertTrue( $this->system_under_test->should_show_express_checkout_button() );

remove_filter( 'woocommerce_is_checkout', '__return_true' );
remove_filter( 'wc_tax_enabled', '__return_true' );
remove_filter( 'pre_option_woocommerce_tax_display_cart', [ $this, '__return_incl' ] );
}

public function test_filter_cart_needs_shipping_address_returns_true() {
WC_Subscriptions_Cart::set_cart_contains_subscription( true );

$this->mock_ece_button_helper
->method( 'is_product' )
public function test_should_not_show_express_checkout_button_for_non_shipping_but_price_does_not_include_tax() {
$this->mock_wcpay_account
->method( 'is_stripe_connected' )
->willReturn( true );

$this->mock_express_checkout_ece_button_handler = new WC_Payments_Express_Checkout_Button_Handler(
$this->mock_wcpay_account,
$this->mock_wcpay_gateway,
$this->mock_ece_button_helper,
$this->mock_express_checkout_ajax_handler
);
WC_Payments::mode()->dev();

add_filter( 'woocommerce_is_checkout', '__return_true' );
add_filter( 'wc_shipping_enabled', '__return_false' );
add_filter( 'wc_tax_enabled', '__return_true' );

update_option( 'woocommerce_tax_based_on', 'billing' );
update_option( 'woocommerce_prices_include_tax', 'no' );

$this->assertTrue( $this->mock_express_checkout_ece_button_handler->filter_cart_needs_shipping_address( true ) );
$this->assertFalse( $this->system_under_test->should_show_express_checkout_button() );

remove_filter( 'woocommerce_is_checkout', '__return_true' );
remove_filter( 'wc_tax_enabled', '__return_true' );
remove_filter( 'pre_option_woocommerce_tax_display_cart', [ $this, '__return_incl' ] );
}

/**
Expand Down

0 comments on commit 2176d63

Please sign in to comment.