fake-smtp/internal/query/filter_emails_test.go

196 lines
4.2 KiB
Go

package query
import (
"net/mail"
"testing"
"time"
"forge.cadoles.com/Cadoles/fake-smtp/internal/model"
"github.com/pkg/errors"
)
type emailMatcherTestCase struct {
Name string
Search *InboxSearch
Email *model.Email
Matcher emailMatcherFunc
Expect bool
}
func TestEmailMatcher(t *testing.T) {
t.Parallel()
johnDoeAddr, err := mail.ParseAddress("john.doe@test.local")
if err != nil {
t.Fatal(errors.WithStack(err))
}
adaLovelaceAddr, err := mail.ParseAddress("ada.lovelace@test.local")
if err != nil {
t.Fatal(errors.WithStack(err))
}
now := time.Now()
testCases := []emailMatcherTestCase{
{
Name: "Simple matching header",
Email: &model.Email{
Headers: map[string][]string{
"X-Swift-To": {johnDoeAddr.Address},
},
},
Search: &InboxSearch{
Headers: map[string]string{
"X-Swift-To": johnDoeAddr.Address,
},
},
Matcher: matchHeaders,
Expect: true,
},
{
Name: "Multiple matching header",
Email: &model.Email{
Headers: map[string][]string{
"X-Swift-To": {johnDoeAddr.Address},
"Content-Type": {"multipart/alternative; boundary=\"_=_swift_1645181013_7b80ab8ab386ba4fcaff4f6f79593adb_=_\""},
},
},
Search: &InboxSearch{
Headers: map[string]string{
"X-Swift-To": johnDoeAddr.Address,
"Content-Type": "multipart/alternative",
},
},
Matcher: matchHeaders,
Expect: true,
},
{
Name: "Simple non matching header",
Email: &model.Email{
Headers: map[string][]string{
"X-Swift-To": {johnDoeAddr.Address},
},
},
Search: &InboxSearch{
Headers: map[string]string{
"X-Swift-To": adaLovelaceAddr.Address,
},
},
Matcher: matchHeaders,
Expect: false,
},
{
Name: "Multiple non matching headers",
Email: &model.Email{
Headers: map[string][]string{
"X-Swift-To": {johnDoeAddr.Address},
"Content-Type": {"foo/bar"},
},
},
Search: &InboxSearch{
Headers: map[string]string{
"X-Swift-To": johnDoeAddr.Address,
"Content-Type": "multipart/alternative",
},
},
Matcher: matchHeaders,
Expect: false,
},
{
Name: "Simple to",
Email: &model.Email{
To: []*mail.Address{johnDoeAddr},
},
Search: &InboxSearch{
To: johnDoeAddr.Address,
},
Matcher: matchTo,
Expect: true,
},
{
Name: "Simple from",
Email: &model.Email{
From: []*mail.Address{johnDoeAddr},
},
Search: &InboxSearch{
From: johnDoeAddr.Address,
},
Matcher: matchFrom,
Expect: true,
},
{
Name: "Simple after",
Email: &model.Email{
SentAt: now,
},
Search: &InboxSearch{
After: now.Add(-5 * time.Second),
},
Matcher: matchAfter,
Expect: true,
},
{
Name: "Simple before",
Email: &model.Email{
SentAt: now,
},
Search: &InboxSearch{
Before: now.Add(5 * time.Second),
},
Matcher: matchBefore,
Expect: true,
},
{
Name: "Matching composite",
Email: &model.Email{
SentAt: now,
Headers: map[string][]string{
"X-Swift-To": {johnDoeAddr.Address},
"Content-Type": {"multipart/alternative; boundary=\"_=_swift_1645181013_7b80ab8ab386ba4fcaff4f6f79593adb_=_\""},
},
},
Search: &InboxSearch{
Before: now.Add(5 * time.Second),
Headers: map[string]string{
"X-Swift-To": johnDoeAddr.Address,
"Content-Type": "multipart/alternative",
},
},
Matcher: and(matchBefore, matchHeaders),
Expect: true,
},
{
Name: "Non matching composite",
Email: &model.Email{
SentAt: now,
Headers: map[string][]string{
"X-Swift-To": {johnDoeAddr.Address},
"Content-Type": {"multipart/alternative; boundary=\"_=_swift_1645181013_7b80ab8ab386ba4fcaff4f6f79593adb_=_\""},
},
},
Search: &InboxSearch{
Before: now.Add(5 * time.Second),
Headers: map[string]string{
"X-Swift-To": adaLovelaceAddr.Address,
"Content-Type": "multipart/alternative",
},
},
Matcher: and(matchBefore, matchHeaders),
Expect: false,
},
}
for _, tc := range testCases {
func(tc emailMatcherTestCase) {
t.Run(tc.Name, func(t *testing.T) {
t.Parallel()
if e, g := tc.Expect, tc.Matcher(tc.Email, tc.Search); e != g {
t.Errorf("'%s': expected '%v', got '%v'", tc.Name, e, g)
}
})
}(tc)
}
}