Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add feature tests for checking plugin with addon enabled #518

Merged
merged 27 commits into from
Sep 5, 2024
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
8b6abd0
Add feature tests for filters
ernilambar Jul 11, 2024
697526f
Separate class files in feature tests
ernilambar Jul 11, 2024
8bc5c7b
Remove before wp load hook
ernilambar Jul 18, 2024
06a018d
Merge branch 'trunk' into add/tests-for-filters
swissspidy Jul 18, 2024
7f43fdc
Remove unused use class import
ernilambar Jul 18, 2024
4139c9d
Revert removed hook
ernilambar Jul 19, 2024
a5df7a7
Merge branch 'trunk' into add/tests-for-filters
ernilambar Jul 30, 2024
82dc502
Move tests to separate feature file
ernilambar Jul 30, 2024
9c8e5cb
Remove PHP file after CLI invoke
ernilambar Aug 20, 2024
dd7e4ba
Merge branch 'trunk' into add/tests-for-filters
ernilambar Aug 20, 2024
3b24b72
Add abstract methods implementation in checks
ernilambar Aug 20, 2024
92dabcb
Update adding hook to CLI command
ernilambar Aug 20, 2024
f37a830
Add runtime checks in the feature tests
ernilambar Aug 20, 2024
3d7d8a3
Update condition for initialization
ernilambar Aug 21, 2024
82cc334
Remove can setup condition
ernilambar Aug 21, 2024
0fbf653
Only delete drop-in if it's ours
swissspidy Aug 30, 2024
dd7827b
Rewrite tests to make them easier to comprehend
swissspidy Aug 30, 2024
90db569
Switch to `after_wp_config_load`
swissspidy Aug 30, 2024
56eb443
Update condition as per suggestion
swissspidy Aug 30, 2024
b30b02f
Don't check for WP-CLI command name
swissspidy Aug 30, 2024
16f1b31
Fix condition
swissspidy Aug 30, 2024
2a8a2a8
Disable known broken tests
swissspidy Aug 30, 2024
714b53a
Merge branch 'trunk' into add/tests-for-filters
swissspidy Sep 2, 2024
c07dc62
Define consts, run in separate process
swissspidy Sep 5, 2024
2ce4dea
Merge branch 'trunk' into add/tests-for-filters
swissspidy Sep 5, 2024
9487cfe
Merge branch 'trunk' into add/tests-for-filters
swissspidy Sep 5, 2024
10b39a9
Add explanatory comment
swissspidy Sep 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 19 additions & 6 deletions cli.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,29 @@

// Create the CLI command instance and add to WP CLI.
$plugin_command = new Plugin_Check_Command( $context );
WP_CLI::add_command( 'plugin', $plugin_command );

WP_CLI::add_command(
'plugin',
$plugin_command,
array(
'after_invoke' => function () {
swissspidy marked this conversation as resolved.
Show resolved Hide resolved
if (
file_exists( ABSPATH . 'wp-content/object-cache.php' ) &&
false !== strpos( file_get_contents( ABSPATH . 'wp-content/object-cache.php' ), 'WP_PLUGIN_CHECK_OBJECT_CACHE_DROPIN_VERSION' )
) {
unlink( ABSPATH . 'wp-content/object-cache.php' );
}
},
)
);

