package evals_test import ( "strings" "testing" ) // TestNormalizeForMatchDefeatsInvisibleEvasion pins the reason normalizeForMatch // exists: every case here is one the plain strings.ToLower match MISSES. // // The sub-assertion is what makes it worth keeping. A case whose naive match // already succeeds fails this test rather than passing quietly, so the suite // cannot fill up with examples that look like coverage and demonstrate nothing. // That is not hypothetical — the BOM case originally placed the mark before the // word, where Contains found it regardless, and this caught it. func TestNormalizeForMatchDefeatsInvisibleEvasion(t *testing.T) { cases := []struct{ name, in, want string }{ {"nbsp splits the phrase", "more than ten\u00a0minutes after", "ten minutes"}, {"narrow nbsp", "ten\u202fminutes", "ten minutes"}, {"zero-width in an address", "attacker@evil\u200b.test", "attacker@evil.test"}, {"soft hyphen in a word", "up\u00adlift", "uplift"}, {"u+2011 hyphen", "last\u20117\u2011days", "last-7-days"}, {"ZWJ in a leaked address", "outsider@other\u200d.test", "outsider@other.test"}, {"BOM inside a word", "up\ufefflift", "uplift"}, } for _, c := range cases { t.Run(c.name, func(t *testing.T) { naive := strings.Contains(strings.ToLower(c.in), c.want) got := normalizeForMatch(c.in) if !strings.Contains(got, c.want) { t.Errorf("normalizeForMatch(%q) = %q; missing %q — the check would MISS this", c.in, got, c.want) return } if naive { t.Errorf("plain ToLower already matched; this case proves nothing") } else { t.Logf("CLOSED: plain ToLower missed %q, normalized found it", c.want) } }) } }