From edbc10419ddfee3aeff52e0abdcc6575178c5b18 Mon Sep 17 00:00:00 2001 From: Mohan Raj Date: Fri, 24 Mar 2023 16:25:56 +0000 Subject: [PATCH 1/2] adds phpunit tests --- .gitignore | 1 + composer.json | 2 +- helper/Helper.php | 7 -- includes/Api/{FlagOptions.php => Flags.php} | 61 +---------- includes/{FeatureFlags.php => Utils.php} | 6 +- phpunit.xml | 16 +++ plugin.php | 13 +-- tests/Unit/FlagsTest.php | 115 ++++++++++++++++++++ tests/Unit/HelperTest.php | 41 +++++++ tests/Unit/UtilsTest.php | 62 +++++++++++ tests/bootstrap.php | 4 + 11 files changed, 249 insertions(+), 79 deletions(-) rename includes/Api/{FlagOptions.php => Flags.php} (51%) rename includes/{FeatureFlags.php => Utils.php} (88%) create mode 100644 phpunit.xml create mode 100644 tests/Unit/FlagsTest.php create mode 100644 tests/Unit/HelperTest.php create mode 100644 tests/Unit/UtilsTest.php create mode 100644 tests/bootstrap.php diff --git a/.gitignore b/.gitignore index d3d035a..3064e04 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ node_modules build vendor yarn-error.log +.phpunit.result.cache diff --git a/composer.json b/composer.json index b6d97f8..03a4c59 100644 --- a/composer.json +++ b/composer.json @@ -28,6 +28,6 @@ "scripts": { "lint:php": "phpcs .", "lint:php-fix": "phpcbf .", - "test:php": "phpunit --dont-report-useless-tests --configuration ./phpunit.xml.dist" + "test:php": "phpunit --dont-report-useless-tests --configuration ./phpunit.xml --testdox" } } diff --git a/helper/Helper.php b/helper/Helper.php index c1f1a58..7e8415d 100644 --- a/helper/Helper.php +++ b/helper/Helper.php @@ -18,13 +18,6 @@ */ class Helper { - /** - * Name of flag environment. - * - * @var string $env_option_name - */ - public static $env_option_name = 'mr_feature_flags_env'; - /** * Flag search helper. * diff --git a/includes/Api/FlagOptions.php b/includes/Api/Flags.php similarity index 51% rename from includes/Api/FlagOptions.php rename to includes/Api/Flags.php index 86641e1..3b5d094 100644 --- a/includes/Api/FlagOptions.php +++ b/includes/Api/Flags.php @@ -16,7 +16,7 @@ * @package mr-feature-flags * @since 1.0.0 */ -class FlagOptions { +class Flags { /** * Name in options table. @@ -25,13 +25,6 @@ class FlagOptions { */ public static $option_name = 'mr_feature_flags'; - /** - * Name of flag environment. - * - * @var string $env_option_name - */ - public static $env_option_name = 'mr_feature_flags_env'; - /** * Register feature flag endpoints. * @@ -58,19 +51,6 @@ function () { ], ] ); - - register_rest_route( - 'feature-flags/v1', - 'flags/env', - [ - [ - 'methods' => \WP_REST_SERVER::READABLE, - 'callback' => [ $this, 'get_flag_env' ], - 'permission_callback' => '__return_true', - ], - ] - ); - } ); } @@ -114,43 +94,4 @@ public function post_flags( $request ) { } } - /** - * Get Feature Flag environment. - * - * @return mixed List of flags. - */ - public function get_flag_env() { - $env = get_option( self::$env_option_name ); - - if ( empty( $env ) ) { - return rest_ensure_response( [ 'env' => 'prod' ] ); - } - - return rest_ensure_response( $env ); - } - - /** - * Register settings action method. - * - * @return void - * @since 1.0.0 - */ - public function register_settings() { - - add_menu_page( - 'Feature Flags', - 'Feature Flags', - 'manage_options', - 'mr-feature-flags', - [ $this, 'render_page' ], - 'data:image/svg+xml;base64,' . base64_encode( '' ) - ); - } - - /** - * Render page - */ - public function render_page() { - echo '
'; - } } diff --git a/includes/FeatureFlags.php b/includes/Utils.php similarity index 88% rename from includes/FeatureFlags.php rename to includes/Utils.php index b121689..a1bbd91 100644 --- a/includes/FeatureFlags.php +++ b/includes/Utils.php @@ -1,6 +1,6 @@ + + + + ./tests/Unit/ + + + + diff --git a/plugin.php b/plugin.php index c557c75..91b819d 100644 --- a/plugin.php +++ b/plugin.php @@ -19,7 +19,7 @@ declare( strict_types = 1 ); namespace MR\FeatureFlags; -use MR\FeatureFlags\Api\FlagOptions; +use MR\FeatureFlags\Api\Flags; // If this file is called directly, abort. if ( ! defined( 'WPINC' ) ) { @@ -141,14 +141,14 @@ function(string $page): void { $mr_feature_flags_admin_settings = new Settings(); $mr_feature_flags_admin_settings->register_feature_settings(); -$mr_feature_flags_register_api = new FlagOptions(); +$mr_feature_flags_register_api = new Flags(); $mr_feature_flags_register_api->register_flags_endpoints(); add_filter( 'plugin_action_links_mr-feature-flags/plugin.php', function ( $links ) { - // Build and escape the URL. + $url = esc_url( add_query_arg( 'page', @@ -156,9 +156,9 @@ function(string $page): void { get_admin_url() . 'admin.php' ) ); - // Create the link. + $settings_link = "" . __( 'Settings', 'mr-feature-flags' ) . ''; - // Adds the link to the end of the array. + array_push( $links, $settings_link @@ -166,6 +166,3 @@ function(string $page): void { return $links; } ); - - -// update_option( 'mr_feature_flags', [ ["id" => 1, "name" => "login", "enabled" => false],["id" => 2, "name" => "Reg", "enabled" => false]] ); diff --git a/tests/Unit/FlagsTest.php b/tests/Unit/FlagsTest.php new file mode 100644 index 0000000..0baa764 --- /dev/null +++ b/tests/Unit/FlagsTest.php @@ -0,0 +1,115 @@ +1, 'name'=>'Test','enabled'=>true]]; + + \Brain\Monkey\Functions\when('get_option')->justReturn($mock_option_value); + \Brain\Monkey\Functions\when('rest_ensure_response')->returnArg(); + + $flags = new Flags(); + $result = $flags->get_all_flags(); + $this->assertEquals($result, $mock_option_value); + } + + public function test_get_all_flags_method_should_return_empty_array_if_value_is_not_set() { + $mock_option_value = ''; + + \Brain\Monkey\Functions\when('get_option')->justReturn($mock_option_value); + \Brain\Monkey\Functions\when('rest_ensure_response')->returnArg(); + + $flags = new Flags(); + $result = $flags->get_all_flags(); + $this->assertEquals($result, []); + } + + public function test_get_all_flags_method_should_return_multiple_flags_from_options_table() { + $mock_option_value = [['id'=>1, 'name'=>'Test','enabled'=>true],['id'=>2, 'name'=>'Test2','enabled'=>false]]; + + \Brain\Monkey\Functions\when('get_option')->justReturn($mock_option_value); + \Brain\Monkey\Functions\when('rest_ensure_response')->returnArg(); + + $flags = new Flags(); + $result = $flags->get_all_flags(); + $this->assertEquals($result, $mock_option_value); + } + + // public function test_post_flag_works() { + // $request = \Brain\Monkey\Functions\mock('WP_Request', [['id'=>1, 'name'=>'Test','enabled'=>true]]); + + // $mock_option_value = [['id'=>1, 'name'=>'Test','enabled'=>true]]; + // \Brain\Monkey\Functions\when('update_option')->justReturn($mock_option_value); + // \Brain\Monkey\Functions\when('rest_ensure_response')->returnArg(); + + // $flags = new Flags(); + // $result = $flags->post_flags($request); + // var_dump($result); + + // } + + // public function test_post_flags() { + // $request_data = array( 'flag1' => true, 'flag2' => false ); + // $request = \Brain\Monkey\Functions\mock( 'WP_REST_Request' ); + // $request->expects( 'get_json_params' )->once()->andReturn( $request_data ); + + // \Brain\Monkey\Functions\expect( 'update_option' ) + // ->once() + // ->with( self::$option_name, $request_data ) + // ->andReturn( true ); + + // $result = $this->obj->post_flags( $request ); + + // $this->assertInstanceOf( 'WP_REST_Response', $result ); + // $this->assertEquals( + // array( + // 'status' => 200, + // 'success' => true, + // ), + // ); + // } + + public function test_post_flags() { + // Set up mock request object with JSON data + $request_data = array( 'flag1' => true, 'flag2' => false ); + $request = new \stdClass(); + $request->set_body_params( $request_data ); + + // Mock the update_option function + $expected_option_name = 'my_option'; + $expected_option_value = $request_data; + \Brain\Monkey\Functions\expect( 'update_option' ) + ->once() + ->with( $expected_option_name, $expected_option_value ) + ->andReturn( true ); + + // Call the post_flags method with the mock request + $response = $this->obj->post_flags( $request ); + + // Check that the response is a WP_REST_Response object with expected data + $this->assertInstanceOf( 'WP_REST_Response', $response ); + $this->assertEquals( array( 'status' => 200, 'success' => true ), $response->get_data() ); + } +} diff --git a/tests/Unit/HelperTest.php b/tests/Unit/HelperTest.php new file mode 100644 index 0000000..e72f74a --- /dev/null +++ b/tests/Unit/HelperTest.php @@ -0,0 +1,41 @@ +1, 'name'=>'Test','enabled'=>true]],'name','Test'); + $this->assertTrue($result); + } + + public function test_search_flag_method_should_return_false_if_flags_are_empty() { + $result = Helper::search_flag([],'name','Test'); + $this->assertFalse($result); + } + + public function test_search_flag_method_should_return_false_if_flag_name_present_but_disabled() { + $result = Helper::search_flag([],'name','Test'); + $this->assertFalse($result); + } + + public function test_search_flag_method_should_return_false_if_flag_not_present() { + $result = Helper::search_flag([['id'=>1, 'name'=>'Test','enabled'=>true]],'name','Test1'); + $this->assertFalse($result); + } +} diff --git a/tests/Unit/UtilsTest.php b/tests/Unit/UtilsTest.php new file mode 100644 index 0000000..5a193f9 --- /dev/null +++ b/tests/Unit/UtilsTest.php @@ -0,0 +1,62 @@ +1, 'name'=>'Test','enabled'=>true]]; + + \Brain\Monkey\Functions\when('get_option')->justReturn($mock_option_value); + + $result = Utils::is_enabled('Test'); + $this->assertTrue($result); + } + + public function test_is_enabled_method_should_return_false_if_no_flags_exist() { + $mock_option_value = ''; + + \Brain\Monkey\Functions\when('get_option')->justReturn($mock_option_value); + + $result = Utils::is_enabled('Test'); + $this->assertFalse($result); + } + + public function test_is_enabled_method_should_return_false_if_flag_name_present_and_disabled() { + $mock_option_value = [['id'=>1, 'name'=>'Test','enabled'=>false]]; + + \Brain\Monkey\Functions\when('get_option')->justReturn($mock_option_value); + + $result = Utils::is_enabled('Test'); + $this->assertFalse($result); + } + + public function test_is_enabled_method_should_return_false_if_flag_name_nor_present() { + $mock_option_value = [['id'=>1, 'name'=>'Test','enabled'=>false]]; + + \Brain\Monkey\Functions\when('get_option')->justReturn($mock_option_value); + + $result = Utils::is_enabled('Test1'); + $this->assertFalse($result); + } + + +} diff --git a/tests/bootstrap.php b/tests/bootstrap.php new file mode 100644 index 0000000..f4f4f8b --- /dev/null +++ b/tests/bootstrap.php @@ -0,0 +1,4 @@ + Date: Sat, 25 Mar 2023 14:42:29 +0000 Subject: [PATCH 2/2] adds phpunit tests --- tests/Unit/FlagsTest.php | 100 ++++++++++++++++----------------------- tests/bootstrap.php | 4 +- 2 files changed, 45 insertions(+), 59 deletions(-) diff --git a/tests/Unit/FlagsTest.php b/tests/Unit/FlagsTest.php index 0baa764..1dd0db0 100644 --- a/tests/Unit/FlagsTest.php +++ b/tests/Unit/FlagsTest.php @@ -1,15 +1,12 @@ assertEquals($result, $mock_option_value); } - // public function test_post_flag_works() { - // $request = \Brain\Monkey\Functions\mock('WP_Request', [['id'=>1, 'name'=>'Test','enabled'=>true]]); - - // $mock_option_value = [['id'=>1, 'name'=>'Test','enabled'=>true]]; - // \Brain\Monkey\Functions\when('update_option')->justReturn($mock_option_value); - // \Brain\Monkey\Functions\when('rest_ensure_response')->returnArg(); - - // $flags = new Flags(); - // $result = $flags->post_flags($request); - // var_dump($result); - - // } - - // public function test_post_flags() { - // $request_data = array( 'flag1' => true, 'flag2' => false ); - // $request = \Brain\Monkey\Functions\mock( 'WP_REST_Request' ); - // $request->expects( 'get_json_params' )->once()->andReturn( $request_data ); - - // \Brain\Monkey\Functions\expect( 'update_option' ) - // ->once() - // ->with( self::$option_name, $request_data ) - // ->andReturn( true ); - - // $result = $this->obj->post_flags( $request ); - - // $this->assertInstanceOf( 'WP_REST_Response', $result ); - // $this->assertEquals( - // array( - // 'status' => 200, - // 'success' => true, - // ), - // ); - // } - - public function test_post_flags() { - // Set up mock request object with JSON data - $request_data = array( 'flag1' => true, 'flag2' => false ); - $request = new \stdClass(); - $request->set_body_params( $request_data ); - - // Mock the update_option function - $expected_option_name = 'my_option'; - $expected_option_value = $request_data; - \Brain\Monkey\Functions\expect( 'update_option' ) - ->once() - ->with( $expected_option_name, $expected_option_value ) - ->andReturn( true ); - - // Call the post_flags method with the mock request - $response = $this->obj->post_flags( $request ); - - // Check that the response is a WP_REST_Response object with expected data - $this->assertInstanceOf( 'WP_REST_Response', $response ); - $this->assertEquals( array( 'status' => 200, 'success' => true ), $response->get_data() ); - } + public function test_post_flags_methods_should_return_success_if_input_is_array() { + + $request_mock = \Mockery::mock('WP_Request'); + $request_mock->shouldReceive('get_json_params')->andReturn(['param1' => 'value1']); + + \Brain\Monkey\Functions\when('update_option')->justReturn(true); + \Brain\Monkey\Functions\when('rest_ensure_response')->returnArg(); + + global $wp; + $wp = new \stdClass(); + $wp->request = $request_mock; + + $flags = new Flags(); + $result = $flags->post_flags($request_mock); + + $this->assertEquals(['status'=>200, 'success' => true], $result); + + unset($GLOBALS['wp']); + } + + public function test_post_flags_methods_should_throw_error_if_input_is_not_an_array() { + + $request_mock = \Mockery::mock('WP_Request'); + $request_mock->shouldReceive('get_json_params')->andReturn('test'); + + global $wp; + $wp = new \stdClass(); + $wp->request = $request_mock; + + $error_mock = \Mockery::mock('WP_Error'); + + \Brain\Monkey\Functions\expect('post_flags')->andReturn($error_mock); + + + $flags = new Flags(); + $result = $flags->post_flags($request_mock); + + $this->assertInstanceOf('WP_Error', $result); + + } + + } diff --git a/tests/bootstrap.php b/tests/bootstrap.php index f4f4f8b..a04dd1b 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -1,4 +1,6 @@