Skip to content

Commit 30b4b8c

Browse files
authored
Allow digits in the generated short name (#820)
## Changes Digits were previously replaced by `_`. ## Tests Additional test cases with uncommon variations of email addresses.
1 parent f31e8b4 commit 30b4b8c

File tree

2 files changed

+57
-19
lines changed

2 files changed

+57
-19
lines changed

bundle/config/mutator/populate_current_user.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,17 @@ func (m *populateCurrentUser) Apply(ctx context.Context, b *bundle.Bundle) error
3838
return nil
3939
}
4040

41+
func replaceNonAlphanumeric(r rune) rune {
42+
if unicode.IsLetter(r) || unicode.IsDigit(r) {
43+
return r
44+
}
45+
return '_'
46+
}
47+
4148
// Get a short-form username, based on the user's primary email address.
4249
// We leave the full range of unicode letters in tact, but remove all "special" characters,
4350
// including dots, which are not supported in e.g. experiment names.
4451
func getShortUserName(emailAddress string) string {
45-
r := []rune(strings.Split(emailAddress, "@")[0])
46-
for i := 0; i < len(r); i++ {
47-
if !unicode.IsLetter(r[i]) {
48-
r[i] = '_'
49-
}
50-
}
51-
return string(r)
52+
local, _, _ := strings.Cut(emailAddress, "@")
53+
return strings.Map(replaceNonAlphanumeric, local)
5254
}
Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package mutator
22

3-
import "testing"
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
)
48

59
func TestPopulateCurrentUser(t *testing.T) {
610
// We need to implement workspace client mocking to implement this test.
@@ -13,28 +17,60 @@ func TestGetShortUserName(t *testing.T) {
1317
expected string
1418
}{
1519
{
16-
name: "test alphanumeric characters",
17-
18-
expected: "test_user",
20+
21+
expected: "test_user_1234",
1922
},
2023
{
21-
name: "test unicode characters",
2224
email: "tést.ü[email protected]",
2325
expected: "tést_üser",
2426
},
2527
{
26-
name: "test special characters",
2728
2829
expected: "test__user",
2930
},
31+
{
32+
email: `jöhn.dœ@domain.com`, // Using non-ASCII characters.
33+
expected: "jöhn_dœ",
34+
},
35+
{
36+
email: `[email protected]`, // The plus (+) sign is used for "sub-addressing" in some email services.
37+
expected: "first_tag",
38+
},
39+
{
40+
email: `[email protected]`, // Using a sub-domain.
41+
expected: "email",
42+
},
43+
{
44+
email: `"_quoted"@domain.com`, // Quoted strings can be part of the local-part.
45+
expected: "__quoted_",
46+
},
47+
{
48+
email: `name-o'[email protected]`, // Single quote in the local-part.
49+
expected: "name_o_mally",
50+
},
51+
{
52+
email: `user%[email protected]`, // Percent sign can be used for email routing in legacy systems.
53+
expected: "user_domain",
54+
},
55+
{
56+
email: `[email protected]`, // Multiple dots in the local-part.
57+
expected: "long_name_with_dots",
58+
},
59+
{
60+
email: `me&[email protected]`, // Using an ampersand (&) in the local-part.
61+
expected: "me_you",
62+
},
63+
{
64+
email: `[email protected]`, // The exclamation mark can be valid in some legacy systems.
65+
expected: "user_def_xyz",
66+
},
67+
{
68+
email: `admin@ιντερνετ.com`, // Domain in non-ASCII characters (IDN or Internationalized Domain Name).
69+
expected: "admin",
70+
},
3071
}
3172

3273
for _, tt := range tests {
33-
t.Run(tt.name, func(t *testing.T) {
34-
result := getShortUserName(tt.email)
35-
if result != tt.expected {
36-
t.Errorf("getShortUserName(%q) = %q; expected %q", tt.email, result, tt.expected)
37-
}
38-
})
74+
assert.Equal(t, tt.expected, getShortUserName(tt.email))
3975
}
4076
}

0 commit comments

Comments
 (0)