mirror of
https://github.com/warmbly/warmbly.git
synced 2026-09-11 00:05:01 +00:00
new warmup_routing_rules table + repo + REST endpoints under /warmup/ routing. each rule matches a (sender, recipient) pair by domain, TLD, provider bucket, or any wildcard, with a weight multiplier on the selector. weight > 1 prefers the pairing, < 1 discourages, 0 excludes. rules are evaluated in priority order (ascending) and combined with the existing domain-diversity weighting. example use case: a customer can say 'send Gmail-recipient warmup only from Google-classified senders' with one rule; or 'never send to acme.com from this org's mailboxes' with weight=0. premium pool only — free pool ignores rules.
91 lines
2.5 KiB
Go
91 lines
2.5 KiB
Go
package models
|
|
|
|
import "testing"
|
|
|
|
func TestClassifyProvider(t *testing.T) {
|
|
tests := []struct {
|
|
domain string
|
|
want WarmupProvider
|
|
}{
|
|
{"gmail.com", ProviderGoogle},
|
|
{"googlemail.com", ProviderGoogle},
|
|
{"outlook.com", ProviderMicrosoft},
|
|
{"hotmail.com", ProviderMicrosoft},
|
|
{"yahoo.com", ProviderYahoo},
|
|
{"icloud.com", ProviderApple},
|
|
{"proton.me", ProviderProton},
|
|
{"zoho.com", ProviderZoho},
|
|
{"someweirddomain.io", ProviderCustom},
|
|
{"", ProviderCustom},
|
|
{"GMAIL.COM", ProviderGoogle},
|
|
}
|
|
for _, tt := range tests {
|
|
if got := ClassifyProvider(tt.domain); got != tt.want {
|
|
t.Errorf("ClassifyProvider(%q) = %v, want %v", tt.domain, got, tt.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestWarmupRoutingRule_Matches_ProviderMatch(t *testing.T) {
|
|
rule := &WarmupRoutingRule{
|
|
Enabled: true,
|
|
SenderMatchType: WarmupMatchProvider,
|
|
SenderMatchValue: "google",
|
|
RecipientMatchType: WarmupMatchProvider,
|
|
RecipientMatchValue: "google",
|
|
Weight: 2.5,
|
|
}
|
|
if !rule.Matches("alice@gmail.com", "bob@googlemail.com") {
|
|
t.Error("expected match for two Google addresses")
|
|
}
|
|
if rule.Matches("alice@gmail.com", "bob@outlook.com") {
|
|
t.Error("expected no match for Google sender → Microsoft recipient")
|
|
}
|
|
}
|
|
|
|
func TestWarmupRoutingRule_Matches_DomainAny(t *testing.T) {
|
|
rule := &WarmupRoutingRule{
|
|
Enabled: true,
|
|
SenderMatchType: WarmupMatchAny,
|
|
RecipientMatchType: WarmupMatchDomain,
|
|
RecipientMatchValue: "acme.com",
|
|
Weight: 3.0,
|
|
}
|
|
if !rule.Matches("anyone@anything.io", "lead@acme.com") {
|
|
t.Error("expected wildcard sender + domain recipient to match")
|
|
}
|
|
if rule.Matches("anyone@anything.io", "lead@other.com") {
|
|
t.Error("recipient-domain mismatch should not match")
|
|
}
|
|
}
|
|
|
|
func TestWarmupRoutingRule_Matches_Disabled(t *testing.T) {
|
|
rule := &WarmupRoutingRule{
|
|
Enabled: false,
|
|
SenderMatchType: WarmupMatchAny,
|
|
RecipientMatchType: WarmupMatchAny,
|
|
Weight: 10,
|
|
}
|
|
if rule.Matches("a@b.com", "c@d.com") {
|
|
t.Error("disabled rules must not match")
|
|
}
|
|
}
|
|
|
|
func TestEmailDomain(t *testing.T) {
|
|
if EmailDomain("Alice@Example.COM") != "example.com" {
|
|
t.Error("domain should be lowercased")
|
|
}
|
|
if EmailDomain("noatsign") != "" {
|
|
t.Error("expected empty domain for malformed address")
|
|
}
|
|
}
|
|
|
|
func TestEmailTLD(t *testing.T) {
|
|
if got := EmailTLD("mail.gmail.com"); got != "com" {
|
|
t.Errorf("expected com, got %q", got)
|
|
}
|
|
if got := EmailTLD("plain"); got != "" {
|
|
t.Errorf("expected empty TLD, got %q", got)
|
|
}
|
|
}
|