From f99e00995384ce27b84dcd92ab62fdaada03e072 Mon Sep 17 00:00:00 2001 From: hbhalodia Date: Tue, 6 Jan 2026 11:40:24 +0530 Subject: [PATCH 01/23] CoreTrac-64071 Show different warning if debug.log is publicly accessible --- .../includes/class-wp-site-health.php | 42 ++++++++++++++----- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/src/wp-admin/includes/class-wp-site-health.php b/src/wp-admin/includes/class-wp-site-health.php index a5a8c7f4dade2..0fba3cda20c36 100644 --- a/src/wp-admin/includes/class-wp-site-health.php +++ b/src/wp-admin/includes/class-wp-site-health.php @@ -1409,18 +1409,40 @@ public function get_test_is_in_debug_mode() { if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { if ( defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG ) { - $result['label'] = __( 'Your site is set to log errors to a potentially public file' ); + // Resolve the actual log path. + $log_path = WP_DEBUG_LOG === true ? WP_CONTENT_DIR . '/debug.log' : WP_DEBUG_LOG; + $log_path = realpath( $log_path ); + $absolute_path = realpath( ABSPATH ); - $result['status'] = str_starts_with( ini_get( 'error_log' ), ABSPATH ) ? 'critical' : 'recommended'; + // Only show warning if log is inside ABSPATH (publicly accessible). + // If paths cannot be resolved or log is outside ABSPATH, skip the warning. + if ( $log_path && $absolute_path && str_starts_with( $log_path, $absolute_path ) ) { + $result['label'] = __( 'Your site is set to log errors to a potentially public file' ); - $result['description'] .= sprintf( - '

%s

', - sprintf( - /* translators: %s: WP_DEBUG_LOG */ - __( 'The value, %s, has been added to this website’s configuration file. This means any errors on the site will be written to a file which is potentially available to all users.' ), - 'WP_DEBUG_LOG' - ) - ); + $result['status'] = 'critical'; + + $result['description'] .= sprintf( + '

%s

', + sprintf( + /* translators: %s: WP_DEBUG_LOG */ + __( 'The value, %s, has been added to this website’s configuration file. This means any errors on the site will be written to a file which is potentially available to all users.' ), + 'WP_DEBUG_LOG' + ) + ); + } elseif ( $log_path && $absolute_path && ! str_starts_with( $log_path, $absolute_path ) ) { + $result['label'] = __( 'Your site is set to log errors to a file outside the public directory' ); + + $result['status'] = 'good'; + + $result['description'] .= sprintf( + '

%s

', + sprintf( + /* translators: %s: WP_DEBUG_LOG */ + __( 'The value, %s, has been configured to write errors to a file outside the WordPress directory. This is a good practice as the log file is not publicly accessible.' ), + 'WP_DEBUG_LOG' + ) + ); + } } if ( defined( 'WP_DEBUG_DISPLAY' ) && WP_DEBUG_DISPLAY ) { From bcebdf81ca11d576cd372a1d8ea078f00627dde9 Mon Sep 17 00:00:00 2001 From: hbhalodia Date: Tue, 6 Jan 2026 11:46:42 +0530 Subject: [PATCH 02/23] CoreTrac-64071 Update the wordings and code structure --- src/wp-admin/includes/class-wp-site-health.php | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/wp-admin/includes/class-wp-site-health.php b/src/wp-admin/includes/class-wp-site-health.php index 0fba3cda20c36..28f9f9229fb03 100644 --- a/src/wp-admin/includes/class-wp-site-health.php +++ b/src/wp-admin/includes/class-wp-site-health.php @@ -1409,14 +1409,11 @@ public function get_test_is_in_debug_mode() { if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { if ( defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG ) { - // Resolve the actual log path. - $log_path = WP_DEBUG_LOG === true ? WP_CONTENT_DIR . '/debug.log' : WP_DEBUG_LOG; - $log_path = realpath( $log_path ); - $absolute_path = realpath( ABSPATH ); - - // Only show warning if log is inside ABSPATH (publicly accessible). - // If paths cannot be resolved or log is outside ABSPATH, skip the warning. - if ( $log_path && $absolute_path && str_starts_with( $log_path, $absolute_path ) ) { + $debug_log_path = WP_DEBUG_LOG === true ? WP_CONTENT_DIR . '/debug.log' : WP_DEBUG_LOG; + $debug_log_path = realpath( $debug_log_path ); + $absolute_path = realpath( ABSPATH ); + + if ( $debug_log_path && $absolute_path && str_starts_with( $debug_log_path, $absolute_path ) ) { $result['label'] = __( 'Your site is set to log errors to a potentially public file' ); $result['status'] = 'critical'; @@ -1429,7 +1426,7 @@ public function get_test_is_in_debug_mode() { 'WP_DEBUG_LOG' ) ); - } elseif ( $log_path && $absolute_path && ! str_starts_with( $log_path, $absolute_path ) ) { + } else { $result['label'] = __( 'Your site is set to log errors to a file outside the public directory' ); $result['status'] = 'good'; From 3749fefe3ced4646735f64013929e8c3dd995f0b Mon Sep 17 00:00:00 2001 From: hbhalodia Date: Thu, 8 Jan 2026 12:18:15 +0530 Subject: [PATCH 03/23] CoreTrac-64071 Add the directory separator to absolute path to prevent false positives --- src/wp-admin/includes/class-wp-site-health.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-admin/includes/class-wp-site-health.php b/src/wp-admin/includes/class-wp-site-health.php index 28f9f9229fb03..845c6e1fcc354 100644 --- a/src/wp-admin/includes/class-wp-site-health.php +++ b/src/wp-admin/includes/class-wp-site-health.php @@ -1411,7 +1411,7 @@ public function get_test_is_in_debug_mode() { if ( defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG ) { $debug_log_path = WP_DEBUG_LOG === true ? WP_CONTENT_DIR . '/debug.log' : WP_DEBUG_LOG; $debug_log_path = realpath( $debug_log_path ); - $absolute_path = realpath( ABSPATH ); + $absolute_path = realpath( ABSPATH ) . DIRECTORY_SEPARATOR; if ( $debug_log_path && $absolute_path && str_starts_with( $debug_log_path, $absolute_path ) ) { $result['label'] = __( 'Your site is set to log errors to a potentially public file' ); From 863600296cfbfd72d4fafd190917135d59f8afdf Mon Sep 17 00:00:00 2001 From: hbhalodia Date: Thu, 8 Jan 2026 12:59:11 +0530 Subject: [PATCH 04/23] CoreTrac-64071 Update wordings in message to show in site-health for debug constants --- src/wp-admin/includes/class-wp-site-health.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wp-admin/includes/class-wp-site-health.php b/src/wp-admin/includes/class-wp-site-health.php index 845c6e1fcc354..19062d32bbf86 100644 --- a/src/wp-admin/includes/class-wp-site-health.php +++ b/src/wp-admin/includes/class-wp-site-health.php @@ -1422,12 +1422,12 @@ public function get_test_is_in_debug_mode() { '

%s

', sprintf( /* translators: %s: WP_DEBUG_LOG */ - __( 'The value, %s, has been added to this website’s configuration file. This means any errors on the site will be written to a file which is potentially available to all users.' ), + __( 'The constant, %s, has been added to this website’s configuration file. This means any errors on the site will be written to a file which is likely publicly accessible.' ), 'WP_DEBUG_LOG' ) ); } else { - $result['label'] = __( 'Your site is set to log errors to a file outside the public directory' ); + $result['label'] = __( 'Your site is set to log errors to a file outside the document root' ); $result['status'] = 'good'; @@ -1435,7 +1435,7 @@ public function get_test_is_in_debug_mode() { '

%s

', sprintf( /* translators: %s: WP_DEBUG_LOG */ - __( 'The value, %s, has been configured to write errors to a file outside the WordPress directory. This is a good practice as the log file is not publicly accessible.' ), + __( 'The configuration constant, %s, has been set to write errors to a file outside the WordPress directory. This is a good practice as the log file should not be publicly accessible' ), 'WP_DEBUG_LOG' ) ); From ffda9d84203ed83031858ed81cf7cd6a60ca1a91 Mon Sep 17 00:00:00 2001 From: hbhalodia Date: Fri, 9 Jan 2026 10:02:16 +0530 Subject: [PATCH 05/23] CoreTrac-64071 Check the directory of log instead of checking file --- src/wp-admin/includes/class-wp-site-health.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-admin/includes/class-wp-site-health.php b/src/wp-admin/includes/class-wp-site-health.php index 19062d32bbf86..bd98483958c43 100644 --- a/src/wp-admin/includes/class-wp-site-health.php +++ b/src/wp-admin/includes/class-wp-site-health.php @@ -1410,7 +1410,7 @@ public function get_test_is_in_debug_mode() { if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { if ( defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG ) { $debug_log_path = WP_DEBUG_LOG === true ? WP_CONTENT_DIR . '/debug.log' : WP_DEBUG_LOG; - $debug_log_path = realpath( $debug_log_path ); + $debug_log_path = realpath( dirname ( $debug_log_path ) ) . DIRECTORY_SEPARATOR; $absolute_path = realpath( ABSPATH ) . DIRECTORY_SEPARATOR; if ( $debug_log_path && $absolute_path && str_starts_with( $debug_log_path, $absolute_path ) ) { From b98ece613c9fc6cf9e7f47d043a5644209a1b81a Mon Sep 17 00:00:00 2001 From: hbhalodia Date: Fri, 9 Jan 2026 10:05:32 +0530 Subject: [PATCH 06/23] CoreTrac-64071 Fix phpcs error --- src/wp-admin/includes/class-wp-site-health.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-admin/includes/class-wp-site-health.php b/src/wp-admin/includes/class-wp-site-health.php index bd98483958c43..f622af863b7de 100644 --- a/src/wp-admin/includes/class-wp-site-health.php +++ b/src/wp-admin/includes/class-wp-site-health.php @@ -1410,7 +1410,7 @@ public function get_test_is_in_debug_mode() { if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { if ( defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG ) { $debug_log_path = WP_DEBUG_LOG === true ? WP_CONTENT_DIR . '/debug.log' : WP_DEBUG_LOG; - $debug_log_path = realpath( dirname ( $debug_log_path ) ) . DIRECTORY_SEPARATOR; + $debug_log_path = realpath( dirname( $debug_log_path ) ) . DIRECTORY_SEPARATOR; $absolute_path = realpath( ABSPATH ) . DIRECTORY_SEPARATOR; if ( $debug_log_path && $absolute_path && str_starts_with( $debug_log_path, $absolute_path ) ) { From 2da8e227d537ce68980c0d5161b5ff6e8be1f992 Mon Sep 17 00:00:00 2001 From: hbhalodia Date: Fri, 9 Jan 2026 10:27:58 +0530 Subject: [PATCH 07/23] CoreTrac-64071 Update the debug_log_path to use error_log config --- src/wp-admin/includes/class-wp-site-health.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/wp-admin/includes/class-wp-site-health.php b/src/wp-admin/includes/class-wp-site-health.php index f622af863b7de..2f0313f4b8486 100644 --- a/src/wp-admin/includes/class-wp-site-health.php +++ b/src/wp-admin/includes/class-wp-site-health.php @@ -1409,8 +1409,7 @@ public function get_test_is_in_debug_mode() { if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { if ( defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG ) { - $debug_log_path = WP_DEBUG_LOG === true ? WP_CONTENT_DIR . '/debug.log' : WP_DEBUG_LOG; - $debug_log_path = realpath( dirname( $debug_log_path ) ) . DIRECTORY_SEPARATOR; + $debug_log_path = realpath( dirname( ini_get( 'error_log' ) ) ) . DIRECTORY_SEPARATOR; $absolute_path = realpath( ABSPATH ) . DIRECTORY_SEPARATOR; if ( $debug_log_path && $absolute_path && str_starts_with( $debug_log_path, $absolute_path ) ) { From ad94980adf9632c5627ad2415543c9f9891771d3 Mon Sep 17 00:00:00 2001 From: hbhalodia Date: Mon, 12 Jan 2026 09:23:16 +0530 Subject: [PATCH 08/23] CoreTrac-64071 Fix grammetical mistake --- src/wp-admin/includes/class-wp-site-health.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-admin/includes/class-wp-site-health.php b/src/wp-admin/includes/class-wp-site-health.php index 48fa53949db30..eb02cfcb8a55f 100644 --- a/src/wp-admin/includes/class-wp-site-health.php +++ b/src/wp-admin/includes/class-wp-site-health.php @@ -1434,7 +1434,7 @@ public function get_test_is_in_debug_mode() { '

%s

', sprintf( /* translators: %s: WP_DEBUG_LOG */ - __( 'The configuration constant, %s, has been set to write errors to a file outside the WordPress directory. This is a good practice as the log file should not be publicly accessible' ), + __( 'The configuration constant, %s, has been set to write errors to a file outside the WordPress directory. This is a good practice as the log file should not be publicly accessible.' ), 'WP_DEBUG_LOG' ) ); From 551f125c799412db94456a137c2da3c0a46c5a07 Mon Sep 17 00:00:00 2001 From: hbhalodia Date: Mon, 12 Jan 2026 09:45:20 +0530 Subject: [PATCH 09/23] CoreTrac-64071 Update message based on how log file is being set --- .../includes/class-wp-site-health.php | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/src/wp-admin/includes/class-wp-site-health.php b/src/wp-admin/includes/class-wp-site-health.php index eb02cfcb8a55f..a0d0cba142f9f 100644 --- a/src/wp-admin/includes/class-wp-site-health.php +++ b/src/wp-admin/includes/class-wp-site-health.php @@ -1408,35 +1408,37 @@ public function get_test_is_in_debug_mode() { ); if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { - if ( defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG ) { - $debug_log_path = realpath( dirname( ini_get( 'error_log' ) ) ) . DIRECTORY_SEPARATOR; - $absolute_path = realpath( ABSPATH ) . DIRECTORY_SEPARATOR; + if ( ! empty( ini_get( 'error_log' ) ) ) { + $debug_log_path = realpath( dirname( ini_get( 'error_log' ) ) ) . DIRECTORY_SEPARATOR; + $absolute_path = realpath( ABSPATH ) . DIRECTORY_SEPARATOR; + $is_public_log = $debug_log_path && $absolute_path && str_starts_with( $debug_log_path, $absolute_path ); + $is_wp_debug_log = defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG; - if ( $debug_log_path && $absolute_path && str_starts_with( $debug_log_path, $absolute_path ) ) { + if ( $is_public_log ) { $result['label'] = __( 'Your site is set to log errors to a potentially public file' ); - $result['status'] = 'critical'; + } else { + $result['label'] = __( 'Your site is set to log errors to a file outside the document root' ); + $result['status'] = 'good'; + } + if ( $is_wp_debug_log ) { $result['description'] .= sprintf( '

%s

', sprintf( /* translators: %s: WP_DEBUG_LOG */ - __( 'The constant, %s, has been added to this website’s configuration file. This means any errors on the site will be written to a file which is likely publicly accessible.' ), + $is_public_log + ? __( 'The constant, %s, has been added to this website’s configuration file. This means any errors on the site will be written to a file which is likely publicly accessible.' ) + : __( 'The configuration constant, %s, has been set to write errors to a file outside the WordPress directory. This is a good practice as the log file should not be publicly accessible.' ), 'WP_DEBUG_LOG' ) ); } else { - $result['label'] = __( 'Your site is set to log errors to a file outside the document root' ); - - $result['status'] = 'good'; - $result['description'] .= sprintf( '

%s

', - sprintf( - /* translators: %s: WP_DEBUG_LOG */ - __( 'The configuration constant, %s, has been set to write errors to a file outside the WordPress directory. This is a good practice as the log file should not be publicly accessible.' ), - 'WP_DEBUG_LOG' - ) + $is_public_log + ? __( 'The error log path has been configured to a file within your WordPress directory. This means any errors on the site will be written to a file which is likely publicly accessible.' ) + : __( 'The error log path has been configured to a file outside your WordPress directory. This is a good practice as the log file should not be publicly accessible.' ) ); } } From d2a8e124a9433cc95c6a0e9b298b3c2d93ee6455 Mon Sep 17 00:00:00 2001 From: hbhalodia Date: Mon, 12 Jan 2026 11:13:54 +0530 Subject: [PATCH 10/23] CoreTrac-64071 Address copilot feedbacks --- .../includes/class-wp-site-health.php | 36 +++++++++++++------ 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/src/wp-admin/includes/class-wp-site-health.php b/src/wp-admin/includes/class-wp-site-health.php index 512b3f406905d..68636c276834b 100644 --- a/src/wp-admin/includes/class-wp-site-health.php +++ b/src/wp-admin/includes/class-wp-site-health.php @@ -1410,17 +1410,27 @@ public function get_test_is_in_debug_mode() { if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { if ( ! empty( ini_get( 'error_log' ) ) ) { - $debug_log_path = realpath( dirname( ini_get( 'error_log' ) ) ) . DIRECTORY_SEPARATOR; + $debug_log_path = realpath( dirname( ini_get( 'error_log' ) ) ); $absolute_path = realpath( ABSPATH ) . DIRECTORY_SEPARATOR; - $is_public_log = $debug_log_path && $absolute_path && str_starts_with( $debug_log_path, $absolute_path ); + $log_path_status = 'private'; + + if ( false === $debug_log_path ) { + $log_path_status = 'error'; + } elseif ( str_starts_with( $debug_log_path . DIRECTORY_SEPARATOR, $absolute_path ) ) { + $log_path_status = 'public'; + } + $is_wp_debug_log = defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG; - if ( $is_public_log ) { - $result['label'] = __( 'Your site is set to log errors to a potentially public file' ); + if ( $log_path_status === 'public' ) { + $result['label'] = __( 'Your site is set to log errors to a potentially public file' ); $result['status'] = 'critical'; - } else { - $result['label'] = __( 'Your site is set to log errors to a file outside the document root' ); + } elseif ( $log_path_status === 'private' ) { + $result['label'] = __( 'Your site is set to log errors to a file outside the document root' ); $result['status'] = 'good'; + } else { + $result['label'] = __( 'Unable to determine error log file location' ); + $result['status'] = 'critical'; } if ( $is_wp_debug_log ) { @@ -1428,18 +1438,24 @@ public function get_test_is_in_debug_mode() { '

%s

', sprintf( /* translators: %s: WP_DEBUG_LOG */ - $is_public_log + $log_path_status === 'public' ? __( 'The constant, %s, has been added to this website’s configuration file. This means any errors on the site will be written to a file which is likely publicly accessible.' ) - : __( 'The configuration constant, %s, has been set to write errors to a file outside the WordPress directory. This is a good practice as the log file should not be publicly accessible.' ), + : ( $log_path_status === 'private' + ? __( 'The configuration constant, %s, is enabled. In addition, your site is set to write errors to a file outside the WordPress directory, which is a good practice as the log file should not be publicly accessible.' ) + : __( 'The configuration constant, %s, is enabled, but the log file location could not be determined.' ) + ), 'WP_DEBUG_LOG' ) ); } else { $result['description'] .= sprintf( '

%s

', - $is_public_log + $log_path_status === 'public' ? __( 'The error log path has been configured to a file within your WordPress directory. This means any errors on the site will be written to a file which is likely publicly accessible.' ) - : __( 'The error log path has been configured to a file outside your WordPress directory. This is a good practice as the log file should not be publicly accessible.' ) + : ( $log_path_status === 'private' + ? __( 'The error log path has been configured to a file outside your WordPress directory. This is a good practice as the log file should not be publicly accessible.' ) + : __( 'The error log path could not be determined. Please check your PHP configuration.' ) + ) ); } } From 940f58aba086b380410192a34b376efd59252dc7 Mon Sep 17 00:00:00 2001 From: hbhalodia Date: Mon, 12 Jan 2026 11:18:34 +0530 Subject: [PATCH 11/23] CoreTrac-64071 Fix phpcs error --- src/wp-admin/includes/class-wp-site-health.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/wp-admin/includes/class-wp-site-health.php b/src/wp-admin/includes/class-wp-site-health.php index 68636c276834b..5a9277e506e51 100644 --- a/src/wp-admin/includes/class-wp-site-health.php +++ b/src/wp-admin/includes/class-wp-site-health.php @@ -1422,10 +1422,10 @@ public function get_test_is_in_debug_mode() { $is_wp_debug_log = defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG; - if ( $log_path_status === 'public' ) { + if ( 'public' === $log_path_status ) { $result['label'] = __( 'Your site is set to log errors to a potentially public file' ); $result['status'] = 'critical'; - } elseif ( $log_path_status === 'private' ) { + } elseif ( 'private' === $log_path_status ) { $result['label'] = __( 'Your site is set to log errors to a file outside the document root' ); $result['status'] = 'good'; } else { @@ -1438,9 +1438,9 @@ public function get_test_is_in_debug_mode() { '

%s

', sprintf( /* translators: %s: WP_DEBUG_LOG */ - $log_path_status === 'public' + 'public' === $log_path_status ? __( 'The constant, %s, has been added to this website’s configuration file. This means any errors on the site will be written to a file which is likely publicly accessible.' ) - : ( $log_path_status === 'private' + : ( 'private' === $log_path_status ? __( 'The configuration constant, %s, is enabled. In addition, your site is set to write errors to a file outside the WordPress directory, which is a good practice as the log file should not be publicly accessible.' ) : __( 'The configuration constant, %s, is enabled, but the log file location could not be determined.' ) ), @@ -1450,9 +1450,9 @@ public function get_test_is_in_debug_mode() { } else { $result['description'] .= sprintf( '

%s

', - $log_path_status === 'public' + 'public' === $log_path_status ? __( 'The error log path has been configured to a file within your WordPress directory. This means any errors on the site will be written to a file which is likely publicly accessible.' ) - : ( $log_path_status === 'private' + : ( 'private' === $log_path_status ? __( 'The error log path has been configured to a file outside your WordPress directory. This is a good practice as the log file should not be publicly accessible.' ) : __( 'The error log path could not be determined. Please check your PHP configuration.' ) ) From 556a7ea1c7ded3c3beaa1cb8e47ca01b661ded7f Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Mon, 12 Jan 2026 10:53:46 -0800 Subject: [PATCH 12/23] Fix placement of translators comments --- src/wp-admin/includes/class-wp-site-health.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/wp-admin/includes/class-wp-site-health.php b/src/wp-admin/includes/class-wp-site-health.php index 5a9277e506e51..470f343afd571 100644 --- a/src/wp-admin/includes/class-wp-site-health.php +++ b/src/wp-admin/includes/class-wp-site-health.php @@ -1437,11 +1437,13 @@ public function get_test_is_in_debug_mode() { $result['description'] .= sprintf( '

%s

', sprintf( - /* translators: %s: WP_DEBUG_LOG */ 'public' === $log_path_status + /* translators: %s: WP_DEBUG_LOG */ ? __( 'The constant, %s, has been added to this website’s configuration file. This means any errors on the site will be written to a file which is likely publicly accessible.' ) : ( 'private' === $log_path_status + /* translators: %s: WP_DEBUG_LOG */ ? __( 'The configuration constant, %s, is enabled. In addition, your site is set to write errors to a file outside the WordPress directory, which is a good practice as the log file should not be publicly accessible.' ) + /* translators: %s: WP_DEBUG_LOG */ : __( 'The configuration constant, %s, is enabled, but the log file location could not be determined.' ) ), 'WP_DEBUG_LOG' From c2704e9d74193cf8757a7b616e38b535c6831fab Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Mon, 12 Jan 2026 10:55:12 -0800 Subject: [PATCH 13/23] Improve phpdoc return tag --- src/wp-admin/includes/class-wp-site-health.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-admin/includes/class-wp-site-health.php b/src/wp-admin/includes/class-wp-site-health.php index 470f343afd571..1e9c5576ebd36 100644 --- a/src/wp-admin/includes/class-wp-site-health.php +++ b/src/wp-admin/includes/class-wp-site-health.php @@ -1383,7 +1383,7 @@ public function get_test_dotorg_communication() { * * @since 5.2.0 * - * @return array The test results. + * @return array> The test results. */ public function get_test_is_in_debug_mode() { $result = array( From 205b76ed9c13abf058468a1b55c53c62be868445 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Mon, 12 Jan 2026 10:56:12 -0800 Subject: [PATCH 14/23] Use else case --- src/wp-admin/includes/class-wp-site-health.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/wp-admin/includes/class-wp-site-health.php b/src/wp-admin/includes/class-wp-site-health.php index 1e9c5576ebd36..9c3065ce7fa74 100644 --- a/src/wp-admin/includes/class-wp-site-health.php +++ b/src/wp-admin/includes/class-wp-site-health.php @@ -1410,14 +1410,14 @@ public function get_test_is_in_debug_mode() { if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { if ( ! empty( ini_get( 'error_log' ) ) ) { - $debug_log_path = realpath( dirname( ini_get( 'error_log' ) ) ); - $absolute_path = realpath( ABSPATH ) . DIRECTORY_SEPARATOR; - $log_path_status = 'private'; - + $debug_log_path = realpath( dirname( ini_get( 'error_log' ) ) ); + $absolute_path = realpath( ABSPATH ) . DIRECTORY_SEPARATOR; if ( false === $debug_log_path ) { $log_path_status = 'error'; } elseif ( str_starts_with( $debug_log_path . DIRECTORY_SEPARATOR, $absolute_path ) ) { $log_path_status = 'public'; + } else { + $log_path_status = 'private'; } $is_wp_debug_log = defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG; From 8286a6c17d83201350e82f56966b050c5fc85bd7 Mon Sep 17 00:00:00 2001 From: hbhalodia Date: Tue, 13 Jan 2026 09:06:49 +0530 Subject: [PATCH 15/23] Resolve copilot feedbacks related to ternary operator and messaging --- .../includes/class-wp-site-health.php | 79 ++++++++++++------- 1 file changed, 50 insertions(+), 29 deletions(-) diff --git a/src/wp-admin/includes/class-wp-site-health.php b/src/wp-admin/includes/class-wp-site-health.php index 9c3065ce7fa74..e6fdbb8c46c08 100644 --- a/src/wp-admin/includes/class-wp-site-health.php +++ b/src/wp-admin/includes/class-wp-site-health.php @@ -1410,11 +1410,12 @@ public function get_test_is_in_debug_mode() { if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { if ( ! empty( ini_get( 'error_log' ) ) ) { - $debug_log_path = realpath( dirname( ini_get( 'error_log' ) ) ); - $absolute_path = realpath( ABSPATH ) . DIRECTORY_SEPARATOR; - if ( false === $debug_log_path ) { + $debug_log_dir = realpath( dirname( ini_get( 'error_log' ) ) ); + $absolute_path = realpath( ABSPATH ) . DIRECTORY_SEPARATOR; + + if ( false === $debug_log_dir ) { $log_path_status = 'error'; - } elseif ( str_starts_with( $debug_log_path . DIRECTORY_SEPARATOR, $absolute_path ) ) { + } elseif ( str_starts_with( $debug_log_dir . DIRECTORY_SEPARATOR, $absolute_path ) ) { $log_path_status = 'public'; } else { $log_path_status = 'private'; @@ -1425,40 +1426,60 @@ public function get_test_is_in_debug_mode() { if ( 'public' === $log_path_status ) { $result['label'] = __( 'Your site is set to log errors to a potentially public file' ); $result['status'] = 'critical'; + + if ( $is_wp_debug_log ) { + $result['description'] .= sprintf( + '

%s

', + sprintf( + /* translators: %s: WP_DEBUG_LOG */ + __( 'The constant, %s, has been added to this website’s configuration file. This means any errors on the site will be written to a file which is likely publicly accessible.' ), + 'WP_DEBUG_LOG' + ) + ); + } else { + $result['description'] .= sprintf( + '

%s

', + __( 'The error log path has been configured to a file within the WordPress directory. This means any errors on the site will be written to a file which is likely publicly accessible.' ) + ); + } } elseif ( 'private' === $log_path_status ) { $result['label'] = __( 'Your site is set to log errors to a file outside the document root' ); $result['status'] = 'good'; + + if ( $is_wp_debug_log ) { + $result['description'] .= sprintf( + '

%s

', + sprintf( + /* translators: %s: WP_DEBUG_LOG */ + __( 'The configuration constant, %s, is enabled. In addition, your site is set to write errors to a file outside the WordPress directory, which is a good practice as the log file should not be publicly accessible.' ), + 'WP_DEBUG_LOG' + ) + ); + } else { + $result['description'] .= sprintf( + '

%s

', + __( 'The error log path has been configured to a file outside the WordPress directory. This is a good practice as the log file should not be publicly accessible.' ) + ); + } } else { $result['label'] = __( 'Unable to determine error log file location' ); $result['status'] = 'critical'; - } - if ( $is_wp_debug_log ) { - $result['description'] .= sprintf( - '

%s

', - sprintf( - 'public' === $log_path_status + if ( $is_wp_debug_log ) { + $result['description'] .= sprintf( + '

%s

', + sprintf( /* translators: %s: WP_DEBUG_LOG */ - ? __( 'The constant, %s, has been added to this website’s configuration file. This means any errors on the site will be written to a file which is likely publicly accessible.' ) - : ( 'private' === $log_path_status - /* translators: %s: WP_DEBUG_LOG */ - ? __( 'The configuration constant, %s, is enabled. In addition, your site is set to write errors to a file outside the WordPress directory, which is a good practice as the log file should not be publicly accessible.' ) - /* translators: %s: WP_DEBUG_LOG */ - : __( 'The configuration constant, %s, is enabled, but the log file location could not be determined.' ) - ), - 'WP_DEBUG_LOG' - ) - ); - } else { - $result['description'] .= sprintf( - '

%s

', - 'public' === $log_path_status - ? __( 'The error log path has been configured to a file within your WordPress directory. This means any errors on the site will be written to a file which is likely publicly accessible.' ) - : ( 'private' === $log_path_status - ? __( 'The error log path has been configured to a file outside your WordPress directory. This is a good practice as the log file should not be publicly accessible.' ) - : __( 'The error log path could not be determined. Please check your PHP configuration.' ) + __( 'The configuration constant, %s, is enabled, but the log file location could not be determined.' ), + 'WP_DEBUG_LOG' ) - ); + ); + } else { + $result['description'] .= sprintf( + '

%s

', + __( 'The error log path could not be determined. Please check your PHP configuration.' ) + ); + } } } From fc6c9d932564b50513c8fab25456e8496b88f66f Mon Sep 17 00:00:00 2001 From: hbhalodia Date: Tue, 13 Jan 2026 09:19:08 +0530 Subject: [PATCH 16/23] Add private members for debug constant to work with tests --- .../includes/class-wp-site-health.php | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/wp-admin/includes/class-wp-site-health.php b/src/wp-admin/includes/class-wp-site-health.php index e6fdbb8c46c08..6b73277787756 100644 --- a/src/wp-admin/includes/class-wp-site-health.php +++ b/src/wp-admin/includes/class-wp-site-health.php @@ -29,6 +29,21 @@ class WP_Site_Health { private $timeout_missed_cron = null; private $timeout_late_cron = null; + /** + * @var bool + */ + private $wp_debug; + + /** + * @var bool|string + */ + private $wp_debug_log; + + /** + * @var bool|null + */ + private $wp_debug_display; + /** * WP_Site_Health constructor. * @@ -54,6 +69,10 @@ public function __construct() { add_action( 'wp_site_health_scheduled_check', array( $this, 'wp_cron_scheduled_check' ) ); add_action( 'site_health_tab_content', array( $this, 'show_site_health_tab' ) ); + + $this->wp_debug = defined( 'WP_DEBUG' ) && WP_DEBUG; + $this->wp_debug_log = defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG; + $this->wp_debug_display = defined( 'WP_DEBUG_DISPLAY' ) ? WP_DEBUG_DISPLAY : null; } /** @@ -1408,7 +1427,7 @@ public function get_test_is_in_debug_mode() { 'test' => 'is_in_debug_mode', ); - if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { + if ( $this->wp_debug ) { if ( ! empty( ini_get( 'error_log' ) ) ) { $debug_log_dir = realpath( dirname( ini_get( 'error_log' ) ) ); $absolute_path = realpath( ABSPATH ) . DIRECTORY_SEPARATOR; @@ -1421,7 +1440,7 @@ public function get_test_is_in_debug_mode() { $log_path_status = 'private'; } - $is_wp_debug_log = defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG; + $is_wp_debug_log = $this->wp_debug_log; if ( 'public' === $log_path_status ) { $result['label'] = __( 'Your site is set to log errors to a potentially public file' ); @@ -1483,7 +1502,7 @@ public function get_test_is_in_debug_mode() { } } - if ( defined( 'WP_DEBUG_DISPLAY' ) && WP_DEBUG_DISPLAY ) { + if ( $this->wp_debug_display ) { $result['label'] = __( 'Your site is set to display errors to site visitors' ); $result['status'] = 'critical'; From a1cc8803c083fa7e42eedaf99b841a2e6841c061 Mon Sep 17 00:00:00 2001 From: hbhalodia Date: Tue, 13 Jan 2026 09:22:54 +0530 Subject: [PATCH 17/23] Remove extra variable storage space and use private member --- src/wp-admin/includes/class-wp-site-health.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/wp-admin/includes/class-wp-site-health.php b/src/wp-admin/includes/class-wp-site-health.php index 6b73277787756..a54e6a0ff1664 100644 --- a/src/wp-admin/includes/class-wp-site-health.php +++ b/src/wp-admin/includes/class-wp-site-health.php @@ -1440,13 +1440,11 @@ public function get_test_is_in_debug_mode() { $log_path_status = 'private'; } - $is_wp_debug_log = $this->wp_debug_log; - if ( 'public' === $log_path_status ) { $result['label'] = __( 'Your site is set to log errors to a potentially public file' ); $result['status'] = 'critical'; - if ( $is_wp_debug_log ) { + if ( $this->wp_debug_log ) { $result['description'] .= sprintf( '

%s

', sprintf( @@ -1465,7 +1463,7 @@ public function get_test_is_in_debug_mode() { $result['label'] = __( 'Your site is set to log errors to a file outside the document root' ); $result['status'] = 'good'; - if ( $is_wp_debug_log ) { + if ( $this->wp_debug_log ) { $result['description'] .= sprintf( '

%s

', sprintf( @@ -1484,7 +1482,7 @@ public function get_test_is_in_debug_mode() { $result['label'] = __( 'Unable to determine error log file location' ); $result['status'] = 'critical'; - if ( $is_wp_debug_log ) { + if ( $this->wp_debug_log ) { $result['description'] .= sprintf( '

%s

', sprintf( From 21a27a68261148616c141d5418822b588ba1ea53 Mon Sep 17 00:00:00 2001 From: hbhalodia Date: Tue, 13 Jan 2026 10:21:05 +0530 Subject: [PATCH 18/23] Add the test cases for the function get_test_is_in_debug_mode --- tests/phpunit/tests/admin/wpSiteHealth.php | 416 +++++++++++++++++++++ 1 file changed, 416 insertions(+) diff --git a/tests/phpunit/tests/admin/wpSiteHealth.php b/tests/phpunit/tests/admin/wpSiteHealth.php index 0c6a42f71bea3..36dcb5728bf96 100644 --- a/tests/phpunit/tests/admin/wpSiteHealth.php +++ b/tests/phpunit/tests/admin/wpSiteHealth.php @@ -572,4 +572,420 @@ public static function set_autoloaded_option( $bytes = 800000 ) { // Force autoloading so that WordPress core does not override it. See https://core.trac.wordpress.org/changeset/57920. add_option( 'test_set_autoloaded_option', $heavy_option_string, '', true ); } + + /** + * Returns the expected result array when debug mode is disabled. + * + * @return array + */ + private function get_debug_mode_disabled_result() { + return array( + 'status' => 'good', + 'label' => 'Your site is not set to output debug information', + 'test' => 'is_in_debug_mode', + 'badge' => array( + 'label' => 'Security', + 'color' => 'blue', + ), + ); + } + + /** + * Returns the expected result array when debug log is in a public location. + * + * @param bool $wp_debug_log_defined Whether WP_DEBUG_LOG is defined. + * + * @return array + */ + private function get_debug_error_log_public_result( bool $wp_debug_log_defined = true ) { + + $result = array( + 'status' => 'critical', + 'label' => 'Your site is set to log errors to a potentially public file', + 'description' => 'The constant, WP_DEBUG_LOG, has been added to this website’s configuration file. This means any errors on the site will be written to a file which is likely publicly accessible.', + 'test' => 'is_in_debug_mode', + ); + + if ( ! $wp_debug_log_defined ) { + $result['description'] = 'The error log path has been configured to a file within the WordPress directory. This means any errors on the site will be written to a file which is likely publicly accessible.'; + } + + return $result; + } + + /** + * Returns the expected result array when debug log is in a private location. + * + * @param bool $wp_debug_log_defined Whether WP_DEBUG_LOG is defined. + * + * @return array + */ + private function get_debug_error_log_private_result( bool $wp_debug_log_defined = true ) { + + $result = array( + 'status' => 'good', + 'label' => 'Your site is set to log errors to a file outside the document root', + 'description' => 'The configuration constant, WP_DEBUG_LOG, is enabled. In addition, your site is set to write errors to a file outside the WordPress directory, which is a good practice as the log file should not be publicly accessible.', + 'test' => 'is_in_debug_mode', + ); + + if ( ! $wp_debug_log_defined ) { + $result['description'] = 'The error log path has been configured to a file outside the WordPress directory. This is a good practice as the log file should not be publicly accessible.'; + } + + return $result; + } + + /** + * Returns the expected result array when debug log path does not exist. + * + * @param bool $wp_debug_log_defined Whether WP_DEBUG_LOG is defined. + * + * @return array + */ + private function get_debug_log_non_existent_path_result( bool $wp_debug_log_defined = true ) { + + $result = array( + 'status' => 'critical', + 'label' => 'Unable to determine error log file location', + 'description' => 'The configuration constant, WP_DEBUG_LOG, is enabled, but the log file location could not be determined.', + 'test' => 'is_in_debug_mode', + ); + + if ( ! $wp_debug_log_defined ) { + $result['description'] = 'The error log path could not be determined. Please check your PHP configuration.'; + } + + return $result; + } + + /** + * Tests get_test_is_in_debug_mode() when debug mode is disabled. + * + * @covers ::get_test_is_in_debug_mode() + */ + public function test_is_in_debug_mode_disabled() { + $site_health = new WP_Site_Health(); + $reflection = new ReflectionClass( $site_health ); + + $wp_debug_property = $reflection->getProperty( 'wp_debug' ); + $wp_debug_property->setAccessible( true ); + $wp_debug_property->setValue( $site_health, false ); + + $actual_result = $site_health->get_test_is_in_debug_mode(); + $expected_result = $this->get_debug_mode_disabled_result(); + + $this->assertSame( $expected_result['status'], $actual_result['status'], 'Status should be "good" when debug mode is disabled.' ); + $this->assertSame( $expected_result['label'], $actual_result['label'], 'Label should indicate debug mode is disabled.' ); + $this->assertSame( $expected_result['test'], $actual_result['test'], 'Test identifier should be "is_in_debug_mode".' ); + $this->assertArrayHasKey( 'badge', $actual_result, 'Result should have a badge.' ); + $this->assertSame( $expected_result['badge']['label'], $actual_result['badge']['label'], 'Badge label should be "Security".' ); + $this->assertSame( $expected_result['badge']['color'], $actual_result['badge']['color'], 'Badge color should be "blue".' ); + } + + /** + * Tests get_test_is_in_debug_mode() when WP_DEBUG is enabled without error logging. + * + * @covers ::get_test_is_in_debug_mode() + */ + public function test_is_in_debug_mode_enabled_no_error_log() { + $site_health = new WP_Site_Health(); + $reflection = new ReflectionClass( $site_health ); + + $wp_debug_property = $reflection->getProperty( 'wp_debug' ); + $wp_debug_property->setAccessible( true ); + $wp_debug_property->setValue( $site_health, true ); + + $original_error_log = ini_get( 'error_log' ); + + ini_set( 'error_log', '' ); + + $actual_result = $site_health->get_test_is_in_debug_mode(); + $expected_result = $this->get_debug_mode_disabled_result(); + + ini_set( 'error_log', $original_error_log ); + + $this->assertSame( $expected_result['status'], $actual_result['status'], 'Status should be "good" when no error log is configured.' ); + $this->assertSame( $expected_result['label'], $actual_result['label'], 'Label should indicate no error log is configured.' ); + $this->assertSame( $expected_result['test'], $actual_result['test'], 'Test identifier should be "is_in_debug_mode".' ); + $this->assertArrayHasKey( 'badge', $actual_result, 'Result should have a badge.' ); + } + + /** + * Tests get_test_is_in_debug_mode() when error log is in a public location. + * + * @covers ::get_test_is_in_debug_mode() + */ + public function test_is_in_debug_mode_error_log_public() { + $site_health = new WP_Site_Health(); + $reflection = new ReflectionClass( $site_health ); + + $wp_debug_property = $reflection->getProperty( 'wp_debug' ); + $wp_debug_property->setAccessible( true ); + $wp_debug_property->setValue( $site_health, true ); + + $wp_debug_log_property = $reflection->getProperty( 'wp_debug_log' ); + $wp_debug_log_property->setAccessible( true ); + $wp_debug_log_property->setValue( $site_health, true ); + + $original_error_log = ini_get( 'error_log' ); + $public_log_path = ABSPATH . 'wp-content/debug.log'; + + ini_set( 'error_log', $public_log_path ); + + $actual_result = $site_health->get_test_is_in_debug_mode(); + $expected_result = $this->get_debug_error_log_public_result( true ); + + ini_set( 'error_log', $original_error_log ); + + $this->assertSame( $expected_result['status'], $actual_result['status'], 'Status should be "critical" when error log is in a public location.' ); + $this->assertSame( $expected_result['label'], $actual_result['label'], 'Label should indicate error log is in a public location.' ); + $this->assertSame( $expected_result['description'], $actual_result['description'], 'Description should display the expected message.' ); + } + + /** + * Tests get_test_is_in_debug_mode() when error log is public without WP_DEBUG_LOG. + * + * @covers ::get_test_is_in_debug_mode() + */ + public function test_is_in_debug_mode_error_log_public_without_wp_debug_log() { + $site_health = new WP_Site_Health(); + $reflection = new ReflectionClass( $site_health ); + + $wp_debug_property = $reflection->getProperty( 'wp_debug' ); + $wp_debug_property->setAccessible( true ); + $wp_debug_property->setValue( $site_health, true ); + + $wp_debug_log_property = $reflection->getProperty( 'wp_debug_log' ); + $wp_debug_log_property->setAccessible( true ); + $wp_debug_log_property->setValue( $site_health, false ); + + $original_error_log = ini_get( 'error_log' ); + $public_log_path = ABSPATH . 'wp-content/debug.log'; + + ini_set( 'error_log', $public_log_path ); + + $actual_result = $site_health->get_test_is_in_debug_mode(); + $expected_result = $this->get_debug_error_log_public_result( false ); + + ini_set( 'error_log', $original_error_log ); + + $this->assertSame( $expected_result['status'], $actual_result['status'], 'Status should be "critical" when error log is in a public location.' ); + $this->assertSame( $expected_result['label'], $actual_result['label'], 'Label should indicate error log is in a public location.' ); + $this->assertSame( $expected_result['description'], $actual_result['description'], 'Description should mention error log configured is without WP_DEBUG_LOG and in public directory.' ); + } + + /** + * Tests get_test_is_in_debug_mode() when error log is in a private location. + * + * @covers ::get_test_is_in_debug_mode() + */ + public function test_is_in_debug_mode_error_log_private() { + $site_health = new WP_Site_Health(); + $reflection = new ReflectionClass( $site_health ); + + $wp_debug_property = $reflection->getProperty( 'wp_debug' ); + $wp_debug_property->setAccessible( true ); + $wp_debug_property->setValue( $site_health, true ); + + $wp_debug_log_property = $reflection->getProperty( 'wp_debug_log' ); + $wp_debug_log_property->setAccessible( true ); + $wp_debug_log_property->setValue( $site_health, true ); + + $original_error_log = ini_get( 'error_log' ); + $private_log_path = '/var/log/php-error.log'; + + ini_set( 'error_log', $private_log_path ); + + $actual_result = $site_health->get_test_is_in_debug_mode(); + $expected_result = $this->get_debug_error_log_private_result( true ); + + ini_set( 'error_log', $original_error_log ); + + $this->assertSame( $expected_result['status'], $actual_result['status'], 'Status should be "good" when error log is in a private location.' ); + $this->assertSame( $expected_result['label'], $actual_result['label'], 'Label should indicate error log is in a private location.' ); + $this->assertSame( $expected_result['description'], $actual_result['description'], 'Description should mention the log is outside WordPress directory.' ); + } + + /** + * Tests get_test_is_in_debug_mode() when error log is private without WP_DEBUG_LOG. + * + * @covers ::get_test_is_in_debug_mode() + */ + public function test_is_in_debug_mode_error_log_private_without_wp_debug_log() { + $site_health = new WP_Site_Health(); + $reflection = new ReflectionClass( $site_health ); + + $wp_debug_property = $reflection->getProperty( 'wp_debug' ); + $wp_debug_property->setAccessible( true ); + $wp_debug_property->setValue( $site_health, true ); + + $wp_debug_log_property = $reflection->getProperty( 'wp_debug_log' ); + $wp_debug_log_property->setAccessible( true ); + $wp_debug_log_property->setValue( $site_health, false ); + + $original_error_log = ini_get( 'error_log' ); + $private_log_path = '/var/log/php-error.log'; + + ini_set( 'error_log', $private_log_path ); + + $actual_result = $site_health->get_test_is_in_debug_mode(); + $expected_result = $this->get_debug_error_log_private_result( false ); + + ini_set( 'error_log', $original_error_log ); + + $this->assertSame( $expected_result['status'], $actual_result['status'], 'Status should be "good" when error log is in a private location.' ); + $this->assertSame( $expected_result['label'], $actual_result['label'], 'Label should indicate error log is in a private location.' ); + $this->assertSame( $expected_result['description'], $actual_result['description'], 'Description should mention log is outside WordPress directory.' ); + } + + /** + * Tests get_test_is_in_debug_mode() when error log path cannot be determined. + * + * @covers ::get_test_is_in_debug_mode() + */ + public function test_is_in_debug_mode_error_log_non_existent() { + $site_health = new WP_Site_Health(); + $reflection = new ReflectionClass( $site_health ); + + $wp_debug_property = $reflection->getProperty( 'wp_debug' ); + $wp_debug_property->setAccessible( true ); + $wp_debug_property->setValue( $site_health, true ); + + $wp_debug_log_property = $reflection->getProperty( 'wp_debug_log' ); + $wp_debug_log_property->setAccessible( true ); + $wp_debug_log_property->setValue( $site_health, true ); + + $original_error_log = ini_get( 'error_log' ); + $invalid_log_path = '/nonexistent/path/that/does/not/exist/debug.log'; + + ini_set( 'error_log', $invalid_log_path ); + + $actual_result = $site_health->get_test_is_in_debug_mode(); + $expected_result = $this->get_debug_log_non_existent_path_result( true ); + + ini_set( 'error_log', $original_error_log ); + + $this->assertSame( $expected_result['status'], $actual_result['status'], 'Status should be "critical" when error log location cannot be determined.' ); + $this->assertSame( $expected_result['label'], $actual_result['label'], 'Label should indicate that error log location could not be determined.' ); + $this->assertSame( $expected_result['description'], $actual_result['description'], 'Description should mention inability to determine log location.' ); + } + + /** + * Tests get_test_is_in_debug_mode() when error log path cannot be determined and WP_DEBUG_LOG is not defined. + * + * @covers ::get_test_is_in_debug_mode() + */ + public function test_is_in_debug_mode_error_log_non_existent_without_wp_debug_log() { + $site_health = new WP_Site_Health(); + $reflection = new ReflectionClass( $site_health ); + + $wp_debug_property = $reflection->getProperty( 'wp_debug' ); + $wp_debug_property->setAccessible( true ); + $wp_debug_property->setValue( $site_health, true ); + + $wp_debug_log_property = $reflection->getProperty( 'wp_debug_log' ); + $wp_debug_log_property->setAccessible( true ); + $wp_debug_log_property->setValue( $site_health, false ); + + $original_error_log = ini_get( 'error_log' ); + $invalid_log_path = '/nonexistent/path/that/does/not/exist/debug.log'; + + ini_set( 'error_log', $invalid_log_path ); + + $actual_result = $site_health->get_test_is_in_debug_mode(); + $expected_result = $this->get_debug_log_non_existent_path_result( false ); + + ini_set( 'error_log', $original_error_log ); + + $this->assertSame( $expected_result['status'], $actual_result['status'], 'Status should be "critical" when error log location cannot be determined.' ); + $this->assertSame( $expected_result['label'], $actual_result['label'], 'Label should indicate that error log location could not be determined.' ); + $this->assertSame( $expected_result['description'], $actual_result['description'], 'Description should mention error log path is nonexistent.' ); + } + + /** + * Tests get_test_is_in_debug_mode() when WP_DEBUG_DISPLAY is enabled in production. + * + * @covers ::get_test_is_in_debug_mode() + */ + public function test_is_in_debug_mode_display_enabled_production() { + $site_health_mock = $this->getMockBuilder( 'WP_Site_Health' ) + ->onlyMethods( array( 'is_development_environment' ) ) + ->getMock(); + + $site_health_mock->method( 'is_development_environment' ) + ->willReturn( false ); + + $reflection_mock = new ReflectionClass( $site_health_mock ); + + $wp_debug_property_mock = $reflection_mock->getProperty( 'wp_debug' ); + $wp_debug_property_mock->setAccessible( true ); + $wp_debug_property_mock->setValue( $site_health_mock, true ); + + $wp_debug_display_property_mock = $reflection_mock->getProperty( 'wp_debug_display' ); + $wp_debug_display_property_mock->setAccessible( true ); + $wp_debug_display_property_mock->setValue( $site_health_mock, true ); + + $result = $site_health_mock->get_test_is_in_debug_mode(); + + $this->assertSame( 'critical', $result['status'], 'Status should be "critical" when WP_DEBUG_DISPLAY is enabled in production.' ); + $this->assertSame( 'Your site is set to display errors to site visitors', $result['label'], 'Label should indicate errors are displayed to visitors.' ); + $this->assertStringContainsString( 'WP_DEBUG_DISPLAY', $result['description'], 'Description should mention WP_DEBUG_DISPLAY.' ); + } + + /** + * Tests get_test_is_in_debug_mode() when WP_DEBUG_DISPLAY is enabled in development. + * + * @covers ::get_test_is_in_debug_mode() + */ + public function test_is_in_debug_mode_display_enabled_development() { + $site_health_mock = $this->getMockBuilder( 'WP_Site_Health' ) + ->onlyMethods( array( 'is_development_environment' ) ) + ->getMock(); + + $site_health_mock->method( 'is_development_environment' ) + ->willReturn( true ); + + $reflection = new ReflectionClass( $site_health_mock ); + + $wp_debug_property = $reflection->getProperty( 'wp_debug' ); + $wp_debug_property->setAccessible( true ); + $wp_debug_property->setValue( $site_health_mock, true ); + + $wp_debug_display_property = $reflection->getProperty( 'wp_debug_display' ); + $wp_debug_display_property->setAccessible( true ); + $wp_debug_display_property->setValue( $site_health_mock, true ); + + $result = $site_health_mock->get_test_is_in_debug_mode(); + + $this->assertSame( 'recommended', $result['status'], 'Status should be "recommended" when WP_DEBUG_DISPLAY is enabled in development.' ); + $this->assertSame( 'Your site is set to display errors to site visitors', $result['label'], 'Label should indicate errors are displayed to visitors.' ); + $this->assertStringContainsString( 'WP_DEBUG_DISPLAY', $result['description'], 'Description should mention WP_DEBUG_DISPLAY.' ); + } + + /** + * Tests get_test_is_in_debug_mode() validates result structure. + * + * @covers ::get_test_is_in_debug_mode() + */ + public function test_is_in_debug_mode_result_structure() { + $site_health = new WP_Site_Health(); + $result = $site_health->get_test_is_in_debug_mode(); + + // Verify all required keys are present. + $this->assertArrayHasKey( 'label', $result, 'Result should have a label.' ); + $this->assertArrayHasKey( 'status', $result, 'Result should have a status.' ); + $this->assertArrayHasKey( 'badge', $result, 'Result should have a badge.' ); + $this->assertArrayHasKey( 'description', $result, 'Result should have a description.' ); + $this->assertArrayHasKey( 'actions', $result, 'Result should have actions.' ); + $this->assertArrayHasKey( 'test', $result, 'Result should have a test identifier.' ); + + // Verify badge structure. + $this->assertIsArray( $result['badge'], 'Badge should be an array.' ); + $this->assertArrayHasKey( 'label', $result['badge'], 'Badge should have a label.' ); + $this->assertArrayHasKey( 'color', $result['badge'], 'Badge should have a color.' ); + + // Verify status is one of the expected values. + $this->assertContains( $result['status'], array( 'good', 'recommended', 'critical' ), 'Status should be one of: good, recommended, critical.' ); + } } From dac31eda4173880227ddc2914493c1104e56422c Mon Sep 17 00:00:00 2001 From: hbhalodia Date: Tue, 13 Jan 2026 11:53:09 +0530 Subject: [PATCH 19/23] Update failing unit test cases --- tests/phpunit/tests/admin/wpSiteHealth.php | 111 +++++++++++++-------- 1 file changed, 68 insertions(+), 43 deletions(-) diff --git a/tests/phpunit/tests/admin/wpSiteHealth.php b/tests/phpunit/tests/admin/wpSiteHealth.php index 36dcb5728bf96..dff5f8f6d24b4 100644 --- a/tests/phpunit/tests/admin/wpSiteHealth.php +++ b/tests/phpunit/tests/admin/wpSiteHealth.php @@ -696,6 +696,10 @@ public function test_is_in_debug_mode_enabled_no_error_log() { $wp_debug_property->setAccessible( true ); $wp_debug_property->setValue( $site_health, true ); + $wp_debug_property = $reflection->getProperty( 'wp_debug_display' ); + $wp_debug_property->setAccessible( true ); + $wp_debug_property->setValue( $site_health, null ); + $original_error_log = ini_get( 'error_log' ); ini_set( 'error_log', '' ); @@ -728,6 +732,10 @@ public function test_is_in_debug_mode_error_log_public() { $wp_debug_log_property->setAccessible( true ); $wp_debug_log_property->setValue( $site_health, true ); + $wp_debug_property = $reflection->getProperty( 'wp_debug_display' ); + $wp_debug_property->setAccessible( true ); + $wp_debug_property->setValue( $site_health, null ); + $original_error_log = ini_get( 'error_log' ); $public_log_path = ABSPATH . 'wp-content/debug.log'; @@ -740,7 +748,7 @@ public function test_is_in_debug_mode_error_log_public() { $this->assertSame( $expected_result['status'], $actual_result['status'], 'Status should be "critical" when error log is in a public location.' ); $this->assertSame( $expected_result['label'], $actual_result['label'], 'Label should indicate error log is in a public location.' ); - $this->assertSame( $expected_result['description'], $actual_result['description'], 'Description should display the expected message.' ); + $this->assertStringContainsString( $expected_result['description'], $actual_result['description'], 'Description should display the expected message.' ); } /** @@ -760,6 +768,10 @@ public function test_is_in_debug_mode_error_log_public_without_wp_debug_log() { $wp_debug_log_property->setAccessible( true ); $wp_debug_log_property->setValue( $site_health, false ); + $wp_debug_property = $reflection->getProperty( 'wp_debug_display' ); + $wp_debug_property->setAccessible( true ); + $wp_debug_property->setValue( $site_health, null ); + $original_error_log = ini_get( 'error_log' ); $public_log_path = ABSPATH . 'wp-content/debug.log'; @@ -772,7 +784,7 @@ public function test_is_in_debug_mode_error_log_public_without_wp_debug_log() { $this->assertSame( $expected_result['status'], $actual_result['status'], 'Status should be "critical" when error log is in a public location.' ); $this->assertSame( $expected_result['label'], $actual_result['label'], 'Label should indicate error log is in a public location.' ); - $this->assertSame( $expected_result['description'], $actual_result['description'], 'Description should mention error log configured is without WP_DEBUG_LOG and in public directory.' ); + $this->assertStringContainsString( $expected_result['description'], $actual_result['description'], 'Description should mention error log configured is without WP_DEBUG_LOG and in public directory.' ); } /** @@ -792,6 +804,10 @@ public function test_is_in_debug_mode_error_log_private() { $wp_debug_log_property->setAccessible( true ); $wp_debug_log_property->setValue( $site_health, true ); + $wp_debug_property = $reflection->getProperty( 'wp_debug_display' ); + $wp_debug_property->setAccessible( true ); + $wp_debug_property->setValue( $site_health, null ); + $original_error_log = ini_get( 'error_log' ); $private_log_path = '/var/log/php-error.log'; @@ -804,7 +820,7 @@ public function test_is_in_debug_mode_error_log_private() { $this->assertSame( $expected_result['status'], $actual_result['status'], 'Status should be "good" when error log is in a private location.' ); $this->assertSame( $expected_result['label'], $actual_result['label'], 'Label should indicate error log is in a private location.' ); - $this->assertSame( $expected_result['description'], $actual_result['description'], 'Description should mention the log is outside WordPress directory.' ); + $this->assertStringContainsString( $expected_result['description'], $actual_result['description'], 'Description should mention the log is outside WordPress directory.' ); } /** @@ -824,6 +840,10 @@ public function test_is_in_debug_mode_error_log_private_without_wp_debug_log() { $wp_debug_log_property->setAccessible( true ); $wp_debug_log_property->setValue( $site_health, false ); + $wp_debug_property = $reflection->getProperty( 'wp_debug_display' ); + $wp_debug_property->setAccessible( true ); + $wp_debug_property->setValue( $site_health, null ); + $original_error_log = ini_get( 'error_log' ); $private_log_path = '/var/log/php-error.log'; @@ -836,7 +856,7 @@ public function test_is_in_debug_mode_error_log_private_without_wp_debug_log() { $this->assertSame( $expected_result['status'], $actual_result['status'], 'Status should be "good" when error log is in a private location.' ); $this->assertSame( $expected_result['label'], $actual_result['label'], 'Label should indicate error log is in a private location.' ); - $this->assertSame( $expected_result['description'], $actual_result['description'], 'Description should mention log is outside WordPress directory.' ); + $this->assertStringContainsString( $expected_result['description'], $actual_result['description'], 'Description should mention log is outside WordPress directory.' ); } /** @@ -856,6 +876,10 @@ public function test_is_in_debug_mode_error_log_non_existent() { $wp_debug_log_property->setAccessible( true ); $wp_debug_log_property->setValue( $site_health, true ); + $wp_debug_property = $reflection->getProperty( 'wp_debug_display' ); + $wp_debug_property->setAccessible( true ); + $wp_debug_property->setValue( $site_health, null ); + $original_error_log = ini_get( 'error_log' ); $invalid_log_path = '/nonexistent/path/that/does/not/exist/debug.log'; @@ -868,7 +892,7 @@ public function test_is_in_debug_mode_error_log_non_existent() { $this->assertSame( $expected_result['status'], $actual_result['status'], 'Status should be "critical" when error log location cannot be determined.' ); $this->assertSame( $expected_result['label'], $actual_result['label'], 'Label should indicate that error log location could not be determined.' ); - $this->assertSame( $expected_result['description'], $actual_result['description'], 'Description should mention inability to determine log location.' ); + $this->assertStringContainsString( $expected_result['description'], $actual_result['description'], 'Description should mention inability to determine log location.' ); } /** @@ -888,6 +912,10 @@ public function test_is_in_debug_mode_error_log_non_existent_without_wp_debug_lo $wp_debug_log_property->setAccessible( true ); $wp_debug_log_property->setValue( $site_health, false ); + $wp_debug_property = $reflection->getProperty( 'wp_debug_display' ); + $wp_debug_property->setAccessible( true ); + $wp_debug_property->setValue( $site_health, null ); + $original_error_log = ini_get( 'error_log' ); $invalid_log_path = '/nonexistent/path/that/does/not/exist/debug.log'; @@ -900,7 +928,7 @@ public function test_is_in_debug_mode_error_log_non_existent_without_wp_debug_lo $this->assertSame( $expected_result['status'], $actual_result['status'], 'Status should be "critical" when error log location cannot be determined.' ); $this->assertSame( $expected_result['label'], $actual_result['label'], 'Label should indicate that error log location could not be determined.' ); - $this->assertSame( $expected_result['description'], $actual_result['description'], 'Description should mention error log path is nonexistent.' ); + $this->assertStringContainsString( $expected_result['description'], $actual_result['description'], 'Description should mention error log path is nonexistent.' ); } /** @@ -916,21 +944,22 @@ public function test_is_in_debug_mode_display_enabled_production() { $site_health_mock->method( 'is_development_environment' ) ->willReturn( false ); - $reflection_mock = new ReflectionClass( $site_health_mock ); + $site_health = new WP_Site_Health(); + $reflection_mock = new ReflectionClass( $site_health ); $wp_debug_property_mock = $reflection_mock->getProperty( 'wp_debug' ); $wp_debug_property_mock->setAccessible( true ); - $wp_debug_property_mock->setValue( $site_health_mock, true ); + $wp_debug_property_mock->setValue( $site_health, true ); $wp_debug_display_property_mock = $reflection_mock->getProperty( 'wp_debug_display' ); $wp_debug_display_property_mock->setAccessible( true ); - $wp_debug_display_property_mock->setValue( $site_health_mock, true ); + $wp_debug_display_property_mock->setValue( $site_health, true ); - $result = $site_health_mock->get_test_is_in_debug_mode(); + $actual_result = $site_health_mock->get_test_is_in_debug_mode(); - $this->assertSame( 'critical', $result['status'], 'Status should be "critical" when WP_DEBUG_DISPLAY is enabled in production.' ); - $this->assertSame( 'Your site is set to display errors to site visitors', $result['label'], 'Label should indicate errors are displayed to visitors.' ); - $this->assertStringContainsString( 'WP_DEBUG_DISPLAY', $result['description'], 'Description should mention WP_DEBUG_DISPLAY.' ); + $this->assertSame( 'critical', $actual_result['status'], 'Status should be "critical" when WP_DEBUG_DISPLAY is enabled in production.' ); + $this->assertSame( 'Your site is set to display errors to site visitors', $actual_result['label'], 'Label should indicate errors are displayed to visitors.' ); + $this->assertStringContainsString( 'WP_DEBUG_DISPLAY', $actual_result['description'], 'Description should mention WP_DEBUG_DISPLAY.' ); } /** @@ -946,46 +975,42 @@ public function test_is_in_debug_mode_display_enabled_development() { $site_health_mock->method( 'is_development_environment' ) ->willReturn( true ); - $reflection = new ReflectionClass( $site_health_mock ); + $site_health = new WP_Site_Health(); + $reflection_mock = new ReflectionClass( $site_health ); - $wp_debug_property = $reflection->getProperty( 'wp_debug' ); - $wp_debug_property->setAccessible( true ); - $wp_debug_property->setValue( $site_health_mock, true ); + $wp_debug_property_mock = $reflection_mock->getProperty( 'wp_debug' ); + $wp_debug_property_mock->setAccessible( true ); + $wp_debug_property_mock->setValue( $site_health, true ); - $wp_debug_display_property = $reflection->getProperty( 'wp_debug_display' ); - $wp_debug_display_property->setAccessible( true ); - $wp_debug_display_property->setValue( $site_health_mock, true ); + $wp_debug_display_property_mock = $reflection_mock->getProperty( 'wp_debug_display' ); + $wp_debug_display_property_mock->setAccessible( true ); + $wp_debug_display_property_mock->setValue( $site_health, true ); - $result = $site_health_mock->get_test_is_in_debug_mode(); + $actual_result = $site_health_mock->get_test_is_in_debug_mode(); - $this->assertSame( 'recommended', $result['status'], 'Status should be "recommended" when WP_DEBUG_DISPLAY is enabled in development.' ); - $this->assertSame( 'Your site is set to display errors to site visitors', $result['label'], 'Label should indicate errors are displayed to visitors.' ); - $this->assertStringContainsString( 'WP_DEBUG_DISPLAY', $result['description'], 'Description should mention WP_DEBUG_DISPLAY.' ); + $this->assertSame( 'recommended', $actual_result['status'], 'Status should be "recommended" when WP_DEBUG_DISPLAY is enabled in development.' ); + $this->assertSame( 'Your site is set to display errors to site visitors', $actual_result['label'], 'Label should indicate errors are displayed to visitors.' ); + $this->assertStringContainsString( 'WP_DEBUG_DISPLAY', $actual_result['description'], 'Description should mention WP_DEBUG_DISPLAY.' ); } /** - * Tests get_test_is_in_debug_mode() validates result structure. + * Tests get_test_is_in_debug_mode() validates actual_result structure. * * @covers ::get_test_is_in_debug_mode() */ public function test_is_in_debug_mode_result_structure() { - $site_health = new WP_Site_Health(); - $result = $site_health->get_test_is_in_debug_mode(); - - // Verify all required keys are present. - $this->assertArrayHasKey( 'label', $result, 'Result should have a label.' ); - $this->assertArrayHasKey( 'status', $result, 'Result should have a status.' ); - $this->assertArrayHasKey( 'badge', $result, 'Result should have a badge.' ); - $this->assertArrayHasKey( 'description', $result, 'Result should have a description.' ); - $this->assertArrayHasKey( 'actions', $result, 'Result should have actions.' ); - $this->assertArrayHasKey( 'test', $result, 'Result should have a test identifier.' ); - - // Verify badge structure. - $this->assertIsArray( $result['badge'], 'Badge should be an array.' ); - $this->assertArrayHasKey( 'label', $result['badge'], 'Badge should have a label.' ); - $this->assertArrayHasKey( 'color', $result['badge'], 'Badge should have a color.' ); - - // Verify status is one of the expected values. - $this->assertContains( $result['status'], array( 'good', 'recommended', 'critical' ), 'Status should be one of: good, recommended, critical.' ); + $site_health = new WP_Site_Health(); + $actual_result = $site_health->get_test_is_in_debug_mode(); + + $this->assertArrayHasKey( 'label', $actual_result, 'Result should have a label.' ); + $this->assertArrayHasKey( 'status', $actual_result, 'Result should have a status.' ); + $this->assertArrayHasKey( 'badge', $actual_result, 'Result should have a badge.' ); + $this->assertArrayHasKey( 'description', $actual_result, 'Result should have a description.' ); + $this->assertArrayHasKey( 'actions', $actual_result, 'Result should have actions.' ); + $this->assertArrayHasKey( 'test', $actual_result, 'Result should have a test identifier.' ); + $this->assertIsArray( $actual_result['badge'], 'Badge should be an array.' ); + $this->assertArrayHasKey( 'label', $actual_result['badge'], 'Badge should have a label.' ); + $this->assertArrayHasKey( 'color', $actual_result['badge'], 'Badge should have a color.' ); + $this->assertContains( $actual_result['status'], array( 'good', 'recommended', 'critical' ), 'Status should be one of: good, recommended, critical.' ); } } From 51a93edda6e22bb4286ad37ba674788ad526a5f5 Mon Sep 17 00:00:00 2001 From: hbhalodia Date: Tue, 13 Jan 2026 12:04:14 +0530 Subject: [PATCH 20/23] Optimise test case to use dry --- tests/phpunit/tests/admin/wpSiteHealth.php | 243 ++++++++------------- 1 file changed, 86 insertions(+), 157 deletions(-) diff --git a/tests/phpunit/tests/admin/wpSiteHealth.php b/tests/phpunit/tests/admin/wpSiteHealth.php index dff5f8f6d24b4..462ae8325558e 100644 --- a/tests/phpunit/tests/admin/wpSiteHealth.php +++ b/tests/phpunit/tests/admin/wpSiteHealth.php @@ -573,6 +573,56 @@ public static function set_autoloaded_option( $bytes = 800000 ) { add_option( 'test_set_autoloaded_option', $heavy_option_string, '', true ); } + /** + * Helper method to set up WP_Site_Health instance with debug properties. + * + * @param bool $wp_debug Value for wp_debug property. + * @param bool $wp_debug_log Value for wp_debug_log property. + * @param bool|null $wp_debug_display Value for wp_debug_display property. + * + * @return WP_Site_Health + */ + private function setup_site_health_with_debug_properties( bool $wp_debug = false, bool $wp_debug_log = false, ?bool $wp_debug_display = null ) { + $site_health = new WP_Site_Health(); + $reflection = new ReflectionClass( $site_health ); + + $wp_debug_property = $reflection->getProperty( 'wp_debug' ); + $wp_debug_property->setAccessible( true ); + $wp_debug_property->setValue( $site_health, $wp_debug ); + + $wp_debug_log_property = $reflection->getProperty( 'wp_debug_log' ); + $wp_debug_log_property->setAccessible( true ); + $wp_debug_log_property->setValue( $site_health, $wp_debug_log ); + + $wp_debug_display_property = $reflection->getProperty( 'wp_debug_display' ); + $wp_debug_display_property->setAccessible( true ); + $wp_debug_display_property->setValue( $site_health, $wp_debug_display ); + + return $site_health; + } + + /** + * Helper method to set error_log ini setting and restore it later. + * + * @param string $log_path Path to set for error_log. + * + * @return string Original error_log value. + */ + private function set_error_log_path( string $log_path = '' ) { + $original_error_log = ini_get( 'error_log' ); + ini_set( 'error_log', $log_path ); + return $original_error_log; + } + + /** + * Helper method to restore error_log ini setting. + * + * @param string $original_value Original error_log value. + */ + private function restore_error_log_path( string $original_value = '' ) { + ini_set( 'error_log', $original_value ); + } + /** * Returns the expected result array when debug mode is disabled. * @@ -665,13 +715,7 @@ private function get_debug_log_non_existent_path_result( bool $wp_debug_log_defi * @covers ::get_test_is_in_debug_mode() */ public function test_is_in_debug_mode_disabled() { - $site_health = new WP_Site_Health(); - $reflection = new ReflectionClass( $site_health ); - - $wp_debug_property = $reflection->getProperty( 'wp_debug' ); - $wp_debug_property->setAccessible( true ); - $wp_debug_property->setValue( $site_health, false ); - + $site_health = $this->setup_site_health_with_debug_properties( false, false, null ); $actual_result = $site_health->get_test_is_in_debug_mode(); $expected_result = $this->get_debug_mode_disabled_result(); @@ -689,25 +733,12 @@ public function test_is_in_debug_mode_disabled() { * @covers ::get_test_is_in_debug_mode() */ public function test_is_in_debug_mode_enabled_no_error_log() { - $site_health = new WP_Site_Health(); - $reflection = new ReflectionClass( $site_health ); + $site_health = $this->setup_site_health_with_debug_properties( true, false, null ); + $original_error_log = $this->set_error_log_path( '' ); + $actual_result = $site_health->get_test_is_in_debug_mode(); + $expected_result = $this->get_debug_mode_disabled_result(); - $wp_debug_property = $reflection->getProperty( 'wp_debug' ); - $wp_debug_property->setAccessible( true ); - $wp_debug_property->setValue( $site_health, true ); - - $wp_debug_property = $reflection->getProperty( 'wp_debug_display' ); - $wp_debug_property->setAccessible( true ); - $wp_debug_property->setValue( $site_health, null ); - - $original_error_log = ini_get( 'error_log' ); - - ini_set( 'error_log', '' ); - - $actual_result = $site_health->get_test_is_in_debug_mode(); - $expected_result = $this->get_debug_mode_disabled_result(); - - ini_set( 'error_log', $original_error_log ); + $this->restore_error_log_path( $original_error_log ); $this->assertSame( $expected_result['status'], $actual_result['status'], 'Status should be "good" when no error log is configured.' ); $this->assertSame( $expected_result['label'], $actual_result['label'], 'Label should indicate no error log is configured.' ); @@ -721,30 +752,13 @@ public function test_is_in_debug_mode_enabled_no_error_log() { * @covers ::get_test_is_in_debug_mode() */ public function test_is_in_debug_mode_error_log_public() { - $site_health = new WP_Site_Health(); - $reflection = new ReflectionClass( $site_health ); - - $wp_debug_property = $reflection->getProperty( 'wp_debug' ); - $wp_debug_property->setAccessible( true ); - $wp_debug_property->setValue( $site_health, true ); - - $wp_debug_log_property = $reflection->getProperty( 'wp_debug_log' ); - $wp_debug_log_property->setAccessible( true ); - $wp_debug_log_property->setValue( $site_health, true ); - - $wp_debug_property = $reflection->getProperty( 'wp_debug_display' ); - $wp_debug_property->setAccessible( true ); - $wp_debug_property->setValue( $site_health, null ); - - $original_error_log = ini_get( 'error_log' ); + $site_health = $this->setup_site_health_with_debug_properties( true, true, null ); $public_log_path = ABSPATH . 'wp-content/debug.log'; + $original_error_log = $this->set_error_log_path( $public_log_path ); + $actual_result = $site_health->get_test_is_in_debug_mode(); + $expected_result = $this->get_debug_error_log_public_result( true ); - ini_set( 'error_log', $public_log_path ); - - $actual_result = $site_health->get_test_is_in_debug_mode(); - $expected_result = $this->get_debug_error_log_public_result( true ); - - ini_set( 'error_log', $original_error_log ); + $this->restore_error_log_path( $original_error_log ); $this->assertSame( $expected_result['status'], $actual_result['status'], 'Status should be "critical" when error log is in a public location.' ); $this->assertSame( $expected_result['label'], $actual_result['label'], 'Label should indicate error log is in a public location.' ); @@ -757,30 +771,13 @@ public function test_is_in_debug_mode_error_log_public() { * @covers ::get_test_is_in_debug_mode() */ public function test_is_in_debug_mode_error_log_public_without_wp_debug_log() { - $site_health = new WP_Site_Health(); - $reflection = new ReflectionClass( $site_health ); - - $wp_debug_property = $reflection->getProperty( 'wp_debug' ); - $wp_debug_property->setAccessible( true ); - $wp_debug_property->setValue( $site_health, true ); - - $wp_debug_log_property = $reflection->getProperty( 'wp_debug_log' ); - $wp_debug_log_property->setAccessible( true ); - $wp_debug_log_property->setValue( $site_health, false ); - - $wp_debug_property = $reflection->getProperty( 'wp_debug_display' ); - $wp_debug_property->setAccessible( true ); - $wp_debug_property->setValue( $site_health, null ); - - $original_error_log = ini_get( 'error_log' ); + $site_health = $this->setup_site_health_with_debug_properties( true, false, null ); $public_log_path = ABSPATH . 'wp-content/debug.log'; + $original_error_log = $this->set_error_log_path( $public_log_path ); + $actual_result = $site_health->get_test_is_in_debug_mode(); + $expected_result = $this->get_debug_error_log_public_result( false ); - ini_set( 'error_log', $public_log_path ); - - $actual_result = $site_health->get_test_is_in_debug_mode(); - $expected_result = $this->get_debug_error_log_public_result( false ); - - ini_set( 'error_log', $original_error_log ); + $this->restore_error_log_path( $original_error_log ); $this->assertSame( $expected_result['status'], $actual_result['status'], 'Status should be "critical" when error log is in a public location.' ); $this->assertSame( $expected_result['label'], $actual_result['label'], 'Label should indicate error log is in a public location.' ); @@ -793,30 +790,13 @@ public function test_is_in_debug_mode_error_log_public_without_wp_debug_log() { * @covers ::get_test_is_in_debug_mode() */ public function test_is_in_debug_mode_error_log_private() { - $site_health = new WP_Site_Health(); - $reflection = new ReflectionClass( $site_health ); - - $wp_debug_property = $reflection->getProperty( 'wp_debug' ); - $wp_debug_property->setAccessible( true ); - $wp_debug_property->setValue( $site_health, true ); - - $wp_debug_log_property = $reflection->getProperty( 'wp_debug_log' ); - $wp_debug_log_property->setAccessible( true ); - $wp_debug_log_property->setValue( $site_health, true ); - - $wp_debug_property = $reflection->getProperty( 'wp_debug_display' ); - $wp_debug_property->setAccessible( true ); - $wp_debug_property->setValue( $site_health, null ); - - $original_error_log = ini_get( 'error_log' ); + $site_health = $this->setup_site_health_with_debug_properties( true, true, null ); $private_log_path = '/var/log/php-error.log'; + $original_error_log = $this->set_error_log_path( $private_log_path ); + $actual_result = $site_health->get_test_is_in_debug_mode(); + $expected_result = $this->get_debug_error_log_private_result( true ); - ini_set( 'error_log', $private_log_path ); - - $actual_result = $site_health->get_test_is_in_debug_mode(); - $expected_result = $this->get_debug_error_log_private_result( true ); - - ini_set( 'error_log', $original_error_log ); + $this->restore_error_log_path( $original_error_log ); $this->assertSame( $expected_result['status'], $actual_result['status'], 'Status should be "good" when error log is in a private location.' ); $this->assertSame( $expected_result['label'], $actual_result['label'], 'Label should indicate error log is in a private location.' ); @@ -829,30 +809,13 @@ public function test_is_in_debug_mode_error_log_private() { * @covers ::get_test_is_in_debug_mode() */ public function test_is_in_debug_mode_error_log_private_without_wp_debug_log() { - $site_health = new WP_Site_Health(); - $reflection = new ReflectionClass( $site_health ); - - $wp_debug_property = $reflection->getProperty( 'wp_debug' ); - $wp_debug_property->setAccessible( true ); - $wp_debug_property->setValue( $site_health, true ); - - $wp_debug_log_property = $reflection->getProperty( 'wp_debug_log' ); - $wp_debug_log_property->setAccessible( true ); - $wp_debug_log_property->setValue( $site_health, false ); - - $wp_debug_property = $reflection->getProperty( 'wp_debug_display' ); - $wp_debug_property->setAccessible( true ); - $wp_debug_property->setValue( $site_health, null ); - - $original_error_log = ini_get( 'error_log' ); + $site_health = $this->setup_site_health_with_debug_properties( true, false, null ); $private_log_path = '/var/log/php-error.log'; + $original_error_log = $this->set_error_log_path( $private_log_path ); + $actual_result = $site_health->get_test_is_in_debug_mode(); + $expected_result = $this->get_debug_error_log_private_result( false ); - ini_set( 'error_log', $private_log_path ); - - $actual_result = $site_health->get_test_is_in_debug_mode(); - $expected_result = $this->get_debug_error_log_private_result( false ); - - ini_set( 'error_log', $original_error_log ); + $this->restore_error_log_path( $original_error_log ); $this->assertSame( $expected_result['status'], $actual_result['status'], 'Status should be "good" when error log is in a private location.' ); $this->assertSame( $expected_result['label'], $actual_result['label'], 'Label should indicate error log is in a private location.' ); @@ -865,30 +828,13 @@ public function test_is_in_debug_mode_error_log_private_without_wp_debug_log() { * @covers ::get_test_is_in_debug_mode() */ public function test_is_in_debug_mode_error_log_non_existent() { - $site_health = new WP_Site_Health(); - $reflection = new ReflectionClass( $site_health ); - - $wp_debug_property = $reflection->getProperty( 'wp_debug' ); - $wp_debug_property->setAccessible( true ); - $wp_debug_property->setValue( $site_health, true ); - - $wp_debug_log_property = $reflection->getProperty( 'wp_debug_log' ); - $wp_debug_log_property->setAccessible( true ); - $wp_debug_log_property->setValue( $site_health, true ); - - $wp_debug_property = $reflection->getProperty( 'wp_debug_display' ); - $wp_debug_property->setAccessible( true ); - $wp_debug_property->setValue( $site_health, null ); - - $original_error_log = ini_get( 'error_log' ); + $site_health = $this->setup_site_health_with_debug_properties( true, true, null ); $invalid_log_path = '/nonexistent/path/that/does/not/exist/debug.log'; + $original_error_log = $this->set_error_log_path( $invalid_log_path ); + $actual_result = $site_health->get_test_is_in_debug_mode(); + $expected_result = $this->get_debug_log_non_existent_path_result( true ); - ini_set( 'error_log', $invalid_log_path ); - - $actual_result = $site_health->get_test_is_in_debug_mode(); - $expected_result = $this->get_debug_log_non_existent_path_result( true ); - - ini_set( 'error_log', $original_error_log ); + $this->restore_error_log_path( $original_error_log ); $this->assertSame( $expected_result['status'], $actual_result['status'], 'Status should be "critical" when error log location cannot be determined.' ); $this->assertSame( $expected_result['label'], $actual_result['label'], 'Label should indicate that error log location could not be determined.' ); @@ -901,30 +847,13 @@ public function test_is_in_debug_mode_error_log_non_existent() { * @covers ::get_test_is_in_debug_mode() */ public function test_is_in_debug_mode_error_log_non_existent_without_wp_debug_log() { - $site_health = new WP_Site_Health(); - $reflection = new ReflectionClass( $site_health ); - - $wp_debug_property = $reflection->getProperty( 'wp_debug' ); - $wp_debug_property->setAccessible( true ); - $wp_debug_property->setValue( $site_health, true ); - - $wp_debug_log_property = $reflection->getProperty( 'wp_debug_log' ); - $wp_debug_log_property->setAccessible( true ); - $wp_debug_log_property->setValue( $site_health, false ); - - $wp_debug_property = $reflection->getProperty( 'wp_debug_display' ); - $wp_debug_property->setAccessible( true ); - $wp_debug_property->setValue( $site_health, null ); - - $original_error_log = ini_get( 'error_log' ); + $site_health = $this->setup_site_health_with_debug_properties( true, false, null ); $invalid_log_path = '/nonexistent/path/that/does/not/exist/debug.log'; + $original_error_log = $this->set_error_log_path( $invalid_log_path ); + $actual_result = $site_health->get_test_is_in_debug_mode(); + $expected_result = $this->get_debug_log_non_existent_path_result( false ); - ini_set( 'error_log', $invalid_log_path ); - - $actual_result = $site_health->get_test_is_in_debug_mode(); - $expected_result = $this->get_debug_log_non_existent_path_result( false ); - - ini_set( 'error_log', $original_error_log ); + $this->restore_error_log_path( $original_error_log ); $this->assertSame( $expected_result['status'], $actual_result['status'], 'Status should be "critical" when error log location cannot be determined.' ); $this->assertSame( $expected_result['label'], $actual_result['label'], 'Label should indicate that error log location could not be determined.' ); From afc7b6089c42276f1892502d2e03a700ae5664a9 Mon Sep 17 00:00:00 2001 From: hbhalodia Date: Tue, 13 Jan 2026 12:18:57 +0530 Subject: [PATCH 21/23] Fix unit test failing with error --- tests/phpunit/tests/admin/wpSiteHealth.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/phpunit/tests/admin/wpSiteHealth.php b/tests/phpunit/tests/admin/wpSiteHealth.php index 462ae8325558e..f7c4f2b371d64 100644 --- a/tests/phpunit/tests/admin/wpSiteHealth.php +++ b/tests/phpunit/tests/admin/wpSiteHealth.php @@ -878,11 +878,11 @@ public function test_is_in_debug_mode_display_enabled_production() { $wp_debug_property_mock = $reflection_mock->getProperty( 'wp_debug' ); $wp_debug_property_mock->setAccessible( true ); - $wp_debug_property_mock->setValue( $site_health, true ); + $wp_debug_property_mock->setValue( $site_health_mock, true ); $wp_debug_display_property_mock = $reflection_mock->getProperty( 'wp_debug_display' ); $wp_debug_display_property_mock->setAccessible( true ); - $wp_debug_display_property_mock->setValue( $site_health, true ); + $wp_debug_display_property_mock->setValue( $site_health_mock, true ); $actual_result = $site_health_mock->get_test_is_in_debug_mode(); @@ -909,11 +909,11 @@ public function test_is_in_debug_mode_display_enabled_development() { $wp_debug_property_mock = $reflection_mock->getProperty( 'wp_debug' ); $wp_debug_property_mock->setAccessible( true ); - $wp_debug_property_mock->setValue( $site_health, true ); + $wp_debug_property_mock->setValue( $site_health_mock, true ); $wp_debug_display_property_mock = $reflection_mock->getProperty( 'wp_debug_display' ); $wp_debug_display_property_mock->setAccessible( true ); - $wp_debug_display_property_mock->setValue( $site_health, true ); + $wp_debug_display_property_mock->setValue( $site_health_mock, true ); $actual_result = $site_health_mock->get_test_is_in_debug_mode(); From fde7a6c1878dc63319bf379196cfb59ac3cd85f4 Mon Sep 17 00:00:00 2001 From: hbhalodia Date: Tue, 13 Jan 2026 12:24:14 +0530 Subject: [PATCH 22/23] Fix phpcs issue and update messaging in unit tests --- tests/phpunit/tests/admin/wpSiteHealth.php | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/phpunit/tests/admin/wpSiteHealth.php b/tests/phpunit/tests/admin/wpSiteHealth.php index f7c4f2b371d64..5075fb0ba3e7b 100644 --- a/tests/phpunit/tests/admin/wpSiteHealth.php +++ b/tests/phpunit/tests/admin/wpSiteHealth.php @@ -582,7 +582,7 @@ public static function set_autoloaded_option( $bytes = 800000 ) { * * @return WP_Site_Health */ - private function setup_site_health_with_debug_properties( bool $wp_debug = false, bool $wp_debug_log = false, ?bool $wp_debug_display = null ) { + private function setup_site_health_with_debug_properties( bool $wp_debug = false, bool $wp_debug_log = false, ?bool $wp_debug_display = null ) { $site_health = new WP_Site_Health(); $reflection = new ReflectionClass( $site_health ); @@ -762,7 +762,7 @@ public function test_is_in_debug_mode_error_log_public() { $this->assertSame( $expected_result['status'], $actual_result['status'], 'Status should be "critical" when error log is in a public location.' ); $this->assertSame( $expected_result['label'], $actual_result['label'], 'Label should indicate error log is in a public location.' ); - $this->assertStringContainsString( $expected_result['description'], $actual_result['description'], 'Description should display the expected message.' ); + $this->assertStringContainsString( $expected_result['description'], $actual_result['description'], 'Description should display error log is configured with WP_DEBUG_LOG and is in a public directory.' ); } /** @@ -781,7 +781,7 @@ public function test_is_in_debug_mode_error_log_public_without_wp_debug_log() { $this->assertSame( $expected_result['status'], $actual_result['status'], 'Status should be "critical" when error log is in a public location.' ); $this->assertSame( $expected_result['label'], $actual_result['label'], 'Label should indicate error log is in a public location.' ); - $this->assertStringContainsString( $expected_result['description'], $actual_result['description'], 'Description should mention error log configured is without WP_DEBUG_LOG and in public directory.' ); + $this->assertStringContainsString( $expected_result['description'], $actual_result['description'], 'Description should mention error log is configured without WP_DEBUG_LOG and in public directory.' ); } /** @@ -800,7 +800,7 @@ public function test_is_in_debug_mode_error_log_private() { $this->assertSame( $expected_result['status'], $actual_result['status'], 'Status should be "good" when error log is in a private location.' ); $this->assertSame( $expected_result['label'], $actual_result['label'], 'Label should indicate error log is in a private location.' ); - $this->assertStringContainsString( $expected_result['description'], $actual_result['description'], 'Description should mention the log is outside WordPress directory.' ); + $this->assertStringContainsString( $expected_result['description'], $actual_result['description'], 'Description should mention error log is configured outside WordPress directory.' ); } /** @@ -819,7 +819,7 @@ public function test_is_in_debug_mode_error_log_private_without_wp_debug_log() { $this->assertSame( $expected_result['status'], $actual_result['status'], 'Status should be "good" when error log is in a private location.' ); $this->assertSame( $expected_result['label'], $actual_result['label'], 'Label should indicate error log is in a private location.' ); - $this->assertStringContainsString( $expected_result['description'], $actual_result['description'], 'Description should mention log is outside WordPress directory.' ); + $this->assertStringContainsString( $expected_result['description'], $actual_result['description'], 'Description should mention error log is configured outside WordPress directory.' ); } /** @@ -838,7 +838,7 @@ public function test_is_in_debug_mode_error_log_non_existent() { $this->assertSame( $expected_result['status'], $actual_result['status'], 'Status should be "critical" when error log location cannot be determined.' ); $this->assertSame( $expected_result['label'], $actual_result['label'], 'Label should indicate that error log location could not be determined.' ); - $this->assertStringContainsString( $expected_result['description'], $actual_result['description'], 'Description should mention inability to determine log location.' ); + $this->assertStringContainsString( $expected_result['description'], $actual_result['description'], 'Description should mention error log path is nonexistent.' ); } /** @@ -887,8 +887,8 @@ public function test_is_in_debug_mode_display_enabled_production() { $actual_result = $site_health_mock->get_test_is_in_debug_mode(); $this->assertSame( 'critical', $actual_result['status'], 'Status should be "critical" when WP_DEBUG_DISPLAY is enabled in production.' ); - $this->assertSame( 'Your site is set to display errors to site visitors', $actual_result['label'], 'Label should indicate errors are displayed to visitors.' ); - $this->assertStringContainsString( 'WP_DEBUG_DISPLAY', $actual_result['description'], 'Description should mention WP_DEBUG_DISPLAY.' ); + $this->assertSame( 'Your site is set to display errors to site visitors', $actual_result['label'], 'Label should indicate that errors are displayed to visitors.' ); + $this->assertStringContainsString( 'WP_DEBUG_DISPLAY', $actual_result['description'], 'Description should contain WP_DEBUG_DISPLAY.' ); } /** @@ -918,8 +918,8 @@ public function test_is_in_debug_mode_display_enabled_development() { $actual_result = $site_health_mock->get_test_is_in_debug_mode(); $this->assertSame( 'recommended', $actual_result['status'], 'Status should be "recommended" when WP_DEBUG_DISPLAY is enabled in development.' ); - $this->assertSame( 'Your site is set to display errors to site visitors', $actual_result['label'], 'Label should indicate errors are displayed to visitors.' ); - $this->assertStringContainsString( 'WP_DEBUG_DISPLAY', $actual_result['description'], 'Description should mention WP_DEBUG_DISPLAY.' ); + $this->assertSame( 'Your site is set to display errors to site visitors', $actual_result['label'], 'Label should indicate that errors are displayed to visitors.' ); + $this->assertStringContainsString( 'WP_DEBUG_DISPLAY', $actual_result['description'], 'Description should contain WP_DEBUG_DISPLAY.' ); } /** From 0ae1b81b0eff60039b2dd62c1ab21bb83a06f289 Mon Sep 17 00:00:00 2001 From: hbhalodia Date: Tue, 13 Jan 2026 12:26:08 +0530 Subject: [PATCH 23/23] Update the wp_debug_display private value to be set --- src/wp-admin/includes/class-wp-site-health.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-admin/includes/class-wp-site-health.php b/src/wp-admin/includes/class-wp-site-health.php index a54e6a0ff1664..c4501eaa09d2a 100644 --- a/src/wp-admin/includes/class-wp-site-health.php +++ b/src/wp-admin/includes/class-wp-site-health.php @@ -72,7 +72,7 @@ public function __construct() { $this->wp_debug = defined( 'WP_DEBUG' ) && WP_DEBUG; $this->wp_debug_log = defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG; - $this->wp_debug_display = defined( 'WP_DEBUG_DISPLAY' ) ? WP_DEBUG_DISPLAY : null; + $this->wp_debug_display = defined( 'WP_DEBUG_DISPLAY' ) && WP_DEBUG_DISPLAY ? WP_DEBUG_DISPLAY : null; } /**