diff --git a/inc/checkout.php b/inc/checkout.php index 309bba5..c8b2708 100644 --- a/inc/checkout.php +++ b/inc/checkout.php @@ -1,6 +1,6 @@ %s', - esc_url( $policy_url ), - esc_html__( 'terms and privacy policy', 'libresign' ) + woocommerce_register_additional_checkout_field( + array( + 'id' => 'libresign/policy-consent', + 'label' => __( 'I agree to the terms and privacy policy before placing the order.', 'libresign' ), + 'location' => 'order', + 'type' => 'checkbox', + 'required' => true, + 'error_message' => __( 'You must agree to the policies before completing the purchase.', 'libresign' ), ) ); } -add_filter( 'woocommerce_get_terms_and_conditions_checkbox_text', 'libresign_theme_checkout_policy_checkbox_text' ); +add_action( 'woocommerce_init', 'libresign_theme_register_policy_consent_field' ); /** - * Prevent checkout submission without policy terms acceptance. + * Refuse an order placed through the classic checkout without the policy consent. */ function libresign_theme_validate_checkout_policy_consent( $data, $errors ) { if ( empty( $data['terms'] ) ) { @@ -37,3 +40,34 @@ function libresign_theme_validate_checkout_policy_consent( $data, $errors ) { } } add_action( 'woocommerce_after_checkout_validation', 'libresign_theme_validate_checkout_policy_consent', 10, 2 ); + +/** + * Link the checkout terms text to the policy. + */ +function libresign_theme_link_checkout_terms_to_policy( $block_content ) { + $text = sprintf( + /* translators: %s: policy page link */ + __( 'Read the %s.', 'libresign' ), + sprintf( + '%s', + esc_url( libresign_theme_get_policy_url() ), + esc_html__( 'terms and privacy policy', 'libresign' ) + ) + ); + + $processor = new WP_HTML_Tag_Processor( (string) $block_content ); + + if ( + $processor->next_tag( + array( + 'tag_name' => 'div', + 'class_name' => 'wp-block-woocommerce-checkout-terms-block', + ) + ) + ) { + $processor->set_attribute( 'data-text', $text ); + } + + return $processor->get_updated_html(); +} +add_filter( 'render_block_woocommerce/checkout-terms-block', 'libresign_theme_link_checkout_terms_to_policy' ); diff --git a/tests/Integration/Inc/CheckoutTest.php b/tests/Integration/Inc/CheckoutTest.php index a306fe7..417acb9 100644 --- a/tests/Integration/Inc/CheckoutTest.php +++ b/tests/Integration/Inc/CheckoutTest.php @@ -2,34 +2,68 @@ namespace LibreSign\WordPressTheme\Tests\Integration\Inc; +use Automattic\WooCommerce\Blocks\Domain\Services\CheckoutFields; +use Automattic\WooCommerce\Blocks\Package; use WP_Error; use WP_UnitTestCase; final class CheckoutTest extends WP_UnitTestCase { - private function checkout_errors( $data ) { - $errors = new WP_Error(); - do_action( 'woocommerce_after_checkout_validation', $data, $errors ); + public function test_requires_the_policy_consent_to_place_an_order() { + __internal_woocommerce_blocks_deregister_checkout_field( 'libresign/policy-consent' ); - return $errors; - } + libresign_theme_register_policy_consent_field(); - public function test_the_terms_checkbox_links_to_the_policy_in_a_new_tab() { - $this->assertSame( - 'I agree to the terms and privacy policy before placing the order.', - apply_filters( 'woocommerce_get_terms_and_conditions_checkbox_text', '' ) - ); + $field = Package::container()->get( CheckoutFields::class )->get_additional_fields()['libresign/policy-consent']; + + $this->assertSame( 'checkbox', $field['type'] ); + $this->assertSame( 'order', $field['location'] ); + $this->assertTrue( $field['required'] ); + $this->assertSame( 'I agree to the terms and privacy policy before placing the order.', $field['label'] ); + $this->assertSame( 'You must agree to the policies before completing the purchase.', $field['errorMessage'] ); } - public function test_refuses_an_order_without_the_policy_consent() { - $errors = $this->checkout_errors( array( 'terms' => 0 ) ); + public function test_the_classic_checkout_refuses_an_order_without_the_consent() { + $errors = new WP_Error(); + + do_action( 'woocommerce_after_checkout_validation', array( 'terms' => 0 ), $errors ); $this->assertContains( 'libresign_policy_consent', $errors->get_error_codes() ); } - public function test_accepts_an_order_with_the_policy_consent() { - $errors = $this->checkout_errors( array( 'terms' => 1 ) ); + public function test_the_classic_checkout_accepts_an_order_with_the_consent() { + $errors = new WP_Error(); + + do_action( 'woocommerce_after_checkout_validation', array( 'terms' => 1 ), $errors ); $this->assertNotContains( 'libresign_policy_consent', $errors->get_error_codes() ); } + + /** + * @dataProvider provide_terms_blocks + */ + public function test_links_the_checkout_terms_to_the_policy( $block_content, $expected ) { + $this->assertSame( $expected, apply_filters( 'render_block_woocommerce/checkout-terms-block', $block_content ) ); + } + + public static function provide_terms_blocks() { + $policy_text = 'data-text="Read the <a href="https://libresign.coop/privacy-policy" target="_blank" rel="noopener noreferrer">terms and privacy policy</a>."'; + + yield 'as saved' => array( + '
', + '
', + ); + yield 'as woocommerce renders it' => array( + '
', + '
', + ); + yield 'with a text already set' => array( + '
', + '
', + ); + } + + public function test_leaves_other_markup_alone() { + $this->assertSame( '
', libresign_theme_link_checkout_terms_to_policy( '
' ) ); + } }