chore: initial snapshot of 2meet-data-optimizer v0.1.0
Baseline before backporting wp-data-optimizer v3.0.1-v3.4.6. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TbG1keQQ7XBa7qMQY16KCY
This commit is contained in:
@@ -0,0 +1,223 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* Integration tests for WPDO_Zone_Cold against real MariaDB.
|
||||
*
|
||||
* Creates a dedicated cold table (wp_itest_wpdo_cold_itest) to exercise all
|
||||
* Zone C operations: set / get, set_many / get_blob, remove, delete, and
|
||||
* Object Cache invalidation.
|
||||
*
|
||||
* post_type = 'itest' maps to table prefix wp_itest_wpdo_cold_itest.
|
||||
*/
|
||||
class ZoneColdIntegrationTest extends TestCase {
|
||||
|
||||
private const POST_TYPE = 'itest';
|
||||
|
||||
/** Derived at runtime: $wpdb->prefix . 'wpdo_cold_itest' */
|
||||
private static string $table;
|
||||
|
||||
// ── Fixture lifecycle ─────────────────────────────────────────────────────
|
||||
|
||||
public static function setUpBeforeClass(): void {
|
||||
global $wpdb;
|
||||
self::$table = $wpdb->prefix . 'wpdo_cold_' . self::POST_TYPE;
|
||||
|
||||
$wpdb->query(
|
||||
"CREATE TABLE IF NOT EXISTS `" . self::$table . "` (
|
||||
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
post_id BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
|
||||
data LONGTEXT NOT NULL,
|
||||
updated_at DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY ui_post_id (post_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4"
|
||||
);
|
||||
}
|
||||
|
||||
public static function tearDownAfterClass(): void {
|
||||
global $wpdb;
|
||||
$wpdb->query( "DROP TABLE IF EXISTS `" . self::$table . "`" );
|
||||
}
|
||||
|
||||
protected function setUp(): void {
|
||||
global $wpdb;
|
||||
$wpdb->query( "TRUNCATE TABLE `" . self::$table . "`" );
|
||||
$GLOBALS['_wp_cache'] = [];
|
||||
}
|
||||
|
||||
// ── set / get ─────────────────────────────────────────────────────────────
|
||||
|
||||
public function test_set_and_get_single_field(): void {
|
||||
WPDO_Zone_Cold::set( 100, self::POST_TYPE, 'hp_description', 'Hello World' );
|
||||
$val = WPDO_Zone_Cold::get( 100, self::POST_TYPE, 'hp_description' );
|
||||
$this->assertSame( 'Hello World', $val );
|
||||
}
|
||||
|
||||
public function test_get_returns_null_for_missing_key(): void {
|
||||
WPDO_Zone_Cold::set( 101, self::POST_TYPE, 'hp_description', 'present' );
|
||||
$val = WPDO_Zone_Cold::get( 101, self::POST_TYPE, 'missing_key' );
|
||||
$this->assertNull( $val );
|
||||
}
|
||||
|
||||
public function test_get_returns_null_for_missing_post(): void {
|
||||
$val = WPDO_Zone_Cold::get( 9999, self::POST_TYPE, 'hp_description' );
|
||||
$this->assertNull( $val );
|
||||
}
|
||||
|
||||
public function test_set_overwrites_existing_value(): void {
|
||||
WPDO_Zone_Cold::set( 102, self::POST_TYPE, 'hp_website', 'http://old.example.com' );
|
||||
WPDO_Zone_Cold::set( 102, self::POST_TYPE, 'hp_website', 'http://new.example.com' );
|
||||
$val = WPDO_Zone_Cold::get( 102, self::POST_TYPE, 'hp_website' );
|
||||
$this->assertSame( 'http://new.example.com', $val );
|
||||
}
|
||||
|
||||
public function test_set_preserves_other_keys_in_blob(): void {
|
||||
WPDO_Zone_Cold::set( 103, self::POST_TYPE, 'hp_description', 'Keep me' );
|
||||
WPDO_Zone_Cold::set( 103, self::POST_TYPE, 'hp_website', 'https://keep.example.com' );
|
||||
|
||||
// Update only one key.
|
||||
WPDO_Zone_Cold::set( 103, self::POST_TYPE, 'hp_website', 'https://updated.example.com' );
|
||||
|
||||
$this->assertSame( 'Keep me', WPDO_Zone_Cold::get( 103, self::POST_TYPE, 'hp_description' ) );
|
||||
$this->assertSame( 'https://updated.example.com', WPDO_Zone_Cold::get( 103, self::POST_TYPE, 'hp_website' ) );
|
||||
}
|
||||
|
||||
// ── set_many / get_blob ───────────────────────────────────────────────────
|
||||
|
||||
public function test_set_many_stores_multiple_fields(): void {
|
||||
WPDO_Zone_Cold::set_many( 200, self::POST_TYPE, [
|
||||
'hp_description' => 'A great listing',
|
||||
'hp_website' => 'https://example.com',
|
||||
'hp_facebook' => 'https://facebook.com/test',
|
||||
] );
|
||||
|
||||
$this->assertSame( 'A great listing', WPDO_Zone_Cold::get( 200, self::POST_TYPE, 'hp_description' ) );
|
||||
$this->assertSame( 'https://example.com', WPDO_Zone_Cold::get( 200, self::POST_TYPE, 'hp_website' ) );
|
||||
$this->assertSame( 'https://facebook.com/test', WPDO_Zone_Cold::get( 200, self::POST_TYPE, 'hp_facebook' ) );
|
||||
}
|
||||
|
||||
public function test_get_blob_returns_all_fields(): void {
|
||||
WPDO_Zone_Cold::set_many( 201, self::POST_TYPE, [
|
||||
'hp_description' => 'Blob test',
|
||||
'hp_website' => 'https://blob.example.com',
|
||||
] );
|
||||
|
||||
$blob = WPDO_Zone_Cold::get_blob( 201, self::POST_TYPE );
|
||||
$this->assertIsArray( $blob );
|
||||
$this->assertArrayHasKey( 'hp_description', $blob );
|
||||
$this->assertArrayHasKey( 'hp_website', $blob );
|
||||
$this->assertSame( 'Blob test', $blob['hp_description'] );
|
||||
$this->assertSame( 'https://blob.example.com', $blob['hp_website'] );
|
||||
}
|
||||
|
||||
public function test_get_blob_returns_empty_array_for_missing_post(): void {
|
||||
$blob = WPDO_Zone_Cold::get_blob( 9998, self::POST_TYPE );
|
||||
$this->assertIsArray( $blob );
|
||||
$this->assertEmpty( $blob );
|
||||
}
|
||||
|
||||
public function test_set_many_merges_with_existing_blob(): void {
|
||||
WPDO_Zone_Cold::set_many( 202, self::POST_TYPE, [ 'hp_description' => 'First' ] );
|
||||
WPDO_Zone_Cold::set_many( 202, self::POST_TYPE, [ 'hp_website' => 'https://merge.example.com' ] );
|
||||
|
||||
$this->assertSame( 'First', WPDO_Zone_Cold::get( 202, self::POST_TYPE, 'hp_description' ) );
|
||||
$this->assertSame( 'https://merge.example.com', WPDO_Zone_Cold::get( 202, self::POST_TYPE, 'hp_website' ) );
|
||||
}
|
||||
|
||||
// ── remove ────────────────────────────────────────────────────────────────
|
||||
|
||||
public function test_remove_key_from_blob(): void {
|
||||
WPDO_Zone_Cold::set_many( 300, self::POST_TYPE, [
|
||||
'hp_description' => 'Keep me',
|
||||
'hp_website' => 'https://remove.example.com',
|
||||
] );
|
||||
|
||||
WPDO_Zone_Cold::remove( 300, self::POST_TYPE, 'hp_website' );
|
||||
|
||||
$this->assertSame( 'Keep me', WPDO_Zone_Cold::get( 300, self::POST_TYPE, 'hp_description' ) );
|
||||
$this->assertNull( WPDO_Zone_Cold::get( 300, self::POST_TYPE, 'hp_website' ) );
|
||||
}
|
||||
|
||||
public function test_remove_nonexistent_key_does_not_error(): void {
|
||||
WPDO_Zone_Cold::set( 301, self::POST_TYPE, 'hp_description', 'Safe' );
|
||||
WPDO_Zone_Cold::remove( 301, self::POST_TYPE, 'no_such_key' );
|
||||
// Original key should still be intact.
|
||||
$this->assertSame( 'Safe', WPDO_Zone_Cold::get( 301, self::POST_TYPE, 'hp_description' ) );
|
||||
}
|
||||
|
||||
// ── delete ────────────────────────────────────────────────────────────────
|
||||
|
||||
public function test_delete_removes_row(): void {
|
||||
global $wpdb;
|
||||
WPDO_Zone_Cold::set( 400, self::POST_TYPE, 'hp_description', 'To be deleted' );
|
||||
|
||||
WPDO_Zone_Cold::delete( 400, self::POST_TYPE );
|
||||
|
||||
$count = (int) $wpdb->get_var( "SELECT COUNT(*) FROM `" . self::$table . "` WHERE post_id = 400" );
|
||||
$this->assertSame( 0, $count );
|
||||
$this->assertNull( WPDO_Zone_Cold::get( 400, self::POST_TYPE, 'hp_description' ) );
|
||||
}
|
||||
|
||||
public function test_delete_nonexistent_post_does_not_error(): void {
|
||||
WPDO_Zone_Cold::delete( 9997, self::POST_TYPE );
|
||||
$this->assertTrue( true ); // Must not throw.
|
||||
}
|
||||
|
||||
// ── Object Cache ──────────────────────────────────────────────────────────
|
||||
|
||||
public function test_get_blob_populates_object_cache(): void {
|
||||
WPDO_Zone_Cold::set( 500, self::POST_TYPE, 'hp_description', 'Cached value' );
|
||||
|
||||
// Clear cache to force a DB read on the next call.
|
||||
$GLOBALS['_wp_cache'] = [];
|
||||
|
||||
// First get: reads from DB, warms the cache.
|
||||
$val = WPDO_Zone_Cold::get( 500, self::POST_TYPE, 'hp_description' );
|
||||
$this->assertSame( 'Cached value', $val );
|
||||
|
||||
// Cache entry must now exist.
|
||||
$cached = wp_cache_get( 'cold_500', 'wpdo_cold_itest' );
|
||||
$this->assertIsArray( $cached );
|
||||
$this->assertSame( 'Cached value', $cached['hp_description'] );
|
||||
}
|
||||
|
||||
public function test_set_invalidates_object_cache(): void {
|
||||
WPDO_Zone_Cold::set( 501, self::POST_TYPE, 'hp_description', 'Original' );
|
||||
|
||||
// Warm the cache by reading once.
|
||||
WPDO_Zone_Cold::get( 501, self::POST_TYPE, 'hp_description' );
|
||||
$this->assertNotFalse( wp_cache_get( 'cold_501', 'wpdo_cold_itest' ) );
|
||||
|
||||
// Write a new value — must invalidate the cached blob.
|
||||
WPDO_Zone_Cold::set( 501, self::POST_TYPE, 'hp_description', 'Updated' );
|
||||
$this->assertFalse( wp_cache_get( 'cold_501', 'wpdo_cold_itest' ) );
|
||||
|
||||
// Subsequent read must return the updated value (from DB).
|
||||
$val = WPDO_Zone_Cold::get( 501, self::POST_TYPE, 'hp_description' );
|
||||
$this->assertSame( 'Updated', $val );
|
||||
}
|
||||
|
||||
public function test_delete_invalidates_object_cache(): void {
|
||||
WPDO_Zone_Cold::set( 502, self::POST_TYPE, 'hp_description', 'Will be deleted' );
|
||||
|
||||
// Warm the cache.
|
||||
WPDO_Zone_Cold::get( 502, self::POST_TYPE, 'hp_description' );
|
||||
|
||||
// Delete — must clear cache.
|
||||
WPDO_Zone_Cold::delete( 502, self::POST_TYPE );
|
||||
$this->assertFalse( wp_cache_get( 'cold_502', 'wpdo_cold_itest' ) );
|
||||
}
|
||||
|
||||
// ── isolation ─────────────────────────────────────────────────────────────
|
||||
|
||||
public function test_different_post_ids_are_independent(): void {
|
||||
WPDO_Zone_Cold::set( 600, self::POST_TYPE, 'hp_description', 'Post 600' );
|
||||
WPDO_Zone_Cold::set( 601, self::POST_TYPE, 'hp_description', 'Post 601' );
|
||||
|
||||
$this->assertSame( 'Post 600', WPDO_Zone_Cold::get( 600, self::POST_TYPE, 'hp_description' ) );
|
||||
$this->assertSame( 'Post 601', WPDO_Zone_Cold::get( 601, self::POST_TYPE, 'hp_description' ) );
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user