Build the Go API and React UI for managing domain denylist/allowlist/recipient deny and spam settings, plus shared lists that import/apply across domains with wildcard compaction, entry verification, and Migadu-friendly list encoding (including per-domain recipient filtering and rejection bisect on apply).
128 lines
3.3 KiB
Go
128 lines
3.3 KiB
Go
package lists
|
|
|
|
import (
|
|
"reflect"
|
|
"testing"
|
|
)
|
|
|
|
func TestCompact(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tests := []struct {
|
|
name string
|
|
input []string
|
|
want []string
|
|
}{
|
|
{
|
|
name: "empty",
|
|
input: nil,
|
|
want: []string{},
|
|
},
|
|
{
|
|
name: "exact duplicates case insensitive",
|
|
input: []string{"Lisa@Simpsons.com", "lisa@simpsons.com", " LISA@SIMPSONS.COM "},
|
|
want: []string{"lisa@simpsons.com"},
|
|
},
|
|
{
|
|
name: "wildcard covers specific",
|
|
input: []string{"lisa@simpsons.com", "*@simpsons.com"},
|
|
want: []string{"*@simpsons.com"},
|
|
},
|
|
{
|
|
name: "specific dropped when wildcard present first",
|
|
input: []string{"*@simpsons.com", "lisa@simpsons.com", "homer@simpsons.com"},
|
|
want: []string{"*@simpsons.com"},
|
|
},
|
|
{
|
|
name: "distinct locals kept",
|
|
input: []string{"lisa@simpsons.com", "homer@simpsons.com"},
|
|
want: []string{"lisa@simpsons.com", "homer@simpsons.com"},
|
|
},
|
|
{
|
|
name: "different domains kept",
|
|
input: []string{"*@simpsons.com", "lisa@flanders.com", "*@flanders.com"},
|
|
want: []string{"*@simpsons.com", "*@flanders.com"},
|
|
},
|
|
{
|
|
name: "bare hostname exact dedupe only",
|
|
input: []string{"simpsons.com", "Simpsons.com", "lisa@simpsons.com"},
|
|
want: []string{"simpsons.com", "lisa@simpsons.com"},
|
|
},
|
|
{
|
|
name: "blank entries dropped",
|
|
input: []string{"", " ", "a@b.com"},
|
|
want: []string{"a@b.com"},
|
|
},
|
|
{
|
|
name: "repair star without at",
|
|
input: []string{"*vsa.instalily.ai", "lisa@vsa.instalily.ai"},
|
|
want: []string{"*@vsa.instalily.ai"},
|
|
},
|
|
{
|
|
name: "suffix glob covers specific domains",
|
|
input: []string{"*@*.shop", "*@alth.shop", "spam@woowstars.shop", "*@other.com"},
|
|
want: []string{"*@*.shop", "*@other.com"},
|
|
},
|
|
{
|
|
name: "repair star-domain without dot",
|
|
input: []string{"*@*rumble.com", "user@foo.rumble.com"},
|
|
want: []string{"*@*.rumble.com"},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
got := Compact(tt.input)
|
|
if !reflect.DeepEqual(got, tt.want) {
|
|
t.Fatalf("Compact() = %#v, want %#v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestFilterRecipientEntriesForDomain(t *testing.T) {
|
|
t.Parallel()
|
|
got := FilterRecipientEntriesForDomain("skaab.nu", []string{
|
|
"brittis@gronberg.info",
|
|
"brgr@tspse.net",
|
|
"abuse@skaab.nu",
|
|
"postmaster",
|
|
"ABUSE@SKAAB.NU",
|
|
})
|
|
want := []string{"abuse@skaab.nu", "postmaster"}
|
|
if !reflect.DeepEqual(got, want) {
|
|
t.Fatalf("got %#v want %#v", got, want)
|
|
}
|
|
}
|
|
|
|
func TestCovers(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tests := []struct {
|
|
broader string
|
|
specific string
|
|
want bool
|
|
}{
|
|
{"*@simpsons.com", "lisa@simpsons.com", true},
|
|
{"*@simpsons.com", "*@simpsons.com", true},
|
|
{"lisa@simpsons.com", "*@simpsons.com", false},
|
|
{"lisa@simpsons.com", "homer@simpsons.com", false},
|
|
{"*@simpsons.com", "lisa@flanders.com", false},
|
|
{"simpsons.com", "lisa@simpsons.com", false},
|
|
{"", "a@b.com", false},
|
|
{"*@*.shop", "*@alth.shop", true},
|
|
{"*@*.shop", "user@alth.shop", true},
|
|
{"*@*.shop", "*@other.com", false},
|
|
{"*@simpsons.com", "lisa@mail.simpsons.com", false},
|
|
{"*vsa.instalily.ai", "x@vsa.instalily.ai", true},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
got := Covers(tt.broader, tt.specific)
|
|
if got != tt.want {
|
|
t.Fatalf("Covers(%q, %q) = %v, want %v", tt.broader, tt.specific, got, tt.want)
|
|
}
|
|
}
|
|
}
|