From 4e80cbccfdbf983a28276559fd89f80d674052ab Mon Sep 17 00:00:00 2001 From: Akshit Sethi Date: Mon, 20 Jul 2020 16:32:24 +0530 Subject: [PATCH] Plugin updates (#15) * Update environment checks for the plugin * Separate css & js code from the plugin file * Update POT file * Updates tests * Increase tests coverage to 100% * CSS fix for mobile and re-genrated POT file * Added back assets to index.php and minute changes * Add support for litespeed * Update readme.txt file --- Makefile | 4 +- phpunit.xml | 3 + src/i18n/spiderblocker.pot | 127 +++--- src/inc/templates/settings.php | 134 ++++++ src/index.php | 736 +++++++++++++++++++-------------- src/readme.txt | 8 +- tests/BlockerTest.php | 439 +++++++++++++++----- tests/autoload.php | 21 +- 8 files changed, 991 insertions(+), 481 deletions(-) create mode 100644 src/inc/templates/settings.php diff --git a/Makefile b/Makefile index 4a42a87..36554c9 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -VERSION := 1.2.0 +VERSION := 1.2.5 PLUGINSLUG := spiderblocker SRCPATH := $(shell pwd)/src @@ -64,7 +64,7 @@ i18n: wp i18n make-pot src src/i18n/spiderblocker.pot cover: vendor - bin/coverage-check clover.xml 85 + bin/coverage-check clover.xml 100 clean: rm -rf vendor/ bin diff --git a/phpunit.xml b/phpunit.xml index b1ea9bf..7a87c5a 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -16,6 +16,9 @@ src + + src/inc/templates + diff --git a/src/i18n/spiderblocker.pot b/src/i18n/spiderblocker.pot index 4be8b83..b257aa5 100644 --- a/src/i18n/spiderblocker.pot +++ b/src/i18n/spiderblocker.pot @@ -9,13 +9,13 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"POT-Creation-Date: 2020-01-13T09:39:59+05:30\n" +"POT-Creation-Date: 2020-07-20T15:38:48+05:30\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"X-Generator: WP-CLI 2.3.0\n" +"X-Generator: WP-CLI 2.4.0\n" "X-Domain: spiderblocker\n" #. Plugin Name of the plugin -#: index.php:752 +#: inc/templates/settings.php:14 msgid "Spider Blocker" msgstr "" @@ -31,97 +31,116 @@ msgstr "" msgid "www.easyblognetworks.com" msgstr "" -#: index.php:41 -msgid "" -"This plugin requires PHP 5.6.0 or higher. Please contact your hosting provider about upgrading your\n" -"\t\t\tserver software. Your PHP version is" +#: inc/templates/settings.php:29 +msgid "Add New Bot" msgstr "" -#: index.php:374 -msgid "SpiderBlocker plugin has enabled blocking of some bots, please review settings by visiting" +#: inc/templates/settings.php:35 +#: inc/templates/settings.php:69 +#: inc/templates/settings.php:90 +msgid "User Agent" msgstr "" -#: index.php:374 -msgid "Setting page" +#: inc/templates/settings.php:39 +msgid "Bot Name" msgstr "" -#: index.php:399 -msgid "This plugin requires Apache2 server with mod_rewrite support. Please contact your hosting provider about upgrading your server software. Your Apache version is" +#: inc/templates/settings.php:44 +msgid "Bot Description URL" msgstr "" -#: index.php:413 -msgid "%1$s %2$s %3$s" +#: inc/templates/settings.php:52 +msgid "Add Bot" msgstr "" -#: index.php:414 -msgid "This plugin requires" +#: inc/templates/settings.php:57 +msgid "List of bots" msgstr "" -#: index.php:416 -msgid "file that is writable by the server. Please enable write access for file" +#: inc/templates/settings.php:60 +msgid "Filter..." msgstr "" -#: index.php:574 -msgid "Failed parsing JSON" +#: inc/templates/settings.php:73 +#: inc/templates/settings.php:94 +msgid "Name" msgstr "" -#: index.php:588 -msgid "Unable to process the request as no data has been received." +#: inc/templates/settings.php:77 +#: inc/templates/settings.php:98 +msgid "State" msgstr "" -#: index.php:766 -msgid "Add New Bot" +#: inc/templates/settings.php:81 +#: inc/templates/settings.php:102 +msgid "Action" msgstr "" -#: index.php:772 -#: index.php:800 -#: index.php:812 -msgid "User Agent" +#: inc/templates/settings.php:115 +msgid "Block" msgstr "" -#: index.php:776 -msgid "Bot Name" +#: inc/templates/settings.php:116 +msgid "Allow" msgstr "" -#: index.php:781 -msgid "Bot Description URL" +#: inc/templates/settings.php:117 +msgid "Remove" msgstr "" -#: index.php:788 -msgid "Add Bot" +#: inc/templates/settings.php:128 +msgid "Save" msgstr "" -#: index.php:791 -msgid "List of bots" +#: inc/templates/settings.php:129 +msgid "Reset to Defaults" msgstr "" -#: index.php:793 -msgid "Filter..." +#: inc/templates/settings.php:130 +msgid "Import/Export Definitions" msgstr "" -#: index.php:802 -#: index.php:813 -msgid "Name" +#: index.php:352 +msgid "%s requires Apache2 server with mod_rewrite support. Please contact your hosting provider about upgrading your server software." msgstr "" -#: index.php:804 -#: index.php:814 -msgid "State" +#: index.php:365 +msgid "%s requires .htaccess file that is writable by the server. Please enable write access for the file." msgstr "" -#: index.php:806 -#: index.php:816 -msgid "Action" +#: index.php:382 +msgid "%1$s requires WordPress version %2$s or higher. Please %3$supdate WordPress »%4$s" msgstr "" -#: index.php:841 -msgid "Save" +#: index.php:397 +msgid "%1$s plugin has enabled blocking of some bots, please review settings by visiting %2$sSettings page%3$s!" msgstr "" -#: index.php:842 -msgid "Reset to Defaults" +#: index.php:599 +#: index.php:604 +msgid "Unable to process the request as no data has been received." msgstr "" -#: index.php:843 -msgid "Import/Export Definitions" +#: index.php:611 +msgid "Failed parsing JSON data." +msgstr "" + +#: index.php:678 +msgid "List of bots was saved and new blocklist applied!" +msgstr "" + +#: index.php:679 +msgid "List of bots was reset to defaults!" +msgstr "" + +#: index.php:680 +msgid "Bot" +msgstr "" + +#: index.php:681 +msgid "was added!" +msgstr "" + +#: index.php:682 +msgid "Bot was removed!" msgstr "" diff --git a/src/inc/templates/settings.php b/src/inc/templates/settings.php new file mode 100644 index 0000000..6300b1e --- /dev/null +++ b/src/inc/templates/settings.php @@ -0,0 +1,134 @@ + + +
+

+
+ +
+
+
+

{{n.msg}} + + + +

+
+
+ +
+

+ +
+ + + + + + + + + + + + + + + + +
+
+ +

+ +

+
+ +
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + +
{{ bot.re }}{{ bot.name }} {{ bot.desc }} {{ bot.state?"Blocked":"Allowed" }} + + + +
+ + + +

+ + + +

+
+
+
diff --git a/src/index.php b/src/index.php index f362bb4..17a9b78 100644 --- a/src/index.php +++ b/src/index.php @@ -13,43 +13,6 @@ * Author URI: www.easyblognetworks.com */ -if ( ! function_exists( 'apache_get_version' ) ) { - /** - * Fetch the Apache version. - * - * @return string|false - */ - function apache_get_version() { - if ( stristr( $_ENV['SERVER_SOFTWARE'], 'Apache' ) ) { - return sanitize_text_field( $_ENV['SERVER_SOFTWARE'] ); - } - if ( stristr( $_SERVER['SERVER_SOFTWARE'], 'Apache' ) ) { - return sanitize_text_field( $_SERVER['SERVER_SOFTWARE'] ); - } - return false; - } -} - -/** - * Checks for PHP version and stop the plugin if the version is < 5.6.0. - */ -if ( version_compare( PHP_VERSION, '5.6.0', '<' ) ) { - ?> -
-

- -

-
- is_environment_compatible() ) { + return; } - // Filter for Robots file. - add_filter( 'robots_txt', array( &$this, 'robots_file' ), ~PHP_INT_MAX, 2 ); - add_action( 'generate_rewrite_rules', array( &$this, 'generate_rewrite_rules' ) ); + $this->deactivate_plugin(); + $this->add_admin_notice( 'bad_environment', 'error', $this->get_plugin_name() . ' has been deactivated. ' . $this->get_environment_message() ); + } + /** + * Checks for server and .htaccess write permissions. + */ + public function check_server() { + // Check Apache version + if ( ! $this->get_server_software( 'Apache' ) && ! $this->get_server_software( 'LiteSpeed' ) ) { + $this->deactivate_plugin(); + $this->add_admin_notice( + 'no_apache', + 'error', + sprintf( + esc_html__( '%s requires Apache2 or LiteSpeed server with mod_rewrite support. Please contact your hosting provider about upgrading your server software.', 'spiderblocker' ), + $this->get_plugin_name() + ) + ); + } + + // Write permission for .htaccess + if ( ! $this->is_htaccess_writable() || ! $this->chmod_htaccess() ) { + $this->deactivate_plugin(); + $this->add_admin_notice( + 'no_htaccess', + 'error', + sprintf( + esc_html__( '%s requires .htaccess file that is writable by the server. Please enable write access for the file.', 'spiderblocker' ), + $this->get_plugin_name() + ) + ); + } + } + + /** + * Adds notices for out-of-date WordPress and/or WooCommerce versions. + */ + public function add_plugin_notices() { + // Check for WP version + if ( ! $this->is_wp_compatible() ) { + $this->add_admin_notice( + 'update_wordpress', + 'error', + sprintf( + esc_html__( '%1$s requires WordPress version %2$s or higher. Please %3$supdate WordPress »%4$s', 'spiderblocker' ), + $this->get_plugin_name(), + $this->get_wp_version(), + '', + '' + ) + ); + } + + // Check for plugin activation + if ( $this->activate_plugin_notice() ) { + $this->add_admin_notice( + 'plugin_activated', + 'success', + sprintf( + esc_html__( '%1$s plugin has enabled blocking of some bots, please review settings by visiting %2$sSettings page%3$s!', 'spiderblocker' ), + $this->get_plugin_name(), + '', + '' + ) + ); + } + } + + /** + * Admin notice which gets fired on plugin activation. + */ + public function activate_plugin_notice() { + if ( get_option( self::OPTIONNAME, false ) ) { + return false; + } + + // Add option to DB and return true + update_option( self::OPTIONNAME, $this->default_bots ); + + return true; + } + + /** + * Displays any admin notices added with add_admin_notice() + */ + public function admin_notices() { + foreach ( (array) $this->notices as $notice_key => $notice ) { + echo '
'; + echo '

' . wp_kses( $notice['message'], array( 'a' => array( 'href' => array() ) ) ) . '

'; + echo '
'; + } + } + + /** + * Adds an admin notice to be displayed. + * + * @param string $slug the slug for the notice + * @param string $class the css class for the notice + * @param string $message the notice message + */ + private function add_admin_notice( $slug, $class, $message ) { + $this->notices[ $slug ] = array( + 'class' => $class, + 'message' => $message, + ); } /** @@ -337,9 +457,8 @@ public function generate_rewrite_rules( $wp_rewrite ) { * Fetch Plugin URL. * * @return string - * @codeCoverageIgnore */ - private function plugin_url() { + public function plugin_url() { $url = wp_make_link_relative( plugin_dir_url( __FILE__ ) ); $url = ltrim( $url, '/' ); @@ -361,22 +480,6 @@ public function admin_menu() { add_action( 'load-' . $menu, array( &$this, 'view_handler_load' ) ); } - /** - * Admin notice which gets fired on plugin activation. - * - * @codeCoverageIgnore - */ - public function activate_plugin_notice() { - if ( get_option( self::OPTIONNAME ) === false ) { - update_option( self::OPTIONNAME, $this->default_bots ); - ?> -
-

!

-
- -
-

-
- -
-

- .htaccess', - esc_html__( 'file that is writable by the server. Please enable write access for file', 'spiderblocker' ) - ); - ?> - .

-
- generate_block_rules(); - - } - - /** - * Check if the .htaccess file is writable. - * - * @return bool - * @codeCoverageIgnore - */ - private static function is_htaccess_writable() { - $htaccess_file = self::join_paths( ABSPATH, '.htaccess' ); - return is_writable( $htaccess_file ); - } - - /** - * Function to join the supplied arguments together. - * - * @return string - * @codeCoverageIgnore - */ - private static function join_paths() { - $paths = array(); - - foreach ( func_get_args() as $arg ) { - if ( '' !== $arg ) { - $paths[] = $arg; - } - } - - return preg_replace( '#/+#', '/', join( '/', $paths ) ); - } - - /** - * Change file permission of the .htaccess file. - * - * @param int $mod octet value for chmod. - * @return bool - * @codeCoverageIgnore - */ - private static function chmod_htaccess( $mod = 0644 ) { - $home_path = function_exists( 'get_home_path' ) ? get_home_path() : ABSPATH; - $htaccess_file = $home_path . '.htaccess'; - - return chmod( $htaccess_file, $mod ); } /** @@ -564,29 +594,34 @@ public function remove_block_rules() { */ public function save_list() { check_ajax_referer( self::NONCE, 'nonce' ); - if ( isset( $_POST['data'] ) && '' !== $_POST['data'] ) { - $data = json_decode( stripcslashes( $_POST['data'] ), true ); - - if ( json_last_error() ) { - if ( function_exists( 'json_last_error_msg' ) ) { - wp_send_json_error( json_last_error_msg() ); - } else { - wp_send_json_error( esc_html__( 'Failed parsing JSON', 'spiderblocker' ) ); - } - } - if ( get_option( self::OPTIONNAME ) !== false ) { - update_option( self::OPTIONNAME, maybe_serialize( $data ) ); - } else { - add_option( self::OPTIONNAME, maybe_serialize( $data ), '', 'no' ); - } + if ( ! isset( $_POST['data'] ) ) { + wp_send_json_error( esc_html__( 'Unable to process the request as no data has been received.', 'spiderblocker' ) ); + return; + } - $this->generate_block_rules(); - add_filter( 'robots_txt', array( &$this, 'robots_file' ), ~PHP_INT_MAX, 2 ); - wp_send_json_success( $this->get_bots() ); - } else { + if ( empty( $_POST['data'] ) ) { wp_send_json_error( esc_html__( 'Unable to process the request as no data has been received.', 'spiderblocker' ) ); + return; } + + $data = json_decode( stripcslashes( $_POST['data'] ), true ); + + if ( json_last_error() ) { + wp_send_json_error( esc_html__( 'Failed parsing JSON data.', 'spiderblocker' ) ); + return; + } + + update_option( self::OPTIONNAME, maybe_serialize( $data ), 'no' ); + + // Add rule to .htaccess file + $this->generate_block_rules(); + + // Update robots_txt file + add_filter( 'robots_txt', array( &$this, 'robots_file' ), ~PHP_INT_MAX, 2 ); + + // Send success response + wp_send_json_success( $this->get_bots() ); } /** @@ -618,28 +653,101 @@ public function robots_file( $output, $public ) { * @codeCoverageIgnore */ public function view_handler() { - ?> - + /** + * Adds action for admin scripts. + */ + public function view_handler_load() { + add_action( 'admin_enqueue_scripts', array( &$this, 'view_handler_scripts' ) ); + } + + /** + * Registers & Enqueues the admin scripts for the view_handler() function. + */ + public function view_handler_scripts() { + wp_enqueue_script( 'spiderblocker-admin', 'https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js', array( 'jquery' ), self::PLUGIN_VERSION, false ); + + $localize = array( + 'nonce' => wp_create_nonce( self::NONCE ), + 'save_text' => esc_html__( 'List of bots was saved and new blocklist applied!', 'spiderblocker' ), + 'save_reset_text' => esc_html__( 'List of bots was reset to defaults!', 'spiderblocker' ), + 'bot_text' => esc_html__( 'Bot', 'spiderblocker' ), + 'added_text' => esc_html__( 'was added!', 'spiderblocker' ), + 'removed_text' => esc_html__( 'Bot was removed!', 'spiderblocker' ), + ); + + // Pass data to JS + wp_localize_script( 'spiderblocker-admin', 'sb_i18n', $localize ); + + wp_enqueue_script( 'thickbox' ); + wp_enqueue_style( 'thickbox' ); + } + + /** + * CSS for settings panel. + * + * @codeCoverageIgnore + */ + public function admin_css() { + ?> + + - window.sb_nonce = ""; + /** + * JS for settings panel. + * + * @codeCoverageIgnore + */ + public function admin_js() { + ?> + -

-
-
-
-
-

{{n.msg}} - - - -

-
-
- -
-

- -
- - - - - - - - - - - - - - - - -
-
- -

-
- -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
-
{{ bot.re }}{{ bot.name }} {{ bot.desc }} {{ bot.state?"Blocked":"Allowed" }} - - - -
- - - -

- - - -

-
-
get_php_version(), '>=' ); } /** - * Registers & Enqueues the admin scripts for the view_handler() function. + * Gets the message for display when the environment is incompatible with this plugin. + * + * @return string */ - public function view_handler_scripts() { - wp_register_script( 'spiderblocker-angular', 'https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js', array( 'jquery' ), '1.0.18', false ); - wp_enqueue_script( 'spiderblocker-angular' ); + public function get_environment_message() { + return sprintf( + esc_html__( 'The minimum PHP version required for this plugin is %1$s. You are running %2$s.', 'eu-vat-b2b-taxes' ), + $this->get_php_version(), + PHP_VERSION + ); + } - wp_enqueue_script( 'thickbox' ); - wp_enqueue_style( 'thickbox' ); + /** + * Determines if the WordPress compatible. + * + * @return bool + */ + public function is_wp_compatible() { + if ( ! $this->get_wp_version() ) { + return true; + } + + return version_compare( get_bloginfo( 'version' ), $this->get_wp_version(), '>=' ); + } + + /** + * Returns PLUGIN_NAME. + */ + public function get_plugin_name() { + return self::PLUGIN_NAME; + } + + /** + * Returns PLUGIN_BASE. + */ + public function get_plugin_base() { + return self::PLUGIN_BASE; + } + + /** + * Returns MINIMUM_PHP_VERSION. + */ + public function get_php_version() { + return self::MINIMUM_PHP_VERSION; + } + + /** + * Returns MINIMUM_WP_VERSION. + */ + public function get_wp_version() { + return self::MINIMUM_WP_VERSION; + } + + /** + * Fetch the Apache version. + * + * @return string|false + */ + public function get_server_software( $server ) { + // Check Apache + if ( stristr( $_ENV['SERVER_SOFTWARE'], $server ) ) { + return sanitize_text_field( $_ENV['SERVER_SOFTWARE'] ); + } + + if ( stristr( $_SERVER['SERVER_SOFTWARE'], $server ) ) { + return sanitize_text_field( $_SERVER['SERVER_SOFTWARE'] ); + } + + return false; + } + + /** + * Deactivates the plugin. + */ + protected function deactivate_plugin() { + deactivate_plugins( $this->get_plugin_base() ); + + if ( isset( $_GET['activate'] ) ) { + unset( $_GET['activate'] ); + } + } + + /** + * Change file permission of the .htaccess file. + * + * @param int $mod octet value for chmod. + * @return bool + * @codeCoverageIgnore + */ + protected function chmod_htaccess( $mod = 0644 ) { + $home_path = function_exists( 'get_home_path' ) ? get_home_path() : ABSPATH; + $htaccess_file = $home_path . '.htaccess'; + + return chmod( $htaccess_file, $mod ); + } + + /** + * Check if the .htaccess file is writable. + * + * @return bool + * @codeCoverageIgnore + */ + protected function is_htaccess_writable() { + $htaccess_file = self::join_paths( ABSPATH, '.htaccess' ); + return is_writable( $htaccess_file ); + } + + /** + * Function to join the supplied arguments together. + * + * @return string + * @codeCoverageIgnore + */ + private static function join_paths() { + $paths = array(); + + foreach ( func_get_args() as $arg ) { + if ( '' !== $arg ) { + $paths[] = $arg; + } + } + + return preg_replace( '#/+#', '/', join( '/', $paths ) ); } } -// Initialize Plugin. +// Initlaize if called from within WordPress if ( defined( 'ABSPATH' ) ) { - $niteo_spider_blocker = new SpiderBlocker(); - - add_action( 'upgrader_process_complete', array( &$niteo_spider_blocker, 'on_plugin_upgrade' ), 10, 2 ); + $spiderblocker = new SpiderBlocker(); - // Activation Hook. - register_activation_hook( __FILE__, array( &$niteo_spider_blocker, 'activate_plugin' ) ); + // Register hooks + add_action( 'upgrader_process_complete', array( $spiderblocker, 'on_plugin_upgrade' ), 10, 2 ); - // Deactivation Hook. - register_deactivation_hook( __FILE__, array( &$niteo_spider_blocker, 'remove_block_rules' ) ); + // Runs on plugin activation & de-activation + register_activation_hook( __FILE__, array( $spiderblocker, 'activate_plugin' ) ); + register_deactivation_hook( __FILE__, array( $spiderblocker, 'remove_block_rules' ) ); } diff --git a/src/readme.txt b/src/readme.txt index a89352d..e30e298 100644 --- a/src/readme.txt +++ b/src/readme.txt @@ -2,8 +2,8 @@ Contributors: niteoweb Tags: seo, block, bots, htaccess, apache, secure Requires at least: 4.0 -Tested up to: 5.3.2 -Stable tag: 1.2.0 +Tested up to: 5.4.2 +Stable tag: 1.2.5 SpiderBlocker will block most common bots that consume bandwidth and slow down your server. @@ -32,6 +32,10 @@ with Apache server and mod_rewrite enabled. == Changelog == += v1.2.5 = +- Visual fixes and code clean-up +- Added support for LiteSpeed server + = v1.2.0 = - Code clean-up - Support for the latest version of WordPress diff --git a/tests/BlockerTest.php b/tests/BlockerTest.php index 407b78f..347bf42 100644 --- a/tests/BlockerTest.php +++ b/tests/BlockerTest.php @@ -13,6 +13,7 @@ function tearDown() { $this->addToAssertionCount( \Mockery::getContainer()->mockery_getExpectationCount() ); + \WP_Mock::tearDown(); \Mockery::close(); } @@ -20,72 +21,222 @@ function tearDown() { /** * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::__construct */ - public function testInitAdmin() { - \WP_Mock::wpFunction( - 'is_admin', - array( - 'return' => true, - ) - ); - - \WP_Mock::wpFunction( - 'wp_next_scheduled', - array( - 'return' => true, - ) - ); - + public function testConstructor() { $plugin = new SpiderBlocker(); + \WP_Mock::expectFilterAdded( 'robots_txt', array( $plugin, 'robots_file' ), ~PHP_INT_MAX, 2 ); + + \WP_Mock::expectActionAdded( 'admin_init', array( $plugin, 'check_environment' ) ); + \WP_Mock::expectActionAdded( 'admin_init', array( $plugin, 'check_server' ) ); + \WP_Mock::expectActionAdded( 'admin_init', array( $plugin, 'add_plugin_notices' ) ); + \WP_Mock::expectActionAdded( 'admin_notices', array( $plugin, 'admin_notices' ), 15 ); \WP_Mock::expectActionAdded( 'admin_menu', array( $plugin, 'admin_menu' ) ); \WP_Mock::expectActionAdded( 'wp_ajax_NSB-get_list', array( $plugin, 'load_list' ) ); \WP_Mock::expectActionAdded( 'wp_ajax_NSB-set_list', array( $plugin, 'save_list' ) ); \WP_Mock::expectActionAdded( 'wp_ajax_NSB-reset_list', array( $plugin, 'reset_list' ) ); - \WP_Mock::expectFilterAdded( 'robots_txt', array( $plugin, 'robots_file' ), ~PHP_INT_MAX, 2 ); \WP_Mock::expectActionAdded( 'generate_rewrite_rules', array( $plugin, 'generate_rewrite_rules' ) ); $plugin->__construct(); \WP_Mock::assertHooksAdded(); } + /** + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::__construct + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::check_environment + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::is_environment_compatible + */ + public function testCheckEnvironmentEmpty() { + $mock = \Mockery::mock( '\Niteoweb\SpiderBlocker\SpiderBlocker' )->makePartial(); + $mock->shouldReceive( 'is_environment_compatible' )->andReturn( true ); + + $this->assertEmpty( $mock->check_environment() ); + } /** * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::__construct + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::check_environment + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::is_environment_compatible + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::deactivate_plugin + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::add_admin_notice + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::get_environment_message + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::get_php_version + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::get_plugin_name + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::get_plugin_base */ - public function testInitNonAdmin() { - \WP_Mock::wpFunction( - 'is_admin', + public function testCheckEnvironment() { + $mock = \Mockery::mock( '\Niteoweb\SpiderBlocker\SpiderBlocker' )->makePartial(); + $mock->shouldReceive( 'is_environment_compatible' )->andReturn( false ); + + $_GET['activate'] = 'yes'; + + \WP_Mock::userFunction( + 'is_plugin_active', array( 'return' => true, ) ); - \WP_Mock::wpFunction( - 'wp_next_scheduled', + \WP_Mock::userFunction( + 'deactivate_plugins', array( 'return' => true, ) ); - $plugin = new SpiderBlocker(); + $mock->check_environment(); + } - \WP_Mock::expectActionAdded( 'generate_rewrite_rules', array( $plugin, 'generate_rewrite_rules' ) ); + /** + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::__construct + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::check_server + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::deactivate_plugin + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::add_admin_notice + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::get_plugin_base + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::get_plugin_name + */ + public function testCheckServer() { + $mock = \Mockery::mock( '\Niteoweb\SpiderBlocker\SpiderBlocker' )->makePartial(); + $mock->shouldAllowMockingProtectedMethods(); + $mock->shouldReceive( 'get_server_software', 'is_htaccess_writable' )->andReturn( false ); - $plugin->__construct(); - \WP_Mock::assertHooksAdded(); + $mock->check_server(); } + /** + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::__construct + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::add_plugin_notices + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::is_wp_compatible + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::add_admin_notice + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::get_plugin_name + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::get_wp_version + */ + public function testAddPluginNotices() { + $mock = \Mockery::mock( '\Niteoweb\SpiderBlocker\SpiderBlocker' )->makePartial(); + $mock->shouldReceive( 'activate_plugin_notice' )->andReturn( true ); + + \WP_Mock::userFunction( + 'get_bloginfo', + array( + 'return' => '4.0', + ) + ); + \WP_Mock::userFunction( + 'admin_url', + array( + 'return' => true, + ) + ); + \WP_Mock::userFunction( + 'esc_url', + array( + 'return' => '#', + ) + ); + + $mock->add_plugin_notices(); + } /** * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::__construct - * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::admin_menu + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::activate_plugin_notice */ - public function testAdminMenu() { - \WP_Mock::wpFunction( - 'wp_next_scheduled', + public function testActivatePluginNoticeFalse() { + $plugin = new SpiderBlocker(); + + \WP_Mock::userFunction( + 'get_option', + array( + 'return' => true, + ) + ); + + $this->assertFalse( $plugin->activate_plugin_notice() ); + } + + /** + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::__construct + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::activate_plugin_notice + */ + public function testActivatePluginNoticeTrue() { + $plugin = new SpiderBlocker(); + + \WP_Mock::userFunction( + 'get_option', + array( + 'return' => false, + ) + ); + \WP_Mock::userFunction( + 'update_option', array( 'return' => true, ) ); + + $this->assertTrue( $plugin->activate_plugin_notice() ); + } + + /** + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::__construct + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::admin_notices + */ + public function testAdminNotices() { + $plugin = new SpiderBlocker(); + $plugin->notices = array( + 'notice1' => array( + 'class' => 'class1', + 'message' => 'message1', + ), + ); + + \WP_Mock::userFunction( + 'wp_kses', + array( + 'return' => 'message1', + ) + ); + + $this->expectOutputString( '

message1

' ); + $plugin->admin_notices(); + } + + /** + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::__construct + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::is_wp_compatible + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::get_wp_version + */ + public function testIsWpCompatible() { + $mock = \Mockery::mock( '\Niteoweb\SpiderBlocker\SpiderBlocker' )->makePartial(); + $mock->shouldReceive( 'get_wp_version' )->andReturn( false ); + $this->assertTrue( $mock->is_wp_compatible() ); + } + + /** + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::__construct + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::is_environment_compatible + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::get_php_version + */ + public function testEnvironmentCompatibleTrue() { + $mock = \Mockery::mock( '\Niteoweb\SpiderBlocker\SpiderBlocker' )->makePartial(); + $mock->shouldReceive( 'get_php_version' )->andReturn( '1.0' ); + $this->assertTrue( $mock->is_environment_compatible() ); + } + + /** + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::__construct + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::is_environment_compatible + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::get_php_version + */ + public function testEnvironmentCompatibleFalse() { + $mock = \Mockery::mock( '\Niteoweb\SpiderBlocker\SpiderBlocker' )->makePartial(); + $mock->shouldReceive( 'get_php_version' )->andReturn( '100.0' ); + $this->assertFalse( $mock->is_environment_compatible() ); + } + + /** + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::__construct + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::admin_menu + */ + public function testAdminMenu() { \WP_Mock::wpFunction( 'add_management_page', array( @@ -98,20 +249,14 @@ public function testAdminMenu() { $plugin->admin_menu(); } - /** * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::__construct * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::generate_rewrite_rules + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::plugin_url */ public function testGenerateRewriteRules() { global $wp_rewrite; - \WP_Mock::wpFunction( - 'wp_next_scheduled', - array( - 'return' => true, - ) - ); \WP_Mock::wpFunction( 'wp_make_link_relative', array( @@ -150,6 +295,31 @@ public function testGenerateRewriteRules() { $plugin->generate_rewrite_rules( $wp_rewrite ); } + /** + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::__construct + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::plugin_url + */ + public function testPluginUrl() { + $plugin = new SpiderBlocker(); + + \WP_Mock::userFunction( + 'plugin_dir_url', + array( + 'return' => 'https://plugin-url.com/', + ) + ); + \WP_Mock::userFunction( + 'wp_make_link_relative', + array( + 'return' => 'https://plugin-url.com/', + ) + ); + + $this->assertEquals( + 'https://plugin-url.com/', + $plugin->plugin_url() + ); + } /** * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::__construct @@ -160,12 +330,6 @@ public function testGenerateRewriteRules() { public function testRulesGeneration() { global $wp_rewrite; - \WP_Mock::wpFunction( - 'wp_next_scheduled', - array( - 'return' => true, - ) - ); $wp_rewrite = \Mockery::mock(); $wp_rewrite->shouldReceive( 'flush_rules' )->once(); @@ -217,7 +381,8 @@ public function testRulesGeneration() { ), ), false - ) + ), + true ), ) ); @@ -245,19 +410,12 @@ public function testRulesGeneration() { ); } - /** * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::__construct * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::get_bots * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::load_list */ public function testAjaxGetList() { - \WP_Mock::wpFunction( - 'wp_next_scheduled', - array( - 'return' => true, - ) - ); $plugin = new SpiderBlocker(); \WP_Mock::wpFunction( @@ -309,7 +467,6 @@ public function testAjaxGetList() { $plugin->load_list(); } - /** * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::__construct * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::generate_block_rules @@ -317,12 +474,6 @@ public function testAjaxGetList() { * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::reset_list */ public function testAjaxResetList() { - \WP_Mock::wpFunction( - 'wp_next_scheduled', - array( - 'return' => true, - ) - ); $plugin = new SpiderBlocker(); \WP_Mock::wpFunction( @@ -377,20 +528,49 @@ public function testAjaxResetList() { $plugin->reset_list(); } + /** + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::__construct + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::save_list + */ + public function testAjaxSaveListNoData() { + $plugin = new SpiderBlocker(); + + \WP_Mock::userFunction( + 'wp_send_json_error', + array( + 'return' => true, + ) + ); + + $this->assertEmpty( $plugin->save_list() ); + } /** * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::__construct - * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::generate_block_rules - * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::get_bots * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::save_list */ - public function testAjaxSaveList() { - \WP_Mock::wpFunction( - 'wp_next_scheduled', + public function testAjaxSaveListEmptyData() { + $plugin = new SpiderBlocker(); + + $_POST['data'] = ''; + + \WP_Mock::userFunction( + 'wp_send_json_error', array( 'return' => true, ) ); + + $this->assertEmpty( $plugin->save_list() ); + } + + /** + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::__construct + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::generate_block_rules + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::get_bots + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::save_list + */ + public function testAjaxSaveList() { $plugin = new SpiderBlocker(); \WP_Mock::wpFunction( @@ -477,7 +657,6 @@ public function testAjaxSaveList() { $plugin->save_list(); } - /** * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::__construct * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::generate_block_rules @@ -485,12 +664,6 @@ public function testAjaxSaveList() { * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::save_list */ public function testAjaxUpdateList() { - \WP_Mock::wpFunction( - 'wp_next_scheduled', - array( - 'return' => true, - ) - ); $plugin = new SpiderBlocker(); \WP_Mock::wpFunction( @@ -571,10 +744,10 @@ public function testAjaxUpdateList() { ); \WP_Mock::wpFunction( - 'add_option', + 'update_option', array( 'called' => 1, - 'args' => array( 'Niteoweb.SpiderBlocker.Bots', '', '', 'no' ), + 'args' => array( 'Niteoweb.SpiderBlocker.Bots', '', 'no' ), ) ); @@ -583,7 +756,6 @@ public function testAjaxUpdateList() { $plugin->save_list(); } - /** * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::__construct * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::generate_block_rules @@ -591,12 +763,6 @@ public function testAjaxUpdateList() { * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::save_list */ public function testAjaxUpdateListInvalid() { - \WP_Mock::wpFunction( - 'wp_next_scheduled', - array( - 'return' => true, - ) - ); $plugin = new SpiderBlocker(); \WP_Mock::wpFunction( @@ -622,18 +788,11 @@ public function testAjaxUpdateListInvalid() { $plugin->save_list(); } - /** * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::__construct * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::generate_block_rules */ public function testSkipRulesGeneration() { - \WP_Mock::wpFunction( - 'wp_next_scheduled', - array( - 'return' => true, - ) - ); $plugin = new SpiderBlocker(); \WP_Mock::wpFunction( @@ -646,7 +805,6 @@ public function testSkipRulesGeneration() { $plugin->generate_block_rules(); } - /** * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::__construct * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::remove_block_rules @@ -654,12 +812,6 @@ public function testSkipRulesGeneration() { public function testRemoveRulesGeneration() { global $wp_rewrite; - \WP_Mock::wpFunction( - 'wp_next_scheduled', - array( - 'return' => true, - ) - ); $wp_rewrite = \Mockery::mock(); $wp_rewrite->shouldReceive( 'flush_rules' )->once(); @@ -726,20 +878,12 @@ public function testRemoveRulesGeneration() { $plugin->remove_block_rules(); } - /** * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::__construct * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::get_bots * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::robots_file */ public function testRobotsFilter() { - \WP_Mock::wpFunction( - 'wp_next_scheduled', - array( - 'return' => true, - ) - ); - $plugin = new SpiderBlocker(); \WP_Mock::wpFunction( @@ -783,23 +927,108 @@ public function testRobotsFilter() { ); } - /** * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::__construct * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::view_handler_load */ public function testViewHandlerLoad() { - \WP_Mock::wpFunction( - 'wp_next_scheduled', + $plugin = new SpiderBlocker(); + + \WP_Mock::expectActionAdded( 'admin_enqueue_scripts', array( $plugin, 'view_handler_scripts' ) ); + $plugin->view_handler_load(); + } + + /** + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::__construct + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::view_handler_scripts + */ + public function testViewHandlerScripts() { + $plugin = new SpiderBlocker(); + + \WP_Mock::userFunction( + 'wp_enqueue_script', array( 'return' => true, ) ); + \WP_Mock::userFunction( + 'wp_enqueue_style', + array( + 'return' => true, + ) + ); + \WP_Mock::userFunction( + 'wp_localize_script', + array( + 'return' => true, + ) + ); + \WP_Mock::userFunction( + 'wp_create_nonce', + array( + 'return' => true, + ) + ); + + $plugin->view_handler_scripts(); + } + + /** + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::__construct + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::get_server_software + */ + public function testGetServerSoftwareEnv() { + $plugin = new SpiderBlocker(); + + $_ENV['SERVER_SOFTWARE'] = 'Apache'; + + \WP_Mock::userFunction( + 'sanitize_text_field', + array( + 'return' => 'Apache', + ) + ); + + $this->assertEquals( + 'Apache', + $plugin->get_server_software( 'Apache' ) + ); + } + /** + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::__construct + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::get_server_software + */ + public function testGetServerSoftwareServer() { $plugin = new SpiderBlocker(); - \WP_Mock::expectActionAdded( 'admin_enqueue_scripts', array( $plugin, 'view_handler_scripts' ) ); - $plugin->view_handler_load(); + $_ENV['SERVER_SOFTWARE'] = ''; + $_SERVER['SERVER_SOFTWARE'] = 'Apache'; + + \WP_Mock::userFunction( + 'sanitize_text_field', + array( + 'return' => 'Apache', + ) + ); + + $this->assertEquals( + 'Apache', + $plugin->get_server_software( 'Apache' ) + ); + } + + /** + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::__construct + * @covers \Niteoweb\SpiderBlocker\SpiderBlocker::get_server_software + */ + public function testGetServerSoftwareFalse() { + $plugin = new SpiderBlocker(); + + $_ENV['SERVER_SOFTWARE'] = ''; + $_SERVER['SERVER_SOFTWARE'] = ''; + + $this->assertFalse( $plugin->get_server_software( 'Apache' ) ); } } diff --git a/tests/autoload.php b/tests/autoload.php index 4ebb1b2..85f45a4 100644 --- a/tests/autoload.php +++ b/tests/autoload.php @@ -1,19 +1,10 @@