setAccessible( true ); $prop->setValue( null, array() ); } // ── 常數契約 ──────────────────────────────────────────────────────────── public function test_protected_options_covers_ninjafirewall_keys(): void { $ref = new ReflectionClass( 'TMDO_Options_Manager' ); $protected = $ref->getConstant( 'PROTECTED_OPTIONS' ); $this->assertIsArray( $protected ); foreach ( array( 'nfw_options', 'nfw_rules', 'nfw_checked' ) as $key ) { $this->assertContains( $key, $protected, "{$key} 必須列入 PROTECTED_OPTIONS,否則重導向後 NinjaFirewall Full WAF 會靜默失效" ); } } // ── 註冊守衛 ──────────────────────────────────────────────────────────── public function test_protected_options_are_not_registered(): void { TMDO_Options_Manager::register_settings_group( 'waf_guard_test', array( 'nfw_options', 'nfw_rules', 'nfw_checked' ) ); $this->assertSame( array(), TMDO_Options_Manager::get_redirected_options(), '受保護的選項不得進入重導向清單' ); } public function test_protected_options_get_no_interception_filters(): void { TMDO_Options_Manager::register_settings_group( 'waf_guard_test', array( 'nfw_options', 'nfw_rules' ) ); $hooks = $GLOBALS['_wp_filter_callbacks'] ?? array(); foreach ( array( 'nfw_options', 'nfw_rules' ) as $key ) { $this->assertArrayNotHasKey( "pre_option_{$key}", $hooks, "pre_option_{$key} 不得被掛上 —— 會讓 WAF 讀到轉址後的值" ); $this->assertArrayNotHasKey( "pre_update_option_{$key}", $hooks, "pre_update_option_{$key} 不得被掛上 —— 會讓設定不再寫回 wp_options" ); } } /** 全部鍵都被擋下時應提前返回,不建立設定表。 */ public function test_all_protected_keys_skips_table_creation(): void { global $wpdb; $before = $wpdb->last_query ?? null; TMDO_Options_Manager::register_settings_group( 'waf_guard_test', array( 'nfw_options' ) ); $this->assertSame( $before, $wpdb->last_query ?? null, '不應對資料庫發出任何查詢' ); } }