feat(ban): mirror reference theme ban/restriction prompt surface
修复公开主页禁封提示框为空的问题,并对齐参考主题(Zibll)全部前台禁封提示入口: - fix(profile): 资料卡下方治理提示框渲染为空——模板读取的 tone/message 键与 数据层实际输出的 state/label/text 契约不匹配;现按禁封类型展示 「违规已封号/小黑屋禁封中/禁言中」+ 可配置说明文案 - feat(ban): 用户中心页头展示治理状态徽章 + 查看详情入口,直达禁封申诉页 (参考主题 user_page_header_desc / zib_get_user_ban_info_link) - feat(ban): 评论拒绝态区分禁封/小黑屋/禁言,附状态徽章与申诉链接 (参考主题 zib_get_user_ban_nocan_info,原为笼统的无权限文案) - feat(ban): 禁封申诉页补全状态信息卡(状态/开始时间/结束时间/原因/说明/ 申诉权限),对齐 zib_get_ban_info_modal;此前仅有「禁封原因」一行且无入口 - feat(ban): 昵称旁禁封徽章 + 头像禁封角标(覆盖 VIP 位,参考主题 user_name_badge / user_avatar_badge 钩子语义),main.css 与入队的 main.min.css 同步新增角标样式 - fix(ban): 举报入口对已封禁/小黑屋目标隐藏(评论、文章下拉、封面菜单三处, 对齐 zib_get_report_link 排除语义;禁言为轻量限制不隐藏) - refactor(ban): 治理展示态收敛为单一数据源 Restriction::get_display_state() + state_labels(),资料卡/用户中心/评论拒绝态/昵称徽章共用 - feat(ban): 小黑屋用户开放申诉(对齐参考主题 zib_user_is_ban 双类型语义), 禁封站内信附加申诉页链接 - test: report-ban 契约测试 +3(展示态单一数据源、提示面入口矩阵、举报排除), 45 个测试文件全部通过
This commit is contained in:
@@ -19,6 +19,16 @@ const functions = read('functions.php')
|
||||
const uninstall = read('uninstall.php')
|
||||
const userBanHelper = read('inc/helpers/user-ban.php')
|
||||
const userBanJs = read('assets/js/user-ban.js')
|
||||
const authorHero = read('templates/parts/user/author-hero.php')
|
||||
const ucHeader = read('inc/helpers/user-center-renderers/profile-header.php')
|
||||
const commentsHelper = read('inc/helpers/aksrt-comments.php')
|
||||
const appealPage = read('templates/pages/page-ban-appeal.php')
|
||||
const identityHelper = read('inc/helpers/aksrt-identity.php')
|
||||
const avatarHelper = read('inc/helpers/aksrt-avatar.php')
|
||||
const singleComponents = read('inc/helpers/aksrt-single-components.php')
|
||||
const banAppeal = read('src/User/BanAppeal.php')
|
||||
const mainCss = read('assets/css/main.css')
|
||||
const mainMinCss = read('assets/css/main.min.css')
|
||||
|
||||
test('report REST surface is canonical: submit + users/reports only', () => {
|
||||
assert.match(userController, /'\/report\/submit'/)
|
||||
@@ -130,9 +140,75 @@ test('ban appeal approval actually lifts restrictions', () => {
|
||||
})
|
||||
|
||||
test('profile governance notice reads from the restriction table', () => {
|
||||
assert.match(home, /->is_banned\(\$user_id\)/)
|
||||
assert.match(home, /->get_display_state\(\$user_id\)/)
|
||||
assert.match(home, /Restriction::state_labels\(\)\[\$state\]/)
|
||||
assert.match(home, /\\AKSRT\\User\\Restriction::get_instance\(\)/)
|
||||
assert.ok(!home.includes('aksrt_user_ban_state'))
|
||||
// 提示框内容契约:state|label|text,label 对齐参考主题公开主页禁封徽章文案。
|
||||
assert.match(home, /'state'\s*=> \$state/)
|
||||
assert.match(home, /'label'\s*=>/)
|
||||
assert.match(home, /'text'\s*=> \(string\) \$settings\['report'\]\['ban_notice_text'\]/)
|
||||
// 模板必须消费真实契约键:tone/message 双键曾导致资料卡下方提示框渲染为空。
|
||||
assert.match(authorHero, /\$notice\['state'\]/)
|
||||
assert.match(authorHero, /\$notice\['text'\]/)
|
||||
assert.match(authorHero, /\$notice\['label'\]/)
|
||||
assert.ok(!authorHero.includes("$notice['message']"), 'template must not read the removed message key')
|
||||
assert.ok(!authorHero.includes("$notice['tone']"), 'template must not read the removed tone key')
|
||||
})
|
||||
|
||||
test('governance display state is a single source shared by every prompt surface', () => {
|
||||
// 展示态与文案集中在 Restriction(资料卡/用户中心/评论拒绝态/昵称徽章共用)。
|
||||
for (const state of ['STATE_BANNED', 'STATE_RESTRICTED', 'STATE_MUTED']) {
|
||||
assert.match(restriction, new RegExp(`const ${state}\\s+=`), `missing display state: ${state}`)
|
||||
}
|
||||
assert.match(restriction, /public function get_display_state\(int \$user_id\): string/)
|
||||
assert.match(restriction, /public static function state_labels\(\): array/)
|
||||
for (const label of ["__('违规已封号', 'aksrt')", "__('小黑屋禁封中', 'aksrt')", "__('禁言中', 'aksrt')"]) {
|
||||
assert.ok(restriction.includes(label), `missing state label: ${label}`)
|
||||
}
|
||||
assert.match(restriction, /is_banned\(\$user_id\)[\s\S]*?is_suspended\(\$user_id\)[\s\S]*?is_restricted\(\$user_id, self::TYPE_MUTE\)/)
|
||||
// 请求级缓存:评论列表逐条渲染昵称徽章不得反复查库。
|
||||
assert.match(userBanHelper, /static \$cache = \[\]/)
|
||||
})
|
||||
|
||||
test('ban prompt surface mirrors the reference theme entry points', () => {
|
||||
// 用户中心页头(参考主题 user_page_header_desc / zib_get_user_ban_info_link)。
|
||||
assert.match(userBanHelper, /function aksrt_get_user_ban_notice_html/)
|
||||
assert.match(userBanHelper, /function aksrt_get_ban_appeal_page_url/)
|
||||
assert.match(ucHeader, /aksrt_get_user_ban_notice_html/)
|
||||
// 评论拒绝态(参考主题 zib_get_user_ban_nocan_info)。
|
||||
assert.match(userBanHelper, /function aksrt_get_user_ban_nocan_html/)
|
||||
assert.match(commentsHelper, /aksrt_get_user_ban_nocan_html/)
|
||||
assert.match(commentsHelper, /暂时无法发表评论/)
|
||||
// 昵称徽章 + 头像角标(参考主题 user_name_badge / user_avatar_badge)。
|
||||
assert.match(userBanHelper, /function aksrt_get_user_ban_name_badge/)
|
||||
assert.match(userBanHelper, /function aksrt_get_user_ban_avatar_badge/)
|
||||
assert.match(identityHelper, /aksrt_get_user_ban_name_badge\(\$user_id\)/)
|
||||
assert.match(avatarHelper, /aksrt_get_user_ban_avatar_badge\(\$user_id\)/)
|
||||
// 禁封申诉页完整状态信息(参考主题 zib_get_ban_info_modal)。
|
||||
assert.match(appealPage, /get_active_suspend\(\$user_id\)/)
|
||||
for (const row of ['状态', '开始时间', '结束时间', '原因', '说明']) {
|
||||
assert.match(appealPage, new RegExp(`__\\('${row}', 'aksrt'\\)`), `appeal page missing status row: ${row}`)
|
||||
}
|
||||
assert.match(appealPage, /esc_html_e\('申诉权限', 'aksrt'\)/)
|
||||
assert.match(appealPage, /禁封中\(禁止登录\)/)
|
||||
assert.match(appealPage, /本次禁封您将不能发起申诉/)
|
||||
// 禁封/小黑屋均可申诉(参考主题 zib_user_is_ban 双类型语义)。
|
||||
assert.match(banAppeal, /STATE_BANNED, \\AKSRT\\User\\Restriction::STATE_RESTRICTED/)
|
||||
// 禁封站内信附申诉入口(参考主题 zib_updata_user_ban_msg 申诉指引)。
|
||||
assert.match(restrictionOps, /aksrt_get_ban_appeal_page_url/)
|
||||
// 头像角标样式:源文件与入队的 min 产物同步。
|
||||
for (const css of [mainCss, mainMinCss]) {
|
||||
assert.ok(css.includes('aksrt-avatar-ban-badge'), 'ban avatar badge CSS must exist in both main.css and main.min.css')
|
||||
}
|
||||
})
|
||||
|
||||
test('report entry hides targets already banned or suspended', () => {
|
||||
// 参考主题 zib_get_report_link:已封禁/小黑屋用户不展示举报入口(禁言不隐藏)。
|
||||
assert.match(userBanHelper, /function aksrt_is_user_ban_restricted/)
|
||||
assert.match(commentItem, /aksrt_is_user_ban_restricted\(\$author_id\)/)
|
||||
assert.match(singleComponents, /aksrt_is_user_ban_restricted\(\$post_author_id\)/)
|
||||
assert.match(authorHero, /aksrt_is_user_ban_restricted\(\$user_id\)/)
|
||||
})
|
||||
|
||||
test('admin report notification links to the real page', () => {
|
||||
|
||||
Reference in New Issue
Block a user