Files
wordpress-theme-aksrt/tests/widget-system/user-center-sidebar-icons-contract.test.cjs
T
kate522 4b18f7ef2c fix(user-center): replicate reference theme sidebar icons via SVG sprite
The user-center sidebar rendered Font Awesome glyphs while the reference theme
paints multi-tone inline SVGs, and several glyphs were simply wrong for their
slot: fa-chart-line served both 我的等级 and 推广收益, fa-money-bill served both
余额 and 积分, and fa-pen stood in for 创作收益.

The theme already ships every sprite key the reference sidebar needs in
assets/js/runtime/svg-icon.js, and main.min.js injects the <symbol id="icon-*">
set on every frontend page, so no new icon system was needed. The two grids now
use the reference theme's icon-but-box / user-icon-but-box shell (four per row,
em16 icon, 12px muted label) in place of AKSRT's tinted 38px pill, and every
remaining sidebar glyph and arrow resolves through aksrt_icon_markup():

  我的服务  我的等级 trend-color, 官方认证 user-auth, 我的订单 order-color
  功能设置  消息通知 msg-color, 个人资料 user-color, 账户安全 security-color
  资产卡    余额 money-color-2, 积分 points-color
  中心卡    创作收益 merchant-color, 推广收益 money-color
  其它      VIP 入口 vip_1, 抽屉触发器 menu, 箭头统一 right

Dead code went with the swap: the whole .uc-service-grid block including the
unused --cart and --revenue tones, the count badge (no caller ever set count),
and the tone key. The two card selectors that targeted <i> now also cover <svg>
so the icon sizes survive the element change, and the VIP arrow keeps
uc-sidebar-vip__arrow for its hover animation. level/profile/settings gained
their missing tab keys, which completes the icon-but-* class names and lets the
existing .is-active sync cover all six entries.

Verification: node --test across widget-system, navigation, admin,
asset-ledger, dev, front-submit and fixtures (620 tests), plus php -l on the
five changed PHP files. Contract-locked in
tests/widget-system/user-center-sidebar-icons-contract.test.cjs.
2026-10-18 12:55:30 +08:00

