package family import ( "strings" "testing" ) // W12 (rehearsal 2026-10-20): a Hungarian family's own names („Ödön", „Írisz") were refused. The name is now kept as // typed and the LOGIN is made from it — accents removed, lower case — and still passes the login's own check. func TestW12_AccentedNamesGetAPlainLogin(t *testing.T) { for in, want := range map[string]string{ "Ödön": "odon", "Írisz": "irisz", "ŐRSÉG": "orseg", "Kis Anna": "kis.anna", "Anna-Mária": "anna-maria", "anna": "anna", "odon2": "odon2", "O'Brien": "obrien", " Ünő ": "uno", "Анна": "", "!!!": "", ".x": "x", } { if got := LoginFrom(in); got != want { t.Errorf("LoginFrom(%q) = %q, want %q", in, got, want) } } if got := LoginFrom(strings.Repeat("é", 40)); got != strings.Repeat("e", 32) { t.Errorf("a long name is not cut to 32: %q", got) } s, dir := testStore(t) login, pw, err := s.AddPerson("Ödön") if err != nil || login != "odon" || !s.Verify("odon", pw) { t.Fatalf("Ödön: %q %v", login, err) } if login, _, err := s.AddPerson("Írisz"); err != nil || login != "irisz" { t.Fatalf("Írisz: %q %v", login, err) } // a second person whose name makes the same login gets the next number login2, pw2, err := s.AddPerson("Odon") if err != nil || login2 != "odon2" || !s.Verify("odon2", pw2) || s.Verify("odon", pw2) { t.Fatalf("the second odon: %q %v", login2, err) } // the same name again is the same person: refused, never a third login if _, _, err := s.AddPerson("ödön"); err != ErrExists { t.Fatalf("the same name twice: %v", err) } for _, bad := range []string{"", " ", "Анна", "!!!", strings.Repeat("a", MaxDisplayRunes+1), "an\x00na"} { if _, _, err := s.AddPerson(bad); err != ErrBadName { t.Fatalf("name %q accepted: %v", bad, err) } } // the display name is kept exactly as typed, and survives a reopen s2, err := Open(dir) if err != nil { t.Fatal(err) } got := map[string]string{} for _, p := range s2.People() { got[p.Login] = p.Display } if got["odon"] != "Ödön" || got["irisz"] != "Írisz" || got["odon2"] != "Odon" || len(got) != 3 { t.Fatalf("people: %v", got) } // the login's own check is unchanged for _, bad := range []string{"Ödön", "a b", "Anna"} { if _, err := s.Add(bad); err != ErrBadName { t.Fatalf("Add(%q) accepted a login outside the safe set", bad) } } } // A long name whose login is taken: the numbered login still fits 32 characters. func TestW12_NumberedLoginStaysInsideTheLimit(t *testing.T) { s, _ := testStore(t) long := strings.Repeat("a", 32) if l, _, err := s.AddPerson(long); err != nil || l != long { t.Fatalf("%q %v", l, err) } l, _, err := s.AddPerson(strings.Repeat("á", 32)) if err != nil || l != strings.Repeat("a", 31)+"2" { t.Fatalf("%q %v", l, err) } }