feat: allow spaces in profile display names (#97)

This commit is contained in:
Xudong Sun 2026-03-19 11:13:52 +08:00 • committed by GitHub
parent d126af15d8
commit 6a62fec9e8
7 changed files with 27 additions and 10 deletions

View file

@ -12,14 +12,14 @@ import jakarta.validation.constraints.Size;
* <p>Validation rules for displayName:
* <ul>
* <li>Length: 2–32 characters (after trim)</li>
* <li>Allowed characters: Chinese, English, digits, underscore, hyphen</li>
* <li>Allowed characters: Chinese, English, digits, spaces, underscore, hyphen</li>
* </ul>
*
* @param displayName new display name (nullable — omit to leave unchanged)
*/
public record UpdateProfileRequest(
@Size(min = 2, max = 32, message = "error.profile.displayName.length")
@Pattern(regexp = "^[\\u4e00-\\u9fa5a-zA-Z0-9_-]+$",
@Pattern(regexp = "^[\\u4e00-\\u9fa5a-zA-Z0-9_ -]+$",
message = "error.profile.displayName.pattern")
String displayName
) {

View file

@ -127,8 +127,7 @@ error.skill.approve.nameConflict=Cannot approve: a published skill with name ''{
# Profile update
error.profile.displayName.length=Display name must be between 2 and 32 characters
error.profile.displayName.pattern=Display name can only contain Chinese characters, English letters, numbers, underscores, and hyphens
error.profile.displayName.pattern=Display name can only contain Chinese characters, English letters, numbers, spaces, underscores, and hyphens
error.profile.noChanges=At least one field must be provided
response.profile.updated=Profile updated successfully
response.profile.pendingReview=Profile changes submitted for review

View file

@ -127,8 +127,7 @@ error.skill.approve.nameConflict=无法通过审核:该命名空间下已存
# 用户资料修改
error.profile.displayName.length=昵称长度需在 2-32 个字符之间
error.profile.displayName.pattern=昵称仅允许中文、英文、数字、下划线和连字符
error.profile.displayName.pattern=昵称仅允许中文、英文、数字、空格、下划线和连字符
error.profile.noChanges=至少需要提供一个修改字段
response.profile.updated=资料已更新
response.profile.pendingReview=资料变更已提交审核

View file

@ -135,6 +135,25 @@ class UserProfileControllerTest {
.andExpect(jsonPath("$.data.status").value("APPLIED"));
}
@Test
void updateProfile_displayNameWithSpaces_shouldReturn200() throws Exception {
var principal = testPrincipal();
var user = new UserAccount("user-1", "OldName", "user@example.com", "https://example.com/avatar.png");
given(userAccountRepository.findById("user-1")).willReturn(Optional.of(user));
given(namespaceMemberRepository.findByUserId("user-1")).willReturn(List.of());
given(userRoleBindingRepository.findByUserId("user-1")).willReturn(List.of());
mockMvc.perform(patch("/api/v1/user/profile")
.with(authentication(testAuth(principal)))
.with(csrf())
.contentType(MediaType.APPLICATION_JSON)
.content("{\"displayName\":\"New Name\"}"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.code").value(0))
.andExpect(jsonPath("$.data.status").value("APPLIED"));
}
// ===== AC-E-001: Display name too short =====
@Test

View file

@ -525,7 +525,7 @@
"defaultError": "Failed to update profile. Please try again.",
"validation": {
"length": "Display name must be 2-32 characters.",
"pattern": "Display name can only contain Chinese, English, digits, underscores, and hyphens."
"pattern": "Display name can only contain Chinese, English, digits, spaces, underscores, and hyphens."
}
},
"security": {

View file

@ -525,7 +525,7 @@
"defaultError": "修改失败,请稍后重试。",
"validation": {
"length": "昵称长度需为 2-32 个字符。",
"pattern": "昵称只能包含中文、英文、数字、下划线和连字符。"
"pattern": "昵称只能包含中文、英文、数字、空格、下划线和连字符。"
}
},
"security": {

View file

@ -9,8 +9,8 @@ import { Button } from '@/shared/ui/button'
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/shared/ui/card'
import { Input } from '@/shared/ui/input'
/** Regex matching allowed display name characters: Chinese, English, digits, underscore, hyphen. */
const DISPLAY_NAME_PATTERN = /^[\u4e00-\u9fa5a-zA-Z0-9_-]+$/
/** Regex matching allowed display name characters: Chinese, English, digits, spaces, underscore, hyphen. */
const DISPLAY_NAME_PATTERN = /^[\u4e00-\u9fa5a-zA-Z0-9_ -]+$/
export function ProfileSettingsPage() {
const { t } = useTranslation()