Files
OpsLog/qrz_confirm_test.go
T
rouggy 284a7a18c7 fix: QRZ download marked every paper-QSL QSO as QRZ-confirmed
Reported: after a confirmation download they all turn to Y.

The test accepted qsl_rcvd = Y as a confirmation. That field is the operator's
OWN paper-QSL flag, which they uploaded to QRZ in the first place — so QRZ handed
it back and OpsLog read it as QRZ's answer. On a log full of paper cards that is
most of the log, which is exactly what was seen.

Only QRZ's own statement counts now: app_qrzlog_status = C, or the ADIF field
qrzcom_qso_download_status = Y that QRZ sets for it. LoTW and eQSL confirmations
are explicitly not accepted either — they are other services' answers, and the
column says QRZ.

This status feeds award slots, so a false Y is a QSO counted as confirmed when it
is not. That asymmetry is why the rule is narrow rather than generous, and the
test lists the negatives as deliberately as the positives.

The changelog warns that earlier downloads may already have set the column
wrongly — the fix stops it happening again but does not undo it.
2026-07-29 17:59:04 +02:00

48 lines
1.8 KiB
Go

package main
import (
"testing"
"hamlog/internal/adif"
)
// What counts as a QRZ.com confirmation.
//
// Reported 2026-07-29: after a confirmation download, every QSO turned to Y. The
// test accepted qsl_rcvd = Y — but that is the operator's own PAPER QSL flag,
// which they uploaded to QRZ themselves, so every QSO with a card came back
// looking QRZ-confirmed. On a log full of paper QSLs that is most of it.
//
// This status feeds the award slots, so a false Y is a QSO counted as confirmed
// when it is not — the reason the rule is narrow rather than generous.
func TestQRZRecordConfirmed(t *testing.T) {
cases := []struct {
name string
rec adif.Record
want bool
}{
// QRZ's own statements.
{"QRZ download status Y", adif.Record{"qrzcom_qso_download_status": "Y"}, true},
{"QRZ log status C", adif.Record{"app_qrzlog_status": "C"}, true},
{"lower case is still QRZ's answer", adif.Record{"app_qrzlog_status": "c"}, true},
{"padded", adif.Record{"app_qrzlog_status": " C "}, true},
// NOT confirmations by QRZ — the bug being fixed.
{"paper QSL received", adif.Record{"qsl_rcvd": "Y"}, false},
{"paper QSL plus a card sent", adif.Record{"qsl_rcvd": "Y", "qsl_sent": "Y"}, false},
{"LoTW confirmed, QRZ silent", adif.Record{"lotw_qsl_rcvd": "Y"}, false},
{"eQSL confirmed, QRZ silent", adif.Record{"eqsl_qsl_rcvd": "Y"}, false},
// Explicit negatives and nothing at all.
{"QRZ says no", adif.Record{"qrzcom_qso_download_status": "N"}, false},
{"QRZ status not confirmed", adif.Record{"app_qrzlog_status": "N"}, false},
{"bare record", adif.Record{"call": "F4XYZ"}, false},
{"empty", adif.Record{}, false},
}
for _, c := range cases {
if got := qrzRecordConfirmed(c.rec); got != c.want {
t.Errorf("%s: qrzRecordConfirmed = %v, want %v (%v)", c.name, got, c.want, c.rec)
}
}
}