Files
wordpress-theme-aksrt/tests/widget-system/message-admin-contract.test.cjs
T
kate522andClaude Fable 5 6681b0c306 feat(messages): redesign native message admin page
- Rebuild users.php?page=aksrt_messages: overview stats, collapsible
  compose card (users list / role recipients), read-state views,
  type/recipient/keyword filters, bulk mark-read/delete, shared
  AdminListPagination
- Extract NotificationAdminQuery / AdminBroadcast / MessageTypes under
  src/Messages; page logic lives in UsersMenusMessages trait
- Page-scoped assets/css/admin/messages.css
- Remove dead aksrt_notification_type_label() and
  Message::get_all_notifications()

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-27 22:51:11 +08:00

56 lines
2.8 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.
'use strict';
/**
* 消息管理后台(users.php → aksrt_messages)契约:
* 1) 页面由独立 trait 承载,UsersMenus 只做组合与路由注册;
* 2) 写操作走 admin_post + nonce + 能力校验;
* 3) SQL 全部在 NotificationAdminQuery 内且经 prepare;
* 4) 分页用共享 AdminListPagination;
* 5) 旧实现与死代码已删除。
*/
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');
test('messages page is composed from its own trait', () => {
const menus = read('src/Admin/Native/UsersMenus.php');
assert.ok(menus.includes('use UsersMenusMessages;'));
assert.ok(menus.includes("'aksrt_messages'"));
assert.ok(menus.includes("add_action('admin_post_aksrt_users_send_message', [$this, 'handle_send_message'])"));
assert.ok(menus.includes("add_action('admin_post_aksrt_users_bulk_messages', [$this, 'handle_bulk_messages'])"));
assert.ok(menus.includes("add_action('admin_enqueue_scripts', [$this, 'enqueue_message_assets'])"));
// 旧实现不得残留在壳类中。
assert.doesNotMatch(menus, /function render_messages_page|function handle_send_message|message_sent|message_failed/);
assert.doesNotMatch(menus, /aksrt_notification/);
});
test('write handlers check capability and nonce', () => {
const page = read('src/Admin/Native/UsersMenusMessages.php');
assert.match(page, /function handle_send_message\(\): void \{\s*\$this->ensure_cap\(\);\s*check_admin_referer\('aksrt_users_send_message'\);/);
assert.match(page, /function handle_bulk_messages\(\): void \{\s*\$this->ensure_cap\(\);\s*check_admin_referer\('aksrt_users_bulk_messages'\);/);
assert.ok(page.includes("wp_nonce_field('aksrt_users_send_message')"));
assert.ok(page.includes("wp_nonce_field('aksrt_users_bulk_messages')"));
// 页面层不直接碰数据库,分页走共享组件。
assert.doesNotMatch(page, /\$wpdb/);
assert.ok(page.includes('AdminListPagination::render('));
});
test('admin query keeps SQL prepared and bulk size capped', () => {
const query = read('src/Messages/NotificationAdminQuery.php');
assert.match(query, /DELETE FROM \{\$table\} WHERE id IN \(\{\$in\}\)", \$ids\)/);
assert.ok(query.includes("array_fill(0, count($ids), '%d')"));
assert.ok(query.includes('array_slice($ids, 0, self::MAX_BULK)'));
assert.ok(query.includes('$wpdb->esc_like($s)'));
});
test('dead notification helpers are removed', () => {
assert.doesNotMatch(read('inc/modules/user-notifications.php'), /aksrt_notification_type_label/);
assert.doesNotMatch(read('src/Messages/Message.php'), /get_all_notifications/);
assert.ok(fs.existsSync(path.join(root, 'assets/css/admin/messages.css')));
});