fix(2meet-data-optimizer): route post entity keys by post_type
- Entity groups can declare post_types; get_field() resolves a post's key against its own type's groups first, then unscoped ones (legacy last-wins lookup kept for callers without a post type) - Hook Bus and the post query router pass the post type, so a listing's hp_rating / hp_status / hp_verified map to hp_listing_core instead of the vendor/request tables; core HP groups declare their post types (schema hashes unchanged) - Behind tmdo_post_scoped_routing: on for sites without post flat rows, off where rows may sit in the wrong table until PR-034 reconciles them (dry-run: dev20–22 off, dev23/24/30/31/40 on) - Verify: EntityRegistryScopeTest (8), PostScopedRoutingTest (4); core unit 630 / integration 443, HP 144/49, WC 10/22 OK - PR: PR-033
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* Post entity groups scoped to post types.
|
||||
*
|
||||
* The post entity used to keep one meta_key index for every post type, so a
|
||||
* key shared by several groups (hp_rating in hp_listing_core and
|
||||
* hp_vendor_core) was routed to whichever group registered last — a
|
||||
* listing's hp_rating landed in the vendor table. Groups can now declare the
|
||||
* post types they belong to, and lookups that pass a post type use it.
|
||||
*/
|
||||
class EntityRegistryScopeTest extends TestCase {
|
||||
|
||||
protected function setUp(): void {
|
||||
TMDO_Entity_Registry::init();
|
||||
TMDO_Entity_Registry::register_adapter( 'post', $this->createMock( TMDO_Entity_Adapter_Interface::class ) );
|
||||
$GLOBALS['_wp_options'] = array( TMDO_Entity_Registry::SCOPED_ROUTING_OPTION => '1' );
|
||||
|
||||
TMDO_Entity_Registry::register_group( 'post', 'site_core', array( array( 'key' => '_edit_lock', 'type' => 'text' ) ) );
|
||||
TMDO_Entity_Registry::register_group(
|
||||
'post',
|
||||
'listing_core',
|
||||
array(
|
||||
array( 'key' => 'rating', 'type' => 'decimal' ),
|
||||
array( 'key' => 'price', 'type' => 'decimal' ),
|
||||
),
|
||||
array( 'post_types' => array( 'hp_listing' ) )
|
||||
);
|
||||
TMDO_Entity_Registry::register_group(
|
||||
'post',
|
||||
'vendor_core',
|
||||
array( array( 'key' => 'rating', 'type' => 'decimal' ) ),
|
||||
array( 'post_types' => array( 'hp_vendor' ) )
|
||||
);
|
||||
}
|
||||
|
||||
public function test_shared_key_resolves_to_the_group_of_the_post_type(): void {
|
||||
$this->assertSame( 'listing_core', TMDO_Entity_Registry::get_field( 'post', 'rating', 'hp_listing' )['group'] );
|
||||
$this->assertSame( 'vendor_core', TMDO_Entity_Registry::get_field( 'post', 'rating', 'hp_vendor' )['group'] );
|
||||
}
|
||||
|
||||
public function test_scoped_key_is_unmanaged_for_other_post_types(): void {
|
||||
$this->assertNull( TMDO_Entity_Registry::get_field( 'post', 'rating', 'post' ) );
|
||||
$this->assertNull( TMDO_Entity_Registry::get_field( 'post', 'price', 'hp_vendor' ) );
|
||||
}
|
||||
|
||||
public function test_unscoped_group_applies_to_every_post_type(): void {
|
||||
$this->assertSame( 'site_core', TMDO_Entity_Registry::get_field( 'post', '_edit_lock', 'hp_listing' )['group'] );
|
||||
$this->assertSame( 'site_core', TMDO_Entity_Registry::get_field( 'post', '_edit_lock', 'page' )['group'] );
|
||||
}
|
||||
|
||||
public function test_lookup_without_post_type_keeps_legacy_last_wins(): void {
|
||||
$this->assertSame( 'vendor_core', TMDO_Entity_Registry::get_field( 'post', 'rating' )['group'] );
|
||||
}
|
||||
|
||||
public function test_scoping_is_off_until_the_option_enables_it(): void {
|
||||
$GLOBALS['_wp_options'][ TMDO_Entity_Registry::SCOPED_ROUTING_OPTION ] = '0';
|
||||
|
||||
$this->assertSame( 'vendor_core', TMDO_Entity_Registry::get_field( 'post', 'rating', 'hp_listing' )['group'] );
|
||||
$this->assertSame( 'listing_core', TMDO_Entity_Registry::get_field( 'post', 'price', 'hp_vendor' )['group'] );
|
||||
}
|
||||
|
||||
public function test_scope_is_not_part_of_the_field_definition(): void {
|
||||
// Keeps schema hashes and PR-017 collision checks unchanged.
|
||||
$fields = TMDO_Entity_Registry::get_group_fields( 'post', 'vendor_core' );
|
||||
$this->assertArrayNotHasKey( 'post_types', $fields[0] );
|
||||
}
|
||||
|
||||
public function test_scoped_routing_default_waits_for_reconcile_on_sites_with_post_flat_data(): void {
|
||||
// Existing flat rows may sit in the wrong group table (legacy routing);
|
||||
// switching lookups before they are reconciled would hide them.
|
||||
$this->assertSame( '0', TMDO_Installer::post_scoped_routing_default( 'aeav_only', true ) );
|
||||
$this->assertSame( '0', TMDO_Installer::post_scoped_routing_default( 'dual_write', true ) );
|
||||
$this->assertSame( '1', TMDO_Installer::post_scoped_routing_default( 'aeav_only', false ) );
|
||||
$this->assertSame( '1', TMDO_Installer::post_scoped_routing_default( 'disabled', true ) );
|
||||
}
|
||||
|
||||
public function test_core_hivepress_groups_are_scoped_without_changing_their_hash(): void {
|
||||
TMDO_Entity_Registry::init();
|
||||
TMDO_Entity_Registry::register_adapter( 'post', $this->createMock( TMDO_Entity_Adapter_Interface::class ) );
|
||||
TMDO_Post_Fields::register_entity_fields();
|
||||
|
||||
$persisted = array(
|
||||
'hp_listing_core' => 'fb5ab760',
|
||||
'hp_request_core' => '27d6f4f5',
|
||||
'hp_vendor_core' => '5366e5c8',
|
||||
);
|
||||
foreach ( $persisted as $group => $hash ) {
|
||||
$fields = TMDO_Entity_Registry::get_group_fields( 'post', $group );
|
||||
$this->assertSame( $hash, substr( TMDO_Schema_Manager::calculate_schema_hash( $fields ), 0, 8 ), $group );
|
||||
}
|
||||
|
||||
$this->assertSame( 'hp_listing_core', TMDO_Entity_Registry::get_field( 'post', 'hp_rating', 'hp_listing' )['group'] );
|
||||
$this->assertSame( 'hp_listing_core', TMDO_Entity_Registry::get_field( 'post', 'hp_status', 'hp_listing' )['group'] );
|
||||
$this->assertSame( 'hp_request_core', TMDO_Entity_Registry::get_field( 'post', 'hp_status', 'hp_request' )['group'] );
|
||||
$this->assertSame( 'hp_vendor_core', TMDO_Entity_Registry::get_field( 'post', 'hp_user', 'hp_vendor' )['group'] );
|
||||
$this->assertSame( 'hp_request_core', TMDO_Entity_Registry::get_field( 'post', 'hp_user', 'hp_request' )['group'] );
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user