|
2 | 2 | /** |
3 | 3 | * PHPUnit bootstrap. |
4 | 4 | * |
5 | | - * Designed to run inside the wp-env `tests-cli` container, where the |
6 | | - * WordPress test suite is mounted at `/wordpress-phpunit` and the repo |
7 | | - * is mounted (via the `mappings` entry in .wp-env.json) at |
8 | | - * `/var/www/html/wp-content/plugins/hey-woo-tests`. |
| 5 | + * Supports two environments: |
| 6 | + * |
| 7 | + * 1. Local wp-env — run via `bin/check`. The tests-cli container mounts the |
| 8 | + * WP test suite at `/wordpress-phpunit` and the repo at |
| 9 | + * `wp-content/plugins/hey-woo-tests` (the --env-cwd target). |
| 10 | + * |
| 11 | + * 2. CI / bare PHP — run after `bin/install-wp-tests.sh`. Set WP_TESTS_DIR to |
| 12 | + * the path where the WP PHPUnit suite was installed; WooCommerce and the |
| 13 | + * plugin are installed into WP_PLUGIN_DIR by the install script. |
9 | 14 | * |
10 | 15 | * @package HeyWoo\Tests |
11 | 16 | */ |
@@ -45,48 +50,48 @@ function hey_woo_tests_load_plugins() { |
45 | 50 | require_once $wc_candidates[0]; |
46 | 51 |
|
47 | 52 | require_once $plugin_dir . '/hey-woo/hey-woo.php'; |
| 53 | + |
| 54 | + // Prevent WooCommerce's own check_version() hook (plugins_loaded) from |
| 55 | + // running WC_Install::install() before we have a chance to set the HPOS |
| 56 | + // options below. We do the controlled install ourselves in the init hook. |
| 57 | + update_option( 'woocommerce_db_version', WC()->version ); |
48 | 58 | } |
49 | 59 | tests_add_filter( 'muplugins_loaded', 'hey_woo_tests_load_plugins' ); |
50 | 60 |
|
51 | 61 | /** |
52 | | - * Activate WooCommerce explicitly so its install routine runs and the |
53 | | - * HPOS tables (wc_orders / wc_orders_meta / wc_order_addresses / |
54 | | - * wc_order_operational_data) exist before the first test query. |
| 62 | + * Run the WooCommerce install routine with the correct options set. |
55 | 63 | * |
56 | | - * HPOS is enabled by setting `woocommerce_custom_orders_table_enabled` |
57 | | - * BEFORE `WC_Install::create_tables()` runs — the installer gates the |
58 | | - * HPOS `dbDelta` on FeaturesController::feature_is_enabled(), which |
59 | | - * reads that option. Data sync is disabled so orders land straight in |
60 | | - * the HPOS tables without a parallel wp_postmeta write. Suppressing |
61 | | - * the incompatible-plugin notice keeps the option update quiet. |
| 64 | + * Hooked to `init` (priority 0) so WordPress is fully bootstrapped before we |
| 65 | + * touch the database. Three things matter here: |
62 | 66 | * |
63 | | - * WC_Install::install() is invoked explicitly after activate_plugin() |
64 | | - * because activate_plugin()'s activation-hook path runs asynchronously |
65 | | - * in some WP paths; calling install() directly guarantees create_tables |
66 | | - * fires once the option is in place. |
| 67 | + * 1. HPOS options must be set before WC_Install::create_tables() runs, otherwise |
| 68 | + * the HPOS order tables are not created. |
| 69 | + * 2. woocommerce_db_version must be deleted first so WC_Install::install() does |
| 70 | + * not bail out early thinking WC is already up-to-date. |
| 71 | + * 3. $wp_roles must be reset after create_roles() writes new capabilities to the |
| 72 | + * database. WP_Roles is a singleton that was already initialized before |
| 73 | + * create_roles() ran; without the reset, current_user_can() checks in tests |
| 74 | + * see the stale pre-install snapshot. |
| 75 | + * See https://core.trac.wordpress.org/ticket/28374 |
67 | 76 | */ |
68 | | -function hey_woo_tests_activate_woocommerce() { |
69 | | - if ( ! function_exists( 'activate_plugin' ) ) { |
70 | | - return; |
71 | | - } |
72 | | - |
| 77 | +function hey_woo_tests_install_woocommerce() { |
73 | 78 | update_option( 'woocommerce_custom_orders_table_enabled', 'yes' ); |
74 | 79 | update_option( 'woocommerce_custom_orders_table_data_sync_enabled', 'no' ); |
75 | 80 | update_option( 'woocommerce_show_feature_enable_notice_custom_order_tables', 'no' ); |
76 | 81 |
|
77 | | - $plugin_dir = defined( 'WP_PLUGIN_DIR' ) ? WP_PLUGIN_DIR : ABSPATH . 'wp-content/plugins'; |
78 | | - $wc_candidates = glob( $plugin_dir . '/woocommerce*/woocommerce.php' ); |
79 | | - if ( empty( $wc_candidates ) ) { |
80 | | - return; |
81 | | - } |
82 | | - $relative = ltrim( str_replace( $plugin_dir, '', $wc_candidates[0] ), '/' ); |
83 | | - activate_plugin( $relative ); |
| 82 | + // Allow install() to run by removing the version we pinned in muplugins_loaded. |
| 83 | + delete_option( 'woocommerce_db_version' ); |
84 | 84 |
|
85 | 85 | if ( class_exists( 'WC_Install' ) ) { |
86 | 86 | WC_Install::install(); |
87 | 87 | } |
| 88 | + |
| 89 | + // Reload the WP_Roles singleton from the database so the capabilities added |
| 90 | + // by create_roles() (e.g. manage_woocommerce) are visible to tests. |
| 91 | + $GLOBALS['wp_roles'] = null; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited |
| 92 | + wp_roles(); |
88 | 93 | } |
89 | | -tests_add_filter( 'setup_theme', 'hey_woo_tests_activate_woocommerce' ); |
| 94 | +tests_add_filter( 'init', 'hey_woo_tests_install_woocommerce', 0 ); |
90 | 95 |
|
91 | 96 | require $_tests_dir . '/includes/bootstrap.php'; |
92 | 97 |
|
|
0 commit comments