refactor: rename the theme brand and every identifier from AKSRT to Jio
Full-project rename. `git grep -i aksrt` is now empty apart from the
DBMigrator 3.3.0 changelog note that documents the rename itself.
Code identifiers
- PHP namespace AKSRT\ -> Jio\ (composer PSR-4 + 378 declarations)
- global constants AKSRT_* -> JIO_* (VERSION/DIR/URI, PAY_TYPE_*, CAPTCHA_*)
- procedural functions, hooks, options, meta keys, table names,
cookies, query vars, ajax actions and nonces: aksrt_ -> jio_
- text domain aksrt -> jio; Theme Name -> Jio
- JS globals: aksrtData/aksrtAdminData/... -> jioData/jioAdminData/...,
window.AKSRTCaptcha & friends -> window.JioCaptcha, Aksrt* -> Jio*
- Vue components Aks*.vue -> Jio*.vue (15 files renamed + imports)
- CSS classes/data-attrs/custom properties: aksrt- -> jio-
- REST namespace aksrt/v1 -> jio/v1 (incl. payment gateway callbacks)
Storage layer
- DB tables {prefix}aksrt_* -> {prefix}jio_*; SCHEMA_VERSION 3.2.0 -> 3.3.0
so dbDelta creates the new names on install
- widget id_base aksrt_widget_* -> jio_widget_*
- uninstall.php drop list rebuilt from the actual migrator tables
(dropped 3 stale entries, added the 17 missing ones)
Removed
- hardcoded https://api.aksrt.com/version.json default update endpoint;
get_endpoint() now reads the 「更新端点」 setting and do_check() no-ops
when it is empty
Files renamed: inc/helpers/aksrt-*.php -> jio-*.php (54),
assets/admin/src/components/form/Aks*.vue -> Jio*.vue (15).
Build artifacts regenerated: assets/css/build, assets/js/runtime,
assets/admin/build.
Verified: audit-psr4-paths errors=0, audit-admin-contracts errors=0
(warnings=56, unchanged baseline), 813/813 widget-system tests,
44/44 phpunit, php -l clean across all PHP.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
5b16bc6e15
commit
35bb96e82f
997 files changed
+28216
-28188
No files matched your search
@@ -22,10 +22,10 @@ const userBanJs = read('assets/js/user-ban.js')
|
||||
const authorHero = read('templates/parts/user/author-hero.php')
|
||||
const banBlock = read('templates/parts/user/ban-block.php')
|
||||
const ucHeader = read('inc/helpers/user-center-renderers/profile-header.php')
|
||||
const commentsHelper = read('inc/helpers/aksrt-comments.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 commentsHelper = read('inc/helpers/jio-comments.php')
|
||||
const identityHelper = read('inc/helpers/jio-identity.php')
|
||||
const avatarHelper = read('inc/helpers/jio-avatar.php')
|
||||
const singleComponents = read('inc/helpers/jio-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')
|
||||
@@ -68,7 +68,7 @@ test('report center has no legacy ajax handlers or option migration', () => {
|
||||
assert.ok(!reportCenter.includes('ajax_counts'))
|
||||
assert.ok(!reportCenter.includes('migrate_from_option'))
|
||||
assert.ok(!reportCenter.includes('maybe_migrate'))
|
||||
assert.ok(!reportCenter.includes("get_option('aksrt_reports'"))
|
||||
assert.ok(!reportCenter.includes("get_option('jio_reports'"))
|
||||
assert.ok(!functions.includes('ReportCenter::get_instance()->init()'), 'ReportCenter init() is gone')
|
||||
assert.match(reportCenter, /public function has_pending_report/)
|
||||
assert.match(reportOps, /has_pending_report\(\$reporter_id, \$target_type, \$target_id\)/)
|
||||
@@ -79,8 +79,8 @@ test('report processing delegates actions to the shared ReportCenter entry', ()
|
||||
assert.match(reportCenter, /public function apply_action\(/)
|
||||
assert.match(reportCenter, /->restrict\(\s*\$target_id,\s*\$action_taken,/)
|
||||
assert.match(reportCenter, /lift_user_restriction\(\$target_id\)/)
|
||||
assert.match(reportCenter, /in_array\(\$action_taken, \\AKSRT\\User\\Restriction::TYPES, true\)/)
|
||||
assert.ok(!reportCenter.includes('aksrt_user_ban_state'), 'dual-track ban state meta must not be written or read')
|
||||
assert.match(reportCenter, /in_array\(\$action_taken, \\Jio\\User\\Restriction::TYPES, true\)/)
|
||||
assert.ok(!reportCenter.includes('jio_user_ban_state'), 'dual-track ban state meta must not be written or read')
|
||||
for (const deadAction of ["'value' => 'warned'", "'value' => 'muted'", "'value' => 'restricted'", "'value' => 'banned'"]) {
|
||||
assert.ok(!reportOps.includes(deadAction), `action value must map to Restriction types: ${deadAction}`)
|
||||
}
|
||||
@@ -96,7 +96,7 @@ test('restriction class supports lifting and kicks sessions on ban', () => {
|
||||
assert.match(restriction, /public function lift_user_restriction\(int \$user_id, array \$types = \[self::TYPE_BAN, self::TYPE_SUSPEND, self::TYPE_MUTE\]\): int/)
|
||||
assert.match(restriction, /WP_Session_Tokens::get_instance\(\$user_id\)->destroy_all\(\)/)
|
||||
assert.ok(!restriction.includes('sync_user_restriction_meta'), 'write-only meta sync is dead code')
|
||||
assert.ok(!restriction.includes('_aksrt_is_banned'))
|
||||
assert.ok(!restriction.includes('_jio_is_banned'))
|
||||
})
|
||||
|
||||
test('ban admin REST endpoints stay in sync with the SPA client', () => {
|
||||
@@ -162,22 +162,22 @@ test('ban appeal approval actually lifts restrictions', () => {
|
||||
test('ban identity badge occupies the public profile meta row', () => {
|
||||
// 公开主页:禁封状态占据身份行元信息位(参考主题 author_header_identity),
|
||||
// 不再是资料卡下方提示框(notice 链已移除)。
|
||||
assert.match(userBanHelper, /function aksrt_get_user_ban_identity_badge/)
|
||||
assert.match(authorHero, /aksrt_get_user_ban_identity_badge\(\$user_id\)/)
|
||||
assert.match(authorHero, /aksrt-author-hero__identity/)
|
||||
assert.ok(!authorHero.includes('aksrt-author-hero__notice'), 'profile notice box must stay removed')
|
||||
assert.match(userBanHelper, /function jio_get_user_ban_identity_badge/)
|
||||
assert.match(authorHero, /jio_get_user_ban_identity_badge\(\$user_id\)/)
|
||||
assert.match(authorHero, /jio-author-hero__identity/)
|
||||
assert.ok(!authorHero.includes('jio-author-hero__notice'), 'profile notice box must stay removed')
|
||||
assert.ok(!authorHero.includes('profile_notice'), 'dashboard must not carry profile_notice anymore')
|
||||
assert.ok(!home.includes('get_profile_notice'), 'Home::get_profile_notice must stay removed')
|
||||
assert.ok(!mainCss.includes('aksrt-author-hero__notice'), 'notice box CSS must stay removed')
|
||||
assert.ok(!mainCss.includes('jio-author-hero__notice'), 'notice box CSS must stay removed')
|
||||
// 徽章字段(文案/颜色/图标)由 Restriction::state_badges() 统一管理。
|
||||
assert.match(userBanHelper, /state_badges\(\)/)
|
||||
// 死配置清理:公开提示开关与提示文案键不再进入运行时。
|
||||
assert.ok(!userRuntime.includes('public_notice'), 'dead public_notice setting must stay removed')
|
||||
assert.ok(!userRuntime.includes('ban_notice_text'), 'dead ban_notice_text setting must stay removed')
|
||||
// 用户中心元信息入口:but 按钮(徽章 + 箭头)→ 查看禁封状态弹窗。
|
||||
assert.match(userBanHelper, /function aksrt_get_user_ban_info_link/)
|
||||
assert.match(userBanHelper, /data-aksrt-ban-info=/)
|
||||
assert.match(ucHeader, /aksrt_get_user_ban_info_link/)
|
||||
assert.match(userBanHelper, /function jio_get_user_ban_info_link/)
|
||||
assert.match(userBanHelper, /data-jio-ban-info=/)
|
||||
assert.match(ucHeader, /jio_get_user_ban_info_link/)
|
||||
})
|
||||
|
||||
test('governance display state is a single source shared by every prompt surface', () => {
|
||||
@@ -188,9 +188,9 @@ test('governance display state is a single source shared by every prompt surface
|
||||
assert.match(restriction, /public function get_display_state\(int \$user_id\): string/)
|
||||
assert.match(restriction, /public static function state_badges\(\): array/)
|
||||
// 颜色统一管理:封号=红、小黑屋=黄、禁言=灰。
|
||||
assert.match(restriction, /'label' => __\('违规已封号', 'aksrt'\),\s*'tone' => 'c-red'/)
|
||||
assert.match(restriction, /'label' => __\('小黑屋禁封中', 'aksrt'\),\s*'tone' => 'c-yellow'/)
|
||||
assert.match(restriction, /'label' => __\('禁言中', 'aksrt'\),\s*'tone' => 'c-gray'/)
|
||||
assert.match(restriction, /'label' => __\('违规已封号', 'jio'\),\s*'tone' => 'c-red'/)
|
||||
assert.match(restriction, /'label' => __\('小黑屋禁封中', 'jio'\),\s*'tone' => 'c-yellow'/)
|
||||
assert.match(restriction, /'label' => __\('禁言中', 'jio'\),\s*'tone' => 'c-gray'/)
|
||||
// 禁封信息行单一数据源(查看禁封状态弹窗/申诉弹窗/禁封页/管理端弹窗共用)。
|
||||
assert.match(restriction, /public function get_ban_info\(int \$user_id\): array/)
|
||||
assert.match(restriction, /'status'\s*=>/)
|
||||
@@ -202,16 +202,16 @@ test('governance display state is a single source shared by every prompt surface
|
||||
|
||||
test('ban prompt surface mirrors the reference theme modals and block page', () => {
|
||||
// 查看禁封状态弹窗(1:1 zib_get_ban_info_modal:多彩头 + 信息行 + 申诉按钮)。
|
||||
assert.match(userBanHelper, /function aksrt_get_user_ban_info_modal/)
|
||||
assert.match(userBanHelper, /aksrt-user-ban-info-modal/)
|
||||
assert.match(userBanHelper, /function jio_get_user_ban_info_modal/)
|
||||
assert.match(userBanHelper, /jio-user-ban-info-modal/)
|
||||
assert.match(userBanHelper, /您已解封,请刷新页面/)
|
||||
assert.match(userBanHelper, /您当前已无法进行申诉/)
|
||||
// 禁封申诉弹窗(1:1 zib_get_user_ban_appeal_modal:edit-header + 信息框 +
|
||||
// 资料项 inputs + 审核中态 + 禁止申诉态;仅本人)。
|
||||
assert.match(userBanHelper, /function aksrt_get_user_ban_appeal_modal/)
|
||||
assert.match(userBanHelper, /aksrt-user-ban-appeal-modal/)
|
||||
assert.match(userBanHelper, /function aksrt_get_user_ban_appeal_link/)
|
||||
assert.match(userBanHelper, /data-aksrt-ban-appeal=/)
|
||||
assert.match(userBanHelper, /function jio_get_user_ban_appeal_modal/)
|
||||
assert.match(userBanHelper, /jio-user-ban-appeal-modal/)
|
||||
assert.match(userBanHelper, /function jio_get_user_ban_appeal_link/)
|
||||
assert.match(userBanHelper, /data-jio-ban-appeal=/)
|
||||
assert.match(userBanHelper, /抱歉!您当前已无法进行申诉/)
|
||||
assert.match(userBanHelper, /您的申诉正在审核中,请耐心等待/)
|
||||
assert.match(userBanHelper, /name="data\[/)
|
||||
@@ -220,7 +220,7 @@ test('ban prompt surface mirrors the reference theme modals and block page', ()
|
||||
// 说明框保持 rows=3 自然高度(禁封弹窗留言框才有 autoHeight/maxHeight)。
|
||||
assert.match(userBanHelper, /scroll-y no-scrollbar max-vh5/)
|
||||
assert.ok(!userBanHelper.includes('mini-scrollbar'), 'ban modals must not show any scrollbar (thin included)')
|
||||
const appealModalFn = userBanHelper.slice(userBanHelper.indexOf('function aksrt_get_user_ban_appeal_modal'))
|
||||
const appealModalFn = userBanHelper.slice(userBanHelper.indexOf('function jio_get_user_ban_appeal_modal'))
|
||||
const appealModalBody = appealModalFn.slice(0, appealModalFn.indexOf('\n}'))
|
||||
const appealTextarea = (appealModalBody.match(/<textarea[^>]*>/) || [''])[0]
|
||||
assert.ok(appealTextarea !== '' && appealTextarea.includes('rows="3"'), 'appeal textarea keeps natural rows=3 height')
|
||||
@@ -229,7 +229,7 @@ test('ban prompt surface mirrors the reference theme modals and block page', ()
|
||||
// JS:autoHeight 仅对显式声明的文本框生效。
|
||||
assert.match(userBanJs, /querySelectorAll\('textarea\[autoHeight\], textarea\[maxHeight\]'\)/)
|
||||
// 用户中心元信息按钮:外层 but 不重复状态色,颜色仅由内层 badg 承载。
|
||||
const infoLinkFn = userBanHelper.slice(userBanHelper.indexOf('function aksrt_get_user_ban_info_link'))
|
||||
const infoLinkFn = userBanHelper.slice(userBanHelper.indexOf('function jio_get_user_ban_info_link'))
|
||||
const infoLinkBody = infoLinkFn.slice(0, infoLinkFn.indexOf('\n}'))
|
||||
assert.match(infoLinkBody, /\$classes = trim\('but p2-10'\s*\./)
|
||||
assert.ok(!infoLinkBody.includes("'but p2-10 ' . (string) \$state['tone']"), 'outer but must not repeat the badge tone')
|
||||
@@ -237,49 +237,49 @@ test('ban prompt surface mirrors the reference theme modals and block page', ()
|
||||
assert.match(banAppeal, /is_array\(\$_POST\['data'\]\)/)
|
||||
assert.match(banAppeal, /申诉说明/)
|
||||
// 禁封记录弹窗 + 记录链接(1:1 zib_get_ban_log_modal / zib_get_user_ban_log_link)。
|
||||
assert.match(userBanHelper, /function aksrt_get_user_ban_log_modal/)
|
||||
assert.match(userBanHelper, /function aksrt_get_user_ban_log_link/)
|
||||
assert.match(userBanHelper, /data-aksrt-ban-log=/)
|
||||
assert.match(userBanHelper, /function jio_get_user_ban_log_modal/)
|
||||
assert.match(userBanHelper, /function jio_get_user_ban_log_link/)
|
||||
assert.match(userBanHelper, /data-jio-ban-log=/)
|
||||
assert.match(userBanHelper, /当前用户已有%d次禁封记录,请谨慎操作/)
|
||||
assert.match(userBanHelper, /该用户共有%d次禁封记录/)
|
||||
// 登录后禁封状态页(1:1 zib_user_ban_restrict_login / zib_die_page)。
|
||||
assert.match(userBanHelper, /function aksrt_render_user_ban_block_page/)
|
||||
assert.match(userBanHelper, /function jio_render_user_ban_block_page/)
|
||||
assert.match(banBlock, /抱歉,您的账号当前处于禁封状态,暂时无法登录/)
|
||||
assert.match(banBlock, /退出登录/)
|
||||
assert.match(banBlock, /aksrt_get_user_ban_appeal_link/)
|
||||
assert.match(banBlock, /jio_get_user_ban_appeal_link/)
|
||||
for (const row of ['用户名', '状态', '开始时间', '结束时间', '原因', '说明', '申诉权限']) {
|
||||
assert.ok(banBlock.includes(`__('${row}', 'aksrt')`), `ban block page missing row: ${row}`)
|
||||
assert.ok(banBlock.includes(`__('${row}', 'jio')`), `ban block page missing row: ${row}`)
|
||||
}
|
||||
// Restriction 以 template_redirect 收口(不禁登录)。
|
||||
assert.match(restriction, /add_action\('template_redirect', \[\$this, 'restrict_frontend_access'\], 1\)/)
|
||||
assert.match(restriction, /public function restrict_frontend_access\(\): void/)
|
||||
assert.ok(!restriction.includes('enforce_login_ban'), 'login-time ban block must stay removed')
|
||||
// 评论拒绝态(参考主题 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(userBanHelper, /function jio_get_user_ban_nocan_html/)
|
||||
assert.match(commentsHelper, /jio_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\)/)
|
||||
assert.match(userBanHelper, /function jio_get_user_ban_name_badge/)
|
||||
assert.match(userBanHelper, /function jio_get_user_ban_avatar_badge/)
|
||||
assert.match(identityHelper, /jio_get_user_ban_name_badge\(\$user_id\)/)
|
||||
assert.match(avatarHelper, /jio_get_user_ban_avatar_badge\(\$user_id\)/)
|
||||
// 三个弹窗 REST 路由(modal-mini 几何 / 每次刷新)。
|
||||
for (const route of ['/user-ban/info-modal', '/user-ban/appeal-modal', '/user-ban/log-modal']) {
|
||||
assert.ok(userController.includes(`'${route}'`), `missing REST route: ${route}`)
|
||||
}
|
||||
// 前端委托与 admin-ajax 提交。
|
||||
for (const attr of ['data-aksrt-ban-info', 'data-aksrt-ban-appeal', 'data-aksrt-ban-log']) {
|
||||
for (const attr of ['data-jio-ban-info', 'data-jio-ban-appeal', 'data-jio-ban-log']) {
|
||||
assert.ok(userBanJs.includes(attr), `missing JS delegation: ${attr}`)
|
||||
}
|
||||
assert.match(userBanJs, /aksrt_ban_appeal_submit/)
|
||||
assert.match(userBanJs, /jio_ban_appeal_submit/)
|
||||
assert.match(userBanJs, /new FormData\(form\)/)
|
||||
// modal-mini 几何(400px)与头部样式覆盖三个新弹窗类。
|
||||
for (const cls of ['aksrt-user-ban-info-modal', 'aksrt-user-ban-appeal-modal', 'aksrt-user-ban-log-modal']) {
|
||||
for (const cls of ['jio-user-ban-info-modal', 'jio-user-ban-appeal-modal', 'jio-user-ban-log-modal']) {
|
||||
assert.ok(modalRuntimeCss.includes(cls), `missing modal geometry for ${cls}`)
|
||||
}
|
||||
// 头像角标样式:源文件与入队的 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')
|
||||
assert.ok(css.includes('jio-avatar-ban-badge'), 'ban avatar badge CSS must exist in both main.css and main.min.css')
|
||||
}
|
||||
// 申诉页面模板与专属资产已移除(死代码清理)。
|
||||
assert.ok(!templatesMap.includes('page-ban-appeal'), 'ban appeal page template registration must stay removed')
|
||||
@@ -288,10 +288,10 @@ test('ban prompt surface mirrors the reference theme modals and block page', ()
|
||||
|
||||
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\)/)
|
||||
assert.match(userBanHelper, /function jio_is_user_ban_restricted/)
|
||||
assert.match(commentItem, /jio_is_user_ban_restricted\(\$author_id\)/)
|
||||
assert.match(singleComponents, /jio_is_user_ban_restricted\(\$post_author_id\)/)
|
||||
assert.match(authorHero, /jio_is_user_ban_restricted\(\$user_id\)/)
|
||||
})
|
||||
|
||||
test('banned users may log in and meet the frontend block page', () => {
|
||||
@@ -313,18 +313,18 @@ test('banned users may log in and meet the frontend block page', () => {
|
||||
// Toast 透传(一般性修复,保留):REST 层不得把失败原因硬编码为凭证错误。
|
||||
assert.match(phoneOps, /\$result\['error'\]/)
|
||||
assert.ok(
|
||||
phoneOps.includes("$login_error !== '' ? $login_error : __('账号或密码错误', 'aksrt')"),
|
||||
phoneOps.includes("$login_error !== '' ? $login_error : __('账号或密码错误', 'jio')"),
|
||||
'auth_login must pass through the real failure reason'
|
||||
)
|
||||
})
|
||||
|
||||
test('admin report notification links to the real page', () => {
|
||||
assert.match(mailNotifications, /users\.php\?page=aksrt_user_ban'/)
|
||||
assert.ok(!mailNotifications.includes('page=aksrt_reports&'), 'dead admin page link')
|
||||
assert.match(mailNotifications, /users\.php\?page=jio_user_ban'/)
|
||||
assert.ok(!mailNotifications.includes('page=jio_reports&'), 'dead admin page link')
|
||||
assert.ok(!mailNotifications.includes('tab=reports'), 'merged ticket page has no reports tab')
|
||||
// 处理说明必须随 aksrt_report_status_changed 传入邮件载荷(此前硬编码空串,
|
||||
// 处理说明必须随 jio_report_status_changed 传入邮件载荷(此前硬编码空串,
|
||||
// 举报人收到的“说明:”永远为空)。
|
||||
assert.match(reportCenter, /do_action\('aksrt_report_status_changed', \$report_id[\s\S]*?new_status, \$note_clean\)/)
|
||||
assert.match(reportCenter, /do_action\('jio_report_status_changed', \$report_id[\s\S]*?new_status, \$note_clean\)/)
|
||||
assert.match(mailNotifications, /function report_status_changed\(int \$report_id, int \$reporter_id, string \$status, string \$note = ''\)/)
|
||||
assert.match(mailNotifications, /'note'\s*=>\s*\$note !== '' \? \$note :/)
|
||||
// 举报通知必须入站内消息系统:提交→管理员(直达工单列表)、
|
||||
@@ -332,7 +332,7 @@ test('admin report notification links to the real page', () => {
|
||||
assert.match(reportCenter, /notify_admins_new_report\(/)
|
||||
assert.match(reportCenter, /notify_reporter_status_changed\(/)
|
||||
assert.match(reportCenter, /Message::get_instance\(\)->send\(/)
|
||||
assert.match(reportCenter, /users\.php\?page=aksrt_user_ban&type=report&status=pending/)
|
||||
assert.match(reportCenter, /users\.php\?page=jio_user_ban&type=report&status=pending/)
|
||||
})
|
||||
|
||||
test('native ban page uses the scoped template-and-dialog admin flow', () => {
|
||||
@@ -344,8 +344,8 @@ test('native ban page uses the scoped template-and-dialog admin flow', () => {
|
||||
const banCss = read('assets/css/admin/user-ban.css');
|
||||
|
||||
assert.match(usersMenus, /use UsersMenusBan;/);
|
||||
assert.match(usersMenus, /admin_post_aksrt_users_update_report/);
|
||||
assert.match(usersMenus, /admin_post_aksrt_users_process_appeal/);
|
||||
assert.match(usersMenus, /admin_post_jio_users_update_report/);
|
||||
assert.match(usersMenus, /admin_post_jio_users_process_appeal/);
|
||||
assert.doesNotMatch(usersMenus, /use UsersMenusTickets;/, 'ban review must not use the deleted ticket renderer');
|
||||
assert.ok(!fs.existsSync(path.join(root, 'src/Admin/Native/UsersMenusTickets.php')));
|
||||
|
||||
@@ -357,17 +357,17 @@ test('native ban page uses the scoped template-and-dialog admin flow', () => {
|
||||
assert.match(banQuery, /array_slice\(\$filtered, \(\$page - 1\) \* self::BAN_PER_PAGE, self::BAN_PER_PAGE\)/);
|
||||
assert.match(banQuery, /'counts'\s*=>\s*\$counts/);
|
||||
|
||||
assert.match(banPage, /if \(\$hook !== 'users_page_aksrt_user_ban'\) return/);
|
||||
assert.match(banPage, /wp_enqueue_style\('aksrt-admin-user-ban'.*NativeUi::STYLE_HANDLE/);
|
||||
assert.match(banPage, /wp_enqueue_script\('aksrt-admin-user-ban'/);
|
||||
assert.match(banPage, /<dialog id="aksrt-ban-dialog"/);
|
||||
assert.match(banDialogs, /<template id="aksrt-ban-detail-/);
|
||||
assert.match(banPage, /data-aksrt-ban-view=/);
|
||||
assert.match(banPage, /if \(\$hook !== 'users_page_jio_user_ban'\) return/);
|
||||
assert.match(banPage, /wp_enqueue_style\('jio-admin-user-ban'.*NativeUi::STYLE_HANDLE/);
|
||||
assert.match(banPage, /wp_enqueue_script\('jio-admin-user-ban'/);
|
||||
assert.match(banPage, /<dialog id="jio-ban-dialog"/);
|
||||
assert.match(banDialogs, /<template id="jio-ban-detail-/);
|
||||
assert.match(banPage, /data-jio-ban-view=/);
|
||||
assert.doesNotMatch(banPage, /update_user_meta|update_status|do_action\(/);
|
||||
assert.doesNotMatch(banPage, /data-aksrt-ticket-toggle|data-aksrt-ticket-cancel|data-aksrt-ban-toggle/);
|
||||
assert.doesNotMatch(banPage, /data-jio-ticket-toggle|data-jio-ticket-cancel|data-jio-ban-toggle/);
|
||||
|
||||
assert.match(banDialogs, /if \(\$pending\) \{[\s\S]*?<form method="post"/);
|
||||
assert.match(banDialogs, /else \{[\s\S]*?<div class="aksrt-ban-dialog__frame">/);
|
||||
assert.match(banDialogs, /else \{[\s\S]*?<div class="jio-ban-dialog__frame">/);
|
||||
assert.match(banDialogs, /'action'\s*=>\s*\$action/);
|
||||
assert.match(banDialogs, /record_version/);
|
||||
assert.match(banDialogs, /wp_nonce_field\(\$action \. '_' \. \(int\) \$row\['id'\]\)/);
|
||||
@@ -382,8 +382,8 @@ test('native ban page uses the scoped template-and-dialog admin flow', () => {
|
||||
for (const method of ['handle_update_report', 'handle_process_appeal']) {
|
||||
assert.match(banActions, new RegExp(`public function ${method}\\(\\): void`));
|
||||
}
|
||||
assert.match(banActions, /check_admin_referer\('aksrt_users_update_report_'/);
|
||||
assert.match(banActions, /check_admin_referer\('aksrt_users_process_appeal_'/);
|
||||
assert.match(banActions, /check_admin_referer\('jio_users_update_report_'/);
|
||||
assert.match(banActions, /check_admin_referer\('jio_users_process_appeal_'/);
|
||||
assert.match(banActions, /hash_equals\(\$this->ban_record_version\(\$row\), \$submitted\)/);
|
||||
assert.match(banActions, /\$this->ban_request_is_current\(\$row, 'pending'\)/);
|
||||
assert.match(banActions, /\$new_status === 'dismissed' && \$note === ''/);
|
||||
@@ -394,7 +394,7 @@ test('native ban page uses the scoped template-and-dialog admin flow', () => {
|
||||
assert.match(banJs, /window\.addEventListener\('pageshow'/);
|
||||
assert.match(banJs, /previousOpener\.focus\(\)/);
|
||||
assert.match(banJs, /if \(!submitting\) dialog\.close\(\)/);
|
||||
assert.match(banCss, /html\.aksrt-ban-modal-open \{ overflow: hidden/);
|
||||
assert.match(banCss, /html\.jio-ban-modal-open \{ overflow: hidden/);
|
||||
});
|
||||
test('report modal uses accessible reasons, automatic target association and optional evidence', () => {
|
||||
const scripts = read('src/Core/ScriptsPart1c.php')
|
||||
@@ -404,10 +404,10 @@ test('report modal uses accessible reasons, automatic target association and opt
|
||||
assert.match(scripts, /report_settings\(\)/)
|
||||
|
||||
const reportJs = read('assets/js/report.js')
|
||||
for (const part of ['aksrt-report-target', 'name="report_reason"', 'type="radio"', '其他原因', '补充说明', '图片举证', '提交举报', '关联对象:']) {
|
||||
for (const part of ['jio-report-target', 'name="report_reason"', 'type="radio"', '其他原因', '补充说明', '图片举证', '提交举报', '关联对象:']) {
|
||||
assert.ok(reportJs.includes(part), `report.js missing form contract: ${part}`)
|
||||
}
|
||||
assert.doesNotMatch(reportJs, /report_url|违规链接|data-aksrt-report-reason=|bindAutoHeight/)
|
||||
assert.doesNotMatch(reportJs, /report_url|违规链接|data-jio-report-reason=|bindAutoHeight/)
|
||||
for (const source of [reportJs, commentItem, authorHero]) assert.doesNotMatch(source, /target_avatar/)
|
||||
assert.match(reportJs, /description\) content\.push\(description\)/)
|
||||
assert.doesNotMatch(reportJs, /category\.slug|reason = category/)
|
||||
@@ -415,37 +415,37 @@ test('report modal uses accessible reasons, automatic target association and opt
|
||||
assert.match(reportCenter, /'category'\s*=>\s*\$category/)
|
||||
assert.doesNotMatch(reportCenter, /sanitize_key\(\$category\)/)
|
||||
assert.match(reportJs, /report\/upload-image/)
|
||||
assert.match(reportJs, /window\.AksrtModalRuntime\.getActive\(\) === shell/)
|
||||
assert.match(reportJs, /window\.JioModalRuntime\.getActive\(\) === shell/)
|
||||
assert.match(userController, /'\/report\/upload-image'/)
|
||||
|
||||
const css = read('assets/css/frontend/report.css')
|
||||
assert.match(css, /\.aksrt-report-modal:not\(\.aksrt-modal-runtime--bottom\) \.aksrt-modal-runtime__dialog/)
|
||||
assert.match(css, /\.jio-report-modal:not\(\.jio-modal-runtime--bottom\) \.jio-modal-runtime__dialog/)
|
||||
assert.match(css, /600px/)
|
||||
assert.match(css, /:focus-visible/)
|
||||
assert.match(css, /\.aksrt-report-reason:has\(input:checked\)/)
|
||||
assert.match(css, /\.jio-report-reason:has\(input:checked\)/)
|
||||
assert.match(css, /clip-path: inset\(50%\)/)
|
||||
assert.match(css, /text-overflow: ellipsis/)
|
||||
assert.doesNotMatch(reportJs, /aksrt-report-target__icon|无需填写链接|正在提交举报,请稍候/)
|
||||
assert.doesNotMatch(reportJs, /jio-report-target__icon|无需填写链接|正在提交举报,请稍候/)
|
||||
assert.match(css, /safe-area-inset-bottom/)
|
||||
assert.match(css, /\[hidden\] \{ display: none !important;/)
|
||||
assert.doesNotMatch(modalRuntimeCss, /aksrt-report-modal/, 'retired report styles must not remain in the shared stylesheet')
|
||||
assert.doesNotMatch(modalRuntimeCss, /jio-report-modal/, 'retired report styles must not remain in the shared stylesheet')
|
||||
assert.match(scriptsPart1b, /assets\/css\/frontend\/report\.css/)
|
||||
})
|
||||
|
||||
test('comments expose a report entry for other users when reporting is enabled', () => {
|
||||
// 举报位于“回复”右侧三点下拉菜单内(参考主题同位置),载荷走 wp_json_encode。
|
||||
assert.match(commentItem, /data-aksrt-report="/)
|
||||
assert.match(commentItem, /function aksrt_get_comment_report_html/)
|
||||
assert.match(commentItem, /data-jio-report="/)
|
||||
assert.match(commentItem, /function jio_get_comment_report_html/)
|
||||
assert.match(commentItem, /comment-report-link/)
|
||||
assert.match(commentItem, /report'\]\['enabled'\]/)
|
||||
assert.match(commentItem, /\$author_id === \$reporter_id/)
|
||||
// 下拉菜单(置顶/编辑/批准/删除 + 禁封或举报)末项走禁封优先、否则举报。
|
||||
assert.match(commentItem, /function aksrt_get_comments_action_dropdown_html[\s\S]*?\$lists \.= aksrt_get_comment_ban_or_report_item/)
|
||||
assert.match(commentItem, /function jio_get_comments_action_dropdown_html[\s\S]*?\$lists \.= jio_get_comment_ban_or_report_item/)
|
||||
// 禁封项(管理员可见):参考主题 comments_action_lists 钩子语义,渲染于 user-ban.php。
|
||||
assert.match(userBanHelper, /comment-ban-link/)
|
||||
assert.match(userBanHelper, /data-aksrt-ban="/)
|
||||
assert.match(userBanHelper, /data-jio-ban="/)
|
||||
// 举报不作为 comt-meta 独立按钮直接渲染。
|
||||
assert.doesNotMatch(commentItem, /\$report\s*=\s*aksrt_get_comment_report_html\(\$comment\)/)
|
||||
assert.doesNotMatch(commentItem, /\$report\s*=\s*jio_get_comment_report_html\(\$comment\)/)
|
||||
})
|
||||
|
||||
test('frontend ban modal mirrors the reference theme zib_get_set_user_ban_modal 1:1', () => {
|
||||
@@ -459,21 +459,21 @@ test('frontend ban modal mirrors the reference theme zib_get_set_user_ban_modal
|
||||
assert.ok(restriction.includes(label), `ban status label missing from Restriction: ${label}`)
|
||||
}
|
||||
// 时长选项 1/7/14/30/100/永久(默认 7 天);类型映射:小黑屋→suspend,禁封→ban。
|
||||
assert.match(userBanHelper, /1 => __\('1天', 'aksrt'\)/)
|
||||
assert.match(userBanHelper, /7 => __\('7天', 'aksrt'\)/)
|
||||
assert.match(userBanHelper, /100 => __\('100天', 'aksrt'\)/)
|
||||
assert.match(userBanHelper, /1 => __\('1天', 'jio'\)/)
|
||||
assert.match(userBanHelper, /7 => __\('7天', 'jio'\)/)
|
||||
assert.match(userBanHelper, /100 => __\('100天', 'jio'\)/)
|
||||
assert.match(userBanHelper, /7 === \$days \? ' checked="checked"' : ''/)
|
||||
// 预置原因来自 UserRuntime::ban_settings(与后台同一数据源)。
|
||||
assert.match(userBanHelper, /UserRuntime::ban_settings\(\)\['reasons'\]/)
|
||||
// 勾选禁止申诉必须填写说明(参考主题同校验),落用户 meta 供申诉入口拦截。
|
||||
assert.match(userBanHelper, /_aksrt_no_appeal|no_appeal/)
|
||||
assert.match(userBanHelper, /_jio_no_appeal|no_appeal/)
|
||||
const appeal = read('src/User/BanAppeal.php')
|
||||
assert.match(appeal, /_aksrt_no_appeal/)
|
||||
// 弹窗入口按钮契约:[data-aksrt-ban] 委托(封面按钮 / 评论菜单项 / 文章作者菜单项)。
|
||||
assert.match(userBanHelper, /data-aksrt-ban="/)
|
||||
assert.match(userBanHelper, /function aksrt_get_user_cover_menu_action_html/)
|
||||
assert.match(userBanHelper, /function aksrt_get_comment_ban_or_report_item/)
|
||||
assert.match(userBanHelper, /function aksrt_get_post_author_ban_item/)
|
||||
assert.match(appeal, /_jio_no_appeal/)
|
||||
// 弹窗入口按钮契约:[data-jio-ban] 委托(封面按钮 / 评论菜单项 / 文章作者菜单项)。
|
||||
assert.match(userBanHelper, /data-jio-ban="/)
|
||||
assert.match(userBanHelper, /function jio_get_user_cover_menu_action_html/)
|
||||
assert.match(userBanHelper, /function jio_get_comment_ban_or_report_item/)
|
||||
assert.match(userBanHelper, /function jio_get_post_author_ban_item/)
|
||||
// 权限模型(参考主题 zib_current_user_can('set_user_ban') 语义):
|
||||
// manage_options + 非本人 + 非超级管理员 + 功能开关。
|
||||
assert.match(userBanHelper, /current_user_can\('manage_options'\)/)
|
||||
@@ -487,31 +487,31 @@ test('frontend ban modal mirrors the reference theme zib_get_set_user_ban_modal
|
||||
assert.match(userBanHelper, /modal-colorful-header colorful-bg c-yellow/)
|
||||
// 提交后整页刷新(禁封 reload:true)/ 仅关闭弹窗(解封 hide_modal:true)。
|
||||
assert.match(userBanJs, /window\.location\.reload\(\)/)
|
||||
assert.match(userBanJs, /AksrtModalRuntime\.close\('submit'\)/)
|
||||
assert.match(userBanJs, /data-aksrt-ban-submit/)
|
||||
assert.match(userBanJs, /data-aksrt-unban-submit/)
|
||||
assert.match(userBanJs, /JioModalRuntime\.close\('submit'\)/)
|
||||
assert.match(userBanJs, /data-jio-ban-submit/)
|
||||
assert.match(userBanJs, /data-jio-unban-submit/)
|
||||
// 桌面 600px(参考主题未传 data-class → Bootstrap .modal-dialog 默认宽)
|
||||
// + min-height 360px(data-height=360);移动端底部抽屉。
|
||||
assert.match(userBanJs, /MODAL_HEIGHT = 360/)
|
||||
assert.match(userBanJs, /mobileBottom: true/)
|
||||
const css = read('assets/css/frontend/modal-runtime.css')
|
||||
assert.match(css, /\.aksrt-user-ban-modal:not\(\.aksrt-modal-runtime--bottom\) \.aksrt-modal-runtime__dialog/)
|
||||
assert.match(css, /\.jio-user-ban-modal:not\(\.jio-modal-runtime--bottom\) \.jio-modal-runtime__dialog/)
|
||||
assert.match(css, /600px/)
|
||||
// textarea autoHeight 1:1(参考主题 maxHeight 锁高 + 边框补偿)。
|
||||
assert.match(userBanJs, /getAttribute\('maxHeight'\)/)
|
||||
// 三个入口模板接线:封面三点菜单 / 评论区三点菜单 / 文章作者 metabox 三点菜单。
|
||||
const authorHero = read('templates/parts/user/author-hero.php')
|
||||
assert.match(authorHero, /aksrt_get_user_cover_menu_action_html\(\$user_id\)/)
|
||||
assert.match(commentItem, /aksrt_get_comment_ban_or_report_item\(\$comment\)/)
|
||||
const singleComponents = read('inc/helpers/aksrt-single-components.php')
|
||||
assert.match(singleComponents, /aksrt_get_post_author_ban_item\(/)
|
||||
assert.match(authorHero, /jio_get_user_cover_menu_action_html\(\$user_id\)/)
|
||||
assert.match(commentItem, /jio_get_comment_ban_or_report_item\(\$comment\)/)
|
||||
const singleComponents = read('inc/helpers/jio-single-components.php')
|
||||
assert.match(singleComponents, /jio_get_post_author_ban_item\(/)
|
||||
// 脚本入队(singular + profile,与 report.js 同组)。
|
||||
const scripts = read('src/Core/ScriptsPart1b.php')
|
||||
assert.match(scripts, /'aksrt-user-ban'/)
|
||||
assert.match(scripts, /'jio-user-ban'/)
|
||||
})
|
||||
|
||||
test('uninstall cleans up every ban/report meta key written by the theme', () => {
|
||||
for (const key of ['_aksrt_active_restrictions', '_aksrt_is_banned', '_aksrt_no_appeal', 'aksrt_user_ban_state']) {
|
||||
for (const key of ['_jio_active_restrictions', '_jio_is_banned', '_jio_no_appeal', 'jio_user_ban_state']) {
|
||||
assert.ok(uninstall.includes(`'${key}'`), `missing uninstall cleanup: ${key}`)
|
||||
}
|
||||
})
|
||||
@@ -539,8 +539,8 @@ test('report modal delegates its labelled title, close button and focus return t
|
||||
const reportJs = read('assets/js/report.js')
|
||||
assert.match(reportJs, /title: TARGETS\[data\.target_type\]\.title/)
|
||||
assert.match(reportJs, /mobileBottom: true, focusReturn: opener/)
|
||||
assert.match(reportJs, /<label class="aksrt-report-label" for=/)
|
||||
assert.match(reportJs, /data-aksrt-report-reason-error role="alert"/)
|
||||
assert.match(reportJs, /<label class="jio-report-label" for=/)
|
||||
assert.match(reportJs, /data-jio-report-reason-error role="alert"/)
|
||||
assert.doesNotMatch(reportJs, /class="close"|style="display:|setTimeout/)
|
||||
})
|
||||
|
||||
|
||||
Reference in new issue
Block a user