feat: full parity pass - suspend enforcement, report modal polish, wechat notify
- Restriction: add is_suspended/get_active_suspend; comment block now covers suspend (小黑屋) in addition to mute, with reason in the deny message - FrontSubmitSave::persist: block post/draft/edit submission for suspended users (reference-theme semantics: 小黑屋 loses all publishing rights) - report.js: close icon switched from fa-times to the SVG sprite ic-close (#icon-close), same as reference theme; textareas gain autoHeight growth (hidden 'other reason' box skips the first measurement) - WeChatNotify: NOTIFY_TYPES now includes report/system so report results and account restriction notices fan out to WeChat template messages; generic title/description fallback for template values - contract tests: +3 tests (suspend enforcement, modal polish, wechat types)
This commit is contained in:
@@ -284,3 +284,38 @@ test('restriction REST operations pass expiry through to the service', () => {
|
||||
assert.match(restrictionOps, /\$params\['expires_at'\] \?\? ''/)
|
||||
assert.match(restrictionOps, /Restriction::get_instance\(\)->restrict\(/)
|
||||
})
|
||||
|
||||
test('suspend (小黑屋) enforcement blocks publishing end to end', () => {
|
||||
// 服务层提供 is_suspended / get_active_suspend(对齐参考主题:小黑屋
|
||||
// 失去所有发布权限——发帖、评论等;此前 suspend 只在公开主页显示提示)。
|
||||
assert.match(restriction, /public function is_suspended\(int \$user_id\): bool/)
|
||||
assert.match(restriction, /public function get_active_suspend\(int \$user_id\): \?array/)
|
||||
// 前台发帖入口(FrontSubmitSave::persist)拦截发帖/草稿/编辑。
|
||||
const frontSave = read('src/Core/FrontSubmitSave.php')
|
||||
assert.match(frontSave, /Restriction::get_instance\(\)->is_suspended\(\$user_id\)/)
|
||||
assert.match(frontSave, /您已被关入小黑屋/)
|
||||
// 评论提交(pre_comment_on_post)同时覆盖禁言(mute)与小黑屋(suspend)。
|
||||
assert.match(restriction, /enforce_comment_mute[\s\S]*?is_suspended\(\$user_id\)/)
|
||||
assert.match(restriction, /您已被关入小黑屋,暂时无法评论/)
|
||||
})
|
||||
|
||||
test('report modal close icon and textarea autoHeight match the reference theme', () => {
|
||||
const reportJs = read('assets/js/report.js')
|
||||
// 关闭按钮走 SVG 雪碧图 icon-close(与参考主题 .ic-close 同构,fa-times 退役)。
|
||||
assert.match(reportJs, /<svg class="ic-close" aria-hidden="true"><use xlink:href="#icon-close"><\/use><\/svg>/)
|
||||
assert.ok(!reportJs.includes('fa-times'), 'close icon must use the SVG sprite, not FontAwesome')
|
||||
// textarea 自动增高(参考主题 autoHeight 行为),隐藏中的“其它原因”跳过首次计算。
|
||||
assert.match(reportJs, /function bindAutoHeight\(/)
|
||||
assert.match(reportJs, /querySelectorAll\('textarea\.form-control'\)\.forEach\(bindAutoHeight\)/)
|
||||
assert.match(reportJs, /offsetHeight > 0\) grow\(\)/)
|
||||
})
|
||||
|
||||
test('wechat template messages cover report and account restriction types', () => {
|
||||
const wechat = read('src/Payment/WeChatNotify.php')
|
||||
assert.match(wechat, /const NOTIFY_TYPES = \['comment_reply', 'system_notice', 'order_paid', 'credits_change', 'report', 'system'\]/)
|
||||
assert.match(wechat, /in_array\(\$type, self::NOTIFY_TYPES, true\)/)
|
||||
// 订阅白名单与状态输出复用同一常量,不允许再出现硬编码子集。
|
||||
assert.ok(!wechat.includes("['comment_reply', 'system_notice', 'order_paid', 'credits_change']"), 'type list must come from NOTIFY_TYPES')
|
||||
// 站内通知缺省模板字段时用 title/description 兜底合成。
|
||||
assert.match(wechat, /\$data\['description'\] \?\? ''/)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user