add eventOrganizer selector (#720)
## Description Adds the eventOrganizer exchange filter, wraps up the addition of eventRecurs filtering, and fixes a couple improperly designed filter constructors. ## Type of change Please check the type of change your PR introduces: - [x] 🌻 Feature ## Issue(s) #501 ## Test Plan - [x] 💪 Manual - [x] ⚡ Unit test - [ ] 💚 E2E
This commit is contained in:
parent
137123294a
commit
a043304e0b
@ -474,7 +474,7 @@ func filterExchangeInfoMailSender(sel *selectors.ExchangeRestore, sender string)
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
sel.Filter(sel.MailSender([]string{sender}))
|
sel.Filter(sel.MailSender(sender))
|
||||||
}
|
}
|
||||||
|
|
||||||
func filterExchangeInfoMailSubject(sel *selectors.ExchangeRestore, subject string) {
|
func filterExchangeInfoMailSubject(sel *selectors.ExchangeRestore, subject string) {
|
||||||
@ -482,7 +482,7 @@ func filterExchangeInfoMailSubject(sel *selectors.ExchangeRestore, subject strin
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
sel.Filter(sel.MailSubject([]string{subject}))
|
sel.Filter(sel.MailSubject(subject))
|
||||||
}
|
}
|
||||||
|
|
||||||
// checks all flags for correctness and interdependencies
|
// checks all flags for correctness and interdependencies
|
||||||
|
|||||||
@ -273,7 +273,7 @@ func filterExchangeInfoMailSender(sel *selectors.ExchangeRestore, sender string)
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
sel.Filter(sel.MailSender([]string{sender}))
|
sel.Filter(sel.MailSender(sender))
|
||||||
}
|
}
|
||||||
|
|
||||||
func filterExchangeInfoMailSubject(sel *selectors.ExchangeRestore, subject string) {
|
func filterExchangeInfoMailSubject(sel *selectors.ExchangeRestore, subject string) {
|
||||||
@ -281,7 +281,7 @@ func filterExchangeInfoMailSubject(sel *selectors.ExchangeRestore, subject strin
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
sel.Filter(sel.MailSubject([]string{subject}))
|
sel.Filter(sel.MailSubject(subject))
|
||||||
}
|
}
|
||||||
|
|
||||||
// checks all flags for correctness and interdependencies
|
// checks all flags for correctness and interdependencies
|
||||||
|
|||||||
@ -274,17 +274,47 @@ func (s *exchange) Users(users []string) []ExchangeScope {
|
|||||||
// -------------------
|
// -------------------
|
||||||
// Filter Factories
|
// Filter Factories
|
||||||
|
|
||||||
|
// ContactName produces one or more exchange contact name filter scopes.
|
||||||
|
// Matches any contact whose name contains the provided string.
|
||||||
|
// If any slice contains selectors.Any, that slice is reduced to [selectors.Any]
|
||||||
|
// If any slice contains selectors.None, that slice is reduced to [selectors.None]
|
||||||
|
// If any slice is empty, it defaults to [selectors.None]
|
||||||
|
func (sr *ExchangeRestore) ContactName(senderID string) []ExchangeScope {
|
||||||
|
return []ExchangeScope{
|
||||||
|
makeFilterScope[ExchangeScope](
|
||||||
|
ExchangeContact,
|
||||||
|
ExchangeFilterContactName,
|
||||||
|
[]string{senderID},
|
||||||
|
wrapFilter(filters.In)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// EventSubject produces one or more exchange event subject filter scopes.
|
||||||
|
// Matches any event where the event subject contains one of the provided strings.
|
||||||
|
// If any slice contains selectors.Any, that slice is reduced to [selectors.Any]
|
||||||
|
// If any slice contains selectors.None, that slice is reduced to [selectors.None]
|
||||||
|
// If any slice is empty, it defaults to [selectors.None]
|
||||||
|
func (sr *ExchangeRestore) EventOrganizer(organizer string) []ExchangeScope {
|
||||||
|
return []ExchangeScope{
|
||||||
|
makeFilterScope[ExchangeScope](
|
||||||
|
ExchangeEvent,
|
||||||
|
ExchangeFilterEventOrganizer,
|
||||||
|
[]string{organizer},
|
||||||
|
wrapFilter(filters.In)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// EventRecurs produces one or more exchange event recurrence filter scopes.
|
// EventRecurs produces one or more exchange event recurrence filter scopes.
|
||||||
// Matches any event if the comparator flag matches the event recurrence flag.
|
// Matches any event if the comparator flag matches the event recurrence flag.
|
||||||
// If any slice contains selectors.Any, that slice is reduced to [selectors.Any]
|
// If any slice contains selectors.Any, that slice is reduced to [selectors.Any]
|
||||||
// If any slice contains selectors.None, that slice is reduced to [selectors.None]
|
// If any slice contains selectors.None, that slice is reduced to [selectors.None]
|
||||||
// If any slice is empty, it defaults to [selectors.None]
|
// If any slice is empty, it defaults to [selectors.None]
|
||||||
func (sr *ExchangeRestore) EventRecurs(recurs bool) []ExchangeScope {
|
func (sr *ExchangeRestore) EventRecurs(recurs string) []ExchangeScope {
|
||||||
return []ExchangeScope{
|
return []ExchangeScope{
|
||||||
makeFilterScope[ExchangeScope](
|
makeFilterScope[ExchangeScope](
|
||||||
ExchangeEvent,
|
ExchangeEvent,
|
||||||
ExchangeFilterEventRecurs,
|
ExchangeFilterEventRecurs,
|
||||||
[]string{strconv.FormatBool(recurs)},
|
[]string{recurs},
|
||||||
wrapFilter(filters.Equal)),
|
wrapFilter(filters.Equal)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -322,27 +352,12 @@ func (sr *ExchangeRestore) EventStartsBefore(timeStrings string) []ExchangeScope
|
|||||||
// If any slice contains selectors.Any, that slice is reduced to [selectors.Any]
|
// If any slice contains selectors.Any, that slice is reduced to [selectors.Any]
|
||||||
// If any slice contains selectors.None, that slice is reduced to [selectors.None]
|
// If any slice contains selectors.None, that slice is reduced to [selectors.None]
|
||||||
// If any slice is empty, it defaults to [selectors.None]
|
// If any slice is empty, it defaults to [selectors.None]
|
||||||
func (sr *ExchangeRestore) EventSubject(subjectSubstrings []string) []ExchangeScope {
|
func (sr *ExchangeRestore) EventSubject(subject string) []ExchangeScope {
|
||||||
return []ExchangeScope{
|
return []ExchangeScope{
|
||||||
makeFilterScope[ExchangeScope](
|
makeFilterScope[ExchangeScope](
|
||||||
ExchangeEvent,
|
ExchangeEvent,
|
||||||
ExchangeFilterEventSubject,
|
ExchangeFilterEventSubject,
|
||||||
subjectSubstrings,
|
[]string{subject},
|
||||||
wrapFilter(filters.In)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ContactName produces one or more exchange contact name filter scopes.
|
|
||||||
// Matches any contact whose name contains the provided string.
|
|
||||||
// If any slice contains selectors.Any, that slice is reduced to [selectors.Any]
|
|
||||||
// If any slice contains selectors.None, that slice is reduced to [selectors.None]
|
|
||||||
// If any slice is empty, it defaults to [selectors.None]
|
|
||||||
func (sr *ExchangeRestore) ContactName(senderID string) []ExchangeScope {
|
|
||||||
return []ExchangeScope{
|
|
||||||
makeFilterScope[ExchangeScope](
|
|
||||||
ExchangeContact,
|
|
||||||
ExchangeFilterContactName,
|
|
||||||
[]string{senderID},
|
|
||||||
wrapFilter(filters.In)),
|
wrapFilter(filters.In)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -380,12 +395,12 @@ func (sr *ExchangeRestore) MailReceivedBefore(timeStrings string) []ExchangeScop
|
|||||||
// If any slice contains selectors.Any, that slice is reduced to [selectors.Any]
|
// If any slice contains selectors.Any, that slice is reduced to [selectors.Any]
|
||||||
// If any slice contains selectors.None, that slice is reduced to [selectors.None]
|
// If any slice contains selectors.None, that slice is reduced to [selectors.None]
|
||||||
// If any slice is empty, it defaults to [selectors.None]
|
// If any slice is empty, it defaults to [selectors.None]
|
||||||
func (sr *ExchangeRestore) MailSender(senderIDs []string) []ExchangeScope {
|
func (sr *ExchangeRestore) MailSender(sender string) []ExchangeScope {
|
||||||
return []ExchangeScope{
|
return []ExchangeScope{
|
||||||
makeFilterScope[ExchangeScope](
|
makeFilterScope[ExchangeScope](
|
||||||
ExchangeMail,
|
ExchangeMail,
|
||||||
ExchangeFilterMailSender,
|
ExchangeFilterMailSender,
|
||||||
senderIDs,
|
[]string{sender},
|
||||||
wrapFilter(filters.In)),
|
wrapFilter(filters.In)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -395,12 +410,12 @@ func (sr *ExchangeRestore) MailSender(senderIDs []string) []ExchangeScope {
|
|||||||
// If any slice contains selectors.Any, that slice is reduced to [selectors.Any]
|
// If any slice contains selectors.Any, that slice is reduced to [selectors.Any]
|
||||||
// If any slice contains selectors.None, that slice is reduced to [selectors.None]
|
// If any slice contains selectors.None, that slice is reduced to [selectors.None]
|
||||||
// If any slice is empty, it defaults to [selectors.None]
|
// If any slice is empty, it defaults to [selectors.None]
|
||||||
func (sr *ExchangeRestore) MailSubject(subjectSubstrings []string) []ExchangeScope {
|
func (sr *ExchangeRestore) MailSubject(subject string) []ExchangeScope {
|
||||||
return []ExchangeScope{
|
return []ExchangeScope{
|
||||||
makeFilterScope[ExchangeScope](
|
makeFilterScope[ExchangeScope](
|
||||||
ExchangeMail,
|
ExchangeMail,
|
||||||
ExchangeFilterMailSubject,
|
ExchangeFilterMailSubject,
|
||||||
subjectSubstrings,
|
[]string{subject},
|
||||||
wrapFilter(filters.In)),
|
wrapFilter(filters.In)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -472,6 +487,7 @@ const (
|
|||||||
ExchangeFilterMailReceivedAfter exchangeCategory = "ExchangeFilterMailReceivedAfter"
|
ExchangeFilterMailReceivedAfter exchangeCategory = "ExchangeFilterMailReceivedAfter"
|
||||||
ExchangeFilterMailReceivedBefore exchangeCategory = "ExchangeFilterMailReceivedBefore"
|
ExchangeFilterMailReceivedBefore exchangeCategory = "ExchangeFilterMailReceivedBefore"
|
||||||
ExchangeFilterContactName exchangeCategory = "ExchangeFilterContactName"
|
ExchangeFilterContactName exchangeCategory = "ExchangeFilterContactName"
|
||||||
|
ExchangeFilterEventOrganizer exchangeCategory = "ExchangeFilterEventOrganizer"
|
||||||
ExchangeFilterEventRecurs exchangeCategory = "ExchangeFilterEventRecurs"
|
ExchangeFilterEventRecurs exchangeCategory = "ExchangeFilterEventRecurs"
|
||||||
ExchangeFilterEventStartsAfter exchangeCategory = "ExchangeFilterEventStartsAfter"
|
ExchangeFilterEventStartsAfter exchangeCategory = "ExchangeFilterEventStartsAfter"
|
||||||
ExchangeFilterEventStartsBefore exchangeCategory = "ExchangeFilterEventStartsBefore"
|
ExchangeFilterEventStartsBefore exchangeCategory = "ExchangeFilterEventStartsBefore"
|
||||||
@ -506,7 +522,7 @@ func (ec exchangeCategory) leafCat() categorizer {
|
|||||||
case ExchangeContact, ExchangeContactFolder, ExchangeFilterContactName:
|
case ExchangeContact, ExchangeContactFolder, ExchangeFilterContactName:
|
||||||
return ExchangeContact
|
return ExchangeContact
|
||||||
|
|
||||||
case ExchangeEvent, ExchangeEventCalendar, ExchangeFilterEventRecurs,
|
case ExchangeEvent, ExchangeEventCalendar, ExchangeFilterEventOrganizer, ExchangeFilterEventRecurs,
|
||||||
ExchangeFilterEventStartsAfter, ExchangeFilterEventStartsBefore, ExchangeFilterEventSubject:
|
ExchangeFilterEventStartsAfter, ExchangeFilterEventStartsBefore, ExchangeFilterEventSubject:
|
||||||
return ExchangeEvent
|
return ExchangeEvent
|
||||||
|
|
||||||
@ -696,18 +712,20 @@ func (s ExchangeScope) matchesInfo(info *details.ExchangeInfo) bool {
|
|||||||
switch filterCat {
|
switch filterCat {
|
||||||
case ExchangeFilterContactName:
|
case ExchangeFilterContactName:
|
||||||
i = info.ContactName
|
i = info.ContactName
|
||||||
|
case ExchangeFilterEventOrganizer:
|
||||||
|
i = info.Organizer
|
||||||
|
case ExchangeFilterEventRecurs:
|
||||||
|
i = strconv.FormatBool(info.EventRecurs)
|
||||||
|
case ExchangeFilterEventStartsAfter, ExchangeFilterEventStartsBefore:
|
||||||
|
i = common.FormatTime(info.EventStart)
|
||||||
|
case ExchangeFilterEventSubject:
|
||||||
|
i = info.Subject
|
||||||
case ExchangeFilterMailSender:
|
case ExchangeFilterMailSender:
|
||||||
i = info.Sender
|
i = info.Sender
|
||||||
case ExchangeFilterMailSubject:
|
case ExchangeFilterMailSubject:
|
||||||
i = info.Subject
|
i = info.Subject
|
||||||
case ExchangeFilterMailReceivedAfter, ExchangeFilterMailReceivedBefore:
|
case ExchangeFilterMailReceivedAfter, ExchangeFilterMailReceivedBefore:
|
||||||
i = common.FormatTime(info.Received)
|
i = common.FormatTime(info.Received)
|
||||||
case ExchangeFilterEventRecurs:
|
|
||||||
i = "" // TODO: add EventRecurs is added to ExchangeInfo.
|
|
||||||
case ExchangeFilterEventStartsAfter, ExchangeFilterEventStartsBefore:
|
|
||||||
i = common.FormatTime(info.EventStart)
|
|
||||||
case ExchangeFilterEventSubject:
|
|
||||||
i = info.Subject
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.Matches(filterCat, i)
|
return s.Matches(filterCat, i)
|
||||||
|
|||||||
@ -698,9 +698,10 @@ func (suite *ExchangeSelectorSuite) TestExchangeScope_MatchesInfo() {
|
|||||||
es := NewExchangeRestore()
|
es := NewExchangeRestore()
|
||||||
|
|
||||||
const (
|
const (
|
||||||
name = "smarf mcfnords"
|
name = "smarf mcfnords"
|
||||||
sender = "smarf@2many.cooks"
|
organizer = "cooks@2many.smarf"
|
||||||
subject = "I have seen the fnords!"
|
sender = "smarf@2many.cooks"
|
||||||
|
subject = "I have seen the fnords!"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -709,11 +710,12 @@ func (suite *ExchangeSelectorSuite) TestExchangeScope_MatchesInfo() {
|
|||||||
future = now.Add(1 * time.Minute)
|
future = now.Add(1 * time.Minute)
|
||||||
info = &details.ExchangeInfo{
|
info = &details.ExchangeInfo{
|
||||||
ContactName: name,
|
ContactName: name,
|
||||||
|
EventRecurs: true,
|
||||||
EventStart: now,
|
EventStart: now,
|
||||||
|
Organizer: organizer,
|
||||||
Sender: sender,
|
Sender: sender,
|
||||||
Subject: subject,
|
Subject: subject,
|
||||||
Received: now,
|
Received: now,
|
||||||
// TODO: event recurs
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -722,33 +724,37 @@ func (suite *ExchangeSelectorSuite) TestExchangeScope_MatchesInfo() {
|
|||||||
scope []ExchangeScope
|
scope []ExchangeScope
|
||||||
expect assert.BoolAssertionFunc
|
expect assert.BoolAssertionFunc
|
||||||
}{
|
}{
|
||||||
{"any mail with a sender", es.MailSender(Any()), assert.True},
|
{"any mail with a sender", es.MailSender(AnyTgt), assert.True},
|
||||||
{"no mail, regardless of sender", es.MailSender(None()), assert.False},
|
{"no mail, regardless of sender", es.MailSender(NoneTgt), assert.False},
|
||||||
{"mail from a different sender", es.MailSender([]string{"magoo@ma.goo"}), assert.False},
|
{"mail from a different sender", es.MailSender("magoo@ma.goo"), assert.False},
|
||||||
{"mail from the matching sender", es.MailSender([]string{sender}), assert.True},
|
{"mail from the matching sender", es.MailSender(sender), assert.True},
|
||||||
{"mail with any subject", es.MailSubject(Any()), assert.True},
|
{"mail with any subject", es.MailSubject(AnyTgt), assert.True},
|
||||||
{"mail with none subject", es.MailSubject(None()), assert.False},
|
{"mail with none subject", es.MailSubject(NoneTgt), assert.False},
|
||||||
{"mail with a different subject", es.MailSubject([]string{"fancy"}), assert.False},
|
{"mail with a different subject", es.MailSubject("fancy"), assert.False},
|
||||||
{"mail with the matching subject", es.MailSubject([]string{subject}), assert.True},
|
{"mail with the matching subject", es.MailSubject(subject), assert.True},
|
||||||
{"mail with a substring subject match", es.MailSubject([]string{subject[5:9]}), assert.True},
|
{"mail with a substring subject match", es.MailSubject(subject[5:9]), assert.True},
|
||||||
{"mail received after the epoch", es.MailReceivedAfter(common.FormatTime(epoch)), assert.True},
|
{"mail received after the epoch", es.MailReceivedAfter(common.FormatTime(epoch)), assert.True},
|
||||||
{"mail received after now", es.MailReceivedAfter(common.FormatTime(now)), assert.False},
|
{"mail received after now", es.MailReceivedAfter(common.FormatTime(now)), assert.False},
|
||||||
{"mail received after sometime later", es.MailReceivedAfter(common.FormatTime(future)), assert.False},
|
{"mail received after sometime later", es.MailReceivedAfter(common.FormatTime(future)), assert.False},
|
||||||
{"mail received before the epoch", es.MailReceivedBefore(common.FormatTime(epoch)), assert.False},
|
{"mail received before the epoch", es.MailReceivedBefore(common.FormatTime(epoch)), assert.False},
|
||||||
{"mail received before now", es.MailReceivedBefore(common.FormatTime(now)), assert.False},
|
{"mail received before now", es.MailReceivedBefore(common.FormatTime(now)), assert.False},
|
||||||
{"mail received before sometime later", es.MailReceivedBefore(common.FormatTime(future)), assert.True},
|
{"mail received before sometime later", es.MailReceivedBefore(common.FormatTime(future)), assert.True},
|
||||||
// TODO: {"event that recurs", es.EventRecurs(true), assert.True},
|
{"event with any organizer", es.EventOrganizer(AnyTgt), assert.True},
|
||||||
// TODO: {"event that does not recur", es.EventRecurs(false), assert.False},
|
{"event with none organizer", es.EventOrganizer(NoneTgt), assert.False},
|
||||||
|
{"event with a different organizer", es.EventOrganizer("fancy"), assert.False},
|
||||||
|
{"event with the matching organizer", es.EventOrganizer(organizer), assert.True},
|
||||||
|
{"event that recurs", es.EventRecurs("true"), assert.True},
|
||||||
|
{"event that does not recur", es.EventRecurs("false"), assert.False},
|
||||||
{"event starting after the epoch", es.EventStartsAfter(common.FormatTime(epoch)), assert.True},
|
{"event starting after the epoch", es.EventStartsAfter(common.FormatTime(epoch)), assert.True},
|
||||||
{"event starting after now", es.EventStartsAfter(common.FormatTime(now)), assert.False},
|
{"event starting after now", es.EventStartsAfter(common.FormatTime(now)), assert.False},
|
||||||
{"event starting after sometime later", es.EventStartsAfter(common.FormatTime(future)), assert.False},
|
{"event starting after sometime later", es.EventStartsAfter(common.FormatTime(future)), assert.False},
|
||||||
{"event starting before the epoch", es.EventStartsBefore(common.FormatTime(epoch)), assert.False},
|
{"event starting before the epoch", es.EventStartsBefore(common.FormatTime(epoch)), assert.False},
|
||||||
{"event starting before now", es.EventStartsBefore(common.FormatTime(now)), assert.False},
|
{"event starting before now", es.EventStartsBefore(common.FormatTime(now)), assert.False},
|
||||||
{"event starting before sometime later", es.EventStartsBefore(common.FormatTime(future)), assert.True},
|
{"event starting before sometime later", es.EventStartsBefore(common.FormatTime(future)), assert.True},
|
||||||
{"event with any subject", es.EventSubject(Any()), assert.True},
|
{"event with any subject", es.EventSubject(AnyTgt), assert.True},
|
||||||
{"event with none subject", es.EventSubject(None()), assert.False},
|
{"event with none subject", es.EventSubject(NoneTgt), assert.False},
|
||||||
{"event with a different subject", es.EventSubject([]string{"fancy"}), assert.False},
|
{"event with a different subject", es.EventSubject("fancy"), assert.False},
|
||||||
{"event with the matching subject", es.EventSubject([]string{subject}), assert.True},
|
{"event with the matching subject", es.EventSubject(subject), assert.True},
|
||||||
{"contact with a different name", es.ContactName("blarps"), assert.False},
|
{"contact with a different name", es.ContactName("blarps"), assert.False},
|
||||||
{"contact with the same name", es.ContactName(name), assert.True},
|
{"contact with the same name", es.ContactName(name), assert.True},
|
||||||
{"contact with a subname search", es.ContactName(name[2:5]), assert.True},
|
{"contact with a subname search", es.ContactName(name[2:5]), assert.True},
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user