113 lines
3.7 KiB
Go
113 lines
3.7 KiB
Go
package main
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"hamlog/internal/award"
|
|
)
|
|
|
|
// The catalog is the channel through which a shipped award is both DELIVERED and
|
|
// CORRECTED. These tests pin the three rules that make that safe:
|
|
// - a new catalog award reaches an operator who already has awards stored;
|
|
// - a fixed one (higher Version) replaces the stored copy;
|
|
// - unless the operator has edited it, in which case their work wins.
|
|
|
|
func catalogDef(t *testing.T, code string) award.Def {
|
|
t.Helper()
|
|
for _, d := range award.Defaults() {
|
|
if d.Code == code {
|
|
return d
|
|
}
|
|
}
|
|
t.Fatalf("%s is not in the catalog", code)
|
|
return award.Def{}
|
|
}
|
|
|
|
func findDef(defs []award.Def, code string) (award.Def, bool) {
|
|
for _, d := range defs {
|
|
if d.Code == code {
|
|
return d, true
|
|
}
|
|
}
|
|
return award.Def{}, false
|
|
}
|
|
|
|
func TestMergeCatalogAddsMissingAward(t *testing.T) {
|
|
stored := []award.Def{{Code: "MYOWN", Name: "Mine", Valid: true}}
|
|
got, updated, changed := mergeCatalog(stored)
|
|
if !changed {
|
|
t.Fatal("merge reported no change, but every catalog award was missing")
|
|
}
|
|
if len(updated) != 0 {
|
|
t.Errorf("updated = %v, want none: an ADDED award is not an UPDATED one", updated)
|
|
}
|
|
if _, ok := findDef(got, "FFMA"); !ok {
|
|
t.Error("FFMA was not added — a newly shipped award never reaches an existing install")
|
|
}
|
|
if _, ok := findDef(got, "MYOWN"); !ok {
|
|
t.Error("the operator's own award was dropped by the merge")
|
|
}
|
|
}
|
|
|
|
func TestMergeCatalogUpdatesOlderVersion(t *testing.T) {
|
|
// The stored copy is an older revision of a shipped award, with a broken rule.
|
|
old := catalogDef(t, "FFMA")
|
|
old.Version = catalogDef(t, "FFMA").Version - 1
|
|
old.Field = "wrong"
|
|
old.Valid = false // the operator disabled it — a preference, not a definition
|
|
|
|
got, updated, changed := mergeCatalog([]award.Def{old})
|
|
if !changed || len(updated) == 0 {
|
|
t.Fatal("a higher catalog version did not replace the stored definition — a shipped award could never be FIXED")
|
|
}
|
|
d, _ := findDef(got, "FFMA")
|
|
if d.Field != "grid4" {
|
|
t.Errorf("FFMA field = %q, want the catalog's %q", d.Field, "grid4")
|
|
}
|
|
if d.Valid {
|
|
t.Error("the update re-enabled an award the operator had switched off; that is their choice to make, not ours")
|
|
}
|
|
}
|
|
|
|
func TestMergeCatalogSkipsUserEdited(t *testing.T) {
|
|
old := catalogDef(t, "FFMA")
|
|
old.Version = catalogDef(t, "FFMA").Version - 1
|
|
old.Field = "mine"
|
|
old.UserEdited = true
|
|
|
|
got, updated, _ := mergeCatalog([]award.Def{old})
|
|
if len(updated) != 0 {
|
|
t.Fatalf("updated = %v: an award the operator has edited must never be overwritten", updated)
|
|
}
|
|
if d, _ := findDef(got, "FFMA"); d.Field != "mine" {
|
|
t.Errorf("field = %q, want the operator's %q", d.Field, "mine")
|
|
}
|
|
}
|
|
|
|
func TestMarkUserEditedOnlyOnRealChange(t *testing.T) {
|
|
prev := []award.Def{
|
|
{Code: "A", Name: "A", Field: "state", Valid: true, Version: 2},
|
|
{Code: "B", Name: "B", Field: "cqz", Valid: true, Version: 2},
|
|
}
|
|
next := []award.Def{
|
|
{Code: "A", Name: "A", Field: "state", Valid: true}, // untouched
|
|
{Code: "B", Name: "B", Field: "county", Valid: true}, // changed
|
|
{Code: "C", Name: "C", Field: "note", Valid: true}, // brand new
|
|
}
|
|
markUserEdited(next, prev)
|
|
|
|
if next[0].UserEdited {
|
|
t.Error("A was flagged as edited although nothing about it changed — every save would freeze every award out of future updates")
|
|
}
|
|
if !next[1].UserEdited {
|
|
t.Error("B changed field and was not flagged; a catalog update would overwrite the operator's work")
|
|
}
|
|
if next[2].UserEdited {
|
|
t.Error("C is a brand-new award; there is no shipped version to protect it from")
|
|
}
|
|
// A save must not pretend to be a new shipped revision.
|
|
if next[0].Version != 2 || next[1].Version != 2 {
|
|
t.Errorf("versions = %d/%d, want both 2: saving is not shipping", next[0].Version, next[1].Version)
|
|
}
|
|
}
|