Files
wordpress-theme-aksrt/tests/widget-system/user-profile-phone-contract.test.cjs
T
kate522andClaude Fable 5 f9b7997ec2 fix(user): match profile validation hook argument type
Accept the stdClass user data passed by WordPress and derive the user ID only from the hook object. Cover callback registration, nonce and permission guards, and mismatched posted IDs; refresh the identity review dialog contract.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-30 20:38:00 +08:00

68 lines
3.7 KiB
JavaScript

'use strict';
const assert = require('node:assert/strict');
const fs = require('node:fs');
const path = require('node:path');
const test = require('node:test');
const { execFileSync } = require('node:child_process');
const root = path.resolve(__dirname, '../..');
const read = (file) => fs.readFileSync(path.join(root, file), 'utf8');
test('phone persistence, uniqueness, and native profile saves pass the PHP harness', () => {
const output = execFileSync('php', [path.join(root, 'tests/widget-system/user-profile-phone-harness.php')], { encoding: 'utf8' });
assert.match(output, /User profile phone harness passed/);
});
test('profile validation follows the WordPress stdClass hook contract without a POST user-ID fallback', () => {
const admin = read('src/User/ProfileAdmin.php');
const validation = admin.slice(admin.indexOf('public static function validate('), admin.indexOf('public static function save('));
assert.match(admin, /add_filter\('user_profile_update_errors', \[self::class, 'validate'\], 10, 3\)/);
assert.match(validation, /validate\(\\WP_Error \$errors, bool \$update, \\stdClass \$user\): void/);
assert.match(validation, /\$user_id = \(int\) \(\$user->ID \?\? 0\)/);
assert.doesNotMatch(validation, /instanceof \\WP_User|\$_POST\['user_id'\]/);
assert.match(admin, /render\(\\WP_User \$user\): void/);
});
test('phone binding, registration, and sign-in share phone_number as the only phone value key', () => {
const service = read('src/Auth/Service.php');
const registrationAndBinding = read('src/Auth/ServicePart1b.php');
const handlers = read('src/Admin/UserControllerAuthPhoneOperations.php');
const account = read('inc/helpers/user-center-renderers/settings-account.php');
const admin = read('src/User/ProfileAdmin.php');
const runtime = [service, registrationAndBinding, handlers, account, admin].join('\n');
assert.match(service, /'meta_key'\s*=>\s*'phone_number'/);
assert.match(registrationAndBinding, /update_user_meta\(\$user_id, 'phone_number', \$phone\)/);
assert.match(registrationAndBinding, /'meta_key'\s*=>\s*'phone_number'/);
assert.match(handlers, /'meta_key'\s*=>\s*'phone_number'/);
assert.match(account, /get_user_meta\(\$account_user_id, 'phone_number', true\)/);
assert.doesNotMatch(runtime, /['"]aksrt_phone['"]/);
assert.match(admin, /aksrt_phone_verified/);
assert.match(admin, /wp_verify_nonce/);
assert.match(admin, /current_user_can\('edit_user'/);
});
test('native profile exposes the reference fields and continues using canonical media/profile metadata', () => {
const admin = read('src/User/ProfileAdmin.php');
const avatar = read('inc/helpers/aksrt-avatar.php');
const profile = read('inc/helpers/aksrt-user-center.php');
const form = read('inc/helpers/user-center-renderers/profile-form.php');
const publicProfile = read('templates/parts/user/author-hero.php');
['自定义头像', '自定义封面', '性别', 'QQ', '微信', '微博', 'GitHub', '住址', '绑定手机号'].forEach((label) => assert.ok(admin.includes(label), `missing ${label}`));
assert.match(admin, /'aksrt_avatar_attachment_id'/);
assert.match(admin, /'aksrt_background_attachment_id'/);
assert.match(admin, /'aksrt_profile_details'/);
assert.match(profile, /'weibo'\s*=>/);
assert.match(profile, /'address'\s*=>/);
assert.match(profile, /\$existing_details\['weibo'\]/);
assert.match(profile, /\$existing_details\['address'\]/);
assert.match(form, /name="weibo"/);
assert.match(form, /name="address"/);
assert.match(publicProfile, /\$profile_details\['weibo'\]/);
assert.match(publicProfile, /\$profile_details\['address'\]/);
assert.doesNotMatch(avatar, /aksrt_render_admin_avatar_field|aksrt_save_admin_avatar_field/);
});