expand restore flags (#382)
* expand restore flags Adds support for info filter flags to the restore command. Also adds (hidden) support for event and contact data types. Finally, exchnages single-string flag data types for multi-value string array support.
This commit is contained in:
parent
dcbc149aa7
commit
9e7755cfa7
@ -440,7 +440,6 @@ func validateExchangeBackupDetailFlags(
|
|||||||
lc, lcf := len(contacts), len(contactFolders)
|
lc, lcf := len(contacts), len(contactFolders)
|
||||||
le, lef := len(emails), len(emailFolders)
|
le, lef := len(emails), len(emailFolders)
|
||||||
lev := len(events)
|
lev := len(events)
|
||||||
// if only the backupID is populated, that's the same as --all
|
|
||||||
if lu+lc+lcf+le+lef+lev == 0 {
|
if lu+lc+lcf+le+lef+lev == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,10 +17,17 @@ import (
|
|||||||
|
|
||||||
// exchange bucket info from flags
|
// exchange bucket info from flags
|
||||||
var (
|
var (
|
||||||
emailFolder string
|
backupID string
|
||||||
email string
|
contact []string
|
||||||
backupID string
|
contactFolder []string
|
||||||
user string
|
email []string
|
||||||
|
emailFolder []string
|
||||||
|
emailReceivedAfter []string
|
||||||
|
emailReceivedBefore []string
|
||||||
|
emailSender []string
|
||||||
|
emailSubject []string
|
||||||
|
event []string
|
||||||
|
user []string
|
||||||
)
|
)
|
||||||
|
|
||||||
// called by restore.go to map parent subcommands to provider-specific handling.
|
// called by restore.go to map parent subcommands to provider-specific handling.
|
||||||
@ -33,11 +40,37 @@ func addExchangeCommands(parent *cobra.Command) *cobra.Command {
|
|||||||
switch parent.Use {
|
switch parent.Use {
|
||||||
case restoreCommand:
|
case restoreCommand:
|
||||||
c, fs = utils.AddCommand(parent, exchangeRestoreCmd)
|
c, fs = utils.AddCommand(parent, exchangeRestoreCmd)
|
||||||
fs.StringVar(&emailFolder, "email-folder", "", "Name of the email folder being restored")
|
|
||||||
fs.StringVar(&email, "email", "", "ID of the email being restored")
|
|
||||||
fs.StringVar(&backupID, "backup", "", "ID of the backup to restore")
|
fs.StringVar(&backupID, "backup", "", "ID of the backup to restore")
|
||||||
cobra.CheckErr(c.MarkFlagRequired("backup"))
|
cobra.CheckErr(c.MarkFlagRequired("backup"))
|
||||||
fs.StringVar(&user, "user", "", "ID of the user whose exchange data will get restored")
|
|
||||||
|
// per-data-type flags
|
||||||
|
fs.StringArrayVar(&contact, "contact", nil, "Restore contacts by ID; accepts "+utils.Wildcard+" to select all contacts")
|
||||||
|
fs.StringArrayVar(
|
||||||
|
&contactFolder,
|
||||||
|
"contact-folder",
|
||||||
|
nil,
|
||||||
|
"Restore all contacts within the folder ID; accepts "+utils.Wildcard+" to select all contact folders")
|
||||||
|
fs.StringArrayVar(&email, "email", nil, "Restore emails by ID; accepts "+utils.Wildcard+" to select all emails")
|
||||||
|
fs.StringArrayVar(
|
||||||
|
&emailFolder,
|
||||||
|
"email-folder",
|
||||||
|
nil,
|
||||||
|
"Restore all emails by folder ID; accepts "+utils.Wildcard+" to select all email folders")
|
||||||
|
fs.StringArrayVar(&event, "event", nil, "Restore events by ID; accepts "+utils.Wildcard+" to select all events")
|
||||||
|
fs.StringArrayVar(&user, "user", nil, "Restore all data by user ID; accepts "+utils.Wildcard+" to select all users")
|
||||||
|
|
||||||
|
// TODO: reveal these flags when their production is supported in GC
|
||||||
|
cobra.CheckErr(fs.MarkHidden("contact"))
|
||||||
|
cobra.CheckErr(fs.MarkHidden("contact-folder"))
|
||||||
|
cobra.CheckErr(fs.MarkHidden("event"))
|
||||||
|
|
||||||
|
// exchange-info flags
|
||||||
|
fs.StringArrayVar(&emailReceivedAfter, "email-received-after", nil, "Restore mail where the email was received after this datetime")
|
||||||
|
fs.StringArrayVar(&emailReceivedBefore, "email-received-before", nil, "Restore mail where the email was received before this datetime")
|
||||||
|
fs.StringArrayVar(&emailSender, "email-sender", nil, "Restore mail where the email sender matches this user id")
|
||||||
|
fs.StringArrayVar(&emailSubject, "email-subject", nil, "Restore mail where the email subject lines contain this value")
|
||||||
|
|
||||||
|
// others
|
||||||
options.AddOperationFlags(c)
|
options.AddOperationFlags(c)
|
||||||
}
|
}
|
||||||
return c
|
return c
|
||||||
@ -61,8 +94,16 @@ func restoreExchangeCmd(cmd *cobra.Command, args []string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := validateRestoreFlags(user, emailFolder, email, backupID); err != nil {
|
if err := validateExchangeRestoreFlags(
|
||||||
return errors.Wrap(err, "Missing required flags")
|
contact,
|
||||||
|
contactFolder,
|
||||||
|
email,
|
||||||
|
emailFolder,
|
||||||
|
event,
|
||||||
|
user,
|
||||||
|
backupID,
|
||||||
|
); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
s, a, err := config.GetStorageAndAccount(true, nil)
|
s, a, err := config.GetStorageAndAccount(true, nil)
|
||||||
@ -88,7 +129,28 @@ func restoreExchangeCmd(cmd *cobra.Command, args []string) error {
|
|||||||
}
|
}
|
||||||
defer utils.CloseRepo(ctx, r)
|
defer utils.CloseRepo(ctx, r)
|
||||||
|
|
||||||
ro, err := r.NewRestore(ctx, backupID, exchangeRestoreSelectors(user, emailFolder, email), options.OperationOptions())
|
sel := selectors.NewExchangeRestore()
|
||||||
|
includeExchangeRestoreDataSelectors(
|
||||||
|
sel,
|
||||||
|
contact,
|
||||||
|
contactFolder,
|
||||||
|
email,
|
||||||
|
emailFolder,
|
||||||
|
event,
|
||||||
|
user)
|
||||||
|
includeExchangeRestoreInfoSelectors(
|
||||||
|
sel,
|
||||||
|
emailReceivedAfter,
|
||||||
|
emailReceivedBefore,
|
||||||
|
emailSender,
|
||||||
|
emailSubject)
|
||||||
|
|
||||||
|
// if no selector flags were specified, get all data in the service.
|
||||||
|
if len(sel.Scopes()) == 0 {
|
||||||
|
sel.Include(sel.Users(selectors.Any()))
|
||||||
|
}
|
||||||
|
|
||||||
|
ro, err := r.NewRestore(ctx, backupID, sel.Selector, options.OperationOptions())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "Failed to initialize Exchange restore")
|
return errors.Wrap(err, "Failed to initialize Exchange restore")
|
||||||
}
|
}
|
||||||
@ -101,34 +163,124 @@ func restoreExchangeCmd(cmd *cobra.Command, args []string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func exchangeRestoreSelectors(u, f, m string) selectors.Selector {
|
// builds the data-selector inclusions for `restore exchange`
|
||||||
sel := selectors.NewExchangeRestore()
|
func includeExchangeRestoreDataSelectors(
|
||||||
if len(m) > 0 {
|
sel *selectors.ExchangeRestore,
|
||||||
sel.Include(sel.Mails(
|
contacts, contactFolders, emails, emailFolders, events, users []string,
|
||||||
[]string{u}, []string{f}, []string{m},
|
) {
|
||||||
))
|
lc, lcf := len(contacts), len(contactFolders)
|
||||||
|
le, lef := len(emails), len(emailFolders)
|
||||||
|
lev := len(events)
|
||||||
|
lu := len(users)
|
||||||
|
|
||||||
|
if lc+lcf+le+lef+lev+lu == 0 {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
if len(f) > 0 && len(m) == 0 {
|
|
||||||
sel.Include(sel.MailFolders(
|
// if only users are provided, we only get one selector
|
||||||
[]string{u}, []string{f},
|
if lu > 0 && lc+lcf+le+lef+lev == 0 {
|
||||||
))
|
sel.Include(sel.Users(users))
|
||||||
|
return
|
||||||
}
|
}
|
||||||
if len(f) == 0 && len(m) == 0 {
|
|
||||||
sel.Include(sel.Users([]string{u}))
|
// otherwise, add selectors for each type of data
|
||||||
}
|
includeExchangeContacts(sel, users, contactFolders, contacts)
|
||||||
return sel.Selector
|
includeExchangeEmails(sel, users, emailFolders, email)
|
||||||
|
includeExchangeEvents(sel, users, events)
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateRestoreFlags(u, f, m, rpid string) error {
|
func includeExchangeContacts(sel *selectors.ExchangeRestore, users, contactFolders, contacts []string) {
|
||||||
if len(rpid) == 0 {
|
if len(contactFolders) == 0 {
|
||||||
return errors.New("a restore point ID is required")
|
return
|
||||||
}
|
}
|
||||||
lu, lf, lm := len(u), len(f), len(m)
|
if len(contacts) > 0 {
|
||||||
if (lu == 0 || u == "*") && (lf+lm > 0) {
|
sel.Include(sel.Contacts(users, contactFolders, contacts))
|
||||||
return errors.New("a specific --user must be provided if --email-folder or --email is specified")
|
} else {
|
||||||
|
sel.Include(sel.ContactFolders(users, contactFolders))
|
||||||
}
|
}
|
||||||
if (lf == 0 || f == "*") && lm > 0 {
|
}
|
||||||
return errors.New("a specific --email-folder must be provided if a --email is specified")
|
|
||||||
|
func includeExchangeEmails(sel *selectors.ExchangeRestore, users, emailFolders, emails []string) {
|
||||||
|
if len(emailFolders) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(emails) > 0 {
|
||||||
|
sel.Include(sel.Mails(users, emailFolders, emails))
|
||||||
|
} else {
|
||||||
|
sel.Include(sel.MailFolders(users, emailFolders))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func includeExchangeEvents(sel *selectors.ExchangeRestore, users, events []string) {
|
||||||
|
if len(events) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
sel.Include(sel.Events(users, events))
|
||||||
|
}
|
||||||
|
|
||||||
|
// builds the info-selector inclusions for `restore exchange`
|
||||||
|
func includeExchangeRestoreInfoSelectors(
|
||||||
|
sel *selectors.ExchangeRestore,
|
||||||
|
emailReceivedAfter, emailReceivedBefore, emailSender, emailSubject []string,
|
||||||
|
) {
|
||||||
|
includeExchangeInfoMailReceivedAfter(sel, emailReceivedAfter)
|
||||||
|
includeExchangeInfoMailReceivedBefore(sel, emailReceivedBefore)
|
||||||
|
includeExchangeInfoMailSender(sel, emailSender)
|
||||||
|
includeExchangeInfoMailSubject(sel, emailSubject)
|
||||||
|
}
|
||||||
|
|
||||||
|
func includeExchangeInfoMailReceivedAfter(sel *selectors.ExchangeRestore, receivedAfter []string) {
|
||||||
|
if len(receivedAfter) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
sel.Include(sel.MailReceivedAfter(receivedAfter))
|
||||||
|
}
|
||||||
|
|
||||||
|
func includeExchangeInfoMailReceivedBefore(sel *selectors.ExchangeRestore, receivedBefore []string) {
|
||||||
|
if len(receivedBefore) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
sel.Include(sel.MailReceivedBefore(receivedBefore))
|
||||||
|
}
|
||||||
|
|
||||||
|
func includeExchangeInfoMailSender(sel *selectors.ExchangeRestore, sender []string) {
|
||||||
|
if len(sender) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
sel.Include(sel.MailSender(sender))
|
||||||
|
}
|
||||||
|
|
||||||
|
func includeExchangeInfoMailSubject(sel *selectors.ExchangeRestore, subject []string) {
|
||||||
|
if len(subject) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
sel.Include(sel.MailSubject(subject))
|
||||||
|
}
|
||||||
|
|
||||||
|
// checks all flags for correctness and interdependencies
|
||||||
|
func validateExchangeRestoreFlags(
|
||||||
|
contacts, contactFolders, emails, emailFolders, events, users []string,
|
||||||
|
backupID string,
|
||||||
|
) error {
|
||||||
|
if len(backupID) == 0 {
|
||||||
|
return errors.New("a backup ID is required")
|
||||||
|
}
|
||||||
|
lu := len(users)
|
||||||
|
lc, lcf := len(contacts), len(contactFolders)
|
||||||
|
le, lef := len(emails), len(emailFolders)
|
||||||
|
lev := len(events)
|
||||||
|
// if only the backupID is populated, that's the same as --all
|
||||||
|
if lu+lc+lcf+le+lef+lev == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if lu == 0 {
|
||||||
|
return errors.New("requires one or more --user ids, the wildcard --user *, or the --all flag.")
|
||||||
|
}
|
||||||
|
if lc > 0 && lcf == 0 {
|
||||||
|
return errors.New("one or more --contact-folder ids or the wildcard --contact-folder * must be included to specify a --contact")
|
||||||
|
}
|
||||||
|
if le > 0 && lef == 0 {
|
||||||
|
return errors.New("one or more --email-folder ids or the wildcard --email-folder * must be included to specify a --email")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import (
|
|||||||
|
|
||||||
"github.com/alcionai/corso/cli/utils"
|
"github.com/alcionai/corso/cli/utils"
|
||||||
ctesting "github.com/alcionai/corso/internal/testing"
|
ctesting "github.com/alcionai/corso/internal/testing"
|
||||||
|
"github.com/alcionai/corso/pkg/selectors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ExchangeSuite struct {
|
type ExchangeSuite struct {
|
||||||
@ -20,31 +21,6 @@ func TestExchangeSuite(t *testing.T) {
|
|||||||
suite.Run(t, new(ExchangeSuite))
|
suite.Run(t, new(ExchangeSuite))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *ExchangeSuite) TestValidateRestoreFlags() {
|
|
||||||
table := []struct {
|
|
||||||
name string
|
|
||||||
u, f, m, rpid string
|
|
||||||
errCheck assert.ErrorAssertionFunc
|
|
||||||
}{
|
|
||||||
{"all populated", "u", "f", "m", "rpid", assert.NoError},
|
|
||||||
{"folder missing user", "", "f", "m", "rpid", assert.Error},
|
|
||||||
{"folder with wildcard user", utils.Wildcard, "f", "m", "rpid", assert.Error},
|
|
||||||
{"mail missing user", "", "", "m", "rpid", assert.Error},
|
|
||||||
{"mail missing folder", "u", "", "m", "rpid", assert.Error},
|
|
||||||
{"mail with wildcard folder", "u", utils.Wildcard, "m", "rpid", assert.Error},
|
|
||||||
{"missing backup id", "u", "f", "m", "", assert.Error},
|
|
||||||
{"all missing", "", "", "", "rpid", assert.NoError},
|
|
||||||
}
|
|
||||||
for _, test := range table {
|
|
||||||
suite.T().Run(test.name, func(t *testing.T) {
|
|
||||||
test.errCheck(
|
|
||||||
t,
|
|
||||||
validateRestoreFlags(test.u, test.f, test.m, test.rpid),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (suite *ExchangeSuite) TestAddExchangeCommands() {
|
func (suite *ExchangeSuite) TestAddExchangeCommands() {
|
||||||
expectUse := exchangeServiceCommand
|
expectUse := exchangeServiceCommand
|
||||||
table := []struct {
|
table := []struct {
|
||||||
@ -73,3 +49,365 @@ func (suite *ExchangeSuite) TestAddExchangeCommands() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (suite *ExchangeSuite) TestValidateExchangeRestoreFlags() {
|
||||||
|
stub := []string{"id-stub"}
|
||||||
|
table := []struct {
|
||||||
|
name string
|
||||||
|
contacts, contactFolders, emails, emailFolders, events, users []string
|
||||||
|
backupID string
|
||||||
|
expect assert.ErrorAssertionFunc
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "only backupid",
|
||||||
|
backupID: "bid",
|
||||||
|
expect: assert.NoError,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "any values populated",
|
||||||
|
backupID: "bid",
|
||||||
|
contacts: stub,
|
||||||
|
contactFolders: stub,
|
||||||
|
emails: stub,
|
||||||
|
emailFolders: stub,
|
||||||
|
events: stub,
|
||||||
|
users: stub,
|
||||||
|
expect: assert.NoError,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "nothing populated",
|
||||||
|
expect: assert.Error,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "no backup id",
|
||||||
|
contacts: stub,
|
||||||
|
contactFolders: stub,
|
||||||
|
emails: stub,
|
||||||
|
emailFolders: stub,
|
||||||
|
events: stub,
|
||||||
|
users: stub,
|
||||||
|
expect: assert.Error,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "no users",
|
||||||
|
backupID: "bid",
|
||||||
|
contacts: stub,
|
||||||
|
contactFolders: stub,
|
||||||
|
emails: stub,
|
||||||
|
emailFolders: stub,
|
||||||
|
events: stub,
|
||||||
|
expect: assert.Error,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "no contact folders",
|
||||||
|
backupID: "bid",
|
||||||
|
contacts: stub,
|
||||||
|
emails: stub,
|
||||||
|
emailFolders: stub,
|
||||||
|
events: stub,
|
||||||
|
users: stub,
|
||||||
|
expect: assert.Error,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "no email folders",
|
||||||
|
backupID: "bid",
|
||||||
|
contacts: stub,
|
||||||
|
contactFolders: stub,
|
||||||
|
emails: stub,
|
||||||
|
events: stub,
|
||||||
|
users: stub,
|
||||||
|
expect: assert.Error,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, test := range table {
|
||||||
|
suite.T().Run(test.name, func(t *testing.T) {
|
||||||
|
test.expect(t, validateExchangeRestoreFlags(
|
||||||
|
test.contacts,
|
||||||
|
test.contactFolders,
|
||||||
|
test.emails,
|
||||||
|
test.emailFolders,
|
||||||
|
test.events,
|
||||||
|
test.users,
|
||||||
|
test.backupID,
|
||||||
|
))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (suite *ExchangeSuite) TestIncludeExchangeRestoreDataSelectors() {
|
||||||
|
stub := []string{"id-stub"}
|
||||||
|
any := []string{utils.Wildcard}
|
||||||
|
table := []struct {
|
||||||
|
name string
|
||||||
|
contacts, contactFolders, emails, emailFolders, events, users []string
|
||||||
|
expectIncludeLen int
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "no selectors",
|
||||||
|
expectIncludeLen: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "any users",
|
||||||
|
users: any,
|
||||||
|
expectIncludeLen: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "single user",
|
||||||
|
users: stub,
|
||||||
|
expectIncludeLen: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "multiple users",
|
||||||
|
users: []string{"fnord", "smarf"},
|
||||||
|
expectIncludeLen: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "any users, any data",
|
||||||
|
contacts: any,
|
||||||
|
contactFolders: any,
|
||||||
|
emails: any,
|
||||||
|
emailFolders: any,
|
||||||
|
events: any,
|
||||||
|
users: any,
|
||||||
|
expectIncludeLen: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "any users, any folders",
|
||||||
|
contactFolders: any,
|
||||||
|
emailFolders: any,
|
||||||
|
users: any,
|
||||||
|
expectIncludeLen: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "single user, single of each data",
|
||||||
|
contacts: stub,
|
||||||
|
contactFolders: stub,
|
||||||
|
emails: stub,
|
||||||
|
emailFolders: stub,
|
||||||
|
events: stub,
|
||||||
|
users: stub,
|
||||||
|
expectIncludeLen: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "single user, single of each folder",
|
||||||
|
contactFolders: stub,
|
||||||
|
emailFolders: stub,
|
||||||
|
users: stub,
|
||||||
|
expectIncludeLen: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "any users, contacts",
|
||||||
|
contacts: any,
|
||||||
|
contactFolders: stub,
|
||||||
|
users: any,
|
||||||
|
expectIncludeLen: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "single user, contacts",
|
||||||
|
contacts: stub,
|
||||||
|
contactFolders: stub,
|
||||||
|
users: stub,
|
||||||
|
expectIncludeLen: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "any users, emails",
|
||||||
|
emails: any,
|
||||||
|
emailFolders: stub,
|
||||||
|
users: any,
|
||||||
|
expectIncludeLen: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "single user, emails",
|
||||||
|
emails: stub,
|
||||||
|
emailFolders: stub,
|
||||||
|
users: stub,
|
||||||
|
expectIncludeLen: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "any users, events",
|
||||||
|
events: any,
|
||||||
|
users: any,
|
||||||
|
expectIncludeLen: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "single user, events",
|
||||||
|
events: stub,
|
||||||
|
users: stub,
|
||||||
|
expectIncludeLen: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "any users, contacts + email",
|
||||||
|
contacts: any,
|
||||||
|
contactFolders: any,
|
||||||
|
emails: any,
|
||||||
|
emailFolders: any,
|
||||||
|
users: any,
|
||||||
|
expectIncludeLen: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "single users, contacts + email",
|
||||||
|
contacts: stub,
|
||||||
|
contactFolders: stub,
|
||||||
|
emails: stub,
|
||||||
|
emailFolders: stub,
|
||||||
|
users: stub,
|
||||||
|
expectIncludeLen: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "any users, email + event",
|
||||||
|
emails: any,
|
||||||
|
emailFolders: any,
|
||||||
|
events: any,
|
||||||
|
users: any,
|
||||||
|
expectIncludeLen: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "single users, email + event",
|
||||||
|
emails: stub,
|
||||||
|
emailFolders: stub,
|
||||||
|
events: stub,
|
||||||
|
users: stub,
|
||||||
|
expectIncludeLen: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "any users, event + contact",
|
||||||
|
contacts: any,
|
||||||
|
contactFolders: any,
|
||||||
|
events: any,
|
||||||
|
users: any,
|
||||||
|
expectIncludeLen: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "single users, event + contact",
|
||||||
|
contacts: stub,
|
||||||
|
contactFolders: stub,
|
||||||
|
events: stub,
|
||||||
|
users: stub,
|
||||||
|
expectIncludeLen: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "many users, events",
|
||||||
|
events: []string{"foo", "bar"},
|
||||||
|
users: []string{"fnord", "smarf"},
|
||||||
|
expectIncludeLen: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "many users, events + contacts",
|
||||||
|
contacts: []string{"foo", "bar"},
|
||||||
|
contactFolders: []string{"foo", "bar"},
|
||||||
|
events: []string{"foo", "bar"},
|
||||||
|
users: []string{"fnord", "smarf"},
|
||||||
|
expectIncludeLen: 6,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, test := range table {
|
||||||
|
suite.T().Run(test.name, func(t *testing.T) {
|
||||||
|
sel := selectors.NewExchangeRestore()
|
||||||
|
includeExchangeRestoreDataSelectors(
|
||||||
|
sel,
|
||||||
|
test.contacts,
|
||||||
|
test.contactFolders,
|
||||||
|
test.emails,
|
||||||
|
test.emailFolders,
|
||||||
|
test.events,
|
||||||
|
test.users)
|
||||||
|
assert.Equal(t, test.expectIncludeLen, len(sel.Includes))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (suite *ExchangeSuite) TestIncludeExchangeRestoreInfoSelectors() {
|
||||||
|
stub := []string{"id-stub"}
|
||||||
|
twoStubs := []string{"a-stub", "b-stub"}
|
||||||
|
any := []string{utils.Wildcard}
|
||||||
|
table := []struct {
|
||||||
|
name string
|
||||||
|
after, before, sender, subject []string
|
||||||
|
expectIncludeLen int
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "no selectors",
|
||||||
|
expectIncludeLen: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "any receivedAfter",
|
||||||
|
after: any,
|
||||||
|
expectIncludeLen: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "single receivedAfter",
|
||||||
|
after: stub,
|
||||||
|
expectIncludeLen: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "multiple receivedAfter",
|
||||||
|
after: twoStubs,
|
||||||
|
expectIncludeLen: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "any receivedBefore",
|
||||||
|
before: any,
|
||||||
|
expectIncludeLen: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "single receivedBefore",
|
||||||
|
before: stub,
|
||||||
|
expectIncludeLen: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "multiple receivedBefore",
|
||||||
|
before: twoStubs,
|
||||||
|
expectIncludeLen: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "any senders",
|
||||||
|
sender: any,
|
||||||
|
expectIncludeLen: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "single sender",
|
||||||
|
sender: stub,
|
||||||
|
expectIncludeLen: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "multiple senders",
|
||||||
|
sender: twoStubs,
|
||||||
|
expectIncludeLen: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "any subjects",
|
||||||
|
subject: any,
|
||||||
|
expectIncludeLen: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "single subject",
|
||||||
|
subject: stub,
|
||||||
|
expectIncludeLen: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "multiple subjects",
|
||||||
|
subject: twoStubs,
|
||||||
|
expectIncludeLen: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "one of each",
|
||||||
|
after: stub,
|
||||||
|
before: stub,
|
||||||
|
sender: stub,
|
||||||
|
subject: stub,
|
||||||
|
expectIncludeLen: 4,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, test := range table {
|
||||||
|
suite.T().Run(test.name, func(t *testing.T) {
|
||||||
|
sel := selectors.NewExchangeRestore()
|
||||||
|
includeExchangeRestoreInfoSelectors(
|
||||||
|
sel,
|
||||||
|
test.after,
|
||||||
|
test.before,
|
||||||
|
test.sender,
|
||||||
|
test.subject)
|
||||||
|
assert.Equal(t, test.expectIncludeLen, len(sel.Includes))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -571,15 +571,6 @@ func (s exchangeScope) matchesPath(cat exchangeCategory, path []string) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// excludesInfo returns true if all filters in the scope matche the info.
|
|
||||||
func (s exchangeScope) excludesInfo(cat exchangeCategory, info *backup.ExchangeInfo) bool {
|
|
||||||
// todo: implement once filters used in scopes
|
|
||||||
if info == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// temporary helper until filters replace string values for scopes.
|
// temporary helper until filters replace string values for scopes.
|
||||||
func contains(super []string, sub string) bool {
|
func contains(super []string, sub string) bool {
|
||||||
for _, s := range super {
|
for _, s := range super {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user