'use strict'; /** * 微信模板消息 REST 契约(修复存量审计错误): * 1) /wechat/status 与 /wechat/settings 的路由回调方法在 UserController 中真实存在; * 2) 状态读取委托 WeChatNotify::get_status(),写入委托 Settings::update_wechat_settings(); * 3) app_secret 掩码 *** 不覆盖已存密钥,输入经 sanitize_text_field 消毒; * 4) PHP harness 驱动真实控制器验证上述行为; * 5) aksrt_settings 上的微信通知死键(wechat_notify_* 等)已彻底移除, * 活配置面仅剩 aksrt_wechat_settings(/users/wechat-template 自定义页)。 */ const assert = require('node:assert/strict'); const { execFileSync } = require('node:child_process'); const fs = require('node:fs'); const path = require('node:path'); const test = require('node:test'); const root = path.resolve(__dirname, '..', '..'); const controller = fs.readFileSync(path.join(root, 'src/Admin/UserController.php'), 'utf8'); const schemaUsers = fs.readFileSync(path.join(root, 'src/Admin/Schema/SchemaUsers.php'), 'utf8'); const usersSchemaIndex = fs.readFileSync(path.join(root, 'assets/admin/src/schema/sections/users/index.js'), 'utf8'); const usersSections = fs.readFileSync(path.join(root, 'assets/admin/src/constants/sections/users.js'), 'utf8'); // 死双路面:写进 aksrt_settings、全仓无消费方的微信通知键。 const DEAD_WECHAT_KEYS = [ 'wechat_notify_enabled', 'wechat_app_id', 'wechat_app_secret', 'wechat_template_id', 'wechat_token', 'wechat_encoding_aes_key', 'wechat_template_comment', 'wechat_template_reply', 'wechat_template_system', 'wechat_template_order', 'wechat_notify_comment', 'wechat_notify_reply', 'wechat_notify_system', 'wechat_notify_order', 'wechat_bind_entry', ]; test('路由与回调方法配对存在', () => { assert.match(controller, /register_rest_route\(self::API_NAMESPACE, '\/wechat\/status'[\s\S]*?'callback'\s*=>\s*\[\$this, 'get_wechat_status'\]/); assert.match(controller, /register_rest_route\(self::API_NAMESPACE, '\/wechat\/settings'[\s\S]*?'callback'\s*=>\s*\[\$this, 'update_wechat_settings'\]/); assert.match(controller, /public function get_wechat_status\(\\WP_REST_Request \$request\)/); assert.match(controller, /public function update_wechat_settings\(\\WP_REST_Request \$request\)/); }); test('状态与写入委托既有服务层', () => { assert.match(controller, /WeChatNotify::get_instance\(\)->get_status\(\)/); assert.match(controller, /Settings::update_wechat_settings\(/); }); test('密钥掩码与输入消毒', () => { assert.match(controller, /\$params\['app_secret'\] !== '\*\*\*'/); assert.match(controller, /sanitize_text_field\(\(string\) \$params\['app_id'\]\)/); assert.match(controller, /sanitize_text_field\(\(string\) \$params\['app_secret'\]\)/); assert.match(controller, /sanitize_text_field\(\(string\) \$params\['template_id'\]\)/); }); test('微信设置行为 harness 通过', () => { const harness = path.join(root, 'tests', 'admin', 'wechat-settings-harness.php'); const output = execFileSync('php', [harness], { encoding: 'utf8' }); assert.match(output, /WeChat settings harness passed/); }); test('死双路面(aksrt_settings 微信通知键)已彻底移除', () => { for (const key of DEAD_WECHAT_KEYS) { assert.ok(!schemaUsers.includes(key), `SchemaUsers 残留: ${key}`); assert.ok(!usersSections.includes(key), `users 菜单常量残留: ${key}`); } assert.ok(!usersSchemaIndex.includes('wechatSchema'), 'users schema index 残留 wechatSchema 注册'); assert.ok(!usersSections.includes("route: '/users/wechat',"), '用户菜单残留微信通知 schema 页'); assert.ok(!fs.existsSync(path.join(root, 'assets/admin/src/schema/sections/users/wechat.js')), 'wechat.js 未删除'); }); test('活配置面保持唯一(aksrt_wechat_settings + 自定义页)', () => { assert.match(usersSections, /key: 'users-wechat-template'/); assert.match(usersSections, /route: '\/users\/wechat-template'/); assert.match(controller, /WeChatNotify::get_instance\(\)->get_status\(\)/); assert.match(controller, /Settings::update_wechat_settings\(/); });