package qso import ( "testing" "time" ) func tm(s string) time.Time { t, _ := time.Parse("2006-01-02T15:04", s) return t } func TestMatchIndexWindowAndMode(t *testing.T) { idx := &MatchIndex{byMode: map[string][]matchRef{}} // Local log: a CW QSO, an SSB (logged as USB) QSO, and an FT8 QSO. idx.Add("4Z4DX", "15m", "CW", tm("2026-06-20T10:13"), 1) idx.Add("V85NPV", "15m", "USB", tm("2025-04-18T17:01"), 2) idx.Add("DK0SWL", "20m", "FT8", tm("2026-03-01T09:00"), 3) win := 10 * time.Minute cases := []struct { name string call, band, mode string when string wantID int64 wantOK bool }{ {"exact", "4Z4DX", "15m", "CW", "2026-06-20T10:13", 1, true}, {"1-min drift", "4Z4DX", "15m", "CW", "2026-06-20T10:12", 1, true}, {"9-min drift ok", "4Z4DX", "15m", "CW", "2026-06-20T10:04", 1, true}, {"30-min drift misses", "4Z4DX", "15m", "CW", "2026-06-20T10:43", 0, false}, // Phone sidebands are interchangeable: an SSB confirmation matches a USB log. {"SSB conf vs USB log", "V85NPV", "15m", "SSB", "2025-04-18T17:00", 2, true}, {"LSB conf vs USB log", "V85NPV", "15m", "LSB", "2025-04-18T17:00", 2, true}, // But a digital/phone mismatch does NOT match (exact for non-phone). {"FT8 conf vs SSB log misses", "V85NPV", "15m", "FT8", "2025-04-18T17:00", 0, false}, // Digital is exact: FT8 matches FT8, but FT4 would not. {"FT8 exact", "DK0SWL", "20m", "FT8", "2026-03-01T09:01", 3, true}, {"FT4 vs FT8 misses", "DK0SWL", "20m", "FT4", "2026-03-01T09:01", 0, false}, {"wrong band misses", "DK0SWL", "40m", "FT8", "2026-03-01T09:01", 0, false}, {"unknown call misses", "N0CALL", "15m", "CW", "2026-06-20T10:13", 0, false}, } for _, c := range cases { id, ok := idx.Match(c.call, c.band, c.mode, tm(c.when), win) if ok != c.wantOK || (ok && id != c.wantID) { t.Errorf("%s: got (id=%d ok=%v), want (id=%d ok=%v)", c.name, id, ok, c.wantID, c.wantOK) } } }