From cd539eff38bc648aabe19a1a31fe6ac476da4775 Mon Sep 17 00:00:00 2001 From: Jordan Pakrosnis Date: Tue, 17 Sep 2024 14:22:33 -0700 Subject: [PATCH 1/3] Spin up Validate class and move REST API validation methods to it (static) --- .../core/classes/class-event-rest-api.php | 140 +-------------- includes/core/classes/class-validate.php | 160 ++++++++++++++++++ 2 files changed, 166 insertions(+), 134 deletions(-) create mode 100644 includes/core/classes/class-validate.php diff --git a/includes/core/classes/class-event-rest-api.php b/includes/core/classes/class-event-rest-api.php index 0d09b528b..c89732e26 100644 --- a/includes/core/classes/class-event-rest-api.php +++ b/includes/core/classes/class-event-rest-api.php @@ -122,7 +122,7 @@ protected function email_route(): array { 'args' => array( 'post_id' => array( 'required' => true, - 'validate_callback' => array( $this, 'validate_event_post_id' ), + 'validate_callback' => array( Validate::class, 'event_post_id' ), ), 'message' => array( 'required' => false, @@ -130,7 +130,7 @@ protected function email_route(): array { ), 'send' => array( 'required' => true, - 'validate_callback' => array( $this, 'validate_send' ), + 'validate_callback' => array( Validate::class, 'send' ), ), ), ), @@ -158,11 +158,11 @@ protected function rsvp_route(): array { 'args' => array( 'post_id' => array( 'required' => true, - 'validate_callback' => array( $this, 'validate_event_post_id' ), + 'validate_callback' => array( Validate::class, 'event_post_id' ), ), 'status' => array( 'required' => true, - 'validate_callback' => array( $this, 'validate_rsvp_status' ), + 'validate_callback' => array( Validate::class, 'rsvp_status' ), ), ), ), @@ -188,11 +188,11 @@ protected function events_list_route(): array { 'args' => array( 'event_list_type' => array( 'required' => true, - 'validate_callback' => array( $this, 'validate_event_list_type' ), + 'validate_callback' => array( Validate::class, 'event_list_type' ), ), 'max_number' => array( 'required' => true, - 'validate_callback' => array( $this, 'validate_number' ), + 'validate_callback' => array( Validate::class, 'number' ), ), 'datetime_format' => array( 'required' => false, @@ -205,134 +205,6 @@ protected function events_list_route(): array { ); } - /** - * Validate RSVP status. - * - * Validates whether a given parameter is a valid RSVP status. - * - * @since 1.0.0 - * - * @param string $param An RSVP status to validate. - * @return bool True if the parameter is a valid RSVP status, false otherwise. - */ - public function validate_rsvp_status( $param ): bool { - return in_array( - $param, - array( - 'attending', - 'waiting_list', - 'not_attending', - 'no_status', - ), - true - ); - } - - /** - * Validate Event Post ID. - * - * Validates whether a given parameter is a valid Event Post ID. - * - * @since 1.0.0 - * - * @param int|string $param A Post ID to validate. - * @return bool True if the parameter is a valid Event Post ID, false otherwise. - */ - public function validate_event_post_id( $param ): bool { - return ( - $this->validate_number( $param ) && - Event::POST_TYPE === get_post_type( $param ) - ); - } - - /** - * Validate recipients for sending emails. - * - * Validates an array of email recipient options to ensure they are correctly structured. - * - * @since 1.0.0 - * - * @param mixed $param An array of email recipients. - * @return bool True if the parameter is a valid array of email recipients, false otherwise. - */ - public function validate_send( $param ): bool { - $expected_params = array( 'all', 'attending', 'waiting_list', 'not_attending' ); - - if ( is_array( $param ) ) { - foreach ( $expected_params as $expected_param ) { - if ( - ! array_key_exists( $expected_param, $param ) || - ! is_bool( $param[ $expected_param ] ) - ) { - return false; - } - } - - return true; - } - - return false; - } - - /** - * Validate a numeric value. - * - * Validates whether the given parameter is a valid numeric value greater than zero. - * - * @since 1.0.0 - * - * @param int|string $param The value to validate. - * @return bool True if the parameter is a valid numeric value greater than zero, false otherwise. - */ - public function validate_number( $param ): bool { - return ( - 0 < intval( $param ) && - is_numeric( $param ) - ); - } - - /** - * Validate an event list type. - * - * Validates whether the given event list type parameter is valid (either 'upcoming' or 'past'). - * - * @since 1.0.0 - * - * @param string $param The event list type to validate. - * @return bool True if the parameter is a valid event list type, false otherwise. - */ - public function validate_event_list_type( string $param ): bool { - return in_array( $param, array( 'upcoming', 'past' ), true ); - } - - /** - * Validate a datetime string. - * - * Validates whether the given datetime string parameter is in the valid 'Y-m-d H:i:s' format. - * - * @since 1.0.0 - * - * @param string $param The datetime string to validate. - * @return bool True if the parameter is a valid datetime string, false otherwise. - */ - public function validate_datetime( string $param ): bool { - return (bool) \DateTime::createFromFormat( 'Y-m-d H:i:s', $param ); - } - - /** - * Validate a timezone identifier. - * - * Validates whether the given timezone identifier parameter is valid. - * - * @since 1.0.0 - * - * @param string $param The timezone identifier to validate. - * @return bool True if the parameter is a valid timezone identifier, false otherwise. - */ - public function validate_timezone( string $param ): bool { - return in_array( Utility::maybe_convert_utc_offset( $param ), Utility::list_timezone_and_utc_offsets(), true ); - } - /** * Send an event email notification to members. * diff --git a/includes/core/classes/class-validate.php b/includes/core/classes/class-validate.php new file mode 100644 index 000000000..69df81183 --- /dev/null +++ b/includes/core/classes/class-validate.php @@ -0,0 +1,160 @@ + Date: Tue, 17 Sep 2024 14:53:48 -0700 Subject: [PATCH 2/3] Migrate validation method coverage to its own PHPUnit test class --- .../classes/class-test-event-rest-api.php | 191 ---------------- .../core/classes/class-test-validate.php | 207 ++++++++++++++++++ 2 files changed, 207 insertions(+), 191 deletions(-) create mode 100644 test/unit/php/includes/core/classes/class-test-validate.php diff --git a/test/unit/php/includes/core/classes/class-test-event-rest-api.php b/test/unit/php/includes/core/classes/class-test-event-rest-api.php index 08c776e6b..d26f28b3b 100644 --- a/test/unit/php/includes/core/classes/class-test-event-rest-api.php +++ b/test/unit/php/includes/core/classes/class-test-event-rest-api.php @@ -129,197 +129,6 @@ public function test_get_event_routes(): void { ); } - /** - * Coverage for validate_rsvp_status method. - * - * @covers ::validate_rsvp_status - * - * @return void - */ - public function test_validate_rsvp_status(): void { - $instance = Event_Rest_Api::get_instance(); - - $this->assertTrue( - $instance->validate_rsvp_status( 'attending' ), - 'Failed to assert valid attendance status.' - ); - $this->assertTrue( - $instance->validate_rsvp_status( 'not_attending' ), - 'Failed to assert valid attendance status.' - ); - $this->assertTrue( - $instance->validate_rsvp_status( 'no_status' ), - 'Failed to assert valid attendance status.' - ); - $this->assertFalse( - $instance->validate_rsvp_status( 'wait_list' ), - 'Failed to assert invalid attendance status.' - ); - $this->assertFalse( - $instance->validate_rsvp_status( 'unit_test' ), - 'Failed to assert invalid attendance status.' - ); - } - - /** - * Data provider for validate_send test. - * - * @return array[] - */ - public function data_validate_send(): array { - return array( - array( - array( - 'all' => true, - 'attending' => false, - 'waiting_list' => false, - 'not_attending' => false, - ), - true, - ), - array( - array( - 'unit_test' => true, - ), - false, - ), - array( - null, - false, - ), - array( - 'unit-test', - false, - ), - array( - array( - 'all' => null, - 'attending' => false, - 'waiting_list' => false, - 'not_attending' => false, - ), - false, - ), - ); - } - - /** - * Coverage for validate_send method. - * - * @dataProvider data_validate_send - * - * @covers ::validate_send - * - * @param mixed $params The parameters to send for validation. - * @param bool $expects Expected response. - * - * @return void - */ - public function test_validate_send( $params, bool $expects ): void { - $instance = Event_Rest_Api::get_instance(); - - $this->assertSame( $expects, $instance->validate_send( $params ) ); - } - - /** - * Coverage for validate_event_post_id method. - * - * @covers ::validate_event_post_id - * @covers ::validate_number - * - * @return void - */ - public function test_validate_event_post_id(): void { - $instance = Event_Rest_Api::get_instance(); - $post = $this->mock->post()->get(); - $event = $this->mock->post( array( 'post_type' => Event::POST_TYPE ) )->get(); - - $this->assertFalse( - $instance->validate_event_post_id( -4 ), - 'Failed to assert invalid event post ID.' - ); - $this->assertFalse( - $instance->validate_event_post_id( 0 ), - 'Failed to assert invalid event post ID.' - ); - $this->assertFalse( - $instance->validate_event_post_id( 'unit-test' ), - 'Failed to assert invalid event post ID.' - ); - $this->assertFalse( - $instance->validate_event_post_id( $post->ID ), - 'Failed to assert invalid event post ID.' - ); - $this->assertTrue( - $instance->validate_event_post_id( $event->ID ), - 'Failed to assert valid event post ID.' - ); - } - - /** - * Coverage for validate_event_list_type method. - * - * @covers ::validate_event_list_type - * - * @return void - */ - public function test_validate_event_list_type(): void { - $instance = Event_Rest_Api::get_instance(); - - $this->assertTrue( - $instance->validate_event_list_type( 'upcoming' ), - 'Failed to assert valid event list type.' - ); - $this->assertTrue( - $instance->validate_event_list_type( 'past' ), - 'Failed to assert valid event list type.' - ); - $this->assertFalse( - $instance->validate_event_list_type( 'unit-test' ), - 'Failed to assert not a valid event list type.' - ); - } - - /** - * Coverage for validate_datetime method. - * - * @covers ::validate_datetime - * - * @return void - */ - public function test_validate_datetime(): void { - $instance = Event_Rest_Api::get_instance(); - - $this->assertFalse( - $instance->validate_datetime( 'unit-test' ), - 'Failed to assert invalid datetime.' - ); - $this->assertTrue( - $instance->validate_datetime( '2023-05-11 08:30:00' ), - 'Failed to assert valid datatime.' - ); - } - - /** - * Coverage for validate_timezone method. - * - * @covers ::validate_timezone - * - * @return void - */ - public function test_validate_timezone(): void { - $instance = Event_Rest_Api::get_instance(); - $this->assertFalse( - $instance->validate_timezone( 'unit-test' ), - 'Failed to assert invalid timezone.' - ); - - $this->assertTrue( - $instance->validate_timezone( 'America/New_York' ), - 'Failed to assert valid timezone.' - ); - } - /** * Coverage for email method. * diff --git a/test/unit/php/includes/core/classes/class-test-validate.php b/test/unit/php/includes/core/classes/class-test-validate.php new file mode 100644 index 000000000..94c300529 --- /dev/null +++ b/test/unit/php/includes/core/classes/class-test-validate.php @@ -0,0 +1,207 @@ +assertTrue( + Validate::rsvp_status( 'attending' ), + 'Failed to assert valid attendance status.' + ); + $this->assertTrue( + Validate::rsvp_status( 'not_attending' ), + 'Failed to assert valid attendance status.' + ); + $this->assertTrue( + Validate::rsvp_status( 'no_status' ), + 'Failed to assert valid attendance status.' + ); + $this->assertFalse( + Validate::rsvp_status( 'wait_list' ), + 'Failed to assert invalid attendance status.' + ); + $this->assertFalse( + Validate::rsvp_status( 'unit_test' ), + 'Failed to assert invalid attendance status.' + ); + } + + /** + * Data provider for send test. + * + * @return array[] + */ + public function data_send(): array { + return array( + array( + array( + 'all' => true, + 'attending' => false, + 'waiting_list' => false, + 'not_attending' => false, + ), + true, + ), + array( + array( + 'unit_test' => true, + ), + false, + ), + array( + null, + false, + ), + array( + 'unit-test', + false, + ), + array( + array( + 'all' => null, + 'attending' => false, + 'waiting_list' => false, + 'not_attending' => false, + ), + false, + ), + ); + } + + /** + * Coverage for send method. + * + * @dataProvider data_send + * + * @covers ::send + * + * @param mixed $params The parameters to send for validation. + * @param bool $expects Expected response. + * + * @return void + */ + public function test_send( $params, bool $expects ): void { + $this->assertSame( $expects, Validate::send( $params ) ); + } + + /** + * Coverage for event_post_id method. + * + * @covers ::event_post_id + * @covers ::number + * + * @return void + */ + public function test_event_post_id(): void { + $post = $this->mock->post()->get(); + $event = $this->mock->post( array( 'post_type' => Event::POST_TYPE ) )->get(); + + $this->assertFalse( + Validate::event_post_id( -4 ), + 'Failed to assert invalid event post ID.' + ); + $this->assertFalse( + Validate::event_post_id( 0 ), + 'Failed to assert invalid event post ID.' + ); + $this->assertFalse( + Validate::event_post_id( 'unit-test' ), + 'Failed to assert invalid event post ID.' + ); + $this->assertFalse( + Validate::event_post_id( $post->ID ), + 'Failed to assert invalid event post ID.' + ); + $this->assertTrue( + Validate::event_post_id( $event->ID ), + 'Failed to assert valid event post ID.' + ); + } + + /** + * Coverage for event_list_type method. + * + * @covers ::event_list_type + * + * @return void + */ + public function test_event_list_type(): void { + + $this->assertTrue( + Validate::event_list_type( 'upcoming' ), + 'Failed to assert valid event list type.' + ); + $this->assertTrue( + Validate::event_list_type( 'past' ), + 'Failed to assert valid event list type.' + ); + $this->assertFalse( + Validate::event_list_type( 'unit-test' ), + 'Failed to assert not a valid event list type.' + ); + } + + /** + * Coverage for datetime method. + * + * @covers ::datetime + * + * @return void + */ + public function test_datetime(): void { + + $this->assertFalse( + Validate::datetime( 'unit-test' ), + 'Failed to assert invalid datetime.' + ); + + $this->assertTrue( + Validate::datetime( '2023-05-11 08:30:00' ), + 'Failed to assert valid datatime.' + ); + } + + /** + * Coverage for timezone method. + * + * @covers ::timezone + * + * @return void + */ + public function test_timezone(): void { + + $this->assertFalse( + Validate::timezone( 'unit-test' ), + 'Failed to assert invalid timezone.' + ); + + $this->assertTrue( + Validate::timezone( 'America/New_York' ), + 'Failed to assert valid timezone.' + ); + } +} From de62a65110276d15646a825b49d61bf16085407e Mon Sep 17 00:00:00 2001 From: Jordan Pakrosnis Date: Tue, 17 Sep 2024 15:02:21 -0700 Subject: [PATCH 3/3] Remove some line breaks from Test_Validate methods --- test/unit/php/includes/core/classes/class-test-validate.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/test/unit/php/includes/core/classes/class-test-validate.php b/test/unit/php/includes/core/classes/class-test-validate.php index 94c300529..798c4816f 100644 --- a/test/unit/php/includes/core/classes/class-test-validate.php +++ b/test/unit/php/includes/core/classes/class-test-validate.php @@ -27,7 +27,6 @@ class Test_Validate extends Base { * @return void */ public function test_rsvp_status(): void { - $this->assertTrue( Validate::rsvp_status( 'attending' ), 'Failed to assert valid attendance status.' @@ -150,7 +149,6 @@ public function test_event_post_id(): void { * @return void */ public function test_event_list_type(): void { - $this->assertTrue( Validate::event_list_type( 'upcoming' ), 'Failed to assert valid event list type.' @@ -173,12 +171,10 @@ public function test_event_list_type(): void { * @return void */ public function test_datetime(): void { - $this->assertFalse( Validate::datetime( 'unit-test' ), 'Failed to assert invalid datetime.' ); - $this->assertTrue( Validate::datetime( '2023-05-11 08:30:00' ), 'Failed to assert valid datatime.' @@ -193,12 +189,10 @@ public function test_datetime(): void { * @return void */ public function test_timezone(): void { - $this->assertFalse( Validate::timezone( 'unit-test' ), 'Failed to assert invalid timezone.' ); - $this->assertTrue( Validate::timezone( 'America/New_York' ), 'Failed to assert valid timezone.'