diff --git a/build/admin_style.asset.php b/build/admin_style.asset.php index 87d61e23..bf697a15 100644 --- a/build/admin_style.asset.php +++ b/build/admin_style.asset.php @@ -1 +1 @@ - array(), 'version' => '95d396adaa06c1b8356f'); + array(), 'version' => 'e113ae6fddb179ebc2fc'); diff --git a/includes/core/classes/class-event.php b/includes/core/classes/class-event.php index 8587fa15..063479ea 100644 --- a/includes/core/classes/class-event.php +++ b/includes/core/classes/class-event.php @@ -329,7 +329,7 @@ public function get_datetime(): array { $data = get_transient( $cache_key ); if ( empty( $data ) || ! is_array( $data ) ) { - $table = sprintf( static::TABLE_FORMAT, $wpdb->prefix ); + $table = sprintf( self::TABLE_FORMAT, $wpdb->prefix ); $data = (array) $wpdb->get_results( $wpdb->prepare( 'SELECT datetime_start, datetime_start_gmt, datetime_end, datetime_end_gmt, timezone FROM %i WHERE post_id = %d LIMIT 1', $table, $this->event->ID ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQLPlaceholders.UnsupportedIdentifierPlaceholder $data = ( ! empty( $data ) ) ? (array) current( $data ) : array(); @@ -721,11 +721,11 @@ public function maybe_get_online_event_link(): string { return ''; } - $user = $this->rsvp->get( get_current_user_id() ); + $response = $this->rsvp->get( get_current_user_id() ); if ( - ! isset( $user['status'] ) || - 'attending' !== $user['status'] || + ! isset( $response['status'] ) || + 'attending' !== $response['status'] || $this->has_event_past() ) { return ''; diff --git a/includes/core/classes/class-rsvp-query.php b/includes/core/classes/class-rsvp-query.php new file mode 100644 index 00000000..974bf3c2 --- /dev/null +++ b/includes/core/classes/class-rsvp-query.php @@ -0,0 +1,184 @@ +setup_hooks(); + } + + /** + * Set up hooks for various purposes. + * + * This method adds hooks for different purposes as needed. + * + * @since 1.0.0 + * + * @return void + */ + protected function setup_hooks(): void { + add_filter( 'pre_get_comments', array( $this, 'exclude_rsvp_from_comment_query' ) ); + add_filter( 'comments_clauses', array( $this, 'taxonomy_query' ), 10, 2 ); + } + + /** + * Modify comment query clauses to include taxonomy query. + * + * This method adds the necessary SQL join and where clauses to a comment query + * based on a taxonomy query if one is present in the query variables. + * + * @since 1.0.0 + * + * @param array $clauses The clauses for the query. + * @param WP_Comment_Query $comment_query The comment query object. + * @return array Modified query clauses. + */ + public function taxonomy_query( array $clauses, WP_Comment_Query $comment_query ): array { + global $wpdb; + + if ( ! empty( $comment_query->query_vars['tax_query'] ) ) { + $comment_query->tax_query = new WP_Tax_Query( $comment_query->query_vars['tax_query'] ); + $pieces = $comment_query->tax_query->get_sql( $wpdb->comments, 'comment_ID' ); + $clauses['join'] .= $pieces['join']; + $clauses['where'] .= $pieces['where']; + } + + return $clauses; + } + + /** + * Retrieve a list of RSVP comments based on specified arguments. + * + * This method fetches RSVP comments by merging the provided arguments with default + * values specific to RSVPs. It ensures the count-only return is disabled and the + * RSVP comments are properly filtered. + * + * @since 1.0.0 + * + * @param array $args Arguments for retrieving RSVPs. + * @return array List of RSVP comments. + */ + public function get_rsvps( array $args ): array { + $args = array_merge( + array( + 'type' => Rsvp::COMMENT_TYPE, + 'status' => 'approve', + ), + $args + ); + + // Never allow count-only return, we always want array. + $args['count'] = false; + + remove_filter( 'pre_get_comments', array( $this, 'exclude_rsvp_from_comment_query' ) ); + + $rsvps = get_comments( $args ); + + add_filter( 'pre_get_comments', array( $this, 'exclude_rsvp_from_comment_query' ) ); + + return (array) $rsvps; + } + + /** + * Retrieve a single RSVP comment based on specified arguments. + * + * This method fetches a single RSVP comment by merging the provided arguments with default + * values specific to RSVPs. It ensures only one comment is returned. + * + * @since 1.0.0 + * + * @param array $args Arguments for retrieving the RSVP. + * @return WP_Comment|null The RSVP comment or null if not found. + */ + public function get_rsvp( array $args ): ?WP_Comment { + $args = array_merge( + array( + 'number' => 1, + ), + $args + ); + + $rsvp = $this->get_rsvps( $args ); + + if ( empty( $rsvp ) ) { + return null; + } + + return $rsvp[0]; + } + + /** + * Exclude RSVP comments from a query. + * + * This method modifies the comment query to exclude comments of the RSVP type. It + * ensures that RSVP comments are not included in the query results by adjusting the + * comment types in the query variables. + * + * @since 1.0.0 + * + * @param WP_Comment_Query $query The comment query object. + * @return void + */ + public function exclude_rsvp_from_comment_query( $query ) { + if ( ! $query instanceof WP_Comment_Query ) { + return; + } + + $current_comment_types = $query->query_vars['type']; + + // Ensure comment type is not empty. + if ( ! empty( $current_comment_types ) ) { + if ( is_array( $current_comment_types ) ) { + // Remove the specific comment type from the array. + $current_comment_types = array_diff( $current_comment_types, array( Rsvp::COMMENT_TYPE ) ); + } elseif ( Rsvp::COMMENT_TYPE === $current_comment_types ) { + // If the only type is the one to exclude, set it to empty. + $current_comment_types = ''; + } + } else { + // If no specific type is set, make sure the one to exclude is not included. + $current_comment_types = array( 'comment', 'pingback', 'trackback' ); // Default types. + $current_comment_types = array_diff( $current_comment_types, array( Rsvp::COMMENT_TYPE ) ); + } + + // Update the query vars with the modified comment types. + $query->query_vars['type'] = $current_comment_types; + } +} diff --git a/includes/core/classes/class-rsvp-setup.php b/includes/core/classes/class-rsvp-setup.php new file mode 100644 index 00000000..81b774a1 --- /dev/null +++ b/includes/core/classes/class-rsvp-setup.php @@ -0,0 +1,103 @@ +setup_hooks(); + } + + /** + * Set up hooks for various purposes. + * + * This method adds hooks for different purposes as needed. + * + * @since 1.0.0 + * @return void + */ + protected function setup_hooks(): void { + add_action( 'init', array( $this, 'register_taxonomy' ) ); + add_filter( 'get_comments_number', array( $this, 'adjust_comments_number' ), 10, 2 ); + } + + /** + * Register custom comment taxonomy for RSVPs. + * + * Registers a custom taxonomy 'gatherpress_rsvp' for managing RSVP related functionalities specifically for comments. + * + * @since 1.0.0 + * @return void + */ + public function register_taxonomy(): void { + register_taxonomy( + Rsvp::TAXONOMY, + 'comment', + array( + 'labels' => array(), + 'hierarchical' => false, + 'public' => true, + 'show_ui' => false, + 'show_admin_column' => false, + 'query_var' => true, + 'publicly_queryable' => false, + 'show_in_rest' => true, + ) + ); + } + + /** + * Adjusts the number of comments displayed for event posts. + * + * Retrieves and returns the count of approved RSVP comments for event posts. + * + * @since 1.0.0 + * + * @param int $comments_number The original number of comments. + * @param int $post_id The ID of the post. + * @return int Adjusted number of comments. + */ + public function adjust_comments_number( int $comments_number, int $post_id ): int { + if ( Event::POST_TYPE !== get_post_type( $post_id ) ) { + return $comments_number; + } + + $comment_count = get_comment_count( $post_id ); + + return $comment_count['approved'] ?? 0; + } +} diff --git a/includes/core/classes/class-rsvp.php b/includes/core/classes/class-rsvp.php index 8057441c..4da75533 100644 --- a/includes/core/classes/class-rsvp.php +++ b/includes/core/classes/class-rsvp.php @@ -26,12 +26,14 @@ */ class Rsvp { /** - * Table format for RSVPs. + * Constant representing the RSVP Taxonomy. + * + * This constant defines the status taxonomy for RSVP comment type. * * @since 1.0.0 - * @var string $TABLE_FORMAT + * @var string */ - const TABLE_FORMAT = '%sgatherpress_rsvps'; + const TAXONOMY = '_gatherpress_rsvp_status'; /** * Cache key format for RSVPs. @@ -41,6 +43,14 @@ class Rsvp { */ const CACHE_KEY = 'gatherpress_rsvp_%d'; + /** + * Comment type for RSVPs. + * + * @since 1.0.0 + * @var string $COMMENT_TYPE + */ + const COMMENT_TYPE = 'gatherpress_rsvp'; + /** * An array of RSVP statuses. * @@ -96,18 +106,18 @@ public function __construct( int $post_id ) { * @since 1.0.0 * * @param int $user_id A user ID. + * * @return array An array containing RSVP information, including ID, post ID, user ID, timestamp, status, and guests. */ public function get( int $user_id ): array { - global $wpdb; - - $post_id = $this->event->ID; + $post_id = $this->event->ID; + $rsvp_query = Rsvp_Query::get_instance(); if ( 1 > $post_id || 1 > $user_id ) { return array(); } - $default = array( + $data = array( 'id' => 0, 'post_id' => $post_id, 'user_id' => $user_id, @@ -117,12 +127,26 @@ public function get( int $user_id ): array { 'anonymous' => 0, ); - $table = sprintf( static::TABLE_FORMAT, $wpdb->prefix ); + $rsvp = $rsvp_query->get_rsvp( + array( + 'post_id' => $post_id, + 'user_id' => $user_id, + ) + ); + + if ( ! empty( $rsvp ) ) { + $data['id'] = $rsvp->user_id; + $data['timestamp'] = $rsvp->comment_date; + $data['anonymous'] = intval( get_comment_meta( $rsvp->comment_ID, 'gatherpress_rsvp_anonymous', true ) ); + $data['guests'] = intval( get_comment_meta( $rsvp->comment_ID, 'gatherpress_rsvp_guests', true ) ); + $terms = wp_get_object_terms( $rsvp->comment_ID, self::TAXONOMY ); - // @todo Consider implementing caching for improved performance in the future. - $data = $wpdb->get_row( $wpdb->prepare( 'SELECT id, timestamp, status, guests, anonymous FROM %i WHERE post_id = %d AND user_id = %d', $table, $post_id, $user_id ), ARRAY_A ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQLPlaceholders.UnsupportedIdentifierPlaceholder + if ( ! empty( $terms ) && is_array( $terms ) ) { + $data['status'] = $terms[0]->slug; + } + } - return array_merge( $default, (array) $data ); + return $data; } /** @@ -152,6 +176,7 @@ public function get( int $user_id ): array { public function save( int $user_id, string $status, int $anonymous = 0, int $guests = 0 ): array { global $wpdb; + $rsvp_query = Rsvp_Query::get_instance(); $max_guest_limit = intval( get_post_meta( $this->event->ID, 'gatherpress_max_guest_limit', true ) ); if ( $max_guest_limit < $guests ) { @@ -173,11 +198,13 @@ public function save( int $user_id, string $status, int $anonymous = 0, int $gue return $data; } - if ( ! in_array( $status, $this->statuses, true ) ) { - return $data; - } + $rsvp = $rsvp_query->get_rsvp( + array( + 'post_id' => $post_id, + 'user_id' => $user_id, + ) + ); - $table = sprintf( static::TABLE_FORMAT, $wpdb->prefix ); $current_response = $this->get( $user_id ); $limit_reached = $this->attending_limit_reached( $current_response, $guests ); @@ -197,6 +224,50 @@ public function save( int $user_id, string $status, int $anonymous = 0, int $gue $guests = 0; } + $args = array( + 'comment_post_ID' => $post_id, + 'comment_type' => self::COMMENT_TYPE, + 'user_id' => $user_id, + ); + + if ( empty( $rsvp ) ) { + $comment_id = wp_insert_comment( $args ); + } else { + $comment_id = $rsvp->comment_ID; + $args['comment_ID'] = $comment_id; + + wp_update_comment( $args ); + } + + if ( is_wp_error( $comment_id ) || empty( $comment_id ) ) { + return $data; + } + + // If not attending and anonymous or status is 'no_status', remove the record. + if ( ( 'not_attending' === $status && $anonymous ) || 'no_status' === $status ) { + wp_delete_comment( $comment_id, true ); + + return $data; + } + + if ( ! in_array( $status, $this->statuses, true ) ) { + return $data; + } + + wp_set_object_terms( $comment_id, $status, self::TAXONOMY ); + + if ( ! empty( $guests ) ) { + update_comment_meta( $comment_id, 'gatherpress_rsvp_guests', $guests ); + } else { + delete_comment_meta( $comment_id, 'gatherpress_rsvp_guests' ); + } + + if ( ! empty( $anonymous ) ) { + update_comment_meta( $comment_id, 'gatherpress_rsvp_anonymous', $anonymous ); + } else { + delete_comment_meta( $comment_id, 'gatherpress_rsvp_anonymous' ); + } + $data = array( 'post_id' => intval( $post_id ), 'user_id' => intval( $user_id ), @@ -206,23 +277,6 @@ public function save( int $user_id, string $status, int $anonymous = 0, int $gue 'anonymous' => intval( $anonymous ), ); - if ( intval( $current_response['id'] ) ) { - $where = array( - 'id' => intval( $current_response['id'] ), - ); - - // If not attending and anonymous, just remove record. - if ( ( 'not_attending' === $status && $anonymous ) || 'no_status' === $status ) { - $wpdb->delete( $table, $where ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery - - $data['status'] = 'no_status'; // Set default status for UI. - } else { - $wpdb->update( $table, $data, $where ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery - } - } else { - $wpdb->insert( $table, $data ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery - } - wp_cache_delete( sprintf( self::CACHE_KEY, $post_id ) ); if ( ! $limit_reached ) { @@ -327,11 +381,10 @@ public function attending_limit_reached( array $current_response, int $guests = * @return array An array containing response information grouped by RSVP status. */ public function responses(): array { - global $wpdb; - - $post_id = $this->event->ID; - $cache_key = sprintf( self::CACHE_KEY, $post_id ); - $retval = wp_cache_get( $cache_key ); + $post_id = $this->event->ID; + $cache_key = sprintf( self::CACHE_KEY, $post_id ); + $retval = wp_cache_get( $cache_key ); + $rsvp_query = Rsvp_Query::get_instance(); // @todo add testing with cache. // @codeCoverageIgnoreStart @@ -351,14 +404,15 @@ public function responses(): array { return $retval; } - $site_users = count_users(); - $total_users = $site_users['total_users']; - $table = sprintf( static::TABLE_FORMAT, $wpdb->prefix ); - $data = (array) $wpdb->get_results( $wpdb->prepare( 'SELECT user_id, timestamp, status, guests, anonymous FROM %i WHERE post_id = %d LIMIT %d', $table, $post_id, $total_users ), ARRAY_A ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.PreparedSQLPlaceholders.UnsupportedIdentifierPlaceholder - $data = ( ! empty( $data ) ) ? (array) $data : array(); - $responses = array(); - $all_guests = 0; - $statuses = $this->statuses; + $data = $rsvp_query->get_rsvps( + array( + 'post_id' => $post_id, + ) + ); + + $responses = array(); + $all_guests = 0; + $statuses = $this->statuses; // `no_status` status is not relevant here. $status_key = array_search( 'no_status', $statuses, true ); @@ -373,12 +427,17 @@ public function responses(): array { } foreach ( $data as $response ) { - $user_id = intval( $response['user_id'] ); - $user_status = sanitize_key( $response['status'] ); - $user_guests = intval( $response['guests'] ); + $user_id = intval( $response->user_id ); + $user_status = ''; + $user_guests = intval( get_comment_meta( $response->comment_ID, 'gatherpress_rsvp_guests', true ) ); $all_guests += $user_guests; $user_info = get_userdata( $user_id ); - $anonymous = intval( $response['anonymous'] ); + $anonymous = intval( get_comment_meta( $response->comment_ID, 'gatherpress_rsvp_anonymous', true ) ); + + $terms = wp_get_object_terms( $response->comment_ID, self::TAXONOMY ); + if ( ! empty( $terms ) && is_array( $terms ) ) { + $user_status = $terms[0]->slug; + } // @todo make a filter so we can use this function if gatherpress-buddypress plugin is activated. // eg for BuddyPress bp_core_get_user_domain( $user_id ) @@ -406,7 +465,7 @@ public function responses(): array { 'photo' => get_avatar_url( $user_id ), 'profile' => $profile, 'role' => Leadership::get_instance()->get_user_role( $user_id ), - 'timestamp' => sanitize_text_field( $response['timestamp'] ), + 'timestamp' => sanitize_text_field( $response->comment_date ), 'status' => $user_status, 'guests' => $user_guests, 'anonymous' => $anonymous, diff --git a/includes/core/classes/class-setup.php b/includes/core/classes/class-setup.php index 6ec1e775..d23d8799 100644 --- a/includes/core/classes/class-setup.php +++ b/includes/core/classes/class-setup.php @@ -63,6 +63,8 @@ protected function instantiate_classes(): void { Event_Query::get_instance(); Event_Setup::get_instance(); Rest_Api::get_instance(); + Rsvp_Query::get_instance(); + Rsvp_Setup::get_instance(); Settings::get_instance(); User::get_instance(); Topic::get_instance(); @@ -365,7 +367,6 @@ public function on_site_delete( array $tables ): array { global $wpdb; $tables[] = sprintf( Event::TABLE_FORMAT, $wpdb->prefix, Event::POST_TYPE ); - $tables[] = sprintf( Rsvp::TABLE_FORMAT, $wpdb->prefix ); return $tables; } @@ -404,21 +405,6 @@ protected function create_tables(): void { KEY datetime_end_gmt (datetime_end_gmt) ) {$charset_collate};"; - $table = sprintf( Rsvp::TABLE_FORMAT, $prefix ); - $sql[] = "CREATE TABLE {$table} ( - id bigint(20) unsigned NOT NULL auto_increment, - post_id bigint(20) unsigned NOT NULL default '0', - user_id bigint(20) unsigned NOT NULL default '0', - timestamp datetime NOT NULL default '0000-00-00 00:00:00', - status varchar(255) default NULL, - anonymous tinyint(1) default 0, - guests tinyint(1) default 0, - PRIMARY KEY (id), - KEY post_id (post_id), - KEY user_id (user_id), - KEY status (status) - ) {$charset_collate};"; - require_once ABSPATH . 'wp-admin/includes/upgrade.php'; dbDelta( $sql ); diff --git a/test/unit/php/includes/core/classes/class-test-rsvp-query.php b/test/unit/php/includes/core/classes/class-test-rsvp-query.php new file mode 100644 index 00000000..c22d6028 --- /dev/null +++ b/test/unit/php/includes/core/classes/class-test-rsvp-query.php @@ -0,0 +1,181 @@ + 'filter', + 'name' => 'pre_get_comments', + 'priority' => 10, + 'callback' => array( $instance, 'exclude_rsvp_from_comment_query' ), + ), + array( + 'type' => 'filter', + 'name' => 'comments_clauses', + 'priority' => 10, + 'callback' => array( $instance, 'taxonomy_query' ), + ), + ); + + $this->assert_hooks( $hooks, $instance ); + } + + /** + * Coverage for taxonomy_query method. + * + * @return void + */ + public function test_taxonomy_query(): void { + $instance = RSVP_Query::get_instance(); + $user_id = $this->factory->user->create(); + $event = $this->mock->post( array( 'post_type' => Event::POST_TYPE ) )->get(); + $clauses = array( + 'join' => '', + 'where' => '', + ); + $rsvp = wp_insert_comment( + array( + 'comment_post_ID' => $event->ID, + 'comment_type' => Rsvp::COMMENT_TYPE, + 'user_id' => $user_id, + ) + ); + + wp_set_object_terms( $rsvp, 'attending', Rsvp::TAXONOMY ); + + $comment_query = new WP_Comment_Query( + array( + 'post_id' => $event->ID, + 'tax_query' => array( //phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query + array( + 'taxonomy' => Rsvp::TAXONOMY, + 'terms' => 'attending', + 'field' => 'slug', + ), + ), + ) + ); + + $pieces = $instance->taxonomy_query( $clauses, $comment_query ); + + $this->assertSame( + ' LEFT JOIN wp_term_relationships ON (wp_comments.comment_ID = wp_term_relationships.object_id)', + $pieces['join'], + 'Failed to assert that join is the same.' + ); + + $this->assertSame( + ' AND ( wp_term_relationships.term_taxonomy_id IN (' . $user_id . ') )', + preg_replace( '/\s+/', ' ', $pieces['where'] ), + 'Failed to assert where is the same.' + ); + } + + /** + * Coverage for get_rsvp and get_rsvps method. + * + * @covers ::get_rsvp + * @covers ::get_rsvps + * + * @return void + */ + public function test_get_rsvps(): void { + $instance = Rsvp_Query::get_instance(); + + $this->assertNull( + $instance->get_rsvp( array() ), + 'Failed to assert null.' + ); + + $user_id_1 = $this->factory->user->create(); + $user_id_2 = $this->factory->user->create(); + $event = $this->mock->post( array( 'post_type' => Event::POST_TYPE ) )->get(); + $rsvp_1 = wp_insert_comment( + array( + 'comment_post_ID' => $event->ID, + 'comment_type' => Rsvp::COMMENT_TYPE, + 'user_id' => $user_id_1, + ) + ); + $rsvp_2 = wp_insert_comment( + array( + 'comment_post_ID' => $event->ID, + 'comment_type' => Rsvp::COMMENT_TYPE, + 'user_id' => $user_id_2, + ) + ); + + wp_insert_comment( + array( + 'comment_post_ID' => $event->ID, + 'comment_content' => 'Test comment 1', + 'user_id' => $user_id_1, + ) + ); + + wp_insert_comment( + array( + 'comment_post_ID' => $event->ID, + 'comment_content' => 'Test comment 2', + 'user_id' => $user_id_2, + ) + ); + + $rsvp = $instance->get_rsvp( + array( + 'post_id' => $event->ID, + 'user_id' => $user_id_2, + ), + ); + + $this->assertEquals( $rsvp_2, $rsvp->comment_ID ); + + $rsvp = $instance->get_rsvp( + array( + 'post_id' => $event->ID, + 'user_id' => $user_id_1, + ), + ); + + $this->assertEquals( $rsvp_1, (int) $rsvp->comment_ID ); + + $this->assertEquals( + 2, + count( + $instance->get_rsvps( + array( 'post_id' => $event->ID ), + ) + ), + 'Failed to assert 2 RSVPs to event.' + ); + } +} diff --git a/test/unit/php/includes/core/classes/class-test-rsvp-setup.php b/test/unit/php/includes/core/classes/class-test-rsvp-setup.php new file mode 100644 index 00000000..cc10e5ff --- /dev/null +++ b/test/unit/php/includes/core/classes/class-test-rsvp-setup.php @@ -0,0 +1,111 @@ + 'action', + 'name' => 'init', + 'priority' => 10, + 'callback' => array( $instance, 'register_taxonomy' ), + ), + array( + 'type' => 'filter', + 'name' => 'get_comments_number', + 'priority' => 10, + 'callback' => array( $instance, 'adjust_comments_number' ), + ), + ); + + $this->assert_hooks( $hooks, $instance ); + } + + /** + * Coverage for register_taxonomy method. + * + * @covers ::register_taxonomy + * + * @return void + */ + public function test_register_taxonomy(): void { + $instance = Rsvp_Setup::get_instance(); + + unregister_taxonomy( Rsvp::TAXONOMY ); + + $this->assertFalse( taxonomy_exists( Rsvp::TAXONOMY ), 'Failed to assert that taxonomy does not exist.' ); + + $instance->register_taxonomy(); + + $this->assertTrue( taxonomy_exists( Rsvp::TAXONOMY ), 'Failed to assert that taxonomy exists.' ); + } + + /** + * Coverage for adjust_comments_number method. + * + * @covers ::adjust_comments_number + * + * @return void + */ + public function test_adjust_comments_number(): void { + $instance = Rsvp_Setup::get_instance(); + $post = $this->mock->post()->get(); + $user = $this->mock->user()->get(); + + $this->assertEquals( + 2, + $instance->adjust_comments_number( 2, $post->ID ), + 'Failed to assert the comments do not equal 2.' + ); + + $event = $this->mock->post( array( 'post_type' => Event::POST_TYPE ) )->get(); + + wp_insert_comment( + array( + 'comment_post_ID' => $event->ID, + 'user_id' => $user->ID, + 'comment_content' => 'Test comment', + ) + ); + + wp_insert_comment( + array( + 'comment_post_ID' => $event->ID, + 'comment_type' => Rsvp::COMMENT_TYPE, + 'user_id' => $user->ID, + ) + ); + + $this->assertEquals( + 1, + $instance->adjust_comments_number( 2, $event->ID ), + 'Failed to assert the comments do not equal 1.' + ); + } +}