Files
Nip-05-api/internal/user/nostr_sync_test.go
2026-04-29 02:35:00 +00:00

120 lines
3.0 KiB
Go

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)
}
}
}