package mailstore import ( "net" "testing" ) // TestSpamScoreArithmetic exercises SpamScore's own weighting logic with synthetic // dkimPass/spfPass inputs — CheckDNSBL still runs (it does live DNS), so this only // asserts the score is monotonically at least as high when signals get worse, rather // than pinning an exact network-dependent number. func TestSpamScoreArithmetic(t *testing.T) { clean := SpamScore("203.0.113.1", map[string]string{"subject": "hello"}, true, true) noDKIM := SpamScore("203.0.113.1", map[string]string{"subject": "hello"}, false, true) noSPF := SpamScore("203.0.113.1", map[string]string{"subject": "hello"}, true, false) keyword := SpamScore("203.0.113.1", map[string]string{"subject": "WIN THE LOTTERY WINNER NOW"}, true, true) if noDKIM <= clean { t.Fatalf("missing DKIM should raise the score: clean=%d noDKIM=%d", clean, noDKIM) } if noSPF <= clean { t.Fatalf("failing SPF should raise the score: clean=%d noSPF=%d", clean, noSPF) } if keyword <= clean { t.Fatalf("a spam keyword in the subject should raise the score: clean=%d keyword=%d", clean, keyword) } } func TestEvalSPF(t *testing.T) { ip := net.ParseIP("203.0.113.10") other := net.ParseIP("198.51.100.5") tests := []struct { name string record string ip net.IP want bool }{ {"ip4 match passes", "v=spf1 ip4:203.0.113.0/24 -all", ip, true}, {"ip4 no match hard fails", "v=spf1 ip4:203.0.113.0/24 -all", other, false}, {"no all and no match is neutral", "v=spf1 ip4:203.0.113.0/24", other, true}, {"soft fail all is neutral for unmatched ip", "v=spf1 ip4:203.0.113.0/24 ~all", other, true}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := evalSPF(tt.record, tt.ip, "example.com", 0) if got != tt.want { t.Fatalf("evalSPF(%q) = %v, want %v", tt.record, got, tt.want) } }) } }