From 86354dedd4b09adc95518bf43116e28682a73612 Mon Sep 17 00:00:00 2001 From: Shail Mehta Date: Mon, 19 Oct 2026 14:18:05 +0530 Subject: [PATCH 1/2] Tests: Add unit tests for `wp_get_active_and_valid_themes()` --- .../tests/load/wpGetActiveAndValidThemes.php | 275 ++++++++++++++++++ 1 file changed, 275 insertions(+) create mode 100644 tests/phpunit/tests/load/wpGetActiveAndValidThemes.php diff --git a/tests/phpunit/tests/load/wpGetActiveAndValidThemes.php b/tests/phpunit/tests/load/wpGetActiveAndValidThemes.php new file mode 100644 index 0000000000000..5ce9a19b1061b --- /dev/null +++ b/tests/phpunit/tests/load/wpGetActiveAndValidThemes.php @@ -0,0 +1,275 @@ +original_stylesheet_path = $wp_stylesheet_path ?? null; + $this->original_template_path = $wp_template_path ?? null; + $this->original_pagenow = $pagenow ?? null; + $this->original_installing = wp_installing(); + $this->original_stylesheet = get_option( 'stylesheet' ); + $this->original_template = get_option( 'template' ); + $this->original_is_active = $this->get_recovery_mode_property( 'is_active' ); + $this->original_session_id = $this->get_recovery_mode_property( 'session_id' ); + $this->original_paused_themes = $GLOBALS['_paused_themes'] ?? null; + + unset( $GLOBALS['_paused_themes'] ); + wp_installing( false ); + } + + public function tear_down() { + global $wp_stylesheet_path, $wp_template_path, $pagenow; + + $wp_stylesheet_path = $this->original_stylesheet_path; + $wp_template_path = $this->original_template_path; + + if ( null !== $this->original_pagenow ) { + $pagenow = $this->original_pagenow; + } else { + unset( $GLOBALS['pagenow'] ); + } + + wp_installing( $this->original_installing ); + update_option( 'stylesheet', $this->original_stylesheet ); + update_option( 'template', $this->original_template ); + $this->set_recovery_mode_state( $this->original_is_active, $this->original_session_id ); + delete_option( self::TEST_SESSION_ID . '_paused_extensions' ); + + if ( null !== $this->original_paused_themes ) { + $GLOBALS['_paused_themes'] = $this->original_paused_themes; + } else { + unset( $GLOBALS['_paused_themes'] ); + } + + remove_all_filters( 'wp_using_themes' ); + + parent::tear_down(); + } + + /** + * Gets a WP_Recovery_Mode property value. + * + * @param string $property Property name. + * @return mixed Property value. + */ + private function get_recovery_mode_property( $property ) { + $reflection = new ReflectionProperty( wp_recovery_mode(), $property ); + if ( PHP_VERSION_ID < 80100 ) { + $reflection->setAccessible( true ); + } + + return $reflection->getValue( wp_recovery_mode() ); + } + + /** + * Sets WP_Recovery_Mode protected state. + * + * @param bool $is_active Whether recovery mode is active. + * @param string $session_id Recovery mode session ID. + */ + private function set_recovery_mode_state( $is_active, $session_id ) { + $recovery_mode = wp_recovery_mode(); + + $is_active_property = new ReflectionProperty( $recovery_mode, 'is_active' ); + if ( PHP_VERSION_ID < 80100 ) { + $is_active_property->setAccessible( true ); + } + $is_active_property->setValue( $recovery_mode, $is_active ); + + $session_id_property = new ReflectionProperty( $recovery_mode, 'session_id' ); + if ( PHP_VERSION_ID < 80100 ) { + $session_id_property->setAccessible( true ); + } + $session_id_property->setValue( $recovery_mode, $session_id ); + } + + /** + * @ticket 65819 + */ + public function test_returns_template_path_for_parent_theme() { + global $wp_stylesheet_path, $wp_template_path; + + $wp_template_path = get_theme_root() . '/twentytwentyone'; + $wp_stylesheet_path = $wp_template_path; + update_option( 'template', 'twentytwentyone' ); + update_option( 'stylesheet', 'twentytwentyone' ); + + $this->assertSame( array( $wp_template_path ), wp_get_active_and_valid_themes() ); + } + + /** + * @ticket 65819 + */ + public function test_includes_stylesheet_path_for_child_theme() { + global $wp_stylesheet_path, $wp_template_path; + + $wp_template_path = get_theme_root() . '/twentytwentyone'; + $wp_stylesheet_path = get_theme_root() . '/twentytwentyfive'; + update_option( 'template', 'twentytwentyone' ); + update_option( 'stylesheet', 'twentytwentyfive' ); + + $this->assertSame( + array( $wp_stylesheet_path, $wp_template_path ), + wp_get_active_and_valid_themes() + ); + } + + /** + * @ticket 65819 + */ + public function test_returns_empty_array_while_installing() { + global $wp_template_path, $pagenow; + + $wp_template_path = get_theme_root() . '/twentytwentyone'; + $pagenow = 'index.php'; + wp_installing( true ); + + $this->assertSame( array(), wp_get_active_and_valid_themes() ); + } + + /** + * @ticket 65819 + */ + public function test_returns_themes_while_installing_on_wp_activate() { + global $wp_stylesheet_path, $wp_template_path, $pagenow; + + $wp_template_path = get_theme_root() . '/twentytwentyone'; + $wp_stylesheet_path = $wp_template_path; + $pagenow = 'wp-activate.php'; + wp_installing( true ); + + $this->assertSame( array( $wp_template_path ), wp_get_active_and_valid_themes() ); + } + + /** + * @ticket 65819 + */ + public function test_skips_paused_themes_in_recovery_mode() { + global $wp_stylesheet_path, $wp_template_path; + + $wp_template_path = get_theme_root() . '/twentytwentyone'; + $wp_stylesheet_path = get_theme_root() . '/twentytwentyfive'; + update_option( 'template', 'twentytwentyone' ); + update_option( 'stylesheet', 'twentytwentyfive' ); + + $this->set_recovery_mode_state( true, self::TEST_SESSION_ID ); + $this->assertTrue( + wp_paused_themes()->set( + 'twentytwentyfive', + array( + 'type' => E_ERROR, + 'file' => $wp_stylesheet_path . '/functions.php', + 'line' => 1, + 'message' => 'Fatal error', + ) + ) + ); + + $this->assertSame( array( 1 => $wp_template_path ), wp_get_active_and_valid_themes() ); + } + + /** + * @ticket 65819 + */ + public function test_disables_themes_when_all_are_paused_in_recovery_mode() { + global $wp_stylesheet_path, $wp_template_path; + + $wp_template_path = get_theme_root() . '/twentytwentyone'; + $wp_stylesheet_path = $wp_template_path; + update_option( 'template', 'twentytwentyone' ); + update_option( 'stylesheet', 'twentytwentyone' ); + + $this->set_recovery_mode_state( true, self::TEST_SESSION_ID ); + $this->assertTrue( + wp_paused_themes()->set( + 'twentytwentyone', + array( + 'type' => E_ERROR, + 'file' => $wp_template_path . '/functions.php', + 'line' => 1, + 'message' => 'Fatal error', + ) + ) + ); + + $this->assertSame( array(), wp_get_active_and_valid_themes() ); + $this->assertNotFalse( has_filter( 'wp_using_themes', '__return_false' ) ); + } +} From e661b71de67bd6e3c93d8e4344dc6c471376541f Mon Sep 17 00:00:00 2001 From: Shail Mehta Date: Mon, 19 Oct 2026 16:59:20 +0530 Subject: [PATCH 2/2] Apply Feedback changes --- tests/phpunit/tests/load/wpGetActiveAndValidThemes.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/tests/load/wpGetActiveAndValidThemes.php b/tests/phpunit/tests/load/wpGetActiveAndValidThemes.php index 5ce9a19b1061b..33e0a44a4986b 100644 --- a/tests/phpunit/tests/load/wpGetActiveAndValidThemes.php +++ b/tests/phpunit/tests/load/wpGetActiveAndValidThemes.php @@ -179,7 +179,7 @@ public function test_returns_template_path_for_parent_theme() { */ public function test_includes_stylesheet_path_for_child_theme() { global $wp_stylesheet_path, $wp_template_path; - + // These are not a real parent/child pair. is_child_theme() only compares the two paths. $wp_template_path = get_theme_root() . '/twentytwentyone'; $wp_stylesheet_path = get_theme_root() . '/twentytwentyfive'; update_option( 'template', 'twentytwentyone' );