/**
* Adds hook to set up the object-cache.php drop-in file.
/*
* Add hook to set up the object-cache.php drop-in file.
*
* @since 1.0.0
* Runs after wp-config.php is loaded and thus ABSPATH is defined,
* but before any plugins are actually loaded.
*/
WP_CLI::add_hook(
'before_wp_load',
'after_wp_config_load',
function () {
if ( CLI_Runner::is_plugin_check() ) {
if ( ! file_exists( ABSPATH . 'wp-content/object-cache.php' ) ) {
Comment on lines 69 to 70
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In principle, this should only be placed if runtime checks are run. If only static checks should be run against a plugin, this isn't needed. But I'm not sure it's reasonably possible to detect that from here.

FWIW at the moment users of WP-CLI have to know about the --require portion anyway, so because of that it's probably okay to also expect of them to only include the --require if they want to run any runtime checks. Something to improve elsewhere, as we've already discussed a few times.

Expand Down
5 changes: 4 additions & 1 deletion includes/Checker/CLI_Runner.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,15 @@
* @return bool Returns true if is an CLI request for the plugin check else false.
*/
public static function is_plugin_check() {
if ( ! defined( 'WP_CLI' ) || ! WP_CLI ) {
return false;

Check warning on line 36 in includes/Checker/CLI_Runner.php

View check run for this annotation

Codecov / codecov/patch

includes/Checker/CLI_Runner.php#L36

Added line #L36 was not covered by tests
swissspidy marked this conversation as resolved.
Show resolved Hide resolved
}

if ( empty( $_SERVER['argv'] ) || 3 > count( $_SERVER['argv'] ) ) {
return false;
}

if (
'wp' === substr( $_SERVER['argv'][0], -2 ) &&
'plugin' === $_SERVER['argv'][1] &&
'check' === $_SERVER['argv'][2]
) {
Expand Down
138 changes: 138 additions & 0 deletions tests/behat/features/plugin-check.feature
Original file line number Diff line number Diff line change
Expand Up @@ -374,3 +374,141 @@ Feature: Test that the WP-CLI command works.
"""
Invalid plugin slug
"""

Scenario: Check a plugin with static checks from an add-on
Given a WP install with the Plugin Check plugin
And a Plugin Check add-on being installed

And a wp-content/plugins/foo-sample/foo-sample.php file:
swissspidy marked this conversation as resolved.
Show resolved Hide resolved
"""
<?php
/**
* Plugin Name: Foo Sample
* Plugin URI: https://example.com
* Description: Sample plugin.
* Version: 0.1.0
* Author: WordPress Performance Team
* Author URI: https://make.wordpress.org/performance/
* License: GPL-2.0+
* License URI: http://www.gnu.org/licenses/gpl-2.0.txt
*/

$text = 'I am bad'; // This should trigger the error.
"""
And I run the WP-CLI command `plugin activate foo-sample`

# The two checks from pcp-addon should be available.
When I run the WP-CLI command `plugin list-checks --fields=slug,category,stability --format=csv`
Then STDOUT should contain:
"""
example_static,new_category,stable
"""
And STDOUT should contain:
"""
example_runtime,new_category,stable
"""

# The new check category should therefore also be available.
When I run the WP-CLI command `plugin list-check-categories --fields=slug,name --format=csv`
Then STDOUT should contain:
"""
new_category,"New Category"
"""

# Running static checks, including the one from pcp-addon
When I run the WP-CLI command `plugin check foo-sample --fields=code,type --format=csv`
Then STDOUT should contain:
"""
prohibited_text_detected,ERROR
"""

# Same again, but after filtering only to the new categories from pcp-addon
When I run the WP-CLI command `plugin check foo-sample --fields=code,type --format=csv --categories=new_category`
Then STDOUT should contain:
"""
prohibited_text_detected,ERROR
"""

# Running only the check from pcp-addon
When I run the WP-CLI command `plugin check foo-sample --checks=example_static --fields=code,type --format=csv`
Then STDOUT should contain:
"""
prohibited_text_detected,ERROR
"""

Scenario: Check a plugin with runtime checks from an add-on
Given a WP install with the Plugin Check plugin
And a Plugin Check add-on being installed

And a wp-content/plugins/foo-sample/foo-sample.php file:
"""
<?php
/**
* Plugin Name: Foo Sample
* Plugin URI: https://example.com
* Description: Sample plugin.
* Version: 0.1.0
* Author: WordPress Performance Team
* Author URI: https://make.wordpress.org/performance/
* License: GPL-2.0+
* License URI: http://www.gnu.org/licenses/gpl-2.0.txt
*/

// This should trigger the error.
add_action(
'wp_enqueue_scripts',
function() {
wp_enqueue_script( 'test', plugin_dir_url( __FILE__ ) . 'test.js', array(), '1.0' );
}
);
"""
And I run the WP-CLI command `plugin activate foo-sample`

# Running runtime checks, including the one from pcp-addon
When I run the WP-CLI command `plugin check foo-sample --fields=code,type --format=csv --require=./wp-content/plugins/plugin-check/cli.php`
Then STDOUT should contain:
"""
Setting up runtime environment.
"""
And STDOUT should contain:
"""
Cleaning up runtime environment.
"""
And STDOUT should contain:
"""
WordPress.WP.EnqueuedResourceParameters.NotInFooter,WARNING
"""
# This doesn't currently work, because we are not actually loading any other plugins, including pcp-addon.
# And STDOUT should contain:
# """
# ExampleRuntimeCheck.ForbiddenScript,WARNING
# """

# Same again, to verify object-cache.php was properly cleared again
When I run the WP-CLI command `plugin check foo-sample --fields=code,type --format=csv --require=./wp-content/plugins/plugin-check/cli.php`
Then STDOUT should contain:
"""
Setting up runtime environment.
"""
And STDOUT should contain:
"""
Cleaning up runtime environment.
"""
And STDOUT should contain:
"""
WordPress.WP.EnqueuedResourceParameters.NotInFooter,WARNING
"""

# This doesn't currently work, because we are not actually loading any other plugins, including pcp-addon.
# And STDOUT should contain:
# """
# ExampleRuntimeCheck.ForbiddenScript,WARNING
# """

# This doesn't currently work, because we are not actually loading any other plugins, including pcp-addon.
# Run only the runtime check from pcp-addon, no others
# When I run the WP-CLI command `plugin check foo-sample --checks=example_runtime --fields=code,type --format=csv --require=./wp-content/plugins/plugin-check/cli.php`
# Then STDOUT should contain:
# """
# ExampleRuntimeCheck.ForbiddenScript,WARNING
# """
13 changes: 13 additions & 0 deletions tests/behat/includes/FeatureContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,19 @@ public function given_a_wp_installation_with_plugin_check() {
// Activate the plugin.
$this->proc( 'wp plugin activate plugin-check' )->run_check();
}
/**
* @Given a Plugin Check add-on being installed
*/
public function given_a_plugin_check_addon_being_installed() {
// Symlink the pcp-addon folder into the WP folder as a plugin.
$src_dir = realpath( self::get_vendor_dir() . '/../tests/behat/testdata/pcp-addon' );
$plugin_dir = $this->variables['RUN_DIR'] . '/wp-content/plugins';
$this->ensure_dir_exists( $plugin_dir );
$this->proc( "ln -s {$src_dir} {$plugin_dir}/pcp-addon" )->run_check();

// Activate the plugin.
$this->proc( 'wp plugin activate pcp-addon' )->run_check();
}

/**
* @When /^I (run|try) the WP-CLI command `([^`]+)`$/
Expand Down
85 changes: 85 additions & 0 deletions tests/behat/testdata/pcp-addon/Example_Runtime_Check.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?php

use WordPress\Plugin_Check\Checker\Check_Result;
use WordPress\Plugin_Check\Checker\Checks\Abstract_Runtime_Check;
use WordPress\Plugin_Check\Traits\Amend_Check_Result;
use WordPress\Plugin_Check\Traits\Stable_Check;
use WordPress\Plugin_Check\Traits\URL_Aware;

class Example_Runtime_Check extends Abstract_Runtime_Check {

use Amend_Check_Result;
use Stable_Check;
use URL_Aware;

public function get_categories() {
return array( 'new_category' );
}

public function prepare() {
$orig_scripts = isset( $GLOBALS['wp_scripts'] ) ? $GLOBALS['wp_scripts'] : null;

// Backup the original values for the global state.
$this->backup_globals();

return function () use ( $orig_scripts ) {
if ( is_null( $orig_scripts ) ) {
unset( $GLOBALS['wp_scripts'] );
} else {
$GLOBALS['wp_scripts'] = $orig_scripts;
}

$this->restore_globals();
};
}

public function run( Check_Result $result ) {
$this->run_for_urls(
array( home_url() ),
function ( $url ) use ( $result ) {
$this->check_url( $result, $url );
}
);
}

protected function check_url( Check_Result $result, $url ) {
// Reset the WP_Scripts instance.
unset( $GLOBALS['wp_scripts'] );

// Run the 'wp_enqueue_script' action, wrapped in an output buffer in case of any callbacks printing scripts
// directly. This is discouraged, but some plugins or themes are still doing it.
ob_start();
wp_enqueue_scripts();
wp_scripts()->do_head_items();
wp_scripts()->do_footer_items();
ob_end_clean();

foreach ( wp_scripts()->done as $handle ) {
$script = wp_scripts()->registered[ $handle ];

if ( strpos( $script->src, $result->plugin()->url() ) !== 0 ) {
continue;
}

$script_path = str_replace( $result->plugin()->url(), $result->plugin()->path(), $script->src );

$this->add_result_warning_for_file(
$result,
sprintf(
'Not allowed to enqueue scripts. Found script handle "%s"',
$handle
),
'ExampleRuntimeCheck.ForbiddenScript',
$script_path
);
}
}

public function get_description(): string {
return '';
}

public function get_documentation_url(): string {
return '';
}
}
41 changes: 41 additions & 0 deletions tests/behat/testdata/pcp-addon/Example_Static_Check.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

use WordPress\Plugin_Check\Checker\Check_Result;
use WordPress\Plugin_Check\Checker\Checks\Abstract_File_Check;
use WordPress\Plugin_Check\Traits\Amend_Check_Result;
use WordPress\Plugin_Check\Traits\Stable_Check;

class Example_Static_Check extends Abstract_File_Check {

use Amend_Check_Result;
use Stable_Check;

public function get_categories() {
return array( 'new_category' );
}

protected function check_files( Check_Result $result, array $files ) {
$php_files = self::filter_files_by_extension( $files, 'php' );
$file = self::file_preg_match( '#I\sam\sbad#', $php_files );
if ( $file ) {
$this->add_result_error_for_file(
$result,
__( 'Prohibited text found.', 'pcp-addon' ),
'prohibited_text_detected',
$file,
0,
0,
'',
8
);
}
}

public function get_description(): string {
return '';
}

public function get_documentation_url(): string {
return '';
}
}
35 changes: 35 additions & 0 deletions tests/behat/testdata/pcp-addon/pcp-addon.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php
/**
* Plugin Name: PCP Addon
* Plugin URI: https://example.com
* Description: Plugin Check addon.
* Version: 0.1.0
* Author: WordPress Performance Team
* Author URI: https://make.wordpress.org/performance/
* License: GPL-2.0+
* License URI: http://www.gnu.org/licenses/gpl-2.0.txt
* Requires Plugins: plugin-check
*/

add_filter(
'wp_plugin_check_categories',
function ( array $categories ) {
return array_merge( $categories, array( 'new_category' => esc_html__( 'New Category', 'pcp-addon' ) ) );
}
);

add_filter(
'wp_plugin_check_checks',
function ( array $checks ) {
require_once plugin_dir_path( __FILE__ ) . 'Example_Static_Check.php';
require_once plugin_dir_path( __FILE__ ) . 'Example_Runtime_Check.php';

return array_merge(
$checks,
array(
'example_static' => new Example_Static_Check(),
'example_runtime' => new Example_Runtime_Check(),
)
);
}
);
6 changes: 6 additions & 0 deletions tests/phpunit/tests/Checker/CLI_Runner_Tests.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,13 @@ public function tear_down() {
parent::tear_down();
}

/**
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function test_is_plugin_check_returns_true() {
define( 'WP_CLI', true );

$_SERVER['argv'] = array(
'wp',
'plugin',
Expand Down
Loading
Loading