Files
OpsLog/internal/awardref/dxcciota_test.go
T
rouggy a8bca8c316 feat(awards): an entity that IS one island group fills its own IOTA reference
QRZ carries <iota> only for the operators who filled it in, and most have not.
But for 99 entities the reference follows from the entity alone — a station in
Ascension is on AF-003 whatever its callbook record says — and the entity is
known for every callsign from cty.dat, with no callbook at all.

So this reaches the operator with no QRZ subscription and the station that has
never touched a callbook, and it lands before the contact is logged, which is
when a reference is worth having.

Filled ONLY when the callbook gave nothing: an operator who typed a reference
knows something a table cannot — an IOTA-heavy entity, a rare island being
activated — and that still wins, as does one picked by hand on the entry.

The table is the IOTA programme's own dxcc_matches_one_iota.json, which lists
exactly the entities that map to ONE reference. France is not among them: a
French station is usually on the mainland and on no island, and guessing would
put a reference on hundreds of contacts that earn none.

Held as a table rather than a download — 3.5 kB that changes when an entity
appears, so fetching it daily would buy nothing and would fail exactly where a
portable station usually is. The header says where it came from and how to
refresh it.

Follows 747c2b9 and eab11db, which read the callbook's own tag.
2026-08-17 02:26:52 +02:00

52 lines
1.7 KiB
Go

package awardref
import (
"regexp"
"testing"
)
// The entities an operator meets: an island group that is its own DXCC, and a
// mainland country that is not.
func TestIOTAForDXCC(t *testing.T) {
cases := []struct {
dxcc int
want string
why string
}{
{205, "AF-003", "Ascension Island is one island and one reference"},
{5, "EU-002", "Aland Islands"},
{12, "NA-022", "Anguilla"},
{24, "AN-002", "Bouvet — the entity whose entry is checked most often and worked least"},
// France holds hundreds of islands and, far more to the point, a
// mainland. Filling a reference here would earn nothing and would put
// one on nearly every European contact in the log.
{227, "", "France is not one IOTA"},
{291, "", "the United States is not one IOTA"},
{0, "", "no entity resolved"},
{99999, "", "not an entity at all"},
}
for _, c := range cases {
if got := IOTAForDXCC(c.dxcc); got != c.want {
t.Errorf("IOTAForDXCC(%d) = %q, want %q — %s", c.dxcc, got, c.want, c.why)
}
}
}
// Every reference in the table must be a well-formed IOTA reference, because
// one that is not would be written onto a contact's award references and count
// for nothing — and would then have to be found by hand, one QSO at a time.
func TestEveryOneIOTAEntryIsWellFormed(t *testing.T) {
ref := regexp.MustCompile(`^(AF|AN|AS|EU|NA|OC|SA)-\d{3}$`)
if len(iotaByDXCC) < 50 {
t.Fatalf("the table holds %d entities — it has been truncated", len(iotaByDXCC))
}
for dxcc, r := range iotaByDXCC {
if dxcc <= 0 {
t.Errorf("entity number %d is not a DXCC entity", dxcc)
}
if !ref.MatchString(r) {
t.Errorf("entity %d maps to %q, which is not an IOTA reference", dxcc, r)
}
}
}