From 5bbf168e97b2c6385fcf4eb0c3f99fcf9a118591 Mon Sep 17 00:00:00 2001 From: TJ Date: Sat, 20 Dec 2025 18:48:14 +0100 Subject: [PATCH 1/4] making other WC Order types (other than subscription) compatible with custom fields --- includes/forms/WC_Order.php | 76 ++++++++++++++++++++++++++++++------- 1 file changed, 63 insertions(+), 13 deletions(-) diff --git a/includes/forms/WC_Order.php b/includes/forms/WC_Order.php index 77161428..7cca98a8 100644 --- a/includes/forms/WC_Order.php +++ b/includes/forms/WC_Order.php @@ -21,9 +21,10 @@ class WC_Order { * @since 6.5 */ public function __construct() { - add_action( 'load-woocommerce_page_wc-orders', array( $this, 'initialize' ) ); - add_action( 'load-woocommerce_page_wc-orders--shop_subscription', array( $this, 'initialize' ) ); - add_action( 'woocommerce_update_order', array( $this, 'save_order' ), 10, 1 ); + add_action( 'load-woocommerce_page_wc-orders', array( $this, 'initialize' ) ); + add_action( 'woocommerce_update_order', array( $this, 'save_order' ), 10, 1 ); + // Defer registering other order type hooks to after all order types are registered + add_action( 'wp_loaded', array( $this, 'register_order_type_hooks' ) ); } /** @@ -39,6 +40,25 @@ public function initialize() { add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ), 10, 2 ); } + /** + * Registers initialization hooks for all WooCommerce order types. + * + * @since 6.4.4 + * @return void + */ + public function register_order_type_hooks() { + + $order_types = wc_get_order_types( 'view-orders' ); + + foreach ( $order_types as $order_type ) { + // shop_order uses the base hook without suffix + if ( 'shop_order' === $order_type ) { + continue; + } + add_action( 'load-woocommerce_page_wc-orders--' . $order_type, array( $this, 'initialize' ) ); + } + } + /** * Adds ACF metaboxes to the WooCommerce Order pages. * @@ -49,17 +69,23 @@ public function initialize() { * @return void */ public function add_meta_boxes( $post_type, $post ) { - // Storage for localized postboxes. - $postboxes = array(); + // Storage for localized postboxes. + $postboxes = array(); - $location = 'shop_order'; - $order = ( $post instanceof \WP_Post ) ? wc_get_order( $post->ID ) : $post; - $screen = $this->is_hpos_enabled() ? wc_get_page_screen_id( 'shop-order' ) : 'shop_order'; + $order = ( $post instanceof \WP_Post ) ? wc_get_order( $post->ID ) : $post; + if ( ! $order ) { + return; + } - if ( $order instanceof \WC_Subscription ) { - $location = 'shop_subscription'; - $screen = function_exists( 'wcs_get_page_screen_id' ) ? wcs_get_page_screen_id( 'shop_subscription' ) : 'shop_subscription'; - } + // Dynamically get order type from the order object + $location = $order->get_type(); + + // Determine screen ID based on HPOS status and order type + if ( $this->is_hpos_enabled() ) { + $screen = $this->get_hpos_screen_id( $location ); + } else { + $screen = $location; + } // Get field groups for this screen. $field_groups = acf_get_field_groups( @@ -141,7 +167,31 @@ public function add_meta_boxes( $post_type, $post ) { do_action( 'acf/add_meta_boxes', $post_type, $post, $field_groups ); } - /** + /** + * Gets the HPOS screen ID for an order type. + * + * @since 6.4.4 + * + * @param string $order_type The order type (e.g., 'shop_order', 'shop_subscription', 'shop_order_charge'). + * @return string The screen ID. + */ + protected function get_hpos_screen_id( string $order_type ): string { + // Check for WooCommerce Subscriptions helper function + if ( 'shop_subscription' === $order_type && function_exists( 'wcs_get_page_screen_id' ) ) { + return wcs_get_page_screen_id( 'shop_subscription' ); + } + + // For shop_order, use the standard WC function + if ( 'shop_order' === $order_type ) { + return wc_get_page_screen_id( 'shop-order' ); + } + + // For custom order types, construct the screen ID + // Pattern: woocommerce_page_wc-orders--{order_type} + return 'woocommerce_page_wc-orders--' . $order_type; + } + + /** * Renders hidden fields. * * @since 6.5 From a4009965622a78cf55e4b114d104d46e02ea955c Mon Sep 17 00:00:00 2001 From: TJ Date: Sat, 20 Dec 2025 18:55:44 +0100 Subject: [PATCH 2/4] fixing phpcs formatting --- includes/forms/WC_Order.php | 112 ++++++++++++++++++------------------ 1 file changed, 56 insertions(+), 56 deletions(-) diff --git a/includes/forms/WC_Order.php b/includes/forms/WC_Order.php index 7cca98a8..c43d7829 100644 --- a/includes/forms/WC_Order.php +++ b/includes/forms/WC_Order.php @@ -21,10 +21,10 @@ class WC_Order { * @since 6.5 */ public function __construct() { - add_action( 'load-woocommerce_page_wc-orders', array( $this, 'initialize' ) ); - add_action( 'woocommerce_update_order', array( $this, 'save_order' ), 10, 1 ); - // Defer registering other order type hooks to after all order types are registered - add_action( 'wp_loaded', array( $this, 'register_order_type_hooks' ) ); + add_action( 'load-woocommerce_page_wc-orders', array( $this, 'initialize' ) ); + add_action( 'woocommerce_update_order', array( $this, 'save_order' ), 10, 1 ); + // Defer registering other order type hooks to after all order types are registered + add_action( 'wp_loaded', array( $this, 'register_order_type_hooks' ) ); } /** @@ -40,24 +40,24 @@ public function initialize() { add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ), 10, 2 ); } - /** - * Registers initialization hooks for all WooCommerce order types. - * - * @since 6.4.4 - * @return void - */ - public function register_order_type_hooks() { + /** + * Registers initialization hooks for all WooCommerce order types. + * + * @since 6.4.4 + * @return void + */ + public function register_order_type_hooks() { - $order_types = wc_get_order_types( 'view-orders' ); + $order_types = wc_get_order_types( 'view-orders' ); - foreach ( $order_types as $order_type ) { - // shop_order uses the base hook without suffix - if ( 'shop_order' === $order_type ) { - continue; - } - add_action( 'load-woocommerce_page_wc-orders--' . $order_type, array( $this, 'initialize' ) ); - } - } + foreach ( $order_types as $order_type ) { + // shop_order uses the base hook without suffix + if ( 'shop_order' === $order_type ) { + continue; + } + add_action( 'load-woocommerce_page_wc-orders--' . $order_type, array( $this, 'initialize' ) ); + } + } /** * Adds ACF metaboxes to the WooCommerce Order pages. @@ -69,23 +69,23 @@ public function register_order_type_hooks() { * @return void */ public function add_meta_boxes( $post_type, $post ) { - // Storage for localized postboxes. - $postboxes = array(); + // Storage for localized postboxes. + $postboxes = array(); - $order = ( $post instanceof \WP_Post ) ? wc_get_order( $post->ID ) : $post; - if ( ! $order ) { - return; - } + $order = ( $post instanceof \WP_Post ) ? wc_get_order( $post->ID ) : $post; + if ( ! $order ) { + return; + } - // Dynamically get order type from the order object - $location = $order->get_type(); + // Dynamically get order type from the order object + $location = $order->get_type(); - // Determine screen ID based on HPOS status and order type - if ( $this->is_hpos_enabled() ) { - $screen = $this->get_hpos_screen_id( $location ); - } else { - $screen = $location; - } + // Determine screen ID based on HPOS status and order type + if ( $this->is_hpos_enabled() ) { + $screen = $this->get_hpos_screen_id( $location ); + } else { + $screen = $location; + } // Get field groups for this screen. $field_groups = acf_get_field_groups( @@ -167,31 +167,31 @@ public function add_meta_boxes( $post_type, $post ) { do_action( 'acf/add_meta_boxes', $post_type, $post, $field_groups ); } - /** - * Gets the HPOS screen ID for an order type. - * - * @since 6.4.4 - * - * @param string $order_type The order type (e.g., 'shop_order', 'shop_subscription', 'shop_order_charge'). - * @return string The screen ID. - */ - protected function get_hpos_screen_id( string $order_type ): string { - // Check for WooCommerce Subscriptions helper function - if ( 'shop_subscription' === $order_type && function_exists( 'wcs_get_page_screen_id' ) ) { - return wcs_get_page_screen_id( 'shop_subscription' ); - } + /** + * Gets the HPOS screen ID for an order type. + * + * @since 6.4.4 + * + * @param string $order_type The order type (e.g., 'shop_order', 'shop_subscription', 'shop_order_charge'). + * @return string The screen ID. + */ + protected function get_hpos_screen_id( string $order_type ): string { + // Check for WooCommerce Subscriptions helper function + if ( 'shop_subscription' === $order_type && function_exists( 'wcs_get_page_screen_id' ) ) { + return wcs_get_page_screen_id( 'shop_subscription' ); + } - // For shop_order, use the standard WC function - if ( 'shop_order' === $order_type ) { - return wc_get_page_screen_id( 'shop-order' ); - } + // For shop_order, use the standard WC function + if ( 'shop_order' === $order_type ) { + return wc_get_page_screen_id( 'shop-order' ); + } - // For custom order types, construct the screen ID - // Pattern: woocommerce_page_wc-orders--{order_type} - return 'woocommerce_page_wc-orders--' . $order_type; - } + // For custom order types, construct the screen ID + // Pattern: woocommerce_page_wc-orders--{order_type} + return 'woocommerce_page_wc-orders--' . $order_type; + } - /** + /** * Renders hidden fields. * * @since 6.5 From d2a6019a89ebfe81f775015ed256cbe4c0fc9ffc Mon Sep 17 00:00:00 2001 From: TJ Date: Sat, 20 Dec 2025 20:01:41 +0100 Subject: [PATCH 3/4] adding phpunit tests for WC form --- .../php/includes/forms/test-form-wc-order.php | 502 ++++++++++++++++++ 1 file changed, 502 insertions(+) create mode 100644 tests/php/includes/forms/test-form-wc-order.php diff --git a/tests/php/includes/forms/test-form-wc-order.php b/tests/php/includes/forms/test-form-wc-order.php new file mode 100644 index 00000000..ccc01322 --- /dev/null +++ b/tests/php/includes/forms/test-form-wc-order.php @@ -0,0 +1,502 @@ +id = $id; + $this->type = $type; + } + + /** + * Get order ID. + * + * @return int + */ + public function get_id() { + return $this->id; + } + + /** + * Get order type. + * + * @return string + */ + public function get_type() { + return $this->type; + } +} + +/** + * Class Test_Form_WC_Order + */ +class Test_Form_WC_Order extends BaseTestCase { + + /** + * Store original function existence states. + * + * @var array + */ + private $original_functions = array(); + + /** + * Set up before each test. + */ + public function set_up() { + parent::set_up(); + + // Define WooCommerce mock functions if they don't exist. + if ( ! function_exists( 'wc_get_order_types' ) ) { + function wc_get_order_types( $for = '' ) { + return array( 'shop_order', 'shop_subscription', 'shop_order_refund' ); + } + } + + if ( ! function_exists( 'wc_get_order' ) ) { + function wc_get_order( $order_id ) { + return new Mock_WC_Order( $order_id ); + } + } + + if ( ! function_exists( 'wc_get_page_screen_id' ) ) { + function wc_get_page_screen_id( $page ) { + return 'woocommerce_page_wc-orders'; + } + } + } + + /** + * Tear down after each test. + */ + public function tear_down() { + parent::tear_down(); + + // Clean up any filters/actions we added. + remove_all_filters( 'acf/input/meta_box_priority' ); + remove_all_actions( 'acf/add_meta_boxes' ); + } + + /** + * Test WC_Order class exists. + */ + public function test_wc_order_class_exists() { + $this->assertTrue( class_exists( WC_Order::class ), 'SCF\Forms\WC_Order class should exist' ); + } + + /** + * Test WC_Order can be instantiated. + */ + public function test_wc_order_instantiation() { + $wc_order = new WC_Order(); + $this->assertInstanceOf( WC_Order::class, $wc_order ); + } + + /** + * Test constructor registers correct actions. + */ + public function test_constructor_registers_actions() { + $wc_order = new WC_Order(); + + $this->assertNotFalse( + has_action( 'load-woocommerce_page_wc-orders', array( $wc_order, 'initialize' ) ), + 'Should register initialize action for base WC orders page' + ); + + $this->assertNotFalse( + has_action( 'woocommerce_update_order', array( $wc_order, 'save_order' ) ), + 'Should register save_order action' + ); + + $this->assertNotFalse( + has_action( 'wp_loaded', array( $wc_order, 'register_order_type_hooks' ) ), + 'Should register register_order_type_hooks action on wp_loaded' + ); + } + + /** + * Test get_hpos_screen_id returns correct screen for shop_order. + */ + public function test_get_hpos_screen_id_shop_order() { + $wc_order = new WC_Order(); + + // Use reflection to access protected method. + $method = new ReflectionMethod( WC_Order::class, 'get_hpos_screen_id' ); + $method->setAccessible( true ); + + $result = $method->invoke( $wc_order, 'shop_order' ); + + $this->assertEquals( + 'woocommerce_page_wc-orders', + $result, + 'shop_order should return WC page screen ID' + ); + } + + /** + * Test get_hpos_screen_id returns correct screen for custom order types. + */ + public function test_get_hpos_screen_id_custom_order_type() { + $wc_order = new WC_Order(); + + $method = new ReflectionMethod( WC_Order::class, 'get_hpos_screen_id' ); + $method->setAccessible( true ); + + // Test with a custom order type. + $result = $method->invoke( $wc_order, 'shop_order_charge' ); + + $this->assertEquals( + 'woocommerce_page_wc-orders--shop_order_charge', + $result, + 'Custom order types should follow pattern: woocommerce_page_wc-orders--{order_type}' + ); + } + + /** + * Test get_hpos_screen_id returns correct screen for shop_order_refund. + */ + public function test_get_hpos_screen_id_refund_order() { + $wc_order = new WC_Order(); + + $method = new ReflectionMethod( WC_Order::class, 'get_hpos_screen_id' ); + $method->setAccessible( true ); + + $result = $method->invoke( $wc_order, 'shop_order_refund' ); + + $this->assertEquals( + 'woocommerce_page_wc-orders--shop_order_refund', + $result, + 'Refund orders should follow custom order type pattern' + ); + } + + /** + * Test get_hpos_screen_id handles shop_subscription when wcs_get_page_screen_id exists. + */ + public function test_get_hpos_screen_id_subscription_with_helper() { + // Define the WooCommerce Subscriptions helper function. + if ( ! function_exists( 'wcs_get_page_screen_id' ) ) { + function wcs_get_page_screen_id( $page ) { + return 'woocommerce_page_wc-orders--shop_subscription'; + } + } + + $wc_order = new WC_Order(); + + $method = new ReflectionMethod( WC_Order::class, 'get_hpos_screen_id' ); + $method->setAccessible( true ); + + $result = $method->invoke( $wc_order, 'shop_subscription' ); + + $this->assertEquals( + 'woocommerce_page_wc-orders--shop_subscription', + $result, + 'shop_subscription should use wcs_get_page_screen_id when available' + ); + } + + /** + * Test register_order_type_hooks skips shop_order. + */ + public function test_register_order_type_hooks_skips_shop_order() { + $wc_order = new WC_Order(); + + // Run the method. + $wc_order->register_order_type_hooks(); + + // shop_order should NOT have its own suffixed hook. + $this->assertFalse( + has_action( 'load-woocommerce_page_wc-orders--shop_order', array( $wc_order, 'initialize' ) ), + 'shop_order should not have a suffixed hook registered' + ); + } + + /** + * Test register_order_type_hooks registers hooks for other order types. + */ + public function test_register_order_type_hooks_registers_other_types() { + $wc_order = new WC_Order(); + + // Run the method. + $wc_order->register_order_type_hooks(); + + // shop_subscription should have its hook registered. + $this->assertNotFalse( + has_action( 'load-woocommerce_page_wc-orders--shop_subscription', array( $wc_order, 'initialize' ) ), + 'shop_subscription should have a hook registered' + ); + + // shop_order_refund should have its hook registered. + $this->assertNotFalse( + has_action( 'load-woocommerce_page_wc-orders--shop_order_refund', array( $wc_order, 'initialize' ) ), + 'shop_order_refund should have a hook registered' + ); + } + + /** + * Test is_hpos_enabled returns boolean. + */ + public function test_is_hpos_enabled_returns_boolean() { + $wc_order = new WC_Order(); + + $result = $wc_order->is_hpos_enabled(); + + $this->assertIsBool( $result, 'is_hpos_enabled should return a boolean' ); + } + + /** + * Test is_hpos_enabled returns false when OrderUtil class does not exist. + */ + public function test_is_hpos_enabled_false_without_order_util() { + $wc_order = new WC_Order(); + + // Without the OrderUtil class being properly set up, should return false. + // In our test environment, the class may not exist or method may return false. + $result = $wc_order->is_hpos_enabled(); + + // We just verify it returns a boolean without throwing errors. + $this->assertIsBool( $result ); + } + + /** + * Test add_meta_boxes returns early when order is null. + */ + public function test_add_meta_boxes_returns_early_for_null_order() { + $wc_order = new WC_Order(); + + // Pass null directly - the method should return early. + // Using a Mock that returns null from wc_get_order isn't easy, + // so we test by passing an invalid object that will fail the order check. + $wc_order->add_meta_boxes( 'shop_order', null ); + + // If we get here without errors, the test passes. + $this->assertTrue( true ); + } + + /** + * Test add_meta_boxes uses order type from order object. + */ + public function test_add_meta_boxes_uses_dynamic_order_type() { + $wc_order = new WC_Order(); + + // Create a mock order with a custom type. + $mock_order = new Mock_WC_Order( 123, 'shop_order_charge' ); + + // Track what location is passed to acf_get_field_groups. + $captured_args = null; + add_filter( + 'acf/get_field_groups', + function ( $field_groups ) use ( &$captured_args ) { + return array(); // Return empty to prevent further processing. + } + ); + + // Call the method with our mock order. + $wc_order->add_meta_boxes( 'shop_order', $mock_order ); + + // The method should have used the order's type. + $this->assertEquals( 'shop_order_charge', $mock_order->get_type() ); + } + + /** + * Test initialize method adds correct action. + */ + public function test_initialize_adds_meta_boxes_action() { + $wc_order = new WC_Order(); + + // Remove any existing add_meta_boxes action first. + remove_all_actions( 'add_meta_boxes' ); + + // Call initialize. + $wc_order->initialize(); + + // Check that add_meta_boxes action was added. + $this->assertNotFalse( + has_action( 'add_meta_boxes', array( $wc_order, 'add_meta_boxes' ) ), + 'initialize should add add_meta_boxes action' + ); + } + + /** + * Test order_edit_form_top renders form data with correct post_id format. + */ + public function test_order_edit_form_top_uses_correct_post_id_format() { + $wc_order = new WC_Order(); + + // Create a mock order. + $mock_order = new Mock_WC_Order( 456 ); + + // Capture output. + ob_start(); + $wc_order->order_edit_form_top( $mock_order ); + $output = ob_get_clean(); + + // The acf_form_data function should be called with 'woo_order_456'. + // Since we can't easily capture function args, we just verify no errors. + $this->assertTrue( true ); + } + + /** + * Test render_meta_box handles WP_Post object. + */ + public function test_render_meta_box_handles_wp_post() { + $wc_order = new WC_Order(); + + $post = new WP_Post( (object) array( 'ID' => 789 ) ); + $metabox = array( + 'args' => array( + 'field_group' => array( + 'ID' => 1, + 'key' => 'group_test', + 'title' => 'Test Group', + 'instruction_placement' => 'label', + ), + ), + ); + + // This should not throw any errors. + ob_start(); + $wc_order->render_meta_box( $post, $metabox ); + ob_get_clean(); + + $this->assertTrue( true ); + } + + /** + * Test render_meta_box handles WC_Order object directly. + */ + public function test_render_meta_box_handles_wc_order() { + $wc_order = new WC_Order(); + + $mock_order = new Mock_WC_Order( 321 ); + $metabox = array( + 'args' => array( + 'field_group' => array( + 'ID' => 1, + 'key' => 'group_test', + 'title' => 'Test Group', + 'instruction_placement' => 'label', + ), + ), + ); + + // This should not throw any errors. + ob_start(); + $wc_order->render_meta_box( $mock_order, $metabox ); + ob_get_clean(); + + $this->assertTrue( true ); + } + + /** + * Test save_order only runs when HPOS is enabled. + */ + public function test_save_order_requires_hpos() { + // Create a partial mock to control is_hpos_enabled. + $wc_order = $this->getMockBuilder( WC_Order::class ) + ->onlyMethods( array( 'is_hpos_enabled' ) ) + ->getMock(); + + $wc_order->method( 'is_hpos_enabled' )->willReturn( false ); + + // Call save_order - should return early without calling acf_save_post. + $wc_order->save_order( 123 ); + + // If we get here without errors, the early return worked. + $this->assertTrue( true ); + } + + /** + * Test save_order removes action to prevent infinite loop. + */ + public function test_save_order_removes_action_to_prevent_loop() { + // Create a partial mock to control is_hpos_enabled. + $wc_order = $this->getMockBuilder( WC_Order::class ) + ->onlyMethods( array( 'is_hpos_enabled' ) ) + ->getMock(); + + $wc_order->method( 'is_hpos_enabled' )->willReturn( true ); + + // Add the action first. + add_action( 'woocommerce_update_order', array( $wc_order, 'save_order' ), 10 ); + + // Verify it's added. + $this->assertNotFalse( has_action( 'woocommerce_update_order', array( $wc_order, 'save_order' ) ) ); + + // Call save_order. + $wc_order->save_order( 123 ); + + // The action should be removed. + $this->assertFalse( + has_action( 'woocommerce_update_order', array( $wc_order, 'save_order' ) ), + 'save_order should remove itself to prevent infinite loop' + ); + } + + /** + * Test multiple order types can be registered dynamically. + * + * @dataProvider order_types_provider + * + * @param string $order_type The order type to test. + * @param string $expected_hook The expected hook name. + */ + public function test_dynamic_order_type_hooks( $order_type, $expected_hook ) { + $wc_order = new WC_Order(); + + $method = new ReflectionMethod( WC_Order::class, 'get_hpos_screen_id' ); + $method->setAccessible( true ); + + if ( 'shop_order' === $order_type ) { + // shop_order uses wc_get_page_screen_id. + $result = $method->invoke( $wc_order, $order_type ); + $this->assertEquals( 'woocommerce_page_wc-orders', $result ); + } else { + // Other types follow the pattern. + $result = $method->invoke( $wc_order, $order_type ); + $this->assertEquals( $expected_hook, $result ); + } + } + + /** + * Data provider for order types. + * + * @return array + */ + public function order_types_provider() { + return array( + 'shop_order' => array( 'shop_order', 'woocommerce_page_wc-orders' ), + 'shop_order_refund' => array( 'shop_order_refund', 'woocommerce_page_wc-orders--shop_order_refund' ), + 'shop_order_charge' => array( 'shop_order_charge', 'woocommerce_page_wc-orders--shop_order_charge' ), + 'custom_order_type' => array( 'custom_order_type', 'woocommerce_page_wc-orders--custom_order_type' ), + ); + } +} From b49d65e00017544e01ec7f0b82c0c753eb81b8c6 Mon Sep 17 00:00:00 2001 From: TJ Date: Sun, 21 Dec 2025 13:53:09 +0100 Subject: [PATCH 4/4] fixing unit tests with help of claude; phpcs passess --- .../includes/forms/class-mock-wc-order.php | 55 ++++++++++ .../php/includes/forms/test-form-wc-order.php | 98 +---------------- .../forms/wc-order-test-functions.php | 103 ++++++++++++++++++ 3 files changed, 163 insertions(+), 93 deletions(-) create mode 100644 tests/php/includes/forms/class-mock-wc-order.php create mode 100644 tests/php/includes/forms/wc-order-test-functions.php diff --git a/tests/php/includes/forms/class-mock-wc-order.php b/tests/php/includes/forms/class-mock-wc-order.php new file mode 100644 index 00000000..5141b4fa --- /dev/null +++ b/tests/php/includes/forms/class-mock-wc-order.php @@ -0,0 +1,55 @@ +id = $id; + $this->type = $type; + } + + /** + * Get order ID. + * + * @return int + */ + public function get_id() { + return $this->id; + } + + /** + * Get order type. + * + * @return string + */ + public function get_type() { + return $this->type; + } +} diff --git a/tests/php/includes/forms/test-form-wc-order.php b/tests/php/includes/forms/test-form-wc-order.php index ccc01322..44123faf 100644 --- a/tests/php/includes/forms/test-form-wc-order.php +++ b/tests/php/includes/forms/test-form-wc-order.php @@ -8,92 +8,14 @@ use WorDBless\BaseTestCase; use SCF\Forms\WC_Order; -/** - * Mock WC_Order class for testing. - */ -class Mock_WC_Order { - /** - * Order ID. - * - * @var int - */ - private $id; - - /** - * Order type. - * - * @var string - */ - private $type; - - /** - * Constructor. - * - * @param int $id Order ID. - * @param string $type Order type. - */ - public function __construct( $id = 1, $type = 'shop_order' ) { - $this->id = $id; - $this->type = $type; - } - - /** - * Get order ID. - * - * @return int - */ - public function get_id() { - return $this->id; - } - - /** - * Get order type. - * - * @return string - */ - public function get_type() { - return $this->type; - } -} +// Load mock functions and classes. +require_once __DIR__ . '/wc-order-test-functions.php'; /** * Class Test_Form_WC_Order */ class Test_Form_WC_Order extends BaseTestCase { - /** - * Store original function existence states. - * - * @var array - */ - private $original_functions = array(); - - /** - * Set up before each test. - */ - public function set_up() { - parent::set_up(); - - // Define WooCommerce mock functions if they don't exist. - if ( ! function_exists( 'wc_get_order_types' ) ) { - function wc_get_order_types( $for = '' ) { - return array( 'shop_order', 'shop_subscription', 'shop_order_refund' ); - } - } - - if ( ! function_exists( 'wc_get_order' ) ) { - function wc_get_order( $order_id ) { - return new Mock_WC_Order( $order_id ); - } - } - - if ( ! function_exists( 'wc_get_page_screen_id' ) ) { - function wc_get_page_screen_id( $page ) { - return 'woocommerce_page_wc-orders'; - } - } - } - /** * Tear down after each test. */ @@ -202,13 +124,6 @@ public function test_get_hpos_screen_id_refund_order() { * Test get_hpos_screen_id handles shop_subscription when wcs_get_page_screen_id exists. */ public function test_get_hpos_screen_id_subscription_with_helper() { - // Define the WooCommerce Subscriptions helper function. - if ( ! function_exists( 'wcs_get_page_screen_id' ) ) { - function wcs_get_page_screen_id( $page ) { - return 'woocommerce_page_wc-orders--shop_subscription'; - } - } - $wc_order = new WC_Order(); $method = new ReflectionMethod( WC_Order::class, 'get_hpos_screen_id' ); @@ -293,8 +208,6 @@ public function test_add_meta_boxes_returns_early_for_null_order() { $wc_order = new WC_Order(); // Pass null directly - the method should return early. - // Using a Mock that returns null from wc_get_order isn't easy, - // so we test by passing an invalid object that will fail the order check. $wc_order->add_meta_boxes( 'shop_order', null ); // If we get here without errors, the test passes. @@ -310,11 +223,10 @@ public function test_add_meta_boxes_uses_dynamic_order_type() { // Create a mock order with a custom type. $mock_order = new Mock_WC_Order( 123, 'shop_order_charge' ); - // Track what location is passed to acf_get_field_groups. - $captured_args = null; + // Add filter to prevent further processing and track calls. add_filter( 'acf/get_field_groups', - function ( $field_groups ) use ( &$captured_args ) { + function () { return array(); // Return empty to prevent further processing. } ); @@ -357,7 +269,7 @@ public function test_order_edit_form_top_uses_correct_post_id_format() { // Capture output. ob_start(); $wc_order->order_edit_form_top( $mock_order ); - $output = ob_get_clean(); + ob_get_clean(); // The acf_form_data function should be called with 'woo_order_456'. // Since we can't easily capture function args, we just verify no errors. diff --git a/tests/php/includes/forms/wc-order-test-functions.php b/tests/php/includes/forms/wc-order-test-functions.php new file mode 100644 index 00000000..dbe30e38 --- /dev/null +++ b/tests/php/includes/forms/wc-order-test-functions.php @@ -0,0 +1,103 @@ +