Files
OpsLog/internal/cat/omnirig_vfo_test.go
T
rouggy 843dccf0c4 fix: bulk edit refused the fields it offered (#3)
My mistake yesterday: the new confirmation columns went into uploadStatusCols —
the QSL Manager's FILTER whitelist — instead of bulkEditableCols. The dialog
listed QRZ.com received status and the ten dates, and the repository refused
them at Apply, after the operator had selected 54 QSOs.

Moved to the right map. And two fields have been broken this way since long
before: State and County were offered under "Contacted station" (whose IOTA /
POTA / SOTA / SIG siblings are all allowed) but were missing from the whitelist,
so choosing one always failed. Added — they are exactly what an import loses and
what a whole run shares.

The real fix is the test. Two lists in two languages had to agree by hand and
nothing checked it, so the failure only ever surfaced as an error message at the
last click. The new tests read the ACTUAL field ids out of BulkEditModal.tsx and
FilterBuilder.tsx and assert the repository accepts every one — a field added to
the UI alone now fails the build instead of the operator.
2026-07-28 09:45:22 +02:00

86 lines
5.1 KiB
Go

package cat
import "testing"
// Every known rig's OmniRig behaviour, pinned. These rules genuinely contradict
// each other between models, so a change that fixes one rig must be shown not to
// break another — that is what this table is for.
func TestResolveOmniRigVFOs(t *testing.T) {
const (
a14200 = 14200000
b14205 = 14205000
b21000 = 21000000
)
cases := []struct {
name string
rig string
main, fa, fb int64
vfo string
split int64
sticky bool
wantTX, wantRX int64
wantSplit bool
}{
// The reported failure: FTDX101D, SUB VFO pressed. OmniRig names VFO B and
// reports it as the generic Freq; freqA still holds the main VFO. Preferring
// freqA meant the display never followed the operator to B.
{"FTDX101D on SUB VFO", "FTDX101D", b14205, a14200, b14205, "B", pmSplitOff, false, b14205, 0, false},
{"FTDX101D on MAIN VFO", "FTDX101D", a14200, a14200, b14205, "A", pmSplitOff, false, a14200, 0, false},
// Yaesu fallback for a rig file that names NO VFO at all (the stock FTDX10
// one, confirmed 2026-07-26): the generic Freq matching FreqB is then the
// only sign that the operator is on SUB. It applies ONLY when the enum is
// silent — when the enum names a VFO, the enum wins (pair cases below).
{"FTDX10, no enum, generic Freq is B", "FTDX10", b14205, a14200, b14205, "", pmSplitOff, false, b14205, 0, false},
// Same alternating ini: one poll says OFF while the rig IS in split. The
// latched ON flag has to survive the contradicting sample.
{"FTDX101D split, contradicting OFF sample", "FTDX101D", a14200, a14200, b14205, "AB", pmSplitOff, true, b14205, a14200, true},
// The latch must not manufacture a split out of a stale cross-band VFO B.
{"FTDX101D latch, VFOs on different bands", "FTDX101D", a14200, a14200, b21000, "AB", pmSplitOff, true, a14200, 0, false},
// Pair enums: first letter is the VFO being listened on. Reported by the
// whole Yaesu family; ignoring them pinned the display to VFO A (F4NBZ,
// 2026-07-26 — Log4OM follows SUB on the same rig through OmniRig).
{"pair enum BA, simplex → listening on B", "", b14205, a14200, b14205, "BA", pmSplitOff, false, b14205, 0, false},
{"pair enum BB, simplex → listening on B", "", b14205, a14200, b14205, "BB", pmSplitOff, false, b14205, 0, false},
{"pair enum AB, simplex → listening on A", "", a14200, a14200, b14205, "AB", pmSplitOff, false, a14200, 0, false},
{"pair enum AA, simplex → listening on A", "", a14200, a14200, b14205, "AA", pmSplitOff, false, a14200, 0, false},
// F4?? IC-7610 report, 2026-07-27: the operator's custom rig file declares
// VFO B permanently while they work on the MAIN VFO. OpsLog then wrote to A
// (SetSimplexMode acts on main) and read B — "the frequency never follows
// the knob". Honouring the enum is right in general, which is why the cure
// is an explicit override in the settings, applied before this function.
{"IC-7610 file wrongly says B — enum honoured, hence the override", "IC-7610", 0, 7150000, 14295000, "B", pmSplitOff, false, 14295000, 0, false},
{"same rig with the override forcing A", "IC-7610", 0, 7150000, 14295000, "A", pmSplitOff, false, 7150000, 0, false},
// Non-regression: a rig that does not report the VFO enum keeps the old
// order — freqA, then the generic Freq, then freqB.
{"no VFO enum, freqA populated (Yaesu/Kenwood)", "FT-891", a14200, a14200, 0, "", pmSplitOff, false, a14200, 0, false},
{"no VFO enum, only generic Freq (IC-9100)", "IC-9100", a14200, 0, 0, "", pmSplitOff, false, a14200, 0, false},
{"IC-7610: generic Freq reports B, enum says A", "IC-7610", b14205, a14200, b14205, "A", pmSplitOff, false, a14200, 0, false},
// Split: PM_SPLITON must be read as a BIT. An exact == 0x8000 reported "no
// split" for any rig that sets the flag alongside another bit.
{"split, ON flag alone", "", a14200, a14200, b14205, "AB", pmSplitOn, false, b14205, a14200, true},
{"split, ON flag with extra bits set", "", a14200, a14200, b14205, "AB", pmSplitOn | 0x40, false, b14205, a14200, true},
{"listening on B → TX on A", "", b14205, a14200, b14205, "BA", pmSplitOn, false, a14200, b14205, true},
// Split must NOT be inferred when the rig says OFF, nor from a stale VFO B
// left on another band (the FT-710 / TS-570 false positive).
{"OFF flag, two distinct VFOs", "", a14200, a14200, b14205, "A", pmSplitOff, false, a14200, 0, false},
{"ON flag but VFOs on different bands", "", a14200, a14200, b21000, "AB", pmSplitOn, false, a14200, 0, false},
{"ON flag but both VFOs identical", "", a14200, a14200, a14200, "AB", pmSplitOn, false, a14200, 0, false},
{"ON and OFF both set — ambiguous, treat as no split", "", a14200, a14200, b14205, "A", pmSplitOn | pmSplitOff, false, a14200, 0, false},
}
for _, c := range cases {
tx, rx, split := resolveOmniRigVFOs(c.rig, c.main, c.fa, c.fb, c.vfo, c.split, c.sticky)
if tx != c.wantTX || rx != c.wantRX || split != c.wantSplit {
t.Errorf("%s:\n got TX=%d RX=%d split=%v\n want TX=%d RX=%d split=%v",
c.name, tx, rx, split, c.wantTX, c.wantRX, c.wantSplit)
}
}
}