From 0603537f0a7acd1cf35878b3db72c3c4e98bddfe Mon Sep 17 00:00:00 2001 From: wpdev Date: Sat, 26 Sep 2026 00:22:20 +0800 Subject: [PATCH] refactor(2meet-data-optimizer): resolve post_type/group/table mappings through the registry - TMDO_Post_Fields::post_type_for_group() / groups_for_post_type() derive HivePress-style groups from their registry post_type scope (core keeps its own attachment / wc_product / nav_menu_item map); the three copy-pasted switches and the query router's POST_TYPE_GROUP_MAP use them - Term/comment backfill, shadow verifier and CLI take their groups from the registry (TMDO_Term_Comment_Backfill::registered_groups()); installer drops the hp_* entries already covered by its table patterns; REST listings default post type is filterable (tmdo_rest_default_post_type, default 'post') - Verify: NoHpMappingsTest guard + mapping/default tests; core unit 640 / integration 449, HP 146/49, WC 10/22 OK - PR: PR-020e --- cli/class-tmdo-cli-post.php | 18 +----- cli/class-tmdo-cli-term-comment.php | 25 ++++++-- includes/class-tmdo-installer.php | 7 -- includes/class-tmdo-post-shadow-verifier.php | 18 +----- includes/class-tmdo-rest-api.php | 16 ++++- includes/class-tmdo-term-comment-backfill.php | 34 +++++----- ...lass-tmdo-term-comment-shadow-verifier.php | 33 ++-------- .../integrations/class-tmdo-post-fields.php | 40 ++++++++++++ .../migration/class-tmdo-post-migration.php | 22 +------ .../query/class-tmdo-post-query-router.php | 20 +----- tests/unit/NoHpMappingsTest.php | 64 +++++++++++++++++++ .../PostFields/PostFieldsRegistrationTest.php | 18 ++++++ tests/unit/RestApiTest.php | 11 ++++ 13 files changed, 196 insertions(+), 130 deletions(-) create mode 100644 tests/unit/NoHpMappingsTest.php diff --git a/cli/class-tmdo-cli-post.php b/cli/class-tmdo-cli-post.php index 1816e36..fcfdc4f 100644 --- a/cli/class-tmdo-cli-post.php +++ b/cli/class-tmdo-cli-post.php @@ -860,23 +860,7 @@ class TMDO_CLI_Post { * @return string|null */ private static function group_post_type_for_cli( string $group ): ?string { - switch ( $group ) { - case 'attachment': - return 'attachment'; - case 'wc_product': - return 'product'; - case 'hp_listing_core': - return 'hp_listing'; - case 'hp_request_core': - return 'hp_request'; - case 'hp_vendor_core': - return 'hp_vendor'; - case 'nav_menu_item': - return 'nav_menu_item'; - case 'wp_core': - default: - return null; - } + return TMDO_Post_Fields::post_type_for_group( $group ); } } diff --git a/cli/class-tmdo-cli-term-comment.php b/cli/class-tmdo-cli-term-comment.php index 5d31dd9..96dea8a 100644 --- a/cli/class-tmdo-cli-term-comment.php +++ b/cli/class-tmdo-cli-term-comment.php @@ -429,7 +429,7 @@ class TMDO_CLI_Term_Comment { WP_CLI::log( sprintf( 'Mode: %s', $term_mode ) ); WP_CLI::log( sprintf( 'wp_terms: %s', number_format_i18n( $terms_count ) ) ); WP_CLI::log( sprintf( 'wp_termmeta: %s (1:%s)', number_format_i18n( $termmeta_count ), $terms_count > 0 ? round( $termmeta_count / $terms_count, 2 ) : 'n/a' ) ); - self::print_flat_row( $wpdb->prefix . 'wpdo_term_hp_taxonomy', 'wpdo_term_hp_taxonomy' ); + self::print_group_rows( 'term' ); self::print_flat_row( $wpdb->prefix . 'wpdo_term_misc', 'wpdo_term_misc' ); WP_CLI::log( '' ); @@ -437,7 +437,7 @@ class TMDO_CLI_Term_Comment { WP_CLI::log( sprintf( 'Mode: %s', $comment_mode ) ); WP_CLI::log( sprintf( 'wp_comments: %s', number_format_i18n( $comments_count ) ) ); WP_CLI::log( sprintf( 'wp_commentmeta: %s (1:%s)', number_format_i18n( $commentmeta_count ), $comments_count > 0 ? round( $commentmeta_count / $comments_count, 2 ) : 'n/a' ) ); - self::print_flat_row( $wpdb->prefix . 'wpdo_comment_hp_review', 'wpdo_comment_hp_review' ); + self::print_group_rows( 'comment' ); self::print_flat_row( $wpdb->prefix . 'wpdo_comment_misc', 'wpdo_comment_misc' ); WP_CLI::log( '' ); @@ -470,6 +470,21 @@ class TMDO_CLI_Term_Comment { return 'Both entities at disabled. Promote to dual_write first to enable Hook Bus interception.'; } + /** + * Print the row count of every registered group table of an entity. + * + * @param string $entity_type 'term' or 'comment'. + * @return void + */ + private static function print_group_rows( string $entity_type ): void { + foreach ( TMDO_Term_Comment_Backfill::registered_groups() as $group => $type ) { + if ( $type === $entity_type ) { + $table = TMDO_Schema_Manager::get_table_name( $entity_type, $group ); + self::print_flat_row( $table, TMDO_TABLE_PREFIX . $entity_type . '_' . $group ); + } + } + } + /** * Print a flat table's row count (or "(missing)" when not present). * @@ -647,7 +662,8 @@ class TMDO_CLI_Term_Comment { ); } - $valid_groups = array( 'all', 'hp_taxonomy', 'hp_review' ); + $registered = TMDO_Term_Comment_Backfill::registered_groups(); + $valid_groups = array_merge( array( 'all' ), array_keys( $registered ) ); if ( ! in_array( $group, $valid_groups, true ) ) { WP_CLI::error( 'Invalid --group. Choose: ' . implode( ', ', $valid_groups ) ); } @@ -656,8 +672,7 @@ class TMDO_CLI_Term_Comment { if ( 'all' === $group ) { $results = TMDO_Term_Comment_Backfill::backfill_all( $dry_run ); } else { - $entity_type = 'hp_review' === $group ? 'comment' : 'term'; - $results = array( $group => TMDO_Term_Comment_Backfill::backfill_group( $entity_type, $group, $dry_run ) ); + $results = array( $group => TMDO_Term_Comment_Backfill::backfill_group( $registered[ $group ], $group, $dry_run ) ); } // Render table. diff --git a/includes/class-tmdo-installer.php b/includes/class-tmdo-installer.php index 7e97f73..27c1eae 100644 --- a/includes/class-tmdo-installer.php +++ b/includes/class-tmdo-installer.php @@ -843,18 +843,11 @@ class TMDO_Installer { $wpdb->prefix . 'wpdo_user_core_profile', $wpdb->prefix . 'wpdo_user_social', $wpdb->prefix . 'wpdo_user_commerce', - $wpdb->prefix . 'wpdo_user_hp_user', $wpdb->prefix . 'wpdo_user_admin_prefs', $wpdb->prefix . 'wpdo_post_wp_core', $wpdb->prefix . 'wpdo_post_attachment', $wpdb->prefix . 'wpdo_post_wc_product', - $wpdb->prefix . 'wpdo_post_hp_listing_core', - $wpdb->prefix . 'wpdo_post_hp_request_core', - $wpdb->prefix . 'wpdo_post_hp_vendor_core', $wpdb->prefix . 'wpdo_post_nav_menu_item', - $wpdb->prefix . 'wpdo_hot_hp_listing', - $wpdb->prefix . 'wpdo_term_hp_taxonomy', - $wpdb->prefix . 'wpdo_comment_hp_review', $wpdb->prefix . 'wpdo_term_misc', $wpdb->prefix . 'wpdo_comment_misc', ); diff --git a/includes/class-tmdo-post-shadow-verifier.php b/includes/class-tmdo-post-shadow-verifier.php index 223aed3..6421ce7 100644 --- a/includes/class-tmdo-post-shadow-verifier.php +++ b/includes/class-tmdo-post-shadow-verifier.php @@ -303,23 +303,7 @@ final class TMDO_Post_Shadow_Verifier { * @return string|null */ private static function group_post_type( string $group ): ?string { - switch ( $group ) { - case 'attachment': - return 'attachment'; - case 'wc_product': - return 'product'; - case 'hp_listing_core': - return 'hp_listing'; - case 'hp_request_core': - return 'hp_request'; - case 'hp_vendor_core': - return 'hp_vendor'; - case 'nav_menu_item': - return 'nav_menu_item'; - case 'wp_core': - default: - return null; - } + return TMDO_Post_Fields::post_type_for_group( $group ); } /** diff --git a/includes/class-tmdo-rest-api.php b/includes/class-tmdo-rest-api.php index 439245a..0f0735d 100644 --- a/includes/class-tmdo-rest-api.php +++ b/includes/class-tmdo-rest-api.php @@ -529,7 +529,7 @@ class TMDO_REST_API { * @return WP_REST_Response REST response. */ public function get_listings( WP_REST_Request $request ): WP_REST_Response { - $post_type = $request->get_param( 'post_type' ) ?? 'hp_listing'; + $post_type = $request->get_param( 'post_type' ) ?? self::default_post_type(); if ( ! post_type_exists( $post_type ) || ! is_post_type_viewable( $post_type ) ) { return new WP_REST_Response( array( @@ -1550,13 +1550,25 @@ class TMDO_REST_API { return $filters; } + /** + * Post type GET /listings serves when the request names none. + * + * Filter `tmdo_rest_default_post_type` lets an integration (e.g. the + * HivePress AddOn) make its own post type the default. + * + * @return string + */ + public static function default_post_type(): string { + return (string) apply_filters( 'tmdo_rest_default_post_type', 'post' ); + } + /** * Argument definitions for GET /listings. */ private function listings_args(): array { return array( 'post_type' => array( - 'default' => 'hp_listing', + 'default' => self::default_post_type(), 'sanitize_callback' => 'sanitize_key', ), 'per_page' => array( diff --git a/includes/class-tmdo-term-comment-backfill.php b/includes/class-tmdo-term-comment-backfill.php index c2b0540..5d9c74a 100644 --- a/includes/class-tmdo-term-comment-backfill.php +++ b/includes/class-tmdo-term-comment-backfill.php @@ -60,20 +60,22 @@ if ( ! defined( 'ABSPATH' ) ) { final class TMDO_Term_Comment_Backfill { /** - * Group → flat table suffix mapping. Mirror of TMDO_Hivepress_Term_Comment_Fields. + * Term and comment groups registered in the entity registry. * - * @var array + * @return array Group name → entity type ('term' | 'comment'). */ - private const GROUP_MAP = array( - 'hp_taxonomy' => array( - 'entity_type' => 'term', - 'table_suffix' => 'wpdo_term_hp_taxonomy', - ), - 'hp_review' => array( - 'entity_type' => 'comment', - 'table_suffix' => 'wpdo_comment_hp_review', - ), - ); + public static function registered_groups(): array { + $groups = array(); + if ( ! class_exists( 'TMDO_Entity_Registry' ) ) { + return $groups; + } + foreach ( array( 'term', 'comment' ) as $entity_type ) { + foreach ( TMDO_Entity_Registry::get_groups_for_type( $entity_type ) as $group ) { + $groups[ $group ] = $groups[ $group ] ?? $entity_type; + } + } + return $groups; + } /** * Run backfill for every registered term + comment group. @@ -83,8 +85,8 @@ final class TMDO_Term_Comment_Backfill { */ public static function backfill_all( bool $dry_run = false ): array { $results = array(); - foreach ( self::GROUP_MAP as $group_name => $cfg ) { - $results[ $group_name ] = self::backfill_group( $cfg['entity_type'], $group_name, $dry_run ); + foreach ( self::registered_groups() as $group_name => $entity_type ) { + $results[ $group_name ] = self::backfill_group( $entity_type, $group_name, $dry_run ); } return $results; } @@ -110,7 +112,7 @@ final class TMDO_Term_Comment_Backfill { $result['error'] = 'Entity Registry unavailable'; return $result; } - if ( ! isset( self::GROUP_MAP[ $group_name ] ) ) { + if ( ( self::registered_groups()[ $group_name ] ?? null ) !== $entity_type ) { $result['error'] = "Unknown group: {$group_name}"; return $result; } @@ -140,7 +142,7 @@ final class TMDO_Term_Comment_Backfill { return $result; } - $flat_table = $wpdb->prefix . self::GROUP_MAP[ $group_name ]['table_suffix']; + $flat_table = TMDO_Schema_Manager::get_table_name( $entity_type, $group_name ); // Count candidate entities — those with at least one of the registered keys in wp_*meta. $placeholders = implode( ',', array_fill( 0, count( $keys ), '%s' ) ); diff --git a/includes/class-tmdo-term-comment-shadow-verifier.php b/includes/class-tmdo-term-comment-shadow-verifier.php index 89cf246..6701f50 100644 --- a/includes/class-tmdo-term-comment-shadow-verifier.php +++ b/includes/class-tmdo-term-comment-shadow-verifier.php @@ -41,23 +41,6 @@ final class TMDO_Term_Comment_Shadow_Verifier { /** Default sample size per entity per cron tick. */ public const DEFAULT_SAMPLE_SIZE = 100; - /** - * Group → flat table suffix mapping. Keep in sync with - * TMDO_Hivepress_Term_Comment_Fields registrations and the misc bucket. - * - * @var array - */ - private const GROUP_MAP = array( - 'hp_taxonomy' => array( - 'entity_type' => 'term', - 'table_suffix' => 'wpdo_term_hp_taxonomy', - ), - 'hp_review' => array( - 'entity_type' => 'comment', - 'table_suffix' => 'wpdo_comment_hp_review', - ), - ); - /** * Run a sample-compare pass for a single entity group. * @@ -215,11 +198,7 @@ final class TMDO_Term_Comment_Shadow_Verifier { return; } - global $wpdb; - - foreach ( self::GROUP_MAP as $group => $cfg ) { - $entity_type = $cfg['entity_type']; - + foreach ( TMDO_Term_Comment_Backfill::registered_groups() as $group => $entity_type ) { // Only run when the entity is in shadow_read mode. if ( 'term' === $entity_type && ! $term_shadow ) { continue; @@ -232,7 +211,7 @@ final class TMDO_Term_Comment_Shadow_Verifier { if ( empty( $keys ) ) { continue; } - $flat_table = $wpdb->prefix . $cfg['table_suffix']; + $flat_table = TMDO_Schema_Manager::get_table_name( $entity_type, $group ); try { self::sample_compare( $entity_type, $group, $flat_table, $keys, self::DEFAULT_SAMPLE_SIZE ); @@ -337,16 +316,14 @@ final class TMDO_Term_Comment_Shadow_Verifier { return array(); } - global $wpdb; $out = array(); - foreach ( self::GROUP_MAP as $group => $cfg ) { - $entity_type = $cfg['entity_type']; - $keys = TMDO_Entity_Registry::get_group_keys( $entity_type, $group ); + foreach ( TMDO_Term_Comment_Backfill::registered_groups() as $group => $entity_type ) { + $keys = TMDO_Entity_Registry::get_group_keys( $entity_type, $group ); if ( empty( $keys ) ) { continue; } - $flat_table = $wpdb->prefix . $cfg['table_suffix']; + $flat_table = TMDO_Schema_Manager::get_table_name( $entity_type, $group ); try { $out[ $group ] = self::sample_compare( $entity_type, $group, $flat_table, $keys, $sample_size ); diff --git a/includes/integrations/class-tmdo-post-fields.php b/includes/integrations/class-tmdo-post-fields.php index 0f2d202..5057c1f 100644 --- a/includes/integrations/class-tmdo-post-fields.php +++ b/includes/integrations/class-tmdo-post-fields.php @@ -43,6 +43,46 @@ if ( ! defined( 'ABSPATH' ) ) { */ final class TMDO_Post_Fields { + /** + * Post type of each core group that is not scoped to post types in the + * registry (wp_core spans every post type and is absent on purpose). + */ + private const GROUP_POST_TYPES = array( + 'attachment' => 'attachment', + 'wc_product' => 'product', + 'nav_menu_item' => 'nav_menu_item', + ); + + /** + * Primary post type of a post group: the registry scope for scoped groups + * (e.g. the HivePress AddOn's), the core mapping otherwise. + * + * @param string $group Entity group name. + * @return string|null Null for cross-post-type groups such as wp_core. + */ + public static function post_type_for_group( string $group ): ?string { + $scoped = class_exists( 'TMDO_Entity_Registry' ) ? TMDO_Entity_Registry::get_group_post_types( 'post', $group ) : array(); + return $scoped[0] ?? ( self::GROUP_POST_TYPES[ $group ] ?? null ); + } + + /** + * Post groups dedicated to a post type (wp_core excluded). + * + * @param string $post_type Post type slug. + * @return string[] + */ + public static function groups_for_post_type( string $post_type ): array { + $groups = array_keys( self::GROUP_POST_TYPES, $post_type, true ); + if ( class_exists( 'TMDO_Entity_Registry' ) ) { + foreach ( TMDO_Entity_Registry::get_groups_for_type( 'post' ) as $group ) { + if ( in_array( $post_type, TMDO_Entity_Registry::get_group_post_types( 'post', $group ), true ) ) { + $groups[] = $group; + } + } + } + return array_values( array_unique( $groups ) ); + } + /** * Hook into WPDO entity field registration. * diff --git a/includes/migration/class-tmdo-post-migration.php b/includes/migration/class-tmdo-post-migration.php index b6b8244..67b54f8 100644 --- a/includes/migration/class-tmdo-post-migration.php +++ b/includes/migration/class-tmdo-post-migration.php @@ -546,8 +546,8 @@ final class TMDO_Post_Migration { } /** - * Map group name to the post_type it targets. The mapping is canonical - * to v2.9.1 group definitions in TMDO_Post_Fields. + * Map group name to the post_type it targets (see + * TMDO_Post_Fields::post_type_for_group()). * * Returns null for cross-post_type groups (e.g. 'wp_core'). * @@ -555,23 +555,7 @@ final class TMDO_Post_Migration { * @return string|null */ private static function group_post_type( string $group ): ?string { - switch ( $group ) { - case 'attachment': - return 'attachment'; - case 'wc_product': - return 'product'; - case 'hp_listing_core': - return 'hp_listing'; - case 'hp_request_core': - return 'hp_request'; - case 'hp_vendor_core': - return 'hp_vendor'; - case 'nav_menu_item': - return 'nav_menu_item'; - case 'wp_core': - default: - return null; - } + return TMDO_Post_Fields::post_type_for_group( $group ); } /** diff --git a/includes/query/class-tmdo-post-query-router.php b/includes/query/class-tmdo-post-query-router.php index ed4c5c3..8060ebc 100644 --- a/includes/query/class-tmdo-post-query-router.php +++ b/includes/query/class-tmdo-post-query-router.php @@ -43,23 +43,6 @@ class TMDO_Post_Query_Router { /** Query var key for capturing routed clauses (consumed by posts_join/where). */ private const QUERY_VAR = 'wpdo_post_clauses'; - /** - * Map post_type → entity group (mirror of TMDO_Post_Migration::group_post_type - * but inverted; a post_type may map to multiple groups eventually, currently - * we route to the most-specific *_core group plus the cross-cutting wp_core - * group when the key is in wp_core). - * - * @var array - */ - private const POST_TYPE_GROUP_MAP = array( - 'product' => 'wc_product', - 'hp_listing' => 'hp_listing_core', - 'hp_request' => 'hp_request_core', - 'hp_vendor' => 'hp_vendor_core', - 'attachment' => 'attachment', - 'nav_menu_item' => 'nav_menu_item', - ); - /** * Register all WP_Query hooks. * @@ -117,8 +100,7 @@ class TMDO_Post_Query_Router { // Confirm the field's group is appropriate for this post_type: // either cross-cutting wp_core (any) or the post_type-specific group. $group = $field['group'] ?? ''; - $expected_grp = self::POST_TYPE_GROUP_MAP[ $pt ] ?? null; - $is_appropriate = ( 'wp_core' === $group ) || ( null !== $expected_grp && $expected_grp === $group ); + $is_appropriate = ( 'wp_core' === $group ) || in_array( $group, TMDO_Post_Fields::groups_for_post_type( (string) $pt ), true ); if ( ! $is_appropriate ) { continue; } diff --git a/tests/unit/NoHpMappingsTest.php b/tests/unit/NoHpMappingsTest.php new file mode 100644 index 0000000..65c3b27 --- /dev/null +++ b/tests/unit/NoHpMappingsTest.php @@ -0,0 +1,64 @@ + array( "array( 'product', 'hp_listing', 'hp_request', 'hp_vendor', 'attachment', 'nav_menu_item', 'post' )" ), + ); + + public function test_routing_code_has_no_hivepress_names(): void { + $root = dirname( __DIR__, 2 ); + $offences = array(); + foreach ( self::FILES as $rel ) { + $code = ''; + foreach ( token_get_all( (string) file_get_contents( $root . '/' . $rel ) ) as $token ) { + if ( is_array( $token ) && in_array( $token[0], array( T_COMMENT, T_DOC_COMMENT ), true ) ) { + continue; + } + $code .= is_array( $token ) ? $token[1] : $token; + } + $code = str_replace( self::ALLOWED[ $rel ] ?? array(), '', $code ); + if ( preg_match_all( '/hp_(listing|request|vendor|taxonomy|review|user)\w*/', $code, $m ) ) { + $offences[] = $rel . ': ' . implode( ', ', array_unique( $m[0] ) ); + } + } + + $this->assertSame( array(), $offences, "Hardcoded HivePress names in core routing:\n" . implode( "\n", $offences ) ); + } + + public function test_term_comment_groups_come_from_the_registry(): void { + TMDO_Entity_Registry::init(); + TMDO_Entity_Registry::register_adapter( 'term', $this->createMock( TMDO_Entity_Adapter_Interface::class ) ); + TMDO_Entity_Registry::register_adapter( 'comment', $this->createMock( TMDO_Entity_Adapter_Interface::class ) ); + TMDO_Entity_Registry::register_group( 'term', 'x_tax', array( array( 'key' => 'x_order', 'type' => 'integer' ) ) ); + TMDO_Entity_Registry::register_group( 'comment', 'x_review', array( array( 'key' => 'x_rating', 'type' => 'integer' ) ) ); + + $this->assertSame( array( 'x_tax' => 'term', 'x_review' => 'comment' ), TMDO_Term_Comment_Backfill::registered_groups() ); + + $result = TMDO_Term_Comment_Backfill::backfill_group( 'term', 'hp_taxonomy', true ); + $this->assertSame( 'Unknown group: hp_taxonomy', $result['error'] ?? '', 'unregistered groups are unknown' ); + } +} diff --git a/tests/unit/PostFields/PostFieldsRegistrationTest.php b/tests/unit/PostFields/PostFieldsRegistrationTest.php index 42dc942..112d572 100644 --- a/tests/unit/PostFields/PostFieldsRegistrationTest.php +++ b/tests/unit/PostFields/PostFieldsRegistrationTest.php @@ -135,6 +135,24 @@ class PostFieldsRegistrationTest extends TestCase { } } + // ── group ↔ post_type mapping ──────────────────────────────────────────── + + public function test_core_groups_map_to_their_post_types(): void { + $this->assertSame( 'attachment', WPDO_Post_Fields::post_type_for_group( 'attachment' ) ); + $this->assertSame( 'product', WPDO_Post_Fields::post_type_for_group( 'wc_product' ) ); + $this->assertSame( 'nav_menu_item', WPDO_Post_Fields::post_type_for_group( 'nav_menu_item' ) ); + $this->assertNull( WPDO_Post_Fields::post_type_for_group( 'wp_core' ), 'wp_core spans every post type' ); + } + + public function test_scoped_groups_map_through_the_registry(): void { + WPDO_Entity_Registry::register_group( 'post', 'x_core', array( array( 'key' => 'x_price', 'type' => 'decimal' ) ), array( 'post_types' => array( 'x_type' ) ) ); + + $this->assertSame( 'x_type', WPDO_Post_Fields::post_type_for_group( 'x_core' ) ); + $this->assertSame( array( 'x_core' ), WPDO_Post_Fields::groups_for_post_type( 'x_type' ) ); + $this->assertSame( array( 'wc_product' ), WPDO_Post_Fields::groups_for_post_type( 'product' ) ); + $this->assertNull( WPDO_Post_Fields::post_type_for_group( 'hp_listing_core' ), 'unregistered HivePress group is unknown to core' ); + } + // ── nav_menu_item group ────────────────────────────────────────────────── public function test_nav_menu_item_has_8_keys(): void { diff --git a/tests/unit/RestApiTest.php b/tests/unit/RestApiTest.php index ede0a39..d17c9cf 100644 --- a/tests/unit/RestApiTest.php +++ b/tests/unit/RestApiTest.php @@ -155,6 +155,17 @@ class RestApiTest extends TestCase { $this->assertIsArray( $response->get_data() ); } + public function test_default_post_type_is_post_and_filterable(): void { + $this->assertSame( 'post', WPDO_REST_API::default_post_type() ); + + $GLOBALS['_wp_filter_callbacks']['tmdo_rest_default_post_type'][] = static fn() => 'hp_listing'; + try { + $this->assertSame( 'hp_listing', WPDO_REST_API::default_post_type() ); + } finally { + unset( $GLOBALS['_wp_filter_callbacks']['tmdo_rest_default_post_type'] ); + } + } + public function test_get_listings_rejects_unregistered_post_type(): void { $req = new WP_REST_Request( 'GET', '/wpdo/v1/listings' ); $req->set_param( 'post_type', 'no_such_type' );