Fixes for the WP CLI Updater (#33264)

* After running db update callbacks, update the `woocommerce_db_version` option.
* Remove dead code.
* Add tests for `wp wc update`.
This commit is contained in:
Barry Hughes 2022-06-07 04:20:28 -07:00 committed by GitHub
parent f04e0761a6
commit 1bca9327ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 150 additions and 12 deletions

View File

@ -0,0 +1,4 @@
Significance: patch
Type: fix
Fixes for the WP CLI updates

View File

@ -21,7 +21,7 @@ class WC_CLI_Update_Command {
* Registers the update command.
*/
public static function register_commands() {
WP_CLI::add_command( 'wc update', array( 'WC_CLI_Update_Command', 'update' ) );
WC()->call_static( WP_CLI::class, 'add_command', 'wc update', array( 'WC_CLI_Update_Command', 'update' ) );
}
/**
@ -51,31 +51,45 @@ class WC_CLI_Update_Command {
if ( empty( $callbacks_to_run ) ) {
// Ensure DB version is set to the current WC version to match WP-Admin update routine.
WC_Install::update_db_version();
/* translators: %s Database version number */
WP_CLI::success( sprintf( __( 'No updates required. Database version is %s', 'woocommerce' ), get_option( 'woocommerce_db_version' ) ) );
WC()->call_static(
WP_CLI::class,
'success',
/* translators: %s Database version number */
sprintf( __( 'No updates required. Database version is %s', 'woocommerce' ), get_option( 'woocommerce_db_version' ) )
);
return;
}
/* translators: 1: Number of database updates 2: List of update callbacks */
WP_CLI::log( sprintf( __( 'Found %1$d updates (%2$s)', 'woocommerce' ), count( $callbacks_to_run ), implode( ', ', $callbacks_to_run ) ) );
WC()->call_static(
WP_CLI::class,
'log',
/* translators: 1: Number of database updates 2: List of update callbacks */
sprintf( __( 'Found %1$d updates (%2$s)', 'woocommerce' ), count( $callbacks_to_run ), implode( ', ', $callbacks_to_run ) )
);
$progress = \WP_CLI\Utils\make_progress_bar( __( 'Updating database', 'woocommerce' ), count( $callbacks_to_run ) ); // phpcs:ignore PHPCompatibility.LanguageConstructs.NewLanguageConstructs.t_ns_separatorFound
$progress = WC()->call_function(
'WP_CLI\Utils\make_progress_bar',
__( 'Updating database', 'woocommerce' ),
count( $callbacks_to_run ) // phpcs:ignore PHPCompatibility.LanguageConstructs.NewLanguageConstructs.t_ns_separatorFound
);
foreach ( $callbacks_to_run as $update_callback ) {
call_user_func( $update_callback );
$result = false;
while ( $result ) {
$result = (bool) call_user_func( $update_callback );
}
$update_count ++;
$progress->tick();
}
WC_Install::update_db_version();
$progress->finish();
WC_Admin_Notices::remove_notice( 'update', true );
/* translators: 1: Number of database updates performed 2: Database version number */
WP_CLI::success( sprintf( __( '%1$d update functions completed. Database version is %2$s', 'woocommerce' ), absint( $update_count ), get_option( 'woocommerce_db_version' ) ) );
WC()->call_static(
WP_CLI::class,
'success',
/* translators: 1: Number of database updates performed 2: Database version number */
sprintf( __( '%1$d update functions completed. Database version is %2$s', 'woocommerce' ), absint( $update_count ), get_option( 'woocommerce_db_version' ) )
);
}
}

View File

@ -0,0 +1,120 @@
<?php
/**
* Tests for the `wp wc update` WP CLI command.
*/
class WC_CLI_Update_Command_Test extends WC_Unit_Test_Case {
/**
* @var array
*/
private $db_updates_original_value;
/**
* @var ReflectionProperty
*/
private $db_updates_property;
/**
* Load the WC_CLI_Update_Command class definition.
*/
public static function set_up_before_class() {
parent::set_up_before_class();
require_once dirname( WC_PLUGIN_FILE ) . '/includes/cli/class-wc-cli-update-command.php';
}
/**
* Make WP_Install::$db_updates readable and capture the original value.
*/
public function set_up() {
$this->db_updates_property = new ReflectionProperty( WC_Install::class, 'db_updates' );
$this->db_updates_property->setAccessible( true );
$this->db_updates_original_value = $this->db_updates_property->getValue();
}
/**
* Restore WP_Install::$db_updates to its earlier state.
*/
public function tear_down() {
$this->db_updates_property->setValue( $this->db_updates_original_value );
$this->db_updates_property->setAccessible( false );
}
/**
* @testdox After `wp wc update` has run, the `woocommerce_db_option` should be left at the expected value.
*/
public function test_db_version_is_updated_if_have_callbacks() {
$this->mock_wp_cli();
// Overwrite with some alternative update callbacks.
$this->db_updates_property->setValue(
array(
'5.0.0' => function () {},
'6.0.0' => function () {},
)
);
update_option( 'woocommerce_db_version', '4.0.0' );
$sut = new WC_CLI_Update_Command();
$sut->update();
$this->assertEquals(
WC()->version,
get_option( 'woocommerce_db_version' ),
'After applying updates via WP CLI, the `woocommerce_db_version` option should match the current `WC()->version` property.'
);
}
/**
* @testdox After `wp wc update` has run, the `woocommerce_db_option` should be left at the expected value (even if no update callbacks were executed)
*/
public function test_db_version_is_updated_if_no_callbacks() {
$this->mock_wp_cli();
// Overwrite with some alternative update callbacks.
$this->db_updates_property->setValue( array() );
update_option( 'woocommerce_db_version', '4.0.0' );
$sut = new WC_CLI_Update_Command();
$sut->update();
$this->assertEquals(
WC()->version,
get_option( 'woocommerce_db_version' ),
'After applying updates via WP CLI, the `woocommerce_db_version` option should match the current `WC()->version` property.'
);
}
/**
* Mock WP_CLI and related functionality.
*/
private function mock_wp_cli() {
parent::set_up();
$this->register_legacy_proxy_static_mocks(
array(
WP_CLI::class => array(
'log' => function () {},
'success' => function () {},
),
)
);
$this->register_legacy_proxy_function_mocks(
array(
'WP_CLI\Utils\make_progress_bar' => function () {
return new class() {
/**
* Stub, implemented so that calls to WP CLI methods do not break the tests.
*/
public function finish() {}
/**
* Stub, implemented so that calls to WP CLI methods do not break the tests.
*/
public function tick() {}
};
},
)
);
}
}