query( "CREATE TABLE `{$wpdb->usermeta}` ( umeta_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, user_id BIGINT UNSIGNED NOT NULL DEFAULT 0, meta_key VARCHAR(255) DEFAULT NULL, meta_value LONGTEXT, PRIMARY KEY (umeta_id), KEY user_id (user_id) ) ENGINE=InnoDB" ); $wpdb->query( 'CREATE TABLE `' . self::DIFFS . "` ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, ts DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', entity_type VARCHAR(20) NOT NULL DEFAULT '', entity_id BIGINT UNSIGNED NOT NULL DEFAULT 0, meta_key VARCHAR(255) NOT NULL DEFAULT '', postmeta_value LONGTEXT, zone_value LONGTEXT, diff_hash VARCHAR(40) NOT NULL DEFAULT '', PRIMARY KEY (id) ) ENGINE=InnoDB" ); $wpdb->query( 'CREATE TABLE `' . self::ERRORS . "` ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, module VARCHAR(100) NOT NULL DEFAULT '', zone VARCHAR(20) NOT NULL DEFAULT '', hook VARCHAR(255) NOT NULL DEFAULT '', message TEXT NOT NULL, context LONGTEXT, created_at DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', PRIMARY KEY (id) ) ENGINE=InnoDB" ); for ( $id = 1; $id <= 30; $id++ ) { $wpdb->insert( $wpdb->usermeta, array( 'user_id' => $id, 'meta_key' => 'total_sales', 'meta_value' => '5' ) ); $wpdb->insert( $wpdb->usermeta, array( 'user_id' => $id, 'meta_key' => 'other_key', 'meta_value' => '5' ) ); } $GLOBALS['_wp_transients'] = array(); WPDO_Entity_Registry::init(); WPDO_Entity_Registry::register_adapter( 'user', new WPDO_Adapter_User() ); } protected function tearDown(): void { self::drop(); WPDO_Entity_Registry::init(); } private static function drop(): void { global $wpdb; foreach ( array( $wpdb->usermeta, self::DIFFS, self::ERRORS ) as $table ) { $wpdb->query( "DROP TABLE IF EXISTS `{$table}`" ); } } private function logged( string $key ): int { global $wpdb; return (int) $wpdb->get_var( $wpdb->prepare( 'SELECT COUNT(*) FROM `' . self::DIFFS . '` WHERE meta_key = %s', $key ) ); } private function stale_read( int $user_id, string $key ): void { TMDO_Shadow_Diff_Logger::compare_and_log( 'user', $user_id, $key, 4, array( 'type' => 'integer' ) ); } public function test_a_key_stale_on_every_object_logs_at_most_the_key_limit(): void { for ( $id = 1; $id <= 30; $id++ ) { $this->stale_read( $id, 'total_sales' ); } $this->assertSame( TMDO_Shadow_Diff_Logger::KEY_LIMIT, $this->logged( 'total_sales' ) ); } public function test_the_limit_is_per_key(): void { for ( $id = 1; $id <= 30; $id++ ) { $this->stale_read( $id, 'total_sales' ); } $this->stale_read( 1, 'other_key' ); $this->assertSame( 1, $this->logged( 'other_key' ) ); } public function test_the_same_object_and_key_still_log_once_per_window(): void { $this->stale_read( 1, 'total_sales' ); $this->stale_read( 1, 'total_sales' ); $this->assertSame( 1, $this->logged( 'total_sales' ) ); } }