package main import ( "context" "path/filepath" "testing" "time" "hamlog/internal/db" "hamlog/internal/dxcc" "hamlog/internal/qso" "hamlog/internal/settings" ) // The operator's exact case, end to end through the real verdict path. // // South Africa is confirmed (LoTW) on 20m and worked-but-unconfirmed on 15m, // with the hunt set to "new + unconfirmed" over LoTW and paper QSL. A 15m FT8 // decode must come back NEW BAND — that is what the settings ask — and carry // the UNCONFIRMED flag, which is what draws the badge as a missing QSL rather // than a band never worked. func TestClusterStatusFlagsUnconfirmedBand(t *testing.T) { dir := t.TempDir() conn, err := db.Open(filepath.Join(dir, "log.db")) if err != nil { t.Fatalf("open: %v", err) } t.Cleanup(func() { conn.Close() }) a := &App{ctx: context.Background(), qso: qso.NewRepo(conn), settings: settings.NewStore(conn)} a.settingsScoped.Store(true) if err := a.settings.Set(a.ctx, keyChaseMode, "new_unconfirmed"); err != nil { t.Fatalf("set chase mode: %v", err) } if err := a.settings.Set(a.ctx, keyChaseConfirm, "lotw,card"); err != nil { t.Fatalf("set chase sources: %v", err) } // The real prefix table, so ZS4AW resolves the way it does in the app. a.dxcc = dxcc.NewManager(filepath.Join("build", "bin", "data")) if err := a.dxcc.LoadFromDisk(); err != nil { t.Skipf("cty.dat not available here: %v", err) } za := 462 add := func(call, band, mode, lotw string) { hz := int64(21074000) if _, err := a.qso.Add(a.ctx, qso.QSO{ Callsign: call, Band: band, Mode: mode, FreqHz: &hz, QSODate: time.Now().UTC().Add(-72 * time.Hour), DXCC: &za, Country: "South Africa", LOTWRcvd: lotw, }); err != nil { t.Fatalf("add %s: %v", call, err) } } add("ZS1AAA", "20m", "FT8", "Y") // the entity IS confirmed, elsewhere add("ZS6GAV", "15m", "FT8", "N") // 15m worked, never confirmed add("ZS4AW", "15m", "FT8", "N") got := a.ClusterSpotStatuses([]SpotQuery{{Call: "ZS4AW", Band: "15m", Mode: "FT8"}}) if len(got) != 1 { t.Fatalf("got %d results", len(got)) } if got[0].Status != "new-band" { t.Fatalf("status = %q, want new-band", got[0].Status) } if !got[0].UnconfStatus { t.Error("UnconfStatus is false — the badge draws solid, as if 15m had never been worked") } }