package pipeline import ( "strings" "testing" "textmachine/backend/internal/membank" "textmachine/backend/internal/store" ) // TestMinedDeltaSeedCollisions covers both paths of the D39.20 deviation-#1 crash guard: a mined-delta // term whose UNIQUE key (src, sense, since_ch, until_ch) already exists in the seed must be reported // (would crash ReplaceGlossary), while a disjoint delta reports nothing. It also asserts a SAME-dst // duplicate is caught (membank.ApprovedSharedKeyCollisions skips it, so this guard is the one that must fire). func TestMinedDeltaSeedCollisions(t *testing.T) { seed := []store.GlossaryEntry{ {Src: "元", Dst: "первооснова", Sense: "корень", Status: "approved"}, {Src: "赤城", Dst: "Чичэн", Status: "approved"}, } // Path A — a mined-delta term duplicating the seed's UNIQUE key (different dst) → loud. minedDiff := []store.GlossaryEntry{{Src: "元", Dst: "юань", Sense: "корень", Status: "approved", Source: "mined"}} if dups := membank.MinedDeltaSeedCollisions(seed, minedDiff); len(dups) != 1 { t.Fatalf("different-dst duplicate: want 1 collision, got %d (%v)", len(dups), dups) } else if !strings.Contains(dups[0], "元") { t.Fatalf("collision message should name the duplicated src: %q", dups[0]) } // Path A' — a SAME-dst duplicate (membank.ApprovedSharedKeyCollisions skips these; this guard must still fire, // since the UNIQUE INSERT crashes regardless of dst). minedSame := []store.GlossaryEntry{{Src: "元", Dst: "первооснова", Sense: "корень", Status: "approved", Source: "mined"}} if dups := membank.MinedDeltaSeedCollisions(seed, minedSame); len(dups) != 1 { t.Fatalf("same-dst duplicate: want 1 collision (the INSERT crashes regardless of dst), got %d", len(dups)) } // Path B — a disjoint delta (a genuinely new term, or the same src in a DIFFERENT spoiler window) → // nothing to report; the append is safe. minedOK := []store.GlossaryEntry{ {Src: "春秋蝉", Dst: "Весенне-осенняя цикада", Status: "approved", Source: "mined"}, {Src: "元", Dst: "юань (валюта)", Sense: "деньги", Status: "approved", Source: "mined"}, // different sense → different UNIQUE key } if dups := membank.MinedDeltaSeedCollisions(seed, minedOK); len(dups) != 0 { t.Fatalf("disjoint delta: want 0 collisions, got %d (%v)", len(dups), dups) } }