diff --git a/inc/class-wp-revisions-control.php b/inc/class-wp-revisions-control.php index a78bb40dd59bcd1f8559732ca64d0f9f4ad48c95..ead01d01a1ce1882b836a94913399534351a6be3 100644 --- a/inc/class-wp-revisions-control.php +++ b/inc/class-wp-revisions-control.php @@ -505,10 +505,12 @@ class WP_Revisions_Control { * @return array */ private function get_settings() { - if ( empty( self::$settings ) ) { - $post_types = $this->get_post_types(); + static $hash = null; + + $settings = get_option( $this->settings_section, array() ); - $settings = get_option( $this->settings_section, array() ); + if ( empty( self::$settings ) || $hash !== $this->hash_settings( $settings ) ) { + $post_types = $this->get_post_types(); if ( ! is_array( $settings ) ) { $settings = array(); @@ -525,11 +527,23 @@ class WP_Revisions_Control { } self::$settings = $merged_settings; + $hash = $this->hash_settings( self::$settings ); } return self::$settings; } + /** + * Hash settings to limit re-parsing. + * + * @param array $settings Settings array. + * @return string + */ + private function hash_settings( $settings ) { + // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize + return md5( serialize( $settings ) ); + } + /** * Retrieve array of supported post types and their labels. * @@ -572,7 +586,7 @@ class WP_Revisions_Control { $_post = new WP_Post( (object) array( 'post_type' => $post_type ) ); $to_keep = wp_revisions_to_keep( $_post ); - if ( $blank_for_all && -1 === $to_keep ) { + if ( $blank_for_all && ( -1 === $to_keep || '-1' === $to_keep ) ) { return ''; } else { return (int) $to_keep; @@ -588,7 +602,7 @@ class WP_Revisions_Control { private function get_post_revisions_to_keep( $post_id ) { $to_keep = get_post_meta( $post_id, $this->meta_key_limit, true ); - if ( -1 === $to_keep || empty( $to_keep ) ) { + if ( empty( $to_keep ) || -1 === $to_keep || '-1' === $to_keep ) { $to_keep = ''; } else { $to_keep = (int) $to_keep; diff --git a/tests/bootstrap.php b/tests/bootstrap.php index bf3d9cf10eeabc2e477142d0a6714834e3d51512..1ed0283d6fa461d12676a99c6309d8449dea5cbe 100755 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -19,6 +19,13 @@ if ( ! file_exists( $_tests_dir . '/includes/functions.php' ) ) { // Give access to tests_add_filter() function. require_once $_tests_dir . '/includes/functions.php'; +/** + * Stub admin-only function not needed for testing. + */ +if ( ! function_exists( 'post_revisions_meta_box' ) ) { + function post_revisions_meta_box() {} +} + /** * Manually load the plugin being tested. */ diff --git a/tests/test-misc.php b/tests/test-misc.php new file mode 100755 index 0000000000000000000000000000000000000000..ec01dbb7b3c39255f6d06b043616eea66432795d --- /dev/null +++ b/tests/test-misc.php @@ -0,0 +1,48 @@ +<?php +/** + * Test miscellaneous methods. + * + * @package WP_Revisions_Control + */ + +/** + * Class TestMisc. + */ +class TestMisc extends WP_UnitTestCase { + /** + * Test settings sanitization. + */ + public function test_settings_sanitization() { + $input = array( + 'minus_ten' => -10, + 'minus_one' => -1, + 'zero' => 0, + 'one' => 1, + 'thirty' => 30, + 'empty_string' => '', + 'bool_false' => false, + 'bool_true' => true, + 'null' => null, + ); + + $expected = array( + 'minus_ten' => -1, + 'minus_one' => -1, + 'zero' => 0, + 'one' => 1, + 'thirty' => 30, + 'empty_string' => -1, + 'bool_false' => -1, + 'bool_true' => 1, + 'null' => -1, + ); + + $sanitized = WP_Revisions_Control::get_instance()->sanitize_options( $input ); + + $this->assertEquals( + $expected, + $sanitized, + 'Failed to assert that options were sanitized correctly.' + ); + } +} diff --git a/tests/test-purges.php b/tests/test-purges.php index 77f9386f4dfd3c3f58c88ea3bf2f45c72afaabed..3bfd4e84f7882e16e46874e4741b330d9e95b191 100755 --- a/tests/test-purges.php +++ b/tests/test-purges.php @@ -9,13 +9,6 @@ * Class TestPurges. */ class TestPurges extends WP_UnitTestCase { - /** - * Plugin slug used in many settings etc. - * - * @var string - */ - protected static $settings_section = 'wp_revisions_control'; - /** * Plugin's limit meta key. * diff --git a/tests/test-ui.php b/tests/test-ui.php new file mode 100755 index 0000000000000000000000000000000000000000..23688c1287ba0c2ee59133d64cf9fc714b0b4d89 --- /dev/null +++ b/tests/test-ui.php @@ -0,0 +1,188 @@ +<?php +/** + * Test UI methods. + * + * @package WP_Revisions_Control + */ + +/** + * Class TestUI. + */ +class TestUI extends WP_UnitTestCase { + /** + * Plugin slug used in many settings etc. + * + * @var string + */ + protected static $settings_section = 'wp_revisions_control'; + + /** + * Plugin's limit meta key. + * + * @var string + */ + protected static $meta_key = '_wp_rev_ctl_limit'; + + /** + * Test meta box with no meta set. + */ + public function test_no_meta() { + $post_id = $this->factory->post->create(); + + ob_start(); + WP_Revisions_Control::get_instance()->revisions_meta_box( get_post( $post_id ) ); + $meta_box = ob_get_clean(); + + $this->assertContains( + 'value=""', + $meta_box, + 'Failed to assert that meta box has no value when no setting exists.' + ); + } + + /** + * Test meta box with no limit set. + */ + public function test_no_limit() { + $post_id = $this->factory->post->create(); + update_post_meta( $post_id, static::$meta_key, -1 ); + + ob_start(); + WP_Revisions_Control::get_instance()->revisions_meta_box( get_post( $post_id ) ); + $meta_box = ob_get_clean(); + + $this->assertContains( + 'value=""', + $meta_box, + 'Failed to assert that meta box has no value when no limit exists.' + ); + } + + /** + * Test settings-field output when no options are set. + */ + public function test_settings_fields_no_options() { + ob_start(); + WP_Revisions_Control::get_instance()->field_post_type( array( 'post_type' => 'post' ) ); + $post_field = ob_get_clean(); + + ob_start(); + WP_Revisions_Control::get_instance()->field_post_type( array( 'post_type' => 'page' ) ); + $page_field = ob_get_clean(); + + $name_format = 'name="%1$s[%2$s]"'; + $value_format = 'value=""'; + + $this->assertContains( + sprintf( + $name_format, + static::$settings_section, + 'post' + ), + $post_field, + 'Failed to assert that post field had correct name for post type.' + ); + + $this->assertContains( + sprintf( + $name_format, + static::$settings_section, + 'page' + ), + $page_field, + 'Failed to assert that page field had correct name for post type.' + ); + + $this->assertContains( + $value_format, + $post_field, + 'Failed to assert that post field had correct value.' + ); + + $this->assertContains( + $value_format, + $page_field, + 'Failed to assert that page field had correct value.' + ); + } + + /** + * Test settings-field output when options are set. + */ + public function test_settings_fields_with_options() { + $value = 12; + + update_option( + static::$settings_section, + [ + 'post' => $value, + ] + ); + + ob_start(); + WP_Revisions_Control::get_instance()->field_post_type( array( 'post_type' => 'post' ) ); + $post_field = ob_get_clean(); + + $name_format = 'name="%1$s[%2$s]"'; + $value_format = 'value="%1$s"'; + + $this->assertContains( + sprintf( + $name_format, + static::$settings_section, + 'post' + ), + $post_field, + 'Failed to assert that post field had correct name for post type.' + ); + + $this->assertContains( + sprintf( + $value_format, + $value + ), + $post_field, + 'Failed to assert that post field had correct value.' + ); + } + + /** + * Test settings-field output when options are set. + */ + public function test_settings_fields_with_options_keep_all() { + $value = -1; + + update_option( + static::$settings_section, + [ + 'post' => $value, + ] + ); + + ob_start(); + WP_Revisions_Control::get_instance()->field_post_type( array( 'post_type' => 'post' ) ); + $post_field = ob_get_clean(); + + $name_format = 'name="%1$s[%2$s]"'; + $value_format = 'value=""'; + + $this->assertContains( + sprintf( + $name_format, + static::$settings_section, + 'post' + ), + $post_field, + 'Failed to assert that post field had correct name for post type.' + ); + + $this->assertContains( + sprintf( + $value_format, + $value + ), + $post_field, + 'Failed to assert that post field had correct value.' + ); + } +}