package lookup import ( "encoding/xml" "testing" ) // A real HamQTH answer, captured from the live API. // // Two things it settles. The email IS returned and must reach the QSO. And the // element names are not the ones a reading of the documentation suggests: // there is no here at all, the full name is , and the picture // is where QRZ calls it . The stray
is an advert the // server injects into its own XML; the parser has to shrug it off. const hamqthEU1EU = `
eu1eu Igor Minsk-5 Belarus 27 29 16 KO33SV Igor Vladimirovich Getman A/ya 143 Minsk-5 220005 Belarus 27 WAARB-LE ? ? ? Y eu1eu@mail.ru 53.88999938964844 27.59000015258789 EU -2 https://www.hamqth.com/images/default/ts-930_qith_old_radios.jpg ` func TestHamQTHParsesEveryUsefulField(t *testing.T) { var root hamqthRoot if err := xml.Unmarshal([]byte(hamqthEU1EU), &root); err != nil { t.Fatalf("parse: %v", err) } s := root.Search for _, c := range []struct{ name, got, want string }{ {"callsign", s.Callsign, "eu1eu"}, {"email", s.Email, "eu1eu@mail.ru"}, {"grid", s.Grid, "KO33SV"}, {"qth", s.QTH, "Minsk-5"}, {"street", s.AdrStreet1, "A/ya 143"}, {"city", s.AdrCity, "Minsk-5"}, {"country", s.AdrCountry, "Belarus"}, {"continent", s.Continent, "EU"}, {"dxcc", s.DXCC, "27"}, {"cq", s.CQ, "16"}, {"itu", s.ITU, "29"}, } { if c.got != c.want { t.Errorf("%s = %q, want %q", c.name, c.got, c.want) } } } // The fields the parser was blind to. Each is data OpsLog has somewhere to put. func TestHamQTHParsesTheFieldsThatWereMissing(t *testing.T) { var root hamqthRoot if err := xml.Unmarshal([]byte(hamqthEU1EU), &root); err != nil { t.Fatalf("parse: %v", err) } s := root.Search // The postal name, the fallback when a record carries no nick and no name. if s.AdrName != "Igor Vladimirovich Getman" { t.Errorf("adr_name = %q", s.AdrName) } if s.LastName != "" { t.Errorf("this record has no ; got %q", s.LastName) } // The profile picture. Result.ImageURL existed and said "QRZ only" — HamQTH // sends one too, under a different element name. if s.Picture == "" { t.Error("picture not parsed") } if s.AdrZip != "220005" { t.Errorf("adr_zip = %q", s.AdrZip) } } // End to end: what the provider hands back must carry the email, the full name // and the picture. func TestHamQTHResultCarriesTheLot(t *testing.T) { r, err := parseHamQTHSearch([]byte(hamqthEU1EU)) if err != nil { t.Fatalf("parse: %v", err) } if r.Email != "eu1eu@mail.ru" { t.Errorf("Email = %q — this is what was reported missing", r.Email) } // The nick, not the postal name: a log wants the name the operator goes by // on the air. adr_name is only the fallback when there is nothing else. if r.Name != "Igor" { t.Errorf("Name = %q, want the on-air nick", r.Name) } if r.ImageURL == "" { t.Error("ImageURL empty — HamQTH sent a picture") } if r.Grid != "KO33SV" { t.Errorf("Grid = %q", r.Grid) } if r.Lat < 53.8 || r.Lat > 53.9 { t.Errorf("Lat = %v", r.Lat) } if r.DXCC != 27 || r.CQZ != 16 || r.ITUZ != 29 { t.Errorf("dxcc/cq/itu = %d/%d/%d", r.DXCC, r.CQZ, r.ITUZ) } if r.Address != "A/ya 143" { t.Errorf("Address = %q", r.Address) } }