Commit 5ed695f04c1 for woocommerce
commit 5ed695f04c160a30c16e9433920aeb23ccfb4396
Author: Vlad Olaru <vlad.olaru@automattic.com>
Date: Thu Sep 24 18:15:07 2026 +0300
Revert "[tests] Move order confirmation policy from 6 E2E tests to PHPUnit" (#69051)
revert: Revert "[tests] Move order confirmation policy from 6 E2E tests to PHPUnit" (#68593)
This reverts commit 9095f377e1e0dee54819119a7c00bed9a59d1f22.
Rubik asked for the E2E migration's test changes in its areas to be
reverted until the team can review them. #68593 is one of the 11 PRs on
the revert list Rubik agreed on 2026-09-24.
The revert brings back the browser tests the PR removed or cut down and
removes the lower-layer tests it added in their place. Only test code
and changelog entries change; nothing ships.
AbstractOrderConfirmationBlockTest stays, trimmed to what #68584 added
to it: the order key proxy and its two regression tests for the
array-valued key fatal. Deleting the file with the rest of the revert
would drop the tests for that product fix.
Refs TESTOPS-234
Refs #68593
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
diff --git a/plugins/woocommerce/changelog/testops-234-order-confirmation-blocks b/plugins/woocommerce/changelog/testops-234-order-confirmation-blocks
deleted file mode 100644
index 51eab3ddcf3..00000000000
--- a/plugins/woocommerce/changelog/testops-234-order-confirmation-blocks
+++ /dev/null
@@ -1,4 +0,0 @@
-Significance: patch
-Type: dev
-Comment: Move order confirmation policy from 6 E2E tests to PHPUnit; the Order Confirmation block spec keeps 3 browser titles.
-
diff --git a/plugins/woocommerce/tests/e2e/tests/blocks/checkout/order-confirmation.block_theme.spec.ts b/plugins/woocommerce/tests/e2e/tests/blocks/checkout/order-confirmation.block_theme.spec.ts
index 81705c691c1..19e19b6fc9e 100644
--- a/plugins/woocommerce/tests/e2e/tests/blocks/checkout/order-confirmation.block_theme.spec.ts
+++ b/plugins/woocommerce/tests/e2e/tests/blocks/checkout/order-confirmation.block_theme.spec.ts
@@ -42,7 +42,7 @@ test.describe( 'Shopper (logged-in) → Order Confirmation', () => {
await editor.transformIntoBlocks();
} );
- test( 'Known shopper details require owner and key unless the filter opts out', async ( {
+ test( 'Place order', async ( {
frontendUtils,
checkoutPageObject,
page,
@@ -61,33 +61,103 @@ test.describe( 'Shopper (logged-in) → Order Confirmation', () => {
await checkoutPageObject.fillInCheckoutWithTestData( TEST_ADDRESS );
await checkoutPageObject.placeOrder();
+ // Confirm Order Confirmation Block sections are visible when logged in
+ // order data are visible and correct
await checkoutPageObject.verifyOrderConfirmationDetails();
+ // Store order received URL to use later
const orderReceivedURL = page.url();
- await page.context().clearCookies();
- await page.goto( '/my-account' );
- await expect(
- page.getByRole( 'button', { name: 'Log in' } )
- ).toBeVisible();
+ // Confirm downloads section is visible when logged in
+ // Open order we created
+ const orderId = checkoutPageObject.getOrderId();
+ await page.goto( `wp-admin/post.php?post=${ orderId }&action=edit` );
+ // Update order status to 'Processing'
+ await page.locator( '#order_status' ).selectOption( 'wc-processing' );
+ await page.locator( 'button.save_order' ).click();
+ // Go back to order received page
await page.goto( orderReceivedURL );
- await checkoutPageObject.verifyOrderConfirmationDetails( false );
+ // Confirm downloads section is visible
+ const DownloadSection = page.locator(
+ '[data-block-name="woocommerce/order-confirmation-downloads"]'
+ );
+ await expect( DownloadSection ).toBeVisible();
- const missingKeyURL = new URL( orderReceivedURL );
- missingKeyURL.searchParams.delete( 'key' );
- await page.goto( missingKeyURL.toString() );
+ // Access page without order key (test visibility of default message, no order details)
+ const urlObj = new URL( orderReceivedURL );
+ urlObj.searchParams.delete( 'key' );
+ await page.goto( urlObj.toString() );
+ // Confirm default message is visible
+ await expect(
+ page.getByText(
+ 'Great news! Your order has been received, and a confirmation will be sent to your email address. Have an account with us?'
+ )
+ ).toBeVisible();
+ // Confirm order details are not visible
await checkoutPageObject.verifyOrderConfirmationDetails( false );
- const wrongKeyURL = new URL( orderReceivedURL );
- wrongKeyURL.searchParams.set( 'key', 'wc_order_wrong' );
- await page.goto( wrongKeyURL.toString() );
+ // Access page without order ID or key (test visibility of default message)
+ await page.goto( '/checkout/order-received' );
+ // Confirm default message is visible
+ await expect(
+ page.getByText(
+ "If you've just placed an order, give your email a quick check for the confirmation. Have an account with us?"
+ )
+ ).toBeVisible();
+ // Confirm order details are not visible
await checkoutPageObject.verifyOrderConfirmationDetails( false );
- await requestUtils.activatePlugin(
- 'woocommerce-blocks-test-order-confirmation-filters'
- );
- await page.goto( orderReceivedURL );
- await checkoutPageObject.verifyOrderConfirmationDetails();
+ await test.step( 'Logout the user and revisit the order received page to verify that details are displayed when woocommerce_order_received_verify_known_shoppers is disabled', async () => {
+ await requestUtils.activatePlugin(
+ 'woocommerce-blocks-test-order-confirmation-filters'
+ );
+ await page.goto( '/my-account' );
+ await page
+ .locator(
+ 'li.woocommerce-MyAccount-navigation-link--customer-logout a'
+ )
+ .click();
+ await expect(
+ page.getByRole( 'button', { name: 'Log in' } )
+ ).toBeVisible();
+ await page.goto( orderReceivedURL );
+ await checkoutPageObject.verifyOrderConfirmationDetails();
+ } );
+ } );
+} );
+
+test.describe( 'Shopper (guest) → Order Confirmation', () => {
+ test.use( { storageState: guestFile } );
+
+ test( 'Place order', async ( {
+ frontendUtils,
+ checkoutPageObject,
+ page,
+ } ) => {
+ await page.goto( '/my-account' );
+
+ await expect(
+ page.getByRole( 'heading', { name: 'Login' } ),
+ 'User is not logged out'
+ ).toBeVisible();
+
+ await frontendUtils.goToShop();
+ await frontendUtils.addToCart( SIMPLE_PHYSICAL_PRODUCT_NAME );
+ await frontendUtils.goToCheckout();
+
+ expect(
+ await checkoutPageObject.selectAndVerifyShippingOption(
+ FREE_SHIPPING_NAME,
+ FREE_SHIPPING_PRICE
+ )
+ ).toBe( true );
+
+ await checkoutPageObject.fillInCheckoutWithTestData( TEST_ADDRESS );
+ await checkoutPageObject.placeOrder();
+
+ await expect(
+ page.getByText( 'Thank you. Your order has been received.' )
+ ).toBeVisible();
} );
} );
@@ -166,6 +236,55 @@ test.describe( 'Shopper (guest) → Order Confirmation → Create Account', () =
} );
} );
+test.describe( 'Shopper → Order Confirmation → Local Pickup', () => {
+ test( 'Confirm shipping address section is hidden, but billing is visible', async ( {
+ checkoutPageObject,
+ frontendUtils,
+ admin,
+ } ) => {
+ await admin.visitAdminPage(
+ 'admin.php',
+ 'page=wc-settings&tab=shipping§ion=pickup_location'
+ );
+ await admin.page.getByLabel( 'Enable local pickup' ).uncheck();
+ await admin.page.getByLabel( 'Enable local pickup' ).check();
+ await admin.page
+ .getByRole( 'button', { name: 'Add pickup location' } )
+ .click();
+ await admin.page.getByLabel( 'Location name' ).fill( 'Testing' );
+ await admin.page.getByPlaceholder( 'Address' ).fill( 'Test Address' );
+ await admin.page.getByPlaceholder( 'City' ).fill( 'Test City' );
+ await admin.page.getByPlaceholder( 'Postcode / ZIP' ).fill( '90210' );
+ await admin.page
+ .getByLabel( 'Pickup details' )
+ .fill( 'Pickup method.' );
+ await admin.page.getByRole( 'button', { name: 'Done' } ).click();
+ await admin.page
+ .getByRole( 'button', { name: 'Save changes' } )
+ .click();
+ await admin.page
+ .getByRole( 'button', { name: 'Dismiss this notice' } )
+ .click();
+ await frontendUtils.emptyCart();
+ await frontendUtils.goToShop();
+ await frontendUtils.addToCart( SIMPLE_PHYSICAL_PRODUCT_NAME );
+ await frontendUtils.goToCheckout();
+ await checkoutPageObject.selectDeliveryOption( 'Pickup' );
+ await checkoutPageObject.fillInCheckoutWithTestData();
+ await checkoutPageObject.placeOrder();
+ await expect(
+ checkoutPageObject.page.getByRole( 'heading', {
+ name: 'Shipping address',
+ } )
+ ).toBeHidden();
+ await expect(
+ checkoutPageObject.page.getByRole( 'heading', {
+ name: 'Billing address',
+ } )
+ ).toBeVisible();
+ } );
+} );
+
test.describe( 'Shopper → Order Confirmation → Downloadable Products', () => {
let confirmationPageUrl: string;
@@ -178,7 +297,22 @@ test.describe( 'Shopper → Order Confirmation → Downloadable Products', () =>
confirmationPageUrl = checkoutPageObject.page.url();
} );
- test( 'Completed downloadable order exposes named entitlement links', async ( {
+ test( 'Confirm shipping address section is hidden, but billing is visible', async ( {
+ checkoutPageObject,
+ } ) => {
+ await expect(
+ checkoutPageObject.page.getByRole( 'heading', {
+ name: 'Shipping address',
+ } )
+ ).toBeHidden();
+ await expect(
+ checkoutPageObject.page.getByRole( 'heading', {
+ name: 'Billing address',
+ } )
+ ).toBeVisible();
+ } );
+
+ test( 'Confirm order downloads are visible', async ( {
checkoutPageObject,
admin,
} ) => {
@@ -209,17 +343,5 @@ test.describe( 'Shopper → Order Confirmation → Downloadable Products', () =>
name: 'Downloads',
} )
).toBeVisible();
-
- const downloadsSection = checkoutPageObject.page.locator(
- '[data-block-name="woocommerce/order-confirmation-downloads"]'
- );
- for ( const downloadName of [ 'Single 1', 'Single 2' ] ) {
- const downloadLink = downloadsSection.getByRole( 'link', {
- name: downloadName,
- exact: true,
- } );
- await expect( downloadLink ).toBeVisible();
- await expect( downloadLink ).toHaveAttribute( 'href', /.+/ );
- }
} );
} );
diff --git a/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/OrderConfirmation/AbstractOrderConfirmationBlockTest.php b/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/OrderConfirmation/AbstractOrderConfirmationBlockTest.php
index 3912f6917a5..462de80d529 100644
--- a/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/OrderConfirmation/AbstractOrderConfirmationBlockTest.php
+++ b/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/OrderConfirmation/AbstractOrderConfirmationBlockTest.php
@@ -8,7 +8,7 @@ use WC_Order;
use WC_Unit_Test_Case;
/**
- * Tests for order-confirmation permission decisions.
+ * Tests for order-confirmation order key validation.
*/
final class AbstractOrderConfirmationBlockTest extends WC_Unit_Test_Case {
/**
@@ -28,14 +28,6 @@ final class AbstractOrderConfirmationBlockTest extends WC_Unit_Test_Case {
public function __construct() {
}
// phpcs:ignore Squiz.Commenting.FunctionComment.Missing
- public function get_view_order_permissions_proxy( ?WC_Order $order ) {
- return $this->get_view_order_permissions( $order );
- }
- // phpcs:ignore Squiz.Commenting.FunctionComment.Missing
- public function email_verification_permitted_proxy( WC_Order $order ): bool {
- return $this->email_verification_permitted( $order );
- }
- // phpcs:ignore Squiz.Commenting.FunctionComment.Missing
public function has_valid_order_key_proxy( WC_Order $order ): bool {
return $this->has_valid_order_key( $order );
}
@@ -65,140 +57,4 @@ final class AbstractOrderConfirmationBlockTest extends WC_Unit_Test_Case {
$this->assertTrue( $this->sut->has_valid_order_key_proxy( $order ), 'A valid string key must keep validating.' );
}
-
- /**
- * @testdox Order details require the correct key and the appropriate owner, session, grace-period, or verified-email context.
- * @dataProvider view_permission_cases
- *
- * @param string $scenario Scenario to arrange.
- * @param string|false $expected Expected permission.
- */
- public function test_get_view_order_permissions( string $scenario, $expected ): void {
- // The session is the only piece of state here the base class does not own:
- // it clears the request globals before every test and the current user after.
- $original_draft_order = WC()->session->get( 'store_api_draft_order' );
- $order = null;
-
- try {
- $_GET = array();
- $_POST = array();
- wp_set_current_user( 0 );
- WC()->session->set( 'store_api_draft_order', null );
-
- if ( 'null order' !== $scenario ) {
- $is_customer_order = in_array(
- $scenario,
- array( 'owner valid key', 'owner missing key', 'owner wrong key', 'wrong logged-in user', 'known shopper logged out', 'known shopper filter disabled' ),
- true
- );
- $customer_id = $is_customer_order ? self::factory()->user->create( array( 'role' => 'customer' ) ) : 0;
- $order = $this->create_order( $customer_id, ! in_array( $scenario, array( 'guest draft session', 'guest expired', 'guest verified email' ), true ) );
- $_GET['key'] = $order->get_order_key();
-
- switch ( $scenario ) {
- case 'owner valid key':
- wp_set_current_user( $customer_id );
- break;
- case 'owner missing key':
- wp_set_current_user( $customer_id );
- unset( $_GET['key'] );
- break;
- case 'owner wrong key':
- wp_set_current_user( $customer_id );
- $_GET['key'] = 'wc_order_wrong';
- break;
- case 'wrong logged-in user':
- wp_set_current_user( self::factory()->user->create( array( 'role' => 'customer' ) ) );
- break;
- case 'known shopper filter disabled':
- add_filter( 'woocommerce_order_received_verify_known_shoppers', '__return_false' );
- break;
- case 'guest draft session':
- WC()->session->set( 'store_api_draft_order', $order->get_id() );
- break;
- case 'guest verified email':
- $_POST['email'] = $order->get_billing_email();
- $_POST['_wpnonce'] = wp_create_nonce( 'wc_verify_email' );
- break;
- }
- }
-
- $this->assertSame( $expected, $this->sut->get_view_order_permissions_proxy( $order ) );
- } finally {
- WC()->session->set( 'store_api_draft_order', $original_draft_order );
- }
- }
-
- /**
- * Named order permission cases.
- *
- * @return array<string, array{string, string|false}>
- */
- public static function view_permission_cases(): array {
- return array(
- 'null order' => array( 'null order', false ),
- 'owner with valid key' => array( 'owner valid key', 'full' ),
- 'owner without key' => array( 'owner missing key', false ),
- 'owner with wrong key' => array( 'owner wrong key', false ),
- 'different logged-in customer' => array( 'wrong logged-in user', false ),
- 'known shopper logged out' => array( 'known shopper logged out', false ),
- 'known shopper filter disabled' => array( 'known shopper filter disabled', 'full' ),
- 'guest Store API draft session' => array( 'guest draft session', 'full' ),
- 'guest within grace period' => array( 'guest grace period', 'full' ),
- 'guest after grace period' => array( 'guest expired', false ),
- 'guest with verified email' => array( 'guest verified email', 'full' ),
- );
- }
-
- /**
- * @testdox Email verification is offered only to guest orders with guest checkout enabled and a valid key.
- * @dataProvider email_verification_permission_cases
- *
- * @param bool $guest_checkout_enabled Whether guest checkout is enabled.
- * @param bool $customer_order Whether the order belongs to a customer.
- * @param bool $valid_key Whether the request has the order key.
- * @param bool $expected Expected result.
- */
- public function test_email_verification_permitted( bool $guest_checkout_enabled, bool $customer_order, bool $valid_key, bool $expected ): void {
- $customer_id = $customer_order ? self::factory()->user->create( array( 'role' => 'customer' ) ) : 0;
- $order = $this->create_order( $customer_id );
-
- update_option( 'woocommerce_enable_guest_checkout', $guest_checkout_enabled ? 'yes' : 'no' );
- $_GET = array( 'key' => $valid_key ? $order->get_order_key() : 'wc_order_wrong' );
-
- $this->assertSame( $expected, $this->sut->email_verification_permitted_proxy( $order ) );
- }
-
- /**
- * Named email-verification eligibility cases.
- *
- * @return array<string, array{bool, bool, bool, bool}>
- */
- public static function email_verification_permission_cases(): array {
- return array(
- 'guest checkout and valid key' => array( true, false, true, true ),
- 'guest checkout disabled' => array( false, false, true, false ),
- 'guest order with wrong key' => array( true, false, false, false ),
- 'known customer order with key' => array( true, true, true, false ),
- 'known customer without guest mode' => array( false, true, false, false ),
- );
- }
-
- /**
- * Create a persisted order for a guest or registered customer.
- *
- * @param int $customer_id Customer ID, or zero for a guest.
- * @param bool $within_grace_period Whether the order is recent.
- * @return WC_Order
- */
- private function create_order( int $customer_id, bool $within_grace_period = true ): WC_Order {
- $order = wc_create_order( array( 'customer_id' => $customer_id ) );
- $order->set_billing_email( 'shopper-' . $order->get_id() . '@example.com' );
- if ( ! $within_grace_period ) {
- $order->set_date_created( time() - ( 20 * MINUTE_IN_SECONDS ) );
- }
- $order->save();
-
- return $order;
- }
}
diff --git a/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/OrderConfirmation/BillingAddress.php b/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/OrderConfirmation/BillingAddress.php
index f58e9290773..8e5c63cc48d 100644
--- a/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/OrderConfirmation/BillingAddress.php
+++ b/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/OrderConfirmation/BillingAddress.php
@@ -5,7 +5,6 @@ namespace Automattic\WooCommerce\Tests\Blocks\BlockTypes\OrderConfirmation;
use Automattic\WooCommerce\Blocks\BlockTypes\OrderConfirmation\BillingAddress as BillingAddressBlock;
use Automattic\WooCommerce\Blocks\Domain\Services\CheckoutFields;
use Automattic\WooCommerce\Blocks\Package;
-use Automattic\WooCommerce\Blocks\Shipping\PickupLocation;
/**
* Test BillingAddress block class.
@@ -61,50 +60,6 @@ final class BillingAddress extends \WP_UnitTestCase {
$this->assertStringContainsString( 'visible value', $this->render( $order ) );
}
- /**
- * @testdox Billing details follow view permission but remain present for shipped, pickup, and virtual orders.
- * @dataProvider billing_address_topology_cases
- *
- * @param string $topology Order fulfillment topology.
- * @param string|false $permission View permission.
- * @param bool $expected_visible Whether billing content should render.
- */
- public function test_billing_address_topology( string $topology, $permission, bool $expected_visible ): void {
- try {
- // Inside the try: create_topology_order() registers PickupLocation partway
- // through, so a throw after that point must still reach the finally below.
- $order = $this->create_topology_order( $topology );
- update_option( 'woocommerce_calc_shipping', 'yes' );
- $content = $this->render( $order, $permission );
-
- if ( $expected_visible ) {
- $this->assertStringContainsString( 'Billing Marker', $content, 'Billing details should be non-empty for an authorized order.' );
- } else {
- $this->assertSame( '', $content, 'Billing details should be empty without view permission.' );
- }
- } finally {
- if ( 'pickup-location' === $topology ) {
- // Drop the memo so the next test reloads the ambient method list.
- WC()->shipping()->unregister_shipping_methods();
- }
- }
- }
-
- /**
- * Named billing-address topology cases.
- *
- * @return array<string, array{string, string|false, bool}>
- */
- public static function billing_address_topology_cases(): array {
- return array(
- 'physical order' => array( 'physical', 'full', true ),
- 'classic local pickup order' => array( 'local-pickup', 'full', true ),
- 'blocks pickup location order' => array( 'pickup-location', 'full', true ),
- 'virtual order' => array( 'virtual', 'full', true ),
- 'no view permission' => array( 'physical', false, false ),
- );
- }
-
/**
* Create an order placed via the Store API with a value persisted for the billing group of the test field.
*
@@ -123,11 +78,10 @@ final class BillingAddress extends \WP_UnitTestCase {
/**
* Render the billing address block content for the given order with full view permissions.
*
- * @param \WC_Order $order Order object.
- * @param string|false $permission View permission.
+ * @param \WC_Order $order Order object.
* @return string
*/
- private function render( \WC_Order $order, $permission = 'full' ): string {
+ private function render( \WC_Order $order ): string {
$proxy = new class() extends BillingAddressBlock {
// phpcs:ignore Squiz.Commenting.FunctionComment.Missing
public function __construct() {
@@ -138,65 +92,6 @@ final class BillingAddress extends \WP_UnitTestCase {
}
};
- return $proxy->render_content_proxy( $order, $permission );
- }
-
- /**
- * Create an order with billing data and a representative fulfillment topology.
- *
- * @param string $topology Order fulfillment topology.
- * @return \WC_Order
- */
- private function create_topology_order( string $topology ): \WC_Order {
- $product = \WC_Helper_Product::create_simple_product(
- true,
- array(
- 'downloadable' => 'virtual' === $topology,
- 'virtual' => 'virtual' === $topology,
- )
- );
- $product->set_virtual( 'virtual' === $topology );
- $product->save();
-
- $order = wc_create_order( array( 'customer_id' => 0 ) );
- $item = new \WC_Order_Item_Product();
- $item->set_product( $product );
- $item->set_quantity( 1 );
- $order->add_item( $item );
- $order->set_billing_first_name( 'Billing' );
- $order->set_billing_last_name( 'Marker' );
- $order->set_billing_address_1( '500 Billing Avenue' );
- $order->set_billing_city( 'San Francisco' );
- $order->set_billing_state( 'CA' );
- $order->set_billing_postcode( '94105' );
- $order->set_billing_country( 'US' );
-
- if ( 'virtual' !== $topology ) {
- $shipping_item = new \WC_Order_Item_Shipping();
- // `local_pickup` is the classic pickup method, `pickup_location` the Blocks one.
- // `needs_shipping_address()` hides the address for both, but it finds
- // `pickup_location` only by asking the registered shipping methods which of them
- // support `local-pickup`. Core registers that method when the Checkout block is
- // the default checkout, which the test store is not, so register it the same way.
- $pickup_methods = array(
- 'local-pickup' => array( 'Local pickup', 'local_pickup' ),
- 'pickup-location' => array( 'Pickup Location', 'pickup_location' ),
- );
-
- if ( 'pickup-location' === $topology ) {
- WC()->shipping()->get_shipping_methods();
- WC()->shipping()->register_shipping_method( new PickupLocation() );
- }
-
- list( $method_title, $method_id ) = $pickup_methods[ $topology ] ?? array( 'Free shipping', 'free_shipping' );
-
- $shipping_item->set_method_title( $method_title );
- $shipping_item->set_method_id( $method_id );
- $order->add_item( $shipping_item );
- }
-
- $order->save();
-
- return $order;
+ return $proxy->render_content_proxy( $order, 'full' );
}
}
diff --git a/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/OrderConfirmation/BillingWrapperTest.php b/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/OrderConfirmation/BillingWrapperTest.php
deleted file mode 100644
index a560b19d877..00000000000
--- a/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/OrderConfirmation/BillingWrapperTest.php
+++ /dev/null
@@ -1,146 +0,0 @@
-<?php
-declare( strict_types = 1 );
-
-namespace Automattic\WooCommerce\Tests\Blocks\BlockTypes\OrderConfirmation;
-
-use Automattic\WooCommerce\Blocks\BlockTypes\OrderConfirmation\BillingWrapper as BillingWrapperBlock;
-use Automattic\WooCommerce\Blocks\Shipping\PickupLocation;
-use WC_Order;
-use WC_Order_Item_Product;
-use WC_Order_Item_Shipping;
-use WC_Product;
-use WC_Unit_Test_Case;
-
-/**
- * Tests for the order-confirmation billing wrapper.
- */
-final class BillingWrapperTest extends WC_Unit_Test_Case {
- /**
- * @testdox Billing wrapper headings and content require an address and permission across fulfillment topologies.
- * @dataProvider billing_wrapper_cases
- *
- * @param string $topology Order fulfillment topology.
- * @param string|false $permission View permission.
- * @param bool $has_address Whether the order has a billing address.
- * @param bool $expected_visible Whether wrapper content should render.
- */
- public function test_billing_wrapper_topology( string $topology, $permission, bool $has_address, bool $expected_visible ): void {
- $content = '<h2>Billing address</h2><p>Billing wrapper marker</p>';
-
- try {
- // Inside the try: create_order() registers PickupLocation partway through,
- // so a throw after that point must still reach the finally below.
- $order = $this->create_order( $topology, $has_address );
- $rendered = $this->render( $order, $permission, $content );
-
- if ( $expected_visible ) {
- $this->assertSame( $content, $rendered, 'An authorized order with billing data should preserve the wrapper heading and content.' );
- } else {
- $this->assertSame( '', $rendered, 'The billing wrapper should be empty without permission or an address.' );
- }
- } finally {
- if ( 'pickup-location' === $topology ) {
- // Drop the memo so the next test reloads the ambient method list.
- WC()->shipping()->unregister_shipping_methods();
- }
- }
- }
-
- /**
- * Named billing-wrapper cases.
- *
- * @return array<string, array{string, string|false, bool, bool}>
- */
- public static function billing_wrapper_cases(): array {
- return array(
- 'physical free-shipping order' => array( 'physical', 'full', true, true ),
- 'classic local pickup order' => array( 'local-pickup', 'full', true, true ),
- 'blocks pickup location order' => array( 'pickup-location', 'full', true, true ),
- 'virtual downloadable order' => array( 'virtual', 'full', true, true ),
- 'no view permission' => array( 'physical', false, true, false ),
- 'no billing address' => array( 'physical', 'full', false, false ),
- );
- }
-
- /**
- * Render wrapper content through a public proxy.
- *
- * @param WC_Order $order Order object.
- * @param string|false $permission View permission.
- * @param string $content Wrapper content.
- * @return string
- */
- private function render( WC_Order $order, $permission, string $content ): string {
- $proxy = new class() extends BillingWrapperBlock {
- // phpcs:ignore Squiz.Commenting.FunctionComment.Missing
- public function __construct() {
- }
- // phpcs:ignore Squiz.Commenting.FunctionComment.Missing
- public function render_content_proxy( $order, $permission, $content ) {
- return $this->render_content( $order, $permission, array(), $content );
- }
- };
-
- return $proxy->render_content_proxy( $order, $permission, $content );
- }
-
- /**
- * Create a persisted order for one fulfillment topology.
- *
- * @param string $topology Order fulfillment topology.
- * @param bool $has_address Whether to add billing data.
- * @return WC_Order
- */
- private function create_order( string $topology, bool $has_address ): WC_Order {
- $product = \WC_Helper_Product::create_simple_product(
- true,
- array(
- 'downloadable' => 'virtual' === $topology,
- 'virtual' => 'virtual' === $topology,
- )
- );
- $order = wc_create_order( array( 'customer_id' => 0 ) );
- $item = new WC_Order_Item_Product();
- $item->set_product( $product );
- $item->set_quantity( 1 );
- $order->add_item( $item );
-
- if ( $has_address ) {
- $order->set_billing_first_name( 'Billing' );
- $order->set_billing_last_name( 'Marker' );
- $order->set_billing_address_1( '500 Billing Avenue' );
- $order->set_billing_city( 'San Francisco' );
- $order->set_billing_state( 'CA' );
- $order->set_billing_postcode( '94105' );
- $order->set_billing_country( 'US' );
- }
-
- if ( 'virtual' !== $topology ) {
- $shipping_item = new WC_Order_Item_Shipping();
- // `local_pickup` is the classic pickup method, `pickup_location` the Blocks one.
- // `needs_shipping_address()` hides the address for both, but it finds
- // `pickup_location` only by asking the registered shipping methods which of them
- // support `local-pickup`. Core registers that method when the Checkout block is
- // the default checkout, which the test store is not, so register it the same way.
- $pickup_methods = array(
- 'local-pickup' => array( 'Local pickup', 'local_pickup' ),
- 'pickup-location' => array( 'Pickup Location', 'pickup_location' ),
- );
-
- if ( 'pickup-location' === $topology ) {
- WC()->shipping()->get_shipping_methods();
- WC()->shipping()->register_shipping_method( new PickupLocation() );
- }
-
- list( $method_title, $method_id ) = $pickup_methods[ $topology ] ?? array( 'Free shipping', 'free_shipping' );
-
- $shipping_item->set_method_title( $method_title );
- $shipping_item->set_method_id( $method_id );
- $order->add_item( $shipping_item );
- }
-
- $order->save();
-
- return $order;
- }
-}
diff --git a/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/OrderConfirmation/DownloadsTest.php b/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/OrderConfirmation/DownloadsTest.php
deleted file mode 100644
index 4d45a6677c6..00000000000
--- a/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/OrderConfirmation/DownloadsTest.php
+++ /dev/null
@@ -1,150 +0,0 @@
-<?php
-declare( strict_types = 1 );
-
-namespace Automattic\WooCommerce\Tests\Blocks\BlockTypes\OrderConfirmation;
-
-use Automattic\WooCommerce\Blocks\BlockTypes\OrderConfirmation\Downloads as DownloadsBlock;
-use Automattic\WooCommerce\Internal\ProductDownloads\ApprovedDirectories\Register as Download_Directories;
-use WC_Order;
-use WC_Order_Item_Product;
-use WC_Product;
-use WC_Unit_Test_Case;
-
-/**
- * Tests for the order-confirmation downloads table.
- */
-final class DownloadsTest extends WC_Unit_Test_Case {
- /**
- * @testdox Download rows render for authorized processing and completed orders with the exact names, URLs, and table classes.
- */
- public function test_download_table_requires_entitlement_and_permission(): void {
- $download_directories = wc_get_container()->get( Download_Directories::class );
-
- $download_directories->set_mode( Download_Directories::MODE_DISABLED );
- update_option( 'woocommerce_downloads_grant_access_after_payment', 'yes' );
- add_filter(
- 'woocommerce_downloadable_file_exists',
- static function (): bool {
- return true;
- }
- );
-
- $product = \WC_Helper_Product::create_downloadable_product(
- array(
- array(
- 'name' => 'Single 1',
- 'file' => 'https://example.com/single-1.txt',
- ),
- array(
- 'name' => 'Single 2',
- 'file' => 'https://example.com/single-2.txt',
- ),
- )
- );
- $order = $this->create_order( $product );
-
- $this->assertSame( '', $this->render( $order, 'full' ), 'Pending orders should not render a downloads table.' );
-
- $order->set_status( 'processing' );
- $order->save();
- wc_downloadable_product_permissions( $order->get_id(), true );
- $order = $this->reload_order( $order );
-
- $this->assert_download_table( $order, 'processing' );
-
- $order->set_status( 'completed' );
- $order->save();
- $order = $this->reload_order( $order );
-
- $this->assert_download_table( $order, 'completed' );
-
- $this->assertSame( '', $this->render( $order, false ), 'Order details permission is required even after entitlement is granted.' );
- }
-
- /**
- * Assert the rendered download table for one entitled order status.
- *
- * @param WC_Order $order Order object.
- * @param string $status Expected order status.
- */
- private function assert_download_table( WC_Order $order, string $status ): void {
- $downloads = $order->get_downloadable_items();
- $download_names = array_column( $downloads, 'download_name' );
- sort( $download_names );
-
- $this->assertSame( $status, $order->get_status() );
- $this->assertCount( 2, $downloads, 'The real order should expose both granted download entitlements.' );
- $this->assertSame( array( 'Single 1', 'Single 2' ), $download_names, 'The exact two unique fixture download names should be granted.' );
-
- foreach ( $downloads as $download ) {
- $this->assertNotSame( '', $download['download_url'], 'A granted entitlement must have a non-empty URL.' );
- }
-
- $content = $this->render( $order, 'full' );
-
- $this->assertStringContainsString( 'wc-block-order-confirmation-downloads__table', $content );
- $this->assertSame( 3, substr_count( $content, '<tr>' ), 'The table should contain one header row and two entitlement rows.' );
- $this->assertSame( 2, substr_count( $content, '<td class="download-file"' ), 'Each entitlement should render a file cell.' );
- $this->assertSame( 2, substr_count( $content, 'class="woocommerce-MyAccount-downloads-file button alt"' ), 'Each entitlement should render the expected download-link classes.' );
-
- foreach ( $downloads as $download ) {
- $escaped_download_url = esc_url( $download['download_url'] );
-
- $this->assertNotSame( '', $escaped_download_url, 'A granted entitlement must retain a non-empty URL after escaping.' );
- $this->assertStringContainsString( esc_html( $download['download_name'] ), $content );
- $this->assertStringContainsString( $escaped_download_url, $content );
- }
- }
-
- /**
- * Reload an order from persistence.
- *
- * @param WC_Order $order Order object.
- * @return WC_Order
- */
- private function reload_order( WC_Order $order ): WC_Order {
- $reloaded_order = wc_get_order( $order->get_id() );
- $this->assertInstanceOf( WC_Order::class, $reloaded_order );
-
- return $reloaded_order;
- }
-
- /**
- * Render the downloads table through a public proxy.
- *
- * @param WC_Order $order Order object.
- * @param string|false $permission View permission.
- * @return string
- */
- private function render( WC_Order $order, $permission ): string {
- $proxy = new class() extends DownloadsBlock {
- // phpcs:ignore Squiz.Commenting.FunctionComment.Missing
- public function __construct() {
- }
- // phpcs:ignore Squiz.Commenting.FunctionComment.Missing
- public function render_content_proxy( $order, $permission ) {
- return $this->render_content( $order, $permission );
- }
- };
-
- return $proxy->render_content_proxy( $order, $permission );
- }
-
- /**
- * Create a guest order containing the downloadable product.
- *
- * @param WC_Product $product Product object.
- * @return WC_Order
- */
- private function create_order( WC_Product $product ): WC_Order {
- $order = wc_create_order( array( 'customer_id' => 0 ) );
- $item = new WC_Order_Item_Product();
- $item->set_product( $product );
- $item->set_quantity( 1 );
- $order->add_item( $item );
- $order->set_billing_email( 'downloads-shopper@example.com' );
- $order->save();
-
- return $order;
- }
-}
diff --git a/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/OrderConfirmation/DownloadsWrapper.php b/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/OrderConfirmation/DownloadsWrapper.php
index 6c731b65b5e..f44bb093cbb 100644
--- a/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/OrderConfirmation/DownloadsWrapper.php
+++ b/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/OrderConfirmation/DownloadsWrapper.php
@@ -3,7 +3,6 @@
namespace Automattic\WooCommerce\Tests\Blocks\BlockTypes\OrderConfirmation;
use Automattic\WooCommerce\Blocks\BlockTypes\OrderConfirmation\DownloadsWrapper as DownloadsWrapperClass;
-use Automattic\WooCommerce\Internal\ProductDownloads\ApprovedDirectories\Register as Download_Directories;
/**
* Test DownloadsWrapper class.
@@ -118,92 +117,4 @@ final class DownloadsWrapper extends \WP_UnitTestCase {
\WC_Helper_Product::create_simple_product( true, array( 'downloadable' => true ) );
$this->assertFalse( $proxy->store_has_downloadable_products_proxy() );
}
-
- /**
- * @testdox Runtime wrapper content requires permission, a downloadable order item, and a download-permitted status.
- */
- public function test_runtime_render_requires_download_permission(): void {
- $download_directories = wc_get_container()->get( Download_Directories::class );
-
- $download_directories->set_mode( Download_Directories::MODE_DISABLED );
- add_filter(
- 'woocommerce_downloadable_file_exists',
- static function (): bool {
- return true;
- }
- );
-
- $downloadable_product = \WC_Helper_Product::create_downloadable_product(
- array(
- array(
- 'name' => 'Wrapper download',
- 'file' => 'https://example.com/wrapper-download.txt',
- ),
- )
- );
- $plain_product = \WC_Helper_Product::create_simple_product();
- $downloadable_order = $this->create_order_with_product( $downloadable_product );
- $plain_order = $this->create_order_with_product( $plain_product );
-
- $this->assertSame( '', $this->render( $downloadable_order, 'full' ), 'A pending order should not expose downloads.' );
-
- // Processing permits downloads only when the store grants access after payment,
- // so the wrapper has to follow that option rather than the status on its own.
- $downloadable_order->set_status( 'processing' );
- $downloadable_order->save();
-
- update_option( 'woocommerce_downloads_grant_access_after_payment', 'no' );
- $this->assertSame( '', $this->render( $downloadable_order, 'full' ), 'A processing order should not expose downloads while access is granted only on completion.' );
-
- update_option( 'woocommerce_downloads_grant_access_after_payment', 'yes' );
- $this->assertSame( '<p>Download marker</p>', $this->render( $downloadable_order, 'full' ), 'A processing order should expose downloads once the store grants access after payment.' );
-
- $plain_order->set_status( 'completed' );
- $plain_order->save();
- $this->assertSame( '', $this->render( $plain_order, 'full' ), 'An order without a downloadable item should not render the wrapper.' );
-
- $downloadable_order->set_status( 'completed' );
- $downloadable_order->save();
- $this->assertSame( '', $this->render( $downloadable_order, false ), 'View permission is required.' );
- $this->assertSame( '<p>Download marker</p>', $this->render( $downloadable_order, 'full' ), 'A completed downloadable order should render non-empty wrapper content.' );
- }
-
- /**
- * Render runtime wrapper content through a public proxy.
- *
- * @param \WC_Order $order Order object.
- * @param string|false $permission View permission.
- * @return string
- */
- private function render( \WC_Order $order, $permission ): string {
- $proxy = new class() extends DownloadsWrapperClass {
- // phpcs:ignore Squiz.Commenting.FunctionComment.Missing
- public function __construct() {
- }
- // phpcs:ignore Squiz.Commenting.FunctionComment.Missing
- public function render_content_proxy( $order, $permission, $content ) {
- return $this->render_content( $order, $permission, array(), $content );
- }
- };
-
- return $proxy->render_content_proxy( $order, $permission, '<p>Download marker</p>' );
- }
-
- /**
- * Create a persisted order containing one product.
- *
- * @param \WC_Product $product Product object.
- * @return \WC_Order
- */
- private function create_order_with_product( \WC_Product $product ): \WC_Order {
- $order = wc_create_order( array( 'customer_id' => 0 ) );
- $item = new \WC_Order_Item_Product();
- $item->set_product( $product );
- $item->set_quantity( 1 );
- $order->add_item( $item );
- $order->set_billing_email( 'wrapper-shopper@example.com' );
- $order->save();
-
- return $order;
- }
}
diff --git a/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/OrderConfirmation/ShippingAddress.php b/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/OrderConfirmation/ShippingAddress.php
index c797af98fbe..51df23985eb 100644
--- a/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/OrderConfirmation/ShippingAddress.php
+++ b/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/OrderConfirmation/ShippingAddress.php
@@ -5,7 +5,6 @@ namespace Automattic\WooCommerce\Tests\Blocks\BlockTypes\OrderConfirmation;
use Automattic\WooCommerce\Blocks\BlockTypes\OrderConfirmation\ShippingAddress as ShippingAddressBlock;
use Automattic\WooCommerce\Blocks\Domain\Services\CheckoutFields;
use Automattic\WooCommerce\Blocks\Package;
-use Automattic\WooCommerce\Blocks\Shipping\PickupLocation;
/**
* Test ShippingAddress block class.
@@ -61,55 +60,6 @@ final class ShippingAddress extends \WP_UnitTestCase {
$this->assertStringContainsString( 'visible value', $this->render( $order ) );
}
- /**
- * @testdox Shipping details render only for authorized orders that require a shipping address.
- * @dataProvider shipping_address_topology_cases
- *
- * @param string $topology Order fulfillment topology.
- * @param string|false $permission View permission.
- * @param bool $expected_visible Whether shipping content should render.
- */
- public function test_shipping_address_topology( string $topology, $permission, bool $expected_visible ): void {
- try {
- // Inside the try: create_topology_order() registers PickupLocation partway
- // through, so a throw after that point must still reach the finally below.
- $order = $this->create_topology_order( $topology );
- update_option( 'woocommerce_calc_shipping', 'yes' );
- $content = $this->render( $order, $permission );
- if ( 'physical' === $topology ) {
- $this->assertTrue( $order->needs_shipping_address(), 'A free-shipping order should require a shipping address.' );
- } else {
- $this->assertFalse( $order->needs_shipping_address(), 'Pickup and virtual orders should not require a shipping address.' );
- }
-
- if ( $expected_visible ) {
- $this->assertStringContainsString( 'Shipping Marker', $content, 'Shipping details should be non-empty for a shipped order.' );
- } else {
- $this->assertSame( '', $content, 'Shipping details should be empty for this topology or permission.' );
- }
- } finally {
- if ( 'pickup-location' === $topology ) {
- // Drop the memo so the next test reloads the ambient method list.
- WC()->shipping()->unregister_shipping_methods();
- }
- }
- }
-
- /**
- * Named shipping-address topology cases.
- *
- * @return array<string, array{string, string|false, bool}>
- */
- public static function shipping_address_topology_cases(): array {
- return array(
- 'physical free-shipping order' => array( 'physical', 'full', true ),
- 'classic local pickup order' => array( 'local-pickup', 'full', false ),
- 'blocks pickup location order' => array( 'pickup-location', 'full', false ),
- 'virtual downloadable order' => array( 'virtual', 'full', false ),
- 'no view permission' => array( 'physical', false, false ),
- );
- }
-
/**
* Create an order placed via the Store API, with a shipping address and a value persisted for the shipping group of the test field.
*
@@ -135,11 +85,10 @@ final class ShippingAddress extends \WP_UnitTestCase {
/**
* Render the shipping address block content for the given order with full view permissions.
*
- * @param \WC_Order $order Order object.
- * @param string|false $permission View permission.
+ * @param \WC_Order $order Order object.
* @return string
*/
- private function render( \WC_Order $order, $permission = 'full' ): string {
+ private function render( \WC_Order $order ): string {
$proxy = new class() extends ShippingAddressBlock {
// phpcs:ignore Squiz.Commenting.FunctionComment.Missing
public function __construct() {
@@ -150,65 +99,6 @@ final class ShippingAddress extends \WP_UnitTestCase {
}
};
- return $proxy->render_content_proxy( $order, $permission );
- }
-
- /**
- * Create an order with a persisted shipping address and fulfillment topology.
- *
- * @param string $topology Order fulfillment topology.
- * @return \WC_Order
- */
- private function create_topology_order( string $topology ): \WC_Order {
- $product = \WC_Helper_Product::create_simple_product(
- true,
- array(
- 'downloadable' => 'virtual' === $topology,
- 'virtual' => 'virtual' === $topology,
- )
- );
- $product->set_virtual( 'virtual' === $topology );
- $product->save();
-
- $order = wc_create_order( array( 'customer_id' => 0 ) );
- $item = new \WC_Order_Item_Product();
- $item->set_product( $product );
- $item->set_quantity( 1 );
- $order->add_item( $item );
- $order->set_shipping_first_name( 'Shipping' );
- $order->set_shipping_last_name( 'Marker' );
- $order->set_shipping_address_1( '500 Shipping Avenue' );
- $order->set_shipping_city( 'San Francisco' );
- $order->set_shipping_state( 'CA' );
- $order->set_shipping_postcode( '94105' );
- $order->set_shipping_country( 'US' );
-
- if ( 'virtual' !== $topology ) {
- $shipping_item = new \WC_Order_Item_Shipping();
- // `local_pickup` is the classic pickup method, `pickup_location` the Blocks one.
- // `needs_shipping_address()` hides the address for both, but it finds
- // `pickup_location` only by asking the registered shipping methods which of them
- // support `local-pickup`. Core registers that method when the Checkout block is
- // the default checkout, which the test store is not, so register it the same way.
- $pickup_methods = array(
- 'local-pickup' => array( 'Local pickup', 'local_pickup' ),
- 'pickup-location' => array( 'Pickup Location', 'pickup_location' ),
- );
-
- if ( 'pickup-location' === $topology ) {
- WC()->shipping()->get_shipping_methods();
- WC()->shipping()->register_shipping_method( new PickupLocation() );
- }
-
- list( $method_title, $method_id ) = $pickup_methods[ $topology ] ?? array( 'Free shipping', 'free_shipping' );
-
- $shipping_item->set_method_title( $method_title );
- $shipping_item->set_method_id( $method_id );
- $order->add_item( $shipping_item );
- }
-
- $order->save();
-
- return $order;
+ return $proxy->render_content_proxy( $order, 'full' );
}
}
diff --git a/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/OrderConfirmation/ShippingWrapperTest.php b/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/OrderConfirmation/ShippingWrapperTest.php
deleted file mode 100644
index cb48f9a52db..00000000000
--- a/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/OrderConfirmation/ShippingWrapperTest.php
+++ /dev/null
@@ -1,153 +0,0 @@
-<?php
-declare( strict_types = 1 );
-
-namespace Automattic\WooCommerce\Tests\Blocks\BlockTypes\OrderConfirmation;
-
-use Automattic\WooCommerce\Blocks\BlockTypes\OrderConfirmation\ShippingWrapper as ShippingWrapperBlock;
-use Automattic\WooCommerce\Blocks\Shipping\PickupLocation;
-use WC_Order;
-use WC_Order_Item_Product;
-use WC_Order_Item_Shipping;
-use WC_Product;
-use WC_Unit_Test_Case;
-
-/**
- * Tests for the order-confirmation shipping wrapper.
- */
-final class ShippingWrapperTest extends WC_Unit_Test_Case {
- /**
- * @testdox Shipping wrapper headings and content render only for an authorized shipped order.
- * @dataProvider shipping_wrapper_cases
- *
- * @param string $topology Order fulfillment topology.
- * @param string|false $permission View permission.
- * @param bool $has_address Whether the order has a shipping address.
- * @param bool $expected_visible Whether wrapper content should render.
- */
- public function test_shipping_wrapper_topology( string $topology, $permission, bool $has_address, bool $expected_visible ): void {
- $content = '<h2>Shipping address</h2><p>Shipping wrapper marker</p>';
-
- try {
- // Inside the try: create_order() registers PickupLocation partway through,
- // so a throw after that point must still reach the finally below.
- $order = $this->create_order( $topology, $has_address );
- update_option( 'woocommerce_calc_shipping', 'yes' );
- $rendered = $this->render( $order, $permission, $content );
-
- if ( 'physical' === $topology ) {
- $this->assertTrue( $order->needs_shipping_address(), 'A free-shipping order should require a shipping address.' );
- } else {
- $this->assertFalse( $order->needs_shipping_address(), 'Pickup and virtual orders should not require a shipping address.' );
- }
-
- if ( $expected_visible ) {
- $this->assertSame( $content, $rendered, 'An authorized shipped order should preserve the wrapper heading and content.' );
- } else {
- $this->assertSame( '', $rendered, 'The shipping wrapper should be empty for pickup, virtual, missing-address, or unauthorized orders.' );
- }
- } finally {
- if ( 'pickup-location' === $topology ) {
- // Drop the memo so the next test reloads the ambient method list.
- WC()->shipping()->unregister_shipping_methods();
- }
- }
- }
-
- /**
- * Named shipping-wrapper cases.
- *
- * @return array<string, array{string, string|false, bool, bool}>
- */
- public static function shipping_wrapper_cases(): array {
- return array(
- 'physical free-shipping order' => array( 'physical', 'full', true, true ),
- 'classic local pickup order' => array( 'local-pickup', 'full', true, false ),
- 'blocks pickup location order' => array( 'pickup-location', 'full', true, false ),
- 'virtual downloadable order' => array( 'virtual', 'full', true, false ),
- 'no view permission' => array( 'physical', false, true, false ),
- 'no shipping address' => array( 'physical', 'full', false, false ),
- );
- }
-
- /**
- * Render wrapper content through a public proxy.
- *
- * @param WC_Order $order Order object.
- * @param string|false $permission View permission.
- * @param string $content Wrapper content.
- * @return string
- */
- private function render( WC_Order $order, $permission, string $content ): string {
- $proxy = new class() extends ShippingWrapperBlock {
- // phpcs:ignore Squiz.Commenting.FunctionComment.Missing
- public function __construct() {
- }
- // phpcs:ignore Squiz.Commenting.FunctionComment.Missing
- public function render_content_proxy( $order, $permission, $content ) {
- return $this->render_content( $order, $permission, array(), $content );
- }
- };
-
- return $proxy->render_content_proxy( $order, $permission, $content );
- }
-
- /**
- * Create a persisted order for one fulfillment topology.
- *
- * @param string $topology Order fulfillment topology.
- * @param bool $has_address Whether to add shipping data.
- * @return WC_Order
- */
- private function create_order( string $topology, bool $has_address ): WC_Order {
- $product = \WC_Helper_Product::create_simple_product(
- true,
- array(
- 'downloadable' => 'virtual' === $topology,
- 'virtual' => 'virtual' === $topology,
- )
- );
- $order = wc_create_order( array( 'customer_id' => 0 ) );
- $item = new WC_Order_Item_Product();
- $item->set_product( $product );
- $item->set_quantity( 1 );
- $order->add_item( $item );
-
- if ( $has_address ) {
- $order->set_shipping_first_name( 'Shipping' );
- $order->set_shipping_last_name( 'Marker' );
- $order->set_shipping_address_1( '500 Shipping Avenue' );
- $order->set_shipping_city( 'San Francisco' );
- $order->set_shipping_state( 'CA' );
- $order->set_shipping_postcode( '94105' );
- $order->set_shipping_country( 'US' );
- }
-
- if ( 'virtual' !== $topology ) {
- $shipping_item = new WC_Order_Item_Shipping();
- // `local_pickup` is the classic pickup method, `pickup_location` the Blocks one.
- // `needs_shipping_address()` hides the address for both, but it finds
- // `pickup_location` only by asking the registered shipping methods which of them
- // support `local-pickup`. Core registers that method when the Checkout block is
- // the default checkout, which the test store is not, so register it the same way.
- $pickup_methods = array(
- 'local-pickup' => array( 'Local pickup', 'local_pickup' ),
- 'pickup-location' => array( 'Pickup Location', 'pickup_location' ),
- );
-
- if ( 'pickup-location' === $topology ) {
- WC()->shipping()->get_shipping_methods();
- WC()->shipping()->register_shipping_method( new PickupLocation() );
- }
-
- list( $method_title, $method_id ) = $pickup_methods[ $topology ] ?? array( 'Free shipping', 'free_shipping' );
-
- $shipping_item->set_method_title( $method_title );
- $shipping_item->set_method_id( $method_id );
- $order->add_item( $shipping_item );
- }
-
- $order->save();
-
- return $order;
- }
-}
diff --git a/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/OrderConfirmation/StatusTest.php b/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/OrderConfirmation/StatusTest.php
index 53e4e39effe..4deea90017a 100644
--- a/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/OrderConfirmation/StatusTest.php
+++ b/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/OrderConfirmation/StatusTest.php
@@ -272,98 +272,4 @@ class StatusTest extends WC_Unit_Test_Case {
return $sut->render_content_proxy( $order, 'full' );
}
-
- /**
- * @testdox A missing order directs the shopper to email and account confirmation paths.
- */
- public function test_missing_order_notice(): void {
- $my_account_url = wc_get_page_permalink( 'myaccount' );
- $content = $this->render_confirmation_notice( null );
-
- $this->assertNotSame( '', $my_account_url, 'The fixture must expose the My account login destination.' );
- $this->assertStringContainsString( 'If you've just placed an order, give your email a quick check for the confirmation.', $content );
- $this->assertStringContainsString( 'Have an account with us?', $content );
- $this->assertStringContainsString( 'Log in here to view your order details', $content );
- $this->assertStringContainsString( 'href="' . esc_url( $my_account_url ) . '"', $content );
- }
-
- /**
- * @testdox An existing customer order without a valid key directs the shopper to email and account confirmation paths.
- * @dataProvider invalid_order_key_cases
- *
- * @param string $key_mode Missing or invalid key mode.
- */
- public function test_invalid_key_notice_uses_real_permission_result( string $key_mode ): void {
- $customer_id = self::factory()->user->create( array( 'role' => 'customer' ) );
- $order = wc_create_order( array( 'customer_id' => $customer_id ) );
- $order->set_billing_email( 'status-shopper@example.com' );
- $order->save();
- wp_set_current_user( $customer_id );
- $_GET = 'wrong' === $key_mode ? array( 'key' => 'wc_order_wrong' ) : array();
-
- $permission = $this->get_view_order_permissions( $order );
- $content = $this->render_confirmation_notice( $order );
- $my_account_url = wc_get_page_permalink( 'myaccount' );
-
- $this->assertFalse( $permission, 'The real permission decision must reject a missing or invalid order key.' );
- $this->assertNotSame( '', $my_account_url, 'The fixture must expose the My account login destination.' );
- $this->assertStringContainsString( 'Great news! Your order has been received, and a confirmation will be sent to your email address.', $content );
- $this->assertStringContainsString( 'Have an account with us?', $content );
- $this->assertStringContainsString( 'Log in here', $content );
- $this->assertStringContainsString( 'to view your order.', $content );
- $this->assertStringContainsString( 'href="' . esc_url( $my_account_url ) . '"', $content );
- }
-
- /**
- * Named invalid-key cases.
- *
- * @return array<string, array{string}>
- */
- public static function invalid_order_key_cases(): array {
- return array(
- 'missing order key' => array( 'missing' ),
- 'wrong order key' => array( 'wrong' ),
- );
- }
-
- /**
- * Render a status notice through the real Status block owner.
- *
- * @param WC_Order|null $order Order object, or null when none exists.
- * @return string
- */
- private function render_confirmation_notice( ?WC_Order $order ): string {
- return $this->create_proxy()->render_confirmation_notice_proxy( $order );
- }
-
- /**
- * Resolve view permission through the real Status block owner.
- *
- * @param WC_Order $order Order object.
- * @return string|false
- */
- private function get_view_order_permissions( WC_Order $order ) {
- return $this->create_proxy()->get_view_order_permissions_proxy( $order );
- }
-
- /**
- * Create a public proxy over the Status block's protected owners.
- *
- * @return StatusBlock
- */
- private function create_proxy(): StatusBlock {
- return new class() extends StatusBlock {
- // phpcs:ignore Squiz.Commenting.FunctionComment.Missing
- public function __construct() {
- }
- // phpcs:ignore Squiz.Commenting.FunctionComment.Missing
- public function render_confirmation_notice_proxy( ?WC_Order $order ): string {
- return $this->render_confirmation_notice( $order );
- }
- // phpcs:ignore Squiz.Commenting.FunctionComment.Missing
- public function get_view_order_permissions_proxy( WC_Order $order ) {
- return $this->get_view_order_permissions( $order );
- }
- };
- }
}