test(2meet-data-optimizer-hivepress-addon): pin hp entity group definitions to persisted schema hashes
- HivePressEntityGroupsTest no longer loads core TMDO_Post_Fields / TMDO_Member_Fields, so it survives core dropping them (PR-020b) - Pin the 4 groups to their wpdo_registry_meta hashes and the current owner of the 8 shared post keys (documented as existing behaviour, not intent) - Verify: HP unit 144 OK; mutating one field type fails the hash test - PR: PR-020a
This commit is contained in:
@@ -7,74 +7,63 @@ use PHPUnit\Framework\TestCase;
|
||||
* The AddOn owns the HivePress entity groups core used to register.
|
||||
*
|
||||
* Their definitions are persisted (wpdo_registry_meta schema hash) and the
|
||||
* flat tables on live sites were built from core's version, so the AddOn must
|
||||
* register byte-identical definitions: any drift changes the schema hash and
|
||||
* would ALTER tables that hold aeav_only data once core stops registering
|
||||
* them (PR-020).
|
||||
* flat tables on live sites were built from them, so they are pinned to the
|
||||
* persisted hashes: any drift would ALTER flat tables that may hold
|
||||
* aeav_only data. (Values recorded on dev20, 2026-09-25.)
|
||||
*/
|
||||
class HivePressEntityGroupsTest extends TestCase {
|
||||
|
||||
private const GROUPS = array(
|
||||
array( 'post', 'hp_listing_core' ),
|
||||
array( 'post', 'hp_request_core' ),
|
||||
array( 'post', 'hp_vendor_core' ),
|
||||
array( 'user', 'hp_user' ),
|
||||
private const PERSISTED_HASHES = array(
|
||||
'post/hp_listing_core' => 'fb5ab760',
|
||||
'post/hp_request_core' => '27d6f4f5',
|
||||
'post/hp_vendor_core' => '5366e5c8',
|
||||
'user/hp_user' => '61ac526f',
|
||||
);
|
||||
|
||||
private function fresh_registry(): void {
|
||||
/**
|
||||
* Keys shared by several post groups resolve to the LAST group registered
|
||||
* (the post entity has a single field index, not one per post_type).
|
||||
*
|
||||
* ⚠️ This pins current behaviour, not desired behaviour: a listing's
|
||||
* hp_rating is routed to the hp_vendor_core table, its hp_status to
|
||||
* hp_request_core, etc. It is pinned so that moving the registration
|
||||
* between plugins cannot change routing silently; fixing the routing is
|
||||
* tracked separately in the backlog.
|
||||
*/
|
||||
private const SHARED_KEY_OWNERS = array(
|
||||
'hp_status' => 'hp_request_core',
|
||||
'hp_expired_time' => 'hp_request_core',
|
||||
'hp_view_count' => 'hp_request_core',
|
||||
'hp_verified' => 'hp_vendor_core',
|
||||
'hp_rating' => 'hp_vendor_core',
|
||||
'hp_rating_count' => 'hp_vendor_core',
|
||||
'hp_hourly_rate' => 'hp_vendor_core',
|
||||
'hp_user' => 'hp_vendor_core',
|
||||
);
|
||||
|
||||
protected function setUp(): void {
|
||||
TMDO_Entity_Registry::init();
|
||||
TMDO_Entity_Registry::register_adapter( 'post', $this->createMock( TMDO_Entity_Adapter_Interface::class ) );
|
||||
TMDO_Entity_Registry::register_adapter( 'user', $this->createMock( TMDO_Entity_Adapter_Interface::class ) );
|
||||
}
|
||||
|
||||
private function register_core(): void {
|
||||
TMDO_Post_Fields::register_entity_fields();
|
||||
TMDO_Member_Fields::register_entity_fields();
|
||||
}
|
||||
|
||||
public function test_definitions_match_core_exactly(): void {
|
||||
$this->fresh_registry();
|
||||
$this->register_core();
|
||||
$core = array();
|
||||
foreach ( self::GROUPS as $g ) {
|
||||
$core[ $g[1] ] = TMDO_Entity_Registry::get_group_fields( $g[0], $g[1] );
|
||||
}
|
||||
|
||||
$this->fresh_registry();
|
||||
TMDO_HivePress_Entity_Groups::register_entity_fields();
|
||||
}
|
||||
|
||||
foreach ( self::GROUPS as $g ) {
|
||||
$this->assertNotEmpty( $core[ $g[1] ], "core no longer registers {$g[1]}" );
|
||||
$this->assertSame( $core[ $g[1] ], TMDO_Entity_Registry::get_group_fields( $g[0], $g[1] ), "{$g[0]}/{$g[1]} drifted from core" );
|
||||
public function test_definitions_match_persisted_schema_hashes(): void {
|
||||
foreach ( self::PERSISTED_HASHES as $id => $hash ) {
|
||||
list( $type, $group ) = explode( '/', $id );
|
||||
$fields = TMDO_Entity_Registry::get_group_fields( $type, $group );
|
||||
$this->assertNotEmpty( $fields, "{$id} not registered" );
|
||||
$this->assertSame( $hash, substr( TMDO_Schema_Manager::calculate_schema_hash( $fields ), 0, 8 ), "{$id} drifted from the persisted definition" );
|
||||
}
|
||||
}
|
||||
|
||||
public function test_shared_keys_resolve_to_the_same_group_as_core(): void {
|
||||
// hp_status / hp_user / hp_view_count … appear in several post groups and
|
||||
// field_index is last-registered-wins, so registration order matters.
|
||||
$this->fresh_registry();
|
||||
$this->register_core();
|
||||
$core = array();
|
||||
foreach ( self::GROUPS as $g ) {
|
||||
foreach ( TMDO_Entity_Registry::get_group_keys( $g[0], $g[1] ) as $key ) {
|
||||
$core[ $g[0] . ':' . $key ] = TMDO_Entity_Registry::get_field( $g[0], $key )['group'];
|
||||
}
|
||||
}
|
||||
|
||||
$this->fresh_registry();
|
||||
TMDO_HivePress_Entity_Groups::register_entity_fields();
|
||||
|
||||
foreach ( $core as $id => $group ) {
|
||||
list( $type, $key ) = explode( ':', $id, 2 );
|
||||
$this->assertSame( $group, TMDO_Entity_Registry::get_field( $type, $key )['group'], $id );
|
||||
public function test_shared_keys_keep_their_current_owner(): void {
|
||||
foreach ( self::SHARED_KEY_OWNERS as $key => $group ) {
|
||||
$this->assertSame( $group, TMDO_Entity_Registry::get_field( 'post', $key )['group'], $key );
|
||||
}
|
||||
}
|
||||
|
||||
public function test_registering_alongside_core_raises_no_collision(): void {
|
||||
$this->fresh_registry();
|
||||
$this->register_core();
|
||||
|
||||
TMDO_HivePress_Entity_Groups::register_entity_fields();
|
||||
public function test_core_adapter_does_not_register_a_conflicting_group(): void {
|
||||
( new TMDO_HivePress_Core_Adapter() )->on_register_entity_fields();
|
||||
|
||||
$this->assertSame( array(), TMDO_Entity_Registry::get_collisions() );
|
||||
|
||||
Reference in New Issue
Block a user