fix(lookup): QRZ Name is the first name, not first + surname

A log greets an operator; it does not address an envelope. "Robert Smith"
filled the Name field with something no one would ever send on the air, and it
is the first name that gets used when the contact is answered.

So fname alone, with the surname kept only as a last resort for a record that
has no first name at all — better a surname than an empty field. The nickname
option now falls back to the first name too, which is what it should have done
from the start.

joinName went with it: nothing composed a name any more.
This commit is contained in:
2026-08-13 10:53:13 +02:00
parent 8e49d37cbd
commit d0f06d9670
3 changed files with 37 additions and 37 deletions
+20 -18
View File
@@ -2,30 +2,32 @@ package lookup
import "testing"
// The nickname is the name an operator goes BY on the air, and that is what
// belongs in a log — "Bob", not "Robert J Smith". HamQTH's <nick> is already
// used that way; this brings QRZ into line for operators who ask for it.
// What goes in a log's Name field is the FIRST name. A log greets an operator;
// it does not address an envelope. "Robert Smith" filled the field with
// something no one would ever send on the air.
//
// The one thing it must never do is blank the name. A published nickname is
// optional, so an empty one has to fall through to the registered name rather
// than win by being "preferred".
func TestQRZNamePrefersNicknameButFallsBack(t *testing.T) {
// The nickname wins ahead of it when asked for — but a published nickname is
// optional, so an empty one must fall through rather than blank the name. That
// is the whole difference between a fallback and a swap.
func TestQRZName(t *testing.T) {
for _, tc := range []struct {
name string
prefer bool
nickname, fname, name string
nickname, fname, last string
want string
}{
{true, "Bob", "Robert", "Smith", "Bob"},
{true, "", "Robert", "Smith", "Robert Smith"}, // no nickname published
{true, " ", "Robert", "Smith", "Robert Smith"}, // blank is not a nickname
{false, "Bob", "Robert", "Smith", "Robert Smith"}, // option off
{true, "Bob", "", "", "Bob"},
{false, "", "Robert", "", "Robert"},
{true, "", "", "Smith", "Smith"},
{"first name only, never the surname", false, "Bob", "Robert", "Smith", "Robert"},
{"nickname when asked for", true, "Bob", "Robert", "Smith", "Bob"},
{"no nickname published falls back to the FIRST name", true, "", "Robert", "Smith", "Robert"},
{"a blank nickname is not a nickname", true, " ", "Robert", "Smith", "Robert"},
{"option off ignores the nickname", false, "Bob", "Robert", "Smith", "Robert"},
{"surname is the last resort, not the default", true, "", "", "Smith", "Smith"},
{"nothing published at all", false, "", "", "", ""},
{"nickname alone", true, "Bob", "", "", "Bob"},
} {
if got := qrzName(tc.prefer, tc.nickname, tc.fname, tc.name); got != tc.want {
t.Errorf("qrzName(%v, %q, %q, %q) = %q, want %q",
tc.prefer, tc.nickname, tc.fname, tc.name, got, tc.want)
if got := qrzName(tc.prefer, tc.nickname, tc.fname, tc.last); got != tc.want {
t.Errorf("%s: qrzName(%v, %q, %q, %q) = %q, want %q",
tc.name, tc.prefer, tc.nickname, tc.fname, tc.last, got, tc.want)
}
}
}