Files
wordpress-theme-aksrt/tests/widget-system/email-system-contract.test.cjs
T

93 lines
4.4 KiB
JavaScript

const test = require('node:test')
const assert = require('node:assert/strict')
const fs = require('node:fs')
const path = require('node:path')
const root = path.resolve(__dirname, '..', '..')
const read = (file) => fs.readFileSync(path.join(root, file), 'utf8')
const templates = read('src/Settings/MailTemplates.php')
const mail = read('src/Settings/Mail.php')
const notifications = read('src/Settings/MailNotifications.php')
const coreHooks = read('inc/core-hooks/part-2.php')
const globalController = read('src/Admin/GlobalController.php')
const userController = read('src/Admin/UserController.php')
const settings = read('src/Settings/Settings.php')
test('email catalog includes required non-forum and financial events', () => {
const required = [
'reg_verify_code', 'reg_success', 'login_code', 'password_reset', 'change_code', 'change_notice',
'order_paid', 'order_status', 'withdraw_submitted', 'withdraw_completed', 'affiliate_commission',
'creator_income', 'transfer_received', 'comment_approved', 'comment_reply', 'post_result',
'phone_changed', 'auth_apply_result', 'user_ban', 'report_result',
'order_paid_admin', 'withdraw_submitted_admin',
]
for (const event of required) {
assert.match(templates, new RegExp(`'${event}'\\s*=>\\s*self::event`), event)
}
})
test('forum-only events stay out of the email catalog', () => {
for (const forbidden of ['bbs', 'moderator', 'answer_adopted', 'answer-adopted']) {
assert.doesNotMatch(templates, new RegExp(forbidden, 'i'))
assert.doesNotMatch(notifications, new RegExp(forbidden, 'i'))
}
})
test('email templates and SMTP use one aksrt_settings schema', () => {
assert.match(templates, /'option_key'\s*=>\s*'aksrt_settings'/)
assert.match(templates, /'mail_passwd'.*'secret'\s*=>\s*true/)
assert.match(mail, /Settings::get_all\(\)/)
assert.match(mail, /'auth'\s*=>\s*\$username\s*!==\s*''\s*&&\s*\$password\s*!==\s*''/)
assert.doesNotMatch(templates, /mail_smtpauth/)
assert.doesNotMatch(mail, /mail_smtpauth/)
assert.doesNotMatch(settings, /aksrt_mail_smtp/)
assert.doesNotMatch(globalController, /aksrt_mail_config|\/settings\/mail'/)
assert.doesNotMatch(userController, /aksrt_mail_templates|mail-templates/)
})
test('SMTP authentication and failures use the canonical mail service', () => {
assert.match(coreHooks, /add_filter\('wp_mail_from',/)
assert.match(coreHooks, /add_filter\('wp_mail_from_name',/)
assert.match(coreHooks, /if \(empty\(\$mail\['enabled'\]\)\) return \$from/)
assert.match(coreHooks, /if \(empty\(\$mail\['enabled'\]\)\) return \$from_name/)
assert.match(coreHooks, /\$mail\['from_address'\]/)
assert.match(coreHooks, /\$mail\['from_name'\]/)
assert.match(coreHooks, /\$phpmailer->SMTPAuth\s*=\s*!empty\(\$mail\['auth'\]\)\s*&&\s*!empty\(\$mail\['username'\]\)/)
assert.doesNotMatch(coreHooks, /\$phpmailer->setFrom\(/)
assert.match(mail, /add_action\('wp_mail_failed',\s*\$capture_failure\)/)
assert.match(mail, /remove_action\('wp_mail_failed',\s*\$capture_failure\)/)
assert.match(mail, /error_log\('\[AKSRT\] SMTP 测试失败:'/)
assert.match(globalController, /详细原因已写入服务器错误日志/)
})
test('canonical mail service contains no obsolete catalog or placeholder branches', () => {
assert.doesNotMatch(mail, /public static function events\s*\(/)
assert.doesNotMatch(mail, /replace_placeholders\([^\n]+,\s*false\)/)
assert.doesNotMatch(mail, /replace_placeholders\(string \$value, array \$placeholders, bool \$html\)/)
})
test('only the canonical mail service calls wp_mail', () => {
const phpFiles = []
const walk = (dir) => {
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
const full = path.join(dir, entry.name)
if (entry.isDirectory()) walk(full)
else if (entry.name.endsWith('.php')) phpFiles.push(full)
}
}
walk(root)
const callers = phpFiles.filter((file) => /wp_mail\s*\(/.test(fs.readFileSync(file, 'utf8')))
assert.deepEqual(callers.map((file) => path.relative(root, file).replaceAll('\\', '/')), ['src/Settings/Mail.php'])
})
test('financial and account hooks are wired to the notification service', () => {
for (const hook of [
'aksrt_order_paid', 'aksrt_order_status_changed', 'aksrt_asset_transaction_committed',
'aksrt_withdrawal_submitted', 'aksrt_withdrawal_status_changed',
'aksrt_user_phone_changed',
]) {
assert.match(notifications, new RegExp(`add_action\\('${hook}'`), hook)
}
})