diff --git a/tests/live/suites/router.php b/tests/live/suites/router.php index 40f326c..f57f83f 100644 --- a/tests/live/suites/router.php +++ b/tests/live/suites/router.php @@ -427,6 +427,7 @@ TMDO_Live::test( /** * HivePress-style sort-only search (rating__order), fields ids, first page. + * DECIMAL(10,1): what the HivePress Rating field (decimals 1) sends. * * @param string $order ASC | DESC. * @return array WP_Query args. @@ -441,8 +442,8 @@ function tmdo_live_router_rating_sort( string $order ): array { 'meta_query' => array( array( 'relation' => 'OR', - 'rating__order' => array( 'key' => 'hp_rating', 'type' => 'DECIMAL', 'compare' => 'NOT EXISTS' ), - array( 'key' => 'hp_rating', 'type' => 'DECIMAL', 'compare' => 'EXISTS' ), + 'rating__order' => array( 'key' => 'hp_rating', 'type' => 'DECIMAL(10,1)', 'compare' => 'NOT EXISTS' ), + array( 'key' => 'hp_rating', 'type' => 'DECIMAL(10,1)', 'compare' => 'EXISTS' ), ), ), 'orderby' => 'rating__order', @@ -450,6 +451,27 @@ function tmdo_live_router_rating_sort( string $order ): array { ); } +/** + * The native sort key of each post, in order (null without a rating). On the + * whole site many listings share a rating and native orders ties by chance, + * so a page is compared by its keys, not its ids. + * + * @param array $ids Post ids. + * @return array + */ +function tmdo_live_router_rating_keys( array $ids ): array { + global $wpdb; + $ids = array_map( 'intval', $ids ); + if ( empty( $ids ) ) { + return array(); + } + $rows = $wpdb->get_results( + "SELECT post_id, CAST(meta_value AS DECIMAL(10,1)) AS k FROM {$wpdb->postmeta} WHERE meta_key = 'hp_rating' AND post_id IN (" . implode( ',', $ids ) . ')', + OBJECT_K + ); + return array_map( static fn( $id ) => isset( $rows[ $id ] ) ? (string) $rows[ $id ]->k : null, $ids ); +} + /** * Native and routed runs of the same query. * @@ -476,7 +498,7 @@ TMDO_Live::test( TMDO_Post_Query_Router::forget_coverage(); foreach ( array( 'DESC', 'ASC' ) as $order ) { list( $native, $routed ) = tmdo_live_router_native_and_routed( tmdo_live_router_rating_sort( $order ) ); - tmdo_live_assert_same( array_map( 'intval', $native->posts ), array_map( 'intval', $routed->posts ), "{$order} ids" ); + tmdo_live_assert_same( tmdo_live_router_rating_keys( $native->posts ), tmdo_live_router_rating_keys( $routed->posts ), "{$order} sort keys" ); tmdo_live_assert_same( $native->found_posts, $routed->found_posts, "{$order} found_posts" ); tmdo_live_assert_true( 0 === strpos( ltrim( $routed->request ), 'SELECT STRAIGHT_JOIN' ), "{$order} flat-first: " . $routed->request ); } @@ -497,7 +519,8 @@ TMDO_Live::test( } finally { TMDO_Post_Query_Router::forget_coverage(); } - tmdo_live_assert_same( array_map( 'intval', $native->posts ), array_map( 'intval', $routed->posts ), 'ids' ); + tmdo_live_assert_same( tmdo_live_router_rating_keys( $native->posts ), tmdo_live_router_rating_keys( $routed->posts ), 'sort keys' ); + tmdo_live_assert_same( $native->found_posts, $routed->found_posts, 'found_posts' ); tmdo_live_assert_true( false === strpos( $routed->request, 'STRAIGHT_JOIN' ), 'not flat-first: ' . $routed->request ); } ); @@ -532,7 +555,8 @@ TMDO_Live::test( 'tax_query' => array( array( 'taxonomy' => 'hp_listing_category', 'field' => 'term_id', 'terms' => array( 999999999 ), 'operator' => 'NOT IN' ) ), ); list( $native, $routed ) = tmdo_live_router_native_and_routed( $args ); - tmdo_live_assert_same( array_map( 'intval', $native->posts ), array_map( 'intval', $routed->posts ), 'ids' ); + tmdo_live_assert_same( tmdo_live_router_rating_keys( $native->posts ), tmdo_live_router_rating_keys( $routed->posts ), 'sort keys' ); + tmdo_live_assert_same( $native->found_posts, $routed->found_posts, 'found_posts' ); tmdo_live_assert_true( 0 === strpos( ltrim( $routed->request ), 'SELECT STRAIGHT_JOIN' ), 'flat-first: ' . $routed->request ); tmdo_live_assert_true( false === stripos( $routed->request, 'GROUP BY' ), 'no GROUP BY: ' . $routed->request ); } @@ -552,7 +576,8 @@ TMDO_Live::test( 'tax_query' => array( array( 'taxonomy' => 'hp_listing_category', 'field' => 'term_id', 'terms' => $terms, 'operator' => 'IN' ) ), ); list( $native, $routed ) = tmdo_live_router_native_and_routed( $args ); - tmdo_live_assert_same( array_map( 'intval', $native->posts ), array_map( 'intval', $routed->posts ), 'ids' ); + tmdo_live_assert_same( tmdo_live_router_rating_keys( $native->posts ), tmdo_live_router_rating_keys( $routed->posts ), 'sort keys' ); + tmdo_live_assert_same( $native->found_posts, $routed->found_posts, 'found_posts' ); tmdo_live_assert_true( false !== stripos( $routed->request, 'GROUP BY' ), 'GROUP BY kept: ' . $routed->request ); } );