Stage 17: cap display-name special characters at 5 (ui + backend)
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 8s
CI / integration (pull_request) Successful in 14s
CI / ui (pull_request) Successful in 35s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m3s
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 8s
CI / integration (pull_request) Successful in 14s
CI / ui (pull_request) Successful in 35s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m3s
display_name validation gains a rule: at most 5 special characters — the '.' / '_' punctuation (spaces, which separate words, don't count) — so a still-well-formed name can't be mostly punctuation. Mirrored in the Go ValidateDisplayName and the UI validDisplayName; both unit-tested (5 ok, 6 rejected, 'J. R. R. Tolkien' ok). Docs: FUNCTIONAL (+ _ru).
This commit is contained in:
@@ -23,6 +23,11 @@ import (
|
||||
// is unbounded; auto-provisioned platform names bypass this editor validation).
|
||||
const maxDisplayName = 32
|
||||
|
||||
// maxDisplayNameSpecials caps the total special characters (the "." / "_" separators —
|
||||
// every name rune that is neither a letter nor a space) an editable display name may
|
||||
// carry, so a still-well-formed name cannot be made of mostly punctuation (Stage 17).
|
||||
const maxDisplayNameSpecials = 5
|
||||
|
||||
// maxAwayWindow bounds the daily away window's duration (midnight-wrap aware).
|
||||
const maxAwayWindow = 12 * time.Hour
|
||||
|
||||
@@ -110,6 +115,15 @@ func ValidateDisplayName(raw string) (string, error) {
|
||||
if !displayNameRe.MatchString(name) {
|
||||
return "", fmt.Errorf("%w: display name has an invalid character or layout", ErrInvalidProfile)
|
||||
}
|
||||
specials := 0
|
||||
for _, r := range name {
|
||||
if r != ' ' && !unicode.IsLetter(r) {
|
||||
specials++
|
||||
}
|
||||
}
|
||||
if specials > maxDisplayNameSpecials {
|
||||
return "", fmt.Errorf("%w: display name has more than %d special characters", ErrInvalidProfile, maxDisplayNameSpecials)
|
||||
}
|
||||
return name, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,9 @@ func TestValidateDisplayName(t *testing.T) {
|
||||
"digit rejected": {"Name2", "", false},
|
||||
"blank": {" ", "", false},
|
||||
"too long": {strings.Repeat("a", 33), "", false},
|
||||
"five specials ok": {"a.a.a.a.a.a", "a.a.a.a.a.a", true}, // 5 dots
|
||||
"six specials": {"a.a.a.a.a.a.a", "", false}, // 6 dots
|
||||
"initials spaces ok": {"J. R. R. Tolkien", "J. R. R. Tolkien", true}, // 3 dots; spaces don't count
|
||||
}
|
||||
for name, tc := range cases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user