Files

99 lines
2.8 KiB
Go

package rules
import "testing"
func TestMatch(t *testing.T) {
msg := MessageFields{
From: "boss@work.com",
To: "me@example.com",
Subject: "Weekly Report Due",
Body: "please see attached",
HasAttachment: true,
RecipientType: "to",
}
cases := []struct {
name string
rules []Rule
want string // expected matched rule action value marker, "" for no match
}{
{
name: "single contains condition matches",
rules: []Rule{
{ID: 1, Priority: 0, MatchType: "all", ActionValue: "hit",
Conditions: []Condition{{Field: "from", Op: "contains", Value: "work.com"}}},
},
want: "hit",
},
{
name: "equals is case-insensitive and exact",
rules: []Rule{
{ID: 1, Priority: 0, MatchType: "all", ActionValue: "hit",
Conditions: []Condition{{Field: "to", Op: "equals", Value: "ME@EXAMPLE.COM"}}},
},
want: "hit",
},
{
name: "starts_with no match",
rules: []Rule{
{ID: 1, Priority: 0, MatchType: "all", ActionValue: "hit",
Conditions: []Condition{{Field: "subject", Op: "starts_with", Value: "URGENT"}}},
},
want: "",
},
{
name: "match_type all requires every condition",
rules: []Rule{
{ID: 1, Priority: 0, MatchType: "all", ActionValue: "hit", Conditions: []Condition{
{Field: "from", Op: "contains", Value: "work.com"},
{Field: "subject", Op: "contains", Value: "NOPE"},
}},
},
want: "",
},
{
name: "match_type any needs only one condition",
rules: []Rule{
{ID: 1, Priority: 0, MatchType: "any", ActionValue: "hit", Conditions: []Condition{
{Field: "from", Op: "contains", Value: "NOPE"},
{Field: "subject", Op: "contains", Value: "Report"},
}},
},
want: "hit",
},
{
name: "has_attachment field",
rules: []Rule{
{ID: 1, Priority: 0, MatchType: "all", ActionValue: "hit",
Conditions: []Condition{{Field: "has_attachment", Op: "equals", Value: "yes"}}},
},
want: "hit",
},
{
name: "first matching rule in list order wins, later matching rules ignored",
rules: []Rule{
{ID: 1, Priority: 5, MatchType: "all", ActionValue: "nope",
Conditions: []Condition{{Field: "from", Op: "contains", Value: "does-not-appear"}}},
{ID: 2, Priority: 0, MatchType: "all", ActionValue: "first",
Conditions: []Condition{{Field: "to", Op: "contains", Value: "example"}}},
{ID: 3, Priority: 10, MatchType: "all", ActionValue: "second",
Conditions: []Condition{{Field: "subject", Op: "contains", Value: "Report"}}},
},
want: "first", // Match trusts caller ordering (ListActiveRules sorts by priority ASC before calling)
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
got := Match(msg, tc.rules)
gotVal := ""
if got != nil {
gotVal = got.ActionValue
}
if gotVal != tc.want {
t.Errorf("Match() = %q, want %q", gotVal, tc.want)
}
})
}
}