Files
go-imap/search_test.go

138 lines
3.8 KiB
Go

package imap
import (
"bytes"
"io"
"net/textproto"
"reflect"
"strings"
"testing"
"time"
)
// Note to myself: writing these boring tests actually fixed 2 bugs :P
var searchSeqSet1, _ = ParseSeqSet("1:42")
var searchSeqSet2, _ = ParseSeqSet("743:938")
var searchDate1 = time.Date(1997, 11, 21, 0, 0, 0, 0, time.UTC)
var searchDate2 = time.Date(1984, 11, 5, 0, 0, 0, 0, time.UTC)
var searchCriteriaTests = []struct {
expected string
criteria *SearchCriteria
}{
{
expected: `(1:42 UID 743:938 ` +
`SINCE "5-Nov-1984" BEFORE "21-Nov-1997" SENTSINCE "5-Nov-1984" SENTBEFORE "21-Nov-1997" ` +
`FROM root@protonmail.com BODY "hey there" TEXT DILLE ` +
`ANSWERED DELETED KEYWORD cc UNKEYWORD microsoft ` +
`LARGER 4242 SMALLER 4342 ` +
`NOT (SENTON "21-Nov-1997" HEADER Content-Type text/csv) ` +
`OR (ON "5-Nov-1984" DRAFT FLAGGED UNANSWERED UNDELETED OLD) (UNDRAFT UNFLAGGED UNSEEN))`,
criteria: &SearchCriteria{
SeqNum: searchSeqSet1,
Uid: searchSeqSet2,
Since: searchDate2,
Before: searchDate1,
SentSince: searchDate2,
SentBefore: searchDate1,
Header: textproto.MIMEHeader{
"From": {"root@protonmail.com"},
},
Body: []string{"hey there"},
Text: []string{"DILLE"},
WithFlags: []string{AnsweredFlag, DeletedFlag, "cc"},
WithoutFlags: []string{"microsoft"},
Larger: 4242,
Smaller: 4342,
Not: []*SearchCriteria{{
SentSince: searchDate1,
SentBefore: searchDate1.Add(24 * time.Hour),
Header: textproto.MIMEHeader{
"Content-Type": {"text/csv"},
},
}},
Or: [][2]*SearchCriteria{{
{
Since: searchDate2,
Before: searchDate2.Add(24 * time.Hour),
WithFlags: []string{DraftFlag, FlaggedFlag},
WithoutFlags: []string{AnsweredFlag, DeletedFlag, RecentFlag},
},
{
WithoutFlags: []string{DraftFlag, FlaggedFlag, SeenFlag},
},
}},
},
},
}
func TestSearchCriteria_Format(t *testing.T) {
for i, test := range searchCriteriaTests {
fields := test.criteria.Format()
got, err := formatFields(fields)
if err != nil {
t.Fatal("Unexpected no error while formatting fields, got:", err)
}
if got != test.expected {
t.Errorf("Invalid search criteria fields for #%v: got \n%v\n instead of \n%v", i+1, got, test.expected)
}
}
}
func TestSearchCriteria_Parse(t *testing.T) {
for i, test := range searchCriteriaTests {
criteria := new(SearchCriteria)
b := bytes.NewBuffer([]byte(test.expected))
r := NewReader(b)
fields, _ := r.ReadFields()
if err := criteria.ParseWithCharset(fields[0].([]interface{}), nil); err != nil {
t.Errorf("Cannot parse search criteria for #%v: %v", i+1, err)
} else if !reflect.DeepEqual(criteria, test.criteria) {
t.Errorf("Invalid search criteria for #%v: got \n%+v\n instead of \n%+v", i+1, criteria, test.criteria)
}
}
}
var searchCriteriaParseTests = []struct {
fields []interface{}
criteria *SearchCriteria
charset func(io.Reader) io.Reader
}{
{
fields: []interface{}{"ALL"},
criteria: &SearchCriteria{},
},
{
fields: []interface{}{"NEW"},
criteria: &SearchCriteria{
WithFlags: []string{RecentFlag},
WithoutFlags: []string{SeenFlag},
},
},
{
fields: []interface{}{"SUBJECT", strings.NewReader("café")},
criteria: &SearchCriteria{
Header: textproto.MIMEHeader{"Subject": {"café"}},
},
charset: func(r io.Reader) io.Reader {
return r
},
},
}
func TestSearchCriteria_Parse_others(t *testing.T) {
for i, test := range searchCriteriaParseTests {
criteria := new(SearchCriteria)
if err := criteria.ParseWithCharset(test.fields, test.charset); err != nil {
t.Errorf("Cannot parse search criteria for #%v: %v", i+1, err)
} else if !reflect.DeepEqual(criteria, test.criteria) {
t.Errorf("Invalid search criteria for #%v: got \n%+v\n instead of \n%+v", i+1, criteria, test.criteria)
}
}
}