Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions classes/class-cli.php
Original file line number Diff line number Diff line change
Expand Up @@ -223,14 +223,19 @@ private function csv_format( $records ) {
* @return void
*/
private function connection() {
$query = wp_stream_get_instance()->db->query(
global $wpdb;

wp_stream_get_instance()->db->query(
array(
'records_per_page' => 1,
'fields' => 'created',
)
);

if ( ! $query ) {
// An empty result set is valid (e.g. a fresh site with no logged
// activity yet); only a genuine database error means the site is
// disconnected.
if ( ! empty( $wpdb->last_error ) ) {
\WP_CLI::error( esc_html__( 'SITE IS DISCONNECTED', 'stream' ) );
}
}
Expand Down
74 changes: 74 additions & 0 deletions tests/phpunit/test-class-cli.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php
namespace WP_Stream;

use ReflectionMethod;
use ReflectionProperty;
use WP_CLI;
use WP_CLI\ExitException;

class Test_CLI extends WP_StreamTestCase {
/**
* Invokes the private CLI::connection() method, capturing any
* WP_CLI::error() exit as an ExitException instead of terminating
* the test process.
*
* @throws ExitException When the connection check fails.
*/
private function invoke_connection() {
$capture_exit = new ReflectionProperty( WP_CLI::class, 'capture_exit' );
$capture_exit->setAccessible( true );
$capture_exit->setValue( null, true );

$connection = new ReflectionMethod( CLI::class, 'connection' );
$connection->setAccessible( true );

try {
$connection->invoke( new CLI() );
} finally {
$capture_exit->setValue( null, false );
}
}

/**
* A query that legitimately matches zero records is not a disconnection.
*/
public function test_connection_does_not_error_on_empty_result() {
global $wpdb;

// Force the connection check's query to match nothing, without
// touching any actual data other tests rely on.
$force_no_matches = function ( $where ) {
return $where . ' AND 1=0';
};
add_filter( 'wp_stream_db_query_where', $force_no_matches );

try {
$this->invoke_connection();
} finally {
remove_filter( 'wp_stream_db_query_where', $force_no_matches );
}

// Reaching this line means WP_CLI::error() was never triggered.
$this->assertEmpty( $wpdb->last_error );
}

/**
* A genuine database error should still be reported as a disconnected site.
*/
public function test_connection_errors_on_database_failure() {
global $wpdb;

$original_table = $wpdb->stream;
$wpdb->stream = $wpdb->prefix . 'stream_table_that_does_not_exist';
$wpdb->suppress_errors( true );

try {
$this->expectException( ExitException::class );
$this->invoke_connection();
} finally {
$wpdb->stream = $original_table;
$wpdb->suppress_errors( false );
$wpdb->last_error = '';
}
}
}