fix(vip): preserve safe HTML in VIP copy
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
7a0445fc4a
commit
573040381d
15 files changed
+155
-118
No files matched your search
@@ -52,7 +52,7 @@ test('弹窗文案字段更名为会员介绍/开通会员更多内容并改为
|
||||
// 会员介绍为单行 input(zibll text「一句话简介」);开通会员更多内容为 rows 4 的 HTML textarea。
|
||||
assert.match(
|
||||
vipSchemaJs,
|
||||
/key: 'pay_user_vip_desc',\s*\n\s*label: '会员介绍',\s*\n\s*type: 'input',\s*\n\s*default: '开通VIP会员,享受会员专属折扣以及多项特权'/
|
||||
/key: 'pay_user_vip_desc',\s*\n\s*label: '会员介绍',\s*\n\s*type: 'input',\s*\n\s*sanitize_type: 'html',\s*\n\s*default: '开通VIP会员,享受会员专属折扣以及多项特权'/
|
||||
);
|
||||
assert.match(
|
||||
vipSchemaJs,
|
||||
@@ -60,7 +60,7 @@ test('弹窗文案字段更名为会员介绍/开通会员更多内容并改为
|
||||
);
|
||||
assert.match(
|
||||
schemaPhp,
|
||||
/'key' => 'pay_user_vip_desc', 'label' => '会员介绍', 'type' => 'input', 'default' => '开通VIP会员,享受会员专属折扣以及多项特权'/
|
||||
/'key' => 'pay_user_vip_desc', 'label' => '会员介绍', 'type' => 'input', 'sanitize_type' => 'html', 'default' => '开通VIP会员,享受会员专属折扣以及多项特权'/
|
||||
);
|
||||
assert.match(
|
||||
schemaPhp,
|
||||
@@ -141,7 +141,7 @@ test('文案默认值三处一致并对齐 zibll', () => {
|
||||
assert.ok(schemaPhp.includes(`'default' => '${DESC_DEFAULT}'`));
|
||||
assert.ok(schemaPhp.includes(`'default' => '${MORE_DEFAULT}'`));
|
||||
// PaymentRuntime 运行时回退(get_all 不合并 schema 默认值,回退即实际默认值)。
|
||||
assert.ok(paymentRuntime.includes(`$desc = sanitize_text_field((string) ($settings['pay_user_vip_desc'] ?? __('${DESC_DEFAULT}', 'aksrt')))`));
|
||||
assert.ok(paymentRuntime.includes(`$desc = wp_kses_post((string) ($settings['pay_user_vip_desc'] ?? __('${DESC_DEFAULT}', 'aksrt')))`));
|
||||
assert.ok(paymentRuntime.includes(`$more = (string) ($settings['pay_user_vip_more'] ?? '${MORE_DEFAULT}')`));
|
||||
assert.ok(paymentRuntime.includes("$name1 = __('黄金会员', 'aksrt');"));
|
||||
assert.ok(paymentRuntime.includes("$name2 = __('钻石会员', 'aksrt');"));
|
||||
@@ -154,19 +154,41 @@ test('文案默认值三处一致并对齐 zibll', () => {
|
||||
}
|
||||
});
|
||||
|
||||
test('权益与卡密说明字段保存时保留 HTML', () => {
|
||||
// 权益字段已并入「会员购买选项」的等级 Tab,标签统一为「会员权益 HTML」。
|
||||
assert.ok(vipSchemaJs.includes("key: `pay_user_vip_${level}_equity`, label: '会员权益 HTML', type: 'textarea', sanitize_type: 'html'"));
|
||||
assert.ok(schemaPhp.includes("['key' => 'pay_user_vip_' . $level . '_equity', 'label' => '会员权益 HTML', 'type' => 'textarea', 'sanitize_type' => 'html'"));
|
||||
assert.ok(rechargeJs.includes("key: 'pay_vip_pass_charge_desc', label: '卡密兑换会员说明', type: 'textarea', sanitize_type: 'html'"));
|
||||
assert.ok(schemaPhp.includes("'key' => 'pay_vip_pass_charge_desc', 'label' => '卡密兑换会员说明', 'type' => 'textarea', 'sanitize_type' => 'html'"));
|
||||
test('会员等级名称、简介、续费和升级介绍都声明 HTML 净化', () => {
|
||||
const levelFieldsJs = slice(vipSchemaJs, 'function vipLevelTabFields', 'export const vipSchema');
|
||||
const levelFieldsPhp = slice(schemaPhp, 'private static function vip_level_tab_fields', 'private static function vip_product_defaults');
|
||||
assert.match(levelFieldsJs, /pay_user_vip_\$\{level\}_name[^\n]*sanitize_type: 'html'/);
|
||||
assert.match(levelFieldsJs, /pay_user_vip_\$\{level\}_desc[^\n]*sanitize_type: 'html'/);
|
||||
assert.match(levelFieldsPhp, /pay_user_vip_' \. \$level \. '_name'[^\n]*'sanitize_type' => 'html'/);
|
||||
assert.match(levelFieldsPhp, /pay_user_vip_' \. \$level \. '_desc'[^\n]*'sanitize_type' => 'html'/);
|
||||
assert.match(vipSchemaJs, /key: 'vip_renew_desc',[\s\S]*?sanitize_type: 'html'/);
|
||||
assert.match(schemaPhp, /'key' => 'vip_renew_desc'[^\n]*'sanitize_type' => 'html'/);
|
||||
assert.match(vipSchemaJs, /key: 'vip_upgrade_desc',[^\n]*sanitize_type: 'html'/);
|
||||
assert.match(schemaPhp, /'key' => 'vip_upgrade_desc'[^\n]*'sanitize_type' => 'html'/);
|
||||
assert.match(vipSchemaJs, /key: 'pay_user_vip_desc',[\s\S]*?sanitize_type: 'html'/);
|
||||
assert.match(schemaPhp, /'key' => 'pay_user_vip_desc'[^\n]*'sanitize_type' => 'html'/);
|
||||
});
|
||||
|
||||
test('会员介绍运行时按单行文本净化', () => {
|
||||
// 只收敛 VIP 设置函数:充值等其它设置的 $desc 与本文无关。
|
||||
test('权益和促销标签 HTML 通过安全净化及 HTML 渲染保留', () => {
|
||||
const vipSettings = slice(paymentRuntime, 'public static function get_payment_vip_settings', 'public static function get_payment_revenue_settings');
|
||||
assert.ok(vipSettings.includes("$desc = sanitize_text_field((string) ($settings['pay_user_vip_desc']"));
|
||||
assert.ok(!vipSettings.includes('$desc = sanitize_textarea_field'));
|
||||
assert.match(vipSettings, /'equity'\s*=> wp_kses_post\(/);
|
||||
assert.doesNotMatch(vipSettings, /\$allowed_equity/);
|
||||
const equityHelper = read('inc', 'helpers', 'aksrt-vip.php');
|
||||
assert.match(equityHelper, /\$clean = trim\(wp_kses_post\(\$raw\)\)/);
|
||||
assert.match(payVipJs, /if \(item\.discount_tag\) append\(product, htmlNode\(/);
|
||||
assert.match(payVipJs, /append\(info, htmlNode\("div", "", levelInfo\.equity\)\)/);
|
||||
assert.match(payVipJs, /htmlNode\("div", "v-name", levelInfo\.name \|\| group\.name/);
|
||||
assert.match(payVipJs, /htmlNode\("div", "v-desc em09", levelInfo\.desc/);
|
||||
assert.match(vipTabPhp, /wp_kses_post\(\$card_desc\)/);
|
||||
});
|
||||
|
||||
test('会员介绍按 post 级 HTML 安全净化并在弹窗与用户中心渲染', () => {
|
||||
const vipSettings = slice(paymentRuntime, 'public static function get_payment_vip_settings', 'public static function get_payment_revenue_settings');
|
||||
assert.match(vipSettings, /\$desc = wp_kses_post\(\(string\) \(\$settings\['pay_user_vip_desc'\]/);
|
||||
assert.match(vipSettings, /'desc'\s+=> wp_kses_post\(\(string\) \(\$settings\['pay_user_vip_1_desc'\]/);
|
||||
assert.match(vipSettings, /'desc'\s+=> wp_kses_post\(\(string\) \(\$settings\['pay_user_vip_2_desc'\]/);
|
||||
assert.match(vipTabPhp, /wp_kses_post\(\$vip_description\)/);
|
||||
assert.match(payVipJs, /htmlNode\("div", "muted-2-color em09", catalog\.desc\)/);
|
||||
});
|
||||
|
||||
test('开通会员更多内容只在弹窗内渲染,不裸露在用户中心页面', () => {
|
||||
|
||||
Reference in new issue
Block a user