first commit
This commit is contained in:
119
internal/user/nostr_sync_test.go
Normal file
119
internal/user/nostr_sync_test.go
Normal file
@@ -0,0 +1,119 @@
|
||||
package user
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestSanitizeForUsername(t *testing.T) {
|
||||
cases := []struct {
|
||||
in, want string
|
||||
}{
|
||||
{"alice", "alice"},
|
||||
{"Alice", "alice"},
|
||||
{" Alice ", "alice"},
|
||||
{"Alice Bob", "alice_bob"},
|
||||
{"alice bob", "alice_bob"},
|
||||
{"Alice!@#Bob", "alice_bob"},
|
||||
{"-alice", "alice"},
|
||||
{"_alice", "alice"},
|
||||
{"alice_", "alice"},
|
||||
{"alice--bob", "alice-bob"},
|
||||
{"alice__bob", "alice_bob"},
|
||||
{" ", ""},
|
||||
{"", ""},
|
||||
{"!!!", ""},
|
||||
{"日本語", ""},
|
||||
{"alice日本", "alice"},
|
||||
{"thisusernameiswaytoolongtobevalid12345", "thisusernameiswaytoolongtobeva"},
|
||||
}
|
||||
for _, tc := range cases {
|
||||
got := SanitizeForUsername(tc.in)
|
||||
if got != tc.want {
|
||||
t.Errorf("SanitizeForUsername(%q) = %q, want %q", tc.in, got, tc.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSanitizeForUsernamePassesValidate(t *testing.T) {
|
||||
inputs := []string{"Alice Bob", " S0me User! ", "alice--bob"}
|
||||
for _, in := range inputs {
|
||||
s := SanitizeForUsername(in)
|
||||
if s == "" {
|
||||
t.Fatalf("unexpected empty sanitize for %q", in)
|
||||
}
|
||||
if err := ValidateUsername(s, nil); err != nil {
|
||||
t.Errorf("sanitized %q -> %q failed ValidateUsername: %v", in, s, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCandidateFromMetadataPrecedence(t *testing.T) {
|
||||
const domain = "azzamo.net"
|
||||
reserved := []string{"admin"}
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
name, dn, dnAlt, username, nip05, dom string
|
||||
want string
|
||||
}{
|
||||
{
|
||||
desc: "nip05 local part wins when domain matches",
|
||||
name: "alice", nip05: "preferred@azzamo.net", dom: domain,
|
||||
want: "preferred",
|
||||
},
|
||||
{
|
||||
desc: "nip05 ignored when domain differs",
|
||||
name: "alice", nip05: "preferred@other.example", dom: domain,
|
||||
want: "alice",
|
||||
},
|
||||
{
|
||||
desc: "name takes precedence over display_name",
|
||||
name: "alice", dn: "Bob Builder", dom: domain,
|
||||
want: "alice",
|
||||
},
|
||||
{
|
||||
desc: "falls back to display_name when name empty",
|
||||
dn: "Bob Builder", dom: domain,
|
||||
want: "bob_builder",
|
||||
},
|
||||
{
|
||||
desc: "falls back to camelCase displayName when others empty",
|
||||
dnAlt: "Bob B", dom: domain,
|
||||
want: "bob_b",
|
||||
},
|
||||
{
|
||||
desc: "falls back to deprecated username last",
|
||||
username: "legacy_user", dom: domain,
|
||||
want: "legacy_user",
|
||||
},
|
||||
{
|
||||
desc: "skips fields that sanitize to empty",
|
||||
name: "!!!", dn: "Real Name", dom: domain,
|
||||
want: "real_name",
|
||||
},
|
||||
{
|
||||
desc: "skips reserved words and falls through",
|
||||
name: "admin", dn: "Real Name", dom: domain,
|
||||
want: "real_name",
|
||||
},
|
||||
{
|
||||
desc: "no usable field returns empty",
|
||||
name: "!!!", dom: domain,
|
||||
want: "",
|
||||
},
|
||||
{
|
||||
desc: "bare nip05 with no @ is ignored",
|
||||
nip05: "alice", name: "fallback", dom: domain,
|
||||
want: "fallback",
|
||||
},
|
||||
{
|
||||
desc: "empty service domain ignores nip05",
|
||||
name: "alice", nip05: "preferred@azzamo.net",
|
||||
want: "alice",
|
||||
},
|
||||
}
|
||||
for _, tc := range cases {
|
||||
got := CandidateFromMetadata(tc.name, tc.dn, tc.dnAlt, tc.username, tc.nip05, tc.dom, reserved)
|
||||
if got != tc.want {
|
||||
t.Errorf("%s: got %q want %q", tc.desc, got, tc.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user