118 lines
5.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 用户中心左侧栏图标契约(参考主题 1:1 对齐)。
*
* 硬约束:
* 1) 「我的服务 / 功能设置」两个网格使用参考主题的 icon-but-box / user-icon-but-box
* 外壳,图标全部来自主题内置 SVG sprite(aksrt_icon_markup('zibsvg-*')),
* 不再出现 Font Awesome 字形。
* 2) 侧栏其余部件(余额/积分卡、创作/推广卡、VIP 入口、抽屉触发器)同样只使用
* sprite 图标,箭头统一为 zibsvg-right,保证侧栏只剩一种图标族。
* 3) 旧的 uc-service-grid 外壳、色调底色与计数角标必须已彻底移除,不得残留。
*/
'use strict';
const assert = require('node:assert/strict');
const fs = require('node:fs');
const path = require('node:path');
const test = require('node:test');
const root = path.resolve(__dirname, '..', '..');
const read = (file) => fs.readFileSync(path.join(root, file), 'utf8');
const sidebarDir = 'inc/helpers/user-center-renderers/';
const sidebarFiles = [
'sidebar-nav.php',
'sidebar-commerce.php',
'sidebar-creator.php',
'sidebar-vip.php',
'profile-sidebar.php',
];
test('服务/设置网格使用参考主题 icon-but-box 外壳与 sprite 图标', () => {
const nav = read(sidebarDir + 'sidebar-nav.php');
assert.match(nav, /class="flex ac hh text-center icon-but-box user-icon-but-box"/);
assert.match(nav, /<div class="em16"><\?php echo \$icon_html;/);
assert.match(nav, /<div class="px12 muted-color mt3">/);
assert.match(nav, /aksrt_icon_markup\('zibsvg-' \. \(string\) \$item\['icon'\]\)/);
// 参考主题选型:我的服务 = trend-color / user-auth / order-color。
assert.match(nav, /'icon'\s+=>\s+'trend-color'/);
assert.match(nav, /'icon'\s+=>\s+'user-auth'/);
assert.match(nav, /'icon'\s+=>\s+'order-color'/);
// 功能设置 = msg-color / user-color / security-color。
assert.match(nav, /'icon'\s+=>\s+'msg-color'/);
assert.match(nav, /'icon'\s+=>\s+'user-color'/);
assert.match(nav, /'icon'\s+=>\s+'security-color'/);
// 每项都带 tab,保证 icon-but-* 类名完整且选中态可同步。
for (const tab of ['level', 'auth', 'orders', 'msg', 'profile', 'settings']) {
assert.match(nav, new RegExp(`'tab'\\s+=>\\s+'${tab}'`), `missing tab key: ${tab}`);
}
// AKSRT 的跳转契约保留 <a href> + data-tab,不搬参考主题的 <item data-onclick>。
assert.match(nav, /<a class="<\?php echo esc_attr\(\$item_class\);/);
assert.match(nav, /data-tab="<\?php echo esc_attr\(\$tab\); \?>/);
assert.doesNotMatch(nav, /data-onclick/);
});
test('侧栏五个部件均不再出现 Font Awesome 字形', () => {
for (const file of sidebarFiles) {
const source = read(sidebarDir + file);
assert.doesNotMatch(source, /fa\s+fas\s+fa-/, `${file} still renders a Font Awesome glyph`);
assert.doesNotMatch(source, /<i class="fa/, `${file} still renders a Font Awesome <i>`);
}
});
test('其余侧栏部件按参考主题选型替换为 sprite 图标', () => {
const commerce = read(sidebarDir + 'sidebar-commerce.php');
assert.match(commerce, /aksrt_icon_markup\('zibsvg-money-color-2'\)/);
assert.match(commerce, /aksrt_icon_markup\('zibsvg-points-color'\)/);
assert.match(commerce, /aksrt_icon_markup\('zibsvg-right'\)/);
const creator = read(sidebarDir + 'sidebar-creator.php');
assert.match(creator, /aksrt_icon_markup\('zibsvg-merchant-color'\)/);
assert.match(creator, /aksrt_icon_markup\('zibsvg-money-color'\)/);
assert.match(creator, /aksrt_icon_markup\('zibsvg-right'\)/);
const vip = read(sidebarDir + 'sidebar-vip.php');
assert.match(vip, /aksrt_icon_markup\('zibsvg-vip_1'\)/);
assert.match(vip, /aksrt_icon_markup\('zibsvg-right', 'uc-sidebar-vip__arrow'\)/);
const profile = read(sidebarDir + 'profile-sidebar.php');
assert.match(profile, /aksrt_icon_markup\('zibsvg-menu'\)/);
});
test('旧 uc-service-grid 外壳与色调底色已彻底移除', () => {
const shell = read('assets/css/routes/user-center/shell.css');
assert.doesNotMatch(shell, /uc-service-grid/);
for (const file of sidebarFiles) {
assert.doesNotMatch(read(sidebarDir + file), /uc-service-grid/);
}
// 计数角标与 tone 键随色调 CSS 一并成为死代码。
assert.doesNotMatch(shell, /uc-service-grid__icon small/);
assert.doesNotMatch(read(sidebarDir + 'sidebar-nav.php'), /\$item\['count'\]/);
assert.doesNotMatch(read(sidebarDir + 'sidebar-nav.php'), /'tone'/);
// 参考主题网格尺寸落地。
assert.match(shell, /\.user-icon-but-box > a \{[^}]*width: calc\(25% - 10px\)/s);
assert.match(shell, /\.user-icon-but-box > a \{[^}]*min-width: 50px/s);
assert.match(shell, /\.user-icon-but-box > a\.is-active/);
// 卡片上的 <i> 已换成 <svg>,元素选择器需覆盖两者。
assert.match(shell, /\.uc-summary-card__body > svg/);
assert.match(shell, /\.uc-center-card > svg/);
});
test('所用 sprite key 均在前端 sprite 中定义', () => {
const sprite = read('assets/js/runtime/svg-icon.js');
const keys = [
'trend-color', 'user-auth', 'order-color', 'msg-color', 'user-color', 'security-color',
'money-color-2', 'points-color', 'merchant-color', 'money-color', 'vip_1', 'menu', 'right',
];
for (const key of keys) {
assert.match(sprite, new RegExp(`aksrt_svgs\\['${key}'\\]\\s*=`), `sprite key missing: ${key}`);
}
});