diff --git a/src/cli/backup/exchange.go b/src/cli/backup/exchange.go index 9640bae45..b95d3e6d7 100644 --- a/src/cli/backup/exchange.go +++ b/src/cli/backup/exchange.go @@ -358,28 +358,29 @@ func detailsExchangeCmd(cmd *cobra.Command, args []string) error { return Only(ctx, errors.Wrap(err, "Failed to get backup details in the repository")) } + opts := utils.ExchangeOpts{ + Contacts: contact, + ContactFolders: contactFolder, + Emails: email, + EmailFolders: emailFolder, + Events: event, + EventCalendars: eventCalendar, + Users: user, + ContactName: contactName, + EmailReceivedAfter: emailReceivedAfter, + EmailReceivedBefore: emailReceivedBefore, + EmailSender: emailSender, + EmailSubject: emailSubject, + EventOrganizer: eventOrganizer, + EventRecurs: eventRecurs, + EventStartsAfter: eventStartsAfter, + EventStartsBefore: eventStartsBefore, + EventSubject: eventSubject, + } + sel := selectors.NewExchangeRestore() - utils.IncludeExchangeRestoreDataSelectors( - sel, - contact, - contactFolder, - email, - emailFolder, - event, - eventCalendar, - user) - utils.FilterExchangeRestoreInfoSelectors( - sel, - contactName, - emailReceivedAfter, - emailReceivedBefore, - emailSender, - emailSubject, - eventOrganizer, - eventRecurs, - eventStartsAfter, - eventStartsBefore, - eventSubject) + utils.IncludeExchangeRestoreDataSelectors(sel, opts) + utils.FilterExchangeRestoreInfoSelectors(sel, opts) // if no selector flags were specified, get all data in the service. if len(sel.Scopes()) == 0 { diff --git a/src/cli/restore/exchange.go b/src/cli/restore/exchange.go index a54996dfc..2d28dd54c 100644 --- a/src/cli/restore/exchange.go +++ b/src/cli/restore/exchange.go @@ -163,28 +163,29 @@ func restoreExchangeCmd(cmd *cobra.Command, args []string) error { defer utils.CloseRepo(ctx, r) + opts := utils.ExchangeOpts{ + Contacts: contact, + ContactFolders: contactFolder, + Emails: email, + EmailFolders: emailFolder, + Events: event, + EventCalendars: eventCalendar, + Users: user, + ContactName: contactName, + EmailReceivedAfter: emailReceivedAfter, + EmailReceivedBefore: emailReceivedBefore, + EmailSender: emailSender, + EmailSubject: emailSubject, + EventOrganizer: eventOrganizer, + EventRecurs: eventRecurs, + EventStartsAfter: eventStartsAfter, + EventStartsBefore: eventStartsBefore, + EventSubject: eventSubject, + } + sel := selectors.NewExchangeRestore() - utils.IncludeExchangeRestoreDataSelectors( - sel, - contact, - contactFolder, - email, - emailFolder, - event, - eventCalendar, - user) - utils.FilterExchangeRestoreInfoSelectors( - sel, - contactName, - emailReceivedAfter, - emailReceivedBefore, - emailSender, - emailSubject, - eventOrganizer, - eventRecurs, - eventStartsAfter, - eventStartsBefore, - eventSubject) + utils.IncludeExchangeRestoreDataSelectors(sel, opts) + utils.FilterExchangeRestoreInfoSelectors(sel, opts) // if no selector flags were specified, get all data in the service. if len(sel.Scopes()) == 0 { diff --git a/src/cli/utils/exchange.go b/src/cli/utils/exchange.go index d27e1fe8f..aba3076be 100644 --- a/src/cli/utils/exchange.go +++ b/src/cli/utils/exchange.go @@ -6,6 +6,26 @@ import ( "github.com/alcionai/corso/src/pkg/selectors" ) +type ExchangeOpts struct { + Contacts []string + ContactFolders []string + Emails []string + EmailFolders []string + Events []string + EventCalendars []string + Users []string + ContactName string + EmailReceivedAfter string + EmailReceivedBefore string + EmailSender string + EmailSubject string + EventOrganizer string + EventRecurs string + EventStartsAfter string + EventStartsBefore string + EventSubject string +} + // AddExchangeInclude adds the scope of the provided values to the selector's // inclusion set. Any unpopulated slice will be replaced with selectors.Any() // to act as a wildcard. @@ -64,43 +84,41 @@ func ValidateExchangeRestoreFlags(backupID string) error { // inclusions for exchange commands. func IncludeExchangeRestoreDataSelectors( sel *selectors.ExchangeRestore, - contacts, contactFolders, emails, emailFolders, events, eventCalendars, users []string, + opts ExchangeOpts, ) { - lc, lcf := len(contacts), len(contactFolders) - le, lef := len(emails), len(emailFolders) - lev, lec := len(events), len(eventCalendars) + lc, lcf := len(opts.Contacts), len(opts.ContactFolders) + le, lef := len(opts.Emails), len(opts.EmailFolders) + lev, lec := len(opts.Events), len(opts.EventCalendars) // either scope the request to a set of users if lc+lcf+le+lef+lev+lec == 0 { - if len(users) == 0 { - users = selectors.Any() + if len(opts.Users) == 0 { + opts.Users = selectors.Any() } - sel.Include(sel.Users(users)) + sel.Include(sel.Users(opts.Users)) return } // or add selectors for each type of data - AddExchangeInclude(sel, users, contactFolders, contacts, sel.Contacts) - AddExchangeInclude(sel, users, emailFolders, emails, sel.Mails) - AddExchangeInclude(sel, users, eventCalendars, events, sel.Events) + AddExchangeInclude(sel, opts.Users, opts.ContactFolders, opts.Contacts, sel.Contacts) + AddExchangeInclude(sel, opts.Users, opts.EmailFolders, opts.Emails, sel.Mails) + AddExchangeInclude(sel, opts.Users, opts.EventCalendars, opts.Events, sel.Events) } // FilterExchangeRestoreInfoSelectors builds the common info-selector filters. func FilterExchangeRestoreInfoSelectors( sel *selectors.ExchangeRestore, - contactName, - emailReceivedAfter, emailReceivedBefore, emailSender, emailSubject, - eventOrganizer, eventRecurs, eventStartsAfter, eventStartsBefore, eventSubject string, + opts ExchangeOpts, ) { - AddExchangeFilter(sel, contactName, sel.ContactName) - AddExchangeFilter(sel, emailReceivedAfter, sel.MailReceivedAfter) - AddExchangeFilter(sel, emailReceivedBefore, sel.MailReceivedBefore) - AddExchangeFilter(sel, emailSender, sel.MailSender) - AddExchangeFilter(sel, emailSubject, sel.MailSubject) - AddExchangeFilter(sel, eventOrganizer, sel.EventOrganizer) - AddExchangeFilter(sel, eventRecurs, sel.EventRecurs) - AddExchangeFilter(sel, eventStartsAfter, sel.EventStartsAfter) - AddExchangeFilter(sel, eventStartsBefore, sel.EventStartsBefore) - AddExchangeFilter(sel, eventSubject, sel.EventSubject) + AddExchangeFilter(sel, opts.ContactName, sel.ContactName) + AddExchangeFilter(sel, opts.EmailReceivedAfter, sel.MailReceivedAfter) + AddExchangeFilter(sel, opts.EmailReceivedBefore, sel.MailReceivedBefore) + AddExchangeFilter(sel, opts.EmailSender, sel.MailSender) + AddExchangeFilter(sel, opts.EmailSubject, sel.MailSubject) + AddExchangeFilter(sel, opts.EventOrganizer, sel.EventOrganizer) + AddExchangeFilter(sel, opts.EventRecurs, sel.EventRecurs) + AddExchangeFilter(sel, opts.EventStartsAfter, sel.EventStartsAfter) + AddExchangeFilter(sel, opts.EventStartsBefore, sel.EventStartsBefore) + AddExchangeFilter(sel, opts.EventSubject, sel.EventSubject) } diff --git a/src/cli/utils/exchange_test.go b/src/cli/utils/exchange_test.go index 924837d07..d1b4e0d92 100644 --- a/src/cli/utils/exchange_test.go +++ b/src/cli/utils/exchange_test.go @@ -47,207 +47,247 @@ func (suite *ExchangeUtilsSuite) TestIncludeExchangeBackupDetailDataSelectors() a := []string{utils.Wildcard} table := []struct { - name string - contacts, contactFolders, emails, emailFolders, events, eventCalendars, users []string - expectIncludeLen int + name string + opts utils.ExchangeOpts + expectIncludeLen int }{ { name: "no selectors", expectIncludeLen: 3, }, { - name: "any users", - users: a, + name: "any users", + opts: utils.ExchangeOpts{ + Users: a, + }, expectIncludeLen: 3, }, { - name: "single user", - users: stub, + name: "single user", + opts: utils.ExchangeOpts{ + Users: stub, + }, expectIncludeLen: 3, }, { - name: "multiple users", - users: many, + name: "multiple users", + opts: utils.ExchangeOpts{ + Users: many, + }, expectIncludeLen: 3, }, { - name: "any users, any data", - contacts: a, - contactFolders: a, - emails: a, - emailFolders: a, - events: a, - eventCalendars: a, - users: a, + name: "any users, any data", + opts: utils.ExchangeOpts{ + Contacts: a, + ContactFolders: a, + Emails: a, + EmailFolders: a, + Events: a, + EventCalendars: a, + Users: a, + }, expectIncludeLen: 3, }, { - name: "any users, any folders", - contactFolders: a, - emailFolders: a, - eventCalendars: a, - users: a, + name: "any users, any folders", + opts: utils.ExchangeOpts{ + ContactFolders: a, + EmailFolders: a, + EventCalendars: a, + Users: a, + }, expectIncludeLen: 3, }, { - name: "single user, single of each data", - contacts: stub, - contactFolders: stub, - emails: stub, - emailFolders: stub, - events: stub, - eventCalendars: stub, - users: stub, + name: "single user, single of each data", + opts: utils.ExchangeOpts{ + Contacts: stub, + ContactFolders: stub, + Emails: stub, + EmailFolders: stub, + Events: stub, + EventCalendars: stub, + Users: stub, + }, expectIncludeLen: 3, }, { - name: "single user, single of each folder", - contactFolders: stub, - emailFolders: stub, - eventCalendars: stub, - users: stub, + name: "single user, single of each folder", + opts: utils.ExchangeOpts{ + ContactFolders: stub, + EmailFolders: stub, + EventCalendars: stub, + Users: stub, + }, expectIncludeLen: 3, }, { - name: "any users, contacts", - contacts: a, - contactFolders: stub, - users: a, + name: "any users, contacts", + opts: utils.ExchangeOpts{ + Contacts: a, + ContactFolders: stub, + Users: a, + }, expectIncludeLen: 1, }, { - name: "single user, contacts", - contacts: stub, - contactFolders: stub, - users: stub, + name: "single user, contacts", + opts: utils.ExchangeOpts{ + Contacts: stub, + ContactFolders: stub, + Users: stub, + }, expectIncludeLen: 1, }, { - name: "any users, emails", - emails: a, - emailFolders: stub, - users: a, + name: "any users, emails", + opts: utils.ExchangeOpts{ + Emails: a, + EmailFolders: stub, + Users: a, + }, expectIncludeLen: 1, }, { - name: "single user, emails", - emails: stub, - emailFolders: stub, - users: stub, + name: "single user, emails", + opts: utils.ExchangeOpts{ + Emails: stub, + EmailFolders: stub, + Users: stub, + }, expectIncludeLen: 1, }, { - name: "any users, events", - events: a, - eventCalendars: a, - users: a, + name: "any users, events", + opts: utils.ExchangeOpts{ + Events: a, + EventCalendars: a, + Users: a, + }, expectIncludeLen: 1, }, { - name: "single user, events", - events: stub, - eventCalendars: stub, - users: stub, + name: "single user, events", + opts: utils.ExchangeOpts{ + Events: stub, + EventCalendars: stub, + Users: stub, + }, expectIncludeLen: 1, }, { - name: "any users, contacts + email", - contacts: a, - contactFolders: a, - emails: a, - emailFolders: a, - users: a, + name: "any users, contacts + email", + opts: utils.ExchangeOpts{ + Contacts: a, + ContactFolders: a, + Emails: a, + EmailFolders: a, + Users: a, + }, expectIncludeLen: 2, }, { - name: "single users, contacts + email", - contacts: stub, - contactFolders: stub, - emails: stub, - emailFolders: stub, - users: stub, + name: "single users, contacts + email", + opts: utils.ExchangeOpts{ + Contacts: stub, + ContactFolders: stub, + Emails: stub, + EmailFolders: stub, + Users: stub, + }, expectIncludeLen: 2, }, { - name: "any users, email + event", - emails: a, - emailFolders: a, - events: a, - eventCalendars: a, - users: a, + name: "any users, email + event", + opts: utils.ExchangeOpts{ + Emails: a, + EmailFolders: a, + Events: a, + EventCalendars: a, + Users: a, + }, expectIncludeLen: 2, }, { - name: "single users, email + event", - emails: stub, - emailFolders: stub, - events: stub, - eventCalendars: stub, - users: stub, + name: "single users, email + event", + opts: utils.ExchangeOpts{ + Emails: stub, + EmailFolders: stub, + Events: stub, + EventCalendars: stub, + Users: stub, + }, expectIncludeLen: 2, }, { - name: "any users, event + contact", - contacts: a, - contactFolders: a, - events: a, - eventCalendars: a, - users: a, + name: "any users, event + contact", + opts: utils.ExchangeOpts{ + Contacts: a, + ContactFolders: a, + Events: a, + EventCalendars: a, + Users: a, + }, expectIncludeLen: 2, }, { - name: "single users, event + contact", - contacts: stub, - contactFolders: stub, - events: stub, - eventCalendars: stub, - users: stub, + name: "single users, event + contact", + opts: utils.ExchangeOpts{ + Contacts: stub, + ContactFolders: stub, + Events: stub, + EventCalendars: stub, + Users: stub, + }, expectIncludeLen: 2, }, { - name: "many users, events", - events: many, - eventCalendars: many, - users: many, + name: "many users, events", + opts: utils.ExchangeOpts{ + Events: many, + EventCalendars: many, + Users: many, + }, expectIncludeLen: 1, }, { - name: "many users, events + contacts", - contacts: many, - contactFolders: many, - events: many, - eventCalendars: many, - users: many, + name: "many users, events + contacts", + opts: utils.ExchangeOpts{ + Contacts: many, + ContactFolders: many, + Events: many, + EventCalendars: many, + Users: many, + }, expectIncludeLen: 2, }, { - name: "mail, no folder or user", - emails: stub, + name: "mail, no folder or user", + opts: utils.ExchangeOpts{ + Emails: stub, + }, expectIncludeLen: 1, }, { - name: "contacts, no folder or user", - contacts: stub, + name: "contacts, no folder or user", + opts: utils.ExchangeOpts{ + Contacts: stub, + }, expectIncludeLen: 1, }, { - name: "event, no folder or user", - events: stub, + name: "event, no folder or user", + opts: utils.ExchangeOpts{ + Events: stub, + }, expectIncludeLen: 1, }, } for _, test := range table { suite.T().Run(test.name, func(t *testing.T) { sel := selectors.NewExchangeRestore() - utils.IncludeExchangeRestoreDataSelectors( - sel, - test.contacts, - test.contactFolders, - test.emails, - test.emailFolders, - test.events, - test.eventCalendars, - test.users) + utils.IncludeExchangeRestoreDataSelectors(sel, test.opts) assert.Len(t, sel.Includes, test.expectIncludeLen) }) } @@ -257,101 +297,112 @@ func (suite *ExchangeUtilsSuite) TestFilterExchangeBackupDetailInfoSelectors() { stub := "id-stub" table := []struct { - name string - contactName string - after, before, sender, subject string - organizer, recurs, startsAfter, startsBefore, eventSubject string - expectFilterLen int + name string + opts utils.ExchangeOpts + expectFilterLen int }{ { name: "no selectors", expectFilterLen: 0, }, { - name: "contactName", - contactName: stub, + name: "contactName", + opts: utils.ExchangeOpts{ + ContactName: stub, + }, expectFilterLen: 1, }, { - name: "receivedAfter", - after: stub, + name: "receivedAfter", + opts: utils.ExchangeOpts{ + EmailReceivedAfter: stub, + }, expectFilterLen: 1, }, { - name: "receivedAfter", - after: stub, + name: "receivedAfter", + opts: utils.ExchangeOpts{ + EmailReceivedAfter: stub, + }, expectFilterLen: 1, }, { - name: "receivedBefore", - before: stub, + name: "receivedBefore", + opts: utils.ExchangeOpts{ + EmailReceivedBefore: stub, + }, expectFilterLen: 1, }, { - name: "sender", - sender: stub, + name: "sender", + opts: utils.ExchangeOpts{ + EmailSender: stub, + }, expectFilterLen: 1, }, { - name: "subject", - subject: stub, + name: "subject", + opts: utils.ExchangeOpts{ + EmailSubject: stub, + }, expectFilterLen: 1, }, { - name: "organizer", - organizer: stub, + name: "organizer", + opts: utils.ExchangeOpts{ + EventOrganizer: stub, + }, expectFilterLen: 1, }, { - name: "recurs", - recurs: stub, + name: "recurs", + opts: utils.ExchangeOpts{ + EventRecurs: stub, + }, expectFilterLen: 1, }, { - name: "startsAfter", - startsAfter: stub, + name: "startsAfter", + opts: utils.ExchangeOpts{ + EventStartsAfter: stub, + }, expectFilterLen: 1, }, { - name: "startsBefore", - startsBefore: stub, + name: "startsBefore", + opts: utils.ExchangeOpts{ + EventStartsBefore: stub, + }, expectFilterLen: 1, }, { - name: "eventSubject", - eventSubject: stub, + name: "eventSubject", + opts: utils.ExchangeOpts{ + EventSubject: stub, + }, expectFilterLen: 1, }, { - name: "one of each", - contactName: stub, - after: stub, - before: stub, - sender: stub, - subject: stub, - organizer: stub, - recurs: stub, - startsAfter: stub, - startsBefore: stub, - eventSubject: stub, + name: "one of each", + opts: utils.ExchangeOpts{ + ContactName: stub, + EmailReceivedAfter: stub, + EmailReceivedBefore: stub, + EmailSender: stub, + EmailSubject: stub, + EventOrganizer: stub, + EventRecurs: stub, + EventStartsAfter: stub, + EventStartsBefore: stub, + EventSubject: stub, + }, expectFilterLen: 10, }, } for _, test := range table { suite.T().Run(test.name, func(t *testing.T) { sel := selectors.NewExchangeRestore() - utils.FilterExchangeRestoreInfoSelectors( - sel, - test.contactName, - test.after, - test.before, - test.sender, - test.subject, - test.organizer, - test.recurs, - test.startsAfter, - test.startsBefore, - test.eventSubject) + utils.FilterExchangeRestoreInfoSelectors(sel, test.opts) assert.Len(t, sel.Filters, test.expectFilterLen) }) }