query( 'DROP TABLE IF EXISTS `' . self::TABLE . '`' ); $wpdb->query( 'CREATE TABLE `' . self::TABLE . '` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `post_id` bigint(20) unsigned NOT NULL DEFAULT 0, `meta_key` varchar(255) NOT NULL DEFAULT \'\', `meta_value` longtext DEFAULT NULL, `expires_at` datetime DEFAULT NULL, `created_at` datetime NOT NULL DEFAULT \'0000-00-00 00:00:00\', PRIMARY KEY (`id`), UNIQUE KEY `ui_post_meta` (`post_id`, `meta_key`), KEY `expires_at` (`expires_at`) ) 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 . '`' ); } // ── set / get ──────────────────────────────────────────────────────── public function test_set_and_get_basic(): void { WPDO_Zone_Warm::set( 1, 'test_key', 'hello' ); $this->assertSame( 'hello', WPDO_Zone_Warm::get( 1, 'test_key' ) ); } public function test_get_returns_null_for_missing_key(): void { $this->assertNull( WPDO_Zone_Warm::get( 9999, 'no_such_key' ) ); } public function test_set_overwrites_existing_value(): void { WPDO_Zone_Warm::set( 2, 'counter', '1' ); WPDO_Zone_Warm::set( 2, 'counter', '5' ); $this->assertSame( '5', WPDO_Zone_Warm::get( 2, 'counter' ) ); } // ── TTL / expiry ───────────────────────────────────────────────────── public function test_set_with_future_ttl_is_readable(): void { WPDO_Zone_Warm::set( 3, 'flag', 'active', 3600 ); // expires in 1 hour $this->assertSame( 'active', WPDO_Zone_Warm::get( 3, 'flag' ) ); } public function test_expired_entry_returns_null(): void { global $wpdb; // Insert directly with a past expiry timestamp. $wpdb->query( "INSERT INTO `" . self::TABLE . "` (post_id, meta_key, meta_value, expires_at, created_at) VALUES (4, 'old_flag', 'gone', '2000-01-01 00:00:00', '2000-01-01 00:00:00')" ); $this->assertNull( WPDO_Zone_Warm::get( 4, 'old_flag' ) ); } public function test_null_ttl_entry_never_expires(): void { WPDO_Zone_Warm::set( 5, 'permanent', 'stays', null ); $this->assertSame( 'stays', WPDO_Zone_Warm::get( 5, 'permanent' ) ); } // ── delete ─────────────────────────────────────────────────────────── public function test_delete_removes_specific_key(): void { WPDO_Zone_Warm::set( 6, 'key_a', 'alpha' ); WPDO_Zone_Warm::set( 6, 'key_b', 'beta' ); WPDO_Zone_Warm::delete( 6, 'key_a' ); $this->assertNull( WPDO_Zone_Warm::get( 6, 'key_a' ) ); $this->assertSame( 'beta', WPDO_Zone_Warm::get( 6, 'key_b' ) ); } public function test_delete_all_removes_all_keys_for_post(): void { WPDO_Zone_Warm::set( 7, 'x', '1' ); WPDO_Zone_Warm::set( 7, 'y', '2' ); WPDO_Zone_Warm::set( 7, 'z', '3' ); WPDO_Zone_Warm::delete_all( 7 ); $this->assertNull( WPDO_Zone_Warm::get( 7, 'x' ) ); $this->assertNull( WPDO_Zone_Warm::get( 7, 'y' ) ); $this->assertNull( WPDO_Zone_Warm::get( 7, 'z' ) ); } public function test_delete_all_does_not_affect_other_posts(): void { WPDO_Zone_Warm::set( 8, 'shared_key', 'post_8' ); WPDO_Zone_Warm::set( 9, 'shared_key', 'post_9' ); WPDO_Zone_Warm::delete_all( 8 ); $this->assertNull( WPDO_Zone_Warm::get( 8, 'shared_key' ) ); $this->assertSame( 'post_9', WPDO_Zone_Warm::get( 9, 'shared_key' ) ); } // ── purge_expired ──────────────────────────────────────────────────── public function test_purge_expired_removes_stale_entries(): void { global $wpdb; // One expired entry. $wpdb->query( "INSERT INTO `" . self::TABLE . "` (post_id, meta_key, meta_value, expires_at, created_at) VALUES (10, 'stale', 'gone', '2000-01-01 00:00:00', '2000-01-01 00:00:00')" ); // One valid entry. WPDO_Zone_Warm::set( 10, 'fresh', 'keep', 3600 ); $deleted = WPDO_Zone_Warm::purge_expired(); $this->assertSame( 1, $deleted ); $this->assertNull( WPDO_Zone_Warm::get( 10, 'stale' ) ); $this->assertSame( 'keep', WPDO_Zone_Warm::get( 10, 'fresh' ) ); } public function test_purge_expired_returns_zero_when_nothing_stale(): void { WPDO_Zone_Warm::set( 11, 'live', 'value', 3600 ); $this->assertSame( 0, WPDO_Zone_Warm::purge_expired() ); } // ── get_all ────────────────────────────────────────────────────────── public function test_get_all_returns_all_valid_keys_for_post(): void { WPDO_Zone_Warm::set( 12, 'ka', 'va' ); WPDO_Zone_Warm::set( 12, 'kb', 'vb' ); $all = WPDO_Zone_Warm::get_all( 12 ); $this->assertArrayHasKey( 'ka', $all ); $this->assertArrayHasKey( 'kb', $all ); $this->assertSame( 'va', $all['ka'] ); $this->assertSame( 'vb', $all['kb'] ); } public function test_get_all_excludes_expired_entries(): void { global $wpdb; WPDO_Zone_Warm::set( 13, 'live', 'yes' ); $wpdb->query( "INSERT INTO `" . self::TABLE . "` (post_id, meta_key, meta_value, expires_at, created_at) VALUES (13, 'dead', 'no', '2000-01-01 00:00:00', '2000-01-01 00:00:00')" ); $all = WPDO_Zone_Warm::get_all( 13 ); $this->assertArrayHasKey( 'live', $all ); $this->assertArrayNotHasKey( 'dead', $all ); } }