fix(chase): the unconfirmed flag survives the next QSO
Reported as 'South Africa shows NEW BAND although I have worked 15m'. The verdict was right — his hunt counts only LoTW and paper QSL, and no 15m contact is confirmed by either — but the badge drew SOLID, saying 'never worked here' about a band with four contacts in the log. Proved with his own data: the confirmed ledger holds 10/12/17/20/30/40/80 and not 15, the all-QSO ledger holds 15m FT8 four times, and the backend sets UnconfStatus correctly for exactly that case (new test, end to end through ClusterSpotStatuses). The flag died in the frontend. FOUR hand-written copies of the same backend-result mapping, and they had drifted: the two that RE-fetch — after a QSO is logged, and when a pane becomes visible — rebuilt each entry without the unconf_* flags, so the first refresh after any contact turned every dimmed badge solid for good. None of the four ever copied grid_state either, so a known-but-unconfirmed square never dimmed at all. One mapper now, used by all four.
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
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")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user