remove resource owners from scopes (#1895)

## Description
    
Now that resource owners are identified via
the selector itself, rather than each scope, we
can remove the resource owner data from
scope production and data.

## Does this PR need a docs update or release note?

- [x]  No 

## Type of change

- [x] 🌻 Feature

## Issue(s)

* #1617

## Test Plan

- [x]  Unit test
- [x] 💚 E2E
This commit is contained in:
Keepers 2023-01-05 14:29:48 -07:00 committed by GitHub
parent 70d5a5ab56
commit 2b45cfa617
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 429 additions and 593 deletions

View File

@ -326,19 +326,19 @@ func exchangeBackupCreateSelectors(userIDs, data []string) *selectors.ExchangeBa
sel := selectors.NewExchangeBackup(userIDs) sel := selectors.NewExchangeBackup(userIDs)
if len(data) == 0 { if len(data) == 0 {
sel.Include(sel.ContactFolders(userIDs, selectors.Any())) sel.Include(sel.ContactFolders(selectors.Any()))
sel.Include(sel.MailFolders(userIDs, selectors.Any())) sel.Include(sel.MailFolders(selectors.Any()))
sel.Include(sel.EventCalendars(userIDs, selectors.Any())) sel.Include(sel.EventCalendars(selectors.Any()))
} }
for _, d := range data { for _, d := range data {
switch d { switch d {
case dataContacts: case dataContacts:
sel.Include(sel.ContactFolders(userIDs, selectors.Any())) sel.Include(sel.ContactFolders(selectors.Any()))
case dataEmail: case dataEmail:
sel.Include(sel.MailFolders(userIDs, selectors.Any())) sel.Include(sel.MailFolders(selectors.Any()))
case dataEvents: case dataEvents:
sel.Include(sel.EventCalendars(userIDs, selectors.Any())) sel.Include(sel.EventCalendars(selectors.Any()))
} }
} }
@ -510,7 +510,7 @@ func runDetailsExchangeCmd(
// if no selector flags were specified, get all data in the service. // if no selector flags were specified, get all data in the service.
if len(sel.Scopes()) == 0 { if len(sel.Scopes()) == 0 {
sel.Include(sel.Users(selectors.Any())) sel.Include(sel.AllData())
} }
return sel.Reduce(ctx, d), nil return sel.Reduce(ctx, d), nil

View File

@ -275,16 +275,13 @@ func (suite *PreparedBackupExchangeIntegrationSuite) SetupSuite() {
switch set { switch set {
case email: case email:
scopes = sel.MailFolders(users, []string{exchange.DefaultMailFolder}, selectors.PrefixMatch()) scopes = sel.MailFolders([]string{exchange.DefaultMailFolder}, selectors.PrefixMatch())
case contacts: case contacts:
scopes = sel.ContactFolders( scopes = sel.ContactFolders([]string{exchange.DefaultContactFolder}, selectors.PrefixMatch())
users,
[]string{exchange.DefaultContactFolder},
selectors.PrefixMatch())
case events: case events:
scopes = sel.EventCalendars(users, []string{exchange.DefaultCalendar}, selectors.PrefixMatch()) scopes = sel.EventCalendars([]string{exchange.DefaultCalendar}, selectors.PrefixMatch())
} }
sel.Include(scopes) sel.Include(scopes)
@ -497,7 +494,7 @@ func (suite *BackupDeleteExchangeIntegrationSuite) SetupSuite() {
// some tests require an existing backup // some tests require an existing backup
sel := selectors.NewExchangeBackup(users) sel := selectors.NewExchangeBackup(users)
sel.Include(sel.MailFolders(users, []string{exchange.DefaultMailFolder}, selectors.PrefixMatch())) sel.Include(sel.MailFolders([]string{exchange.DefaultMailFolder}, selectors.PrefixMatch()))
suite.backupOp, err = suite.repo.NewBackup(ctx, sel.Selector) suite.backupOp, err = suite.repo.NewBackup(ctx, sel.Selector)
require.NoError(t, suite.backupOp.Run(ctx)) require.NoError(t, suite.backupOp.Run(ctx))

View File

@ -254,7 +254,7 @@ func validateOneDriveBackupCreateFlags(users []string) error {
func oneDriveBackupCreateSelectors(users []string) *selectors.OneDriveBackup { func oneDriveBackupCreateSelectors(users []string) *selectors.OneDriveBackup {
sel := selectors.NewOneDriveBackup(users) sel := selectors.NewOneDriveBackup(users)
sel.Include(sel.Users(users)) sel.Include(sel.AllData())
return sel return sel
} }
@ -401,7 +401,7 @@ func runDetailsOneDriveCmd(
// if no selector flags were specified, get all data in the service. // if no selector flags were specified, get all data in the service.
if len(sel.Scopes()) == 0 { if len(sel.Scopes()) == 0 {
sel.Include(sel.Users(selectors.Any())) sel.Include(sel.AllData())
} }
return sel.Reduce(ctx, d), nil return sel.Reduce(ctx, d), nil

View File

@ -160,7 +160,7 @@ func (suite *BackupDeleteOneDriveIntegrationSuite) SetupSuite() {
// some tests require an existing backup // some tests require an existing backup
sel := selectors.NewOneDriveBackup(users) sel := selectors.NewOneDriveBackup(users)
sel.Include(sel.Folders(users, selectors.Any())) sel.Include(sel.Folders(selectors.Any()))
suite.backupOp, err = suite.repo.NewBackup(ctx, sel.Selector) suite.backupOp, err = suite.repo.NewBackup(ctx, sel.Selector)
require.NoError(t, suite.backupOp.Run(ctx)) require.NoError(t, suite.backupOp.Run(ctx))

View File

@ -263,6 +263,7 @@ func validateSharePointBackupCreateFlags(sites, weburls []string) error {
return nil return nil
} }
// TODO: users might specify a data type, this only supports AllData().
func sharePointBackupCreateSelectors( func sharePointBackupCreateSelectors(
ctx context.Context, ctx context.Context,
sites, weburls []string, sites, weburls []string,
@ -275,7 +276,7 @@ func sharePointBackupCreateSelectors(
for _, site := range sites { for _, site := range sites {
if site == utils.Wildcard { if site == utils.Wildcard {
sel := selectors.NewSharePointBackup(selectors.Any()) sel := selectors.NewSharePointBackup(selectors.Any())
sel.Include(sel.Sites(selectors.Any())) sel.Include(sel.AllData())
return sel, nil return sel, nil
} }
@ -284,7 +285,7 @@ func sharePointBackupCreateSelectors(
for _, wURL := range weburls { for _, wURL := range weburls {
if wURL == utils.Wildcard { if wURL == utils.Wildcard {
sel := selectors.NewSharePointBackup(selectors.Any()) sel := selectors.NewSharePointBackup(selectors.Any())
sel.Include(sel.Sites(selectors.Any())) sel.Include(sel.AllData())
return sel, nil return sel, nil
} }
@ -296,7 +297,7 @@ func sharePointBackupCreateSelectors(
} }
sel := selectors.NewSharePointBackup(union) sel := selectors.NewSharePointBackup(union)
sel.Include(sel.Sites(union)) sel.Include(sel.AllData())
return sel, nil return sel, nil
} }
@ -484,7 +485,7 @@ func runDetailsSharePointCmd(
// if no selector flags were specified, get all data in the service. // if no selector flags were specified, get all data in the service.
if len(sel.Scopes()) == 0 { if len(sel.Scopes()) == 0 {
sel.Include(sel.Sites(selectors.Any())) sel.Include(sel.AllData())
} }
return sel.Reduce(ctx, d), nil return sel.Reduce(ctx, d), nil

View File

@ -156,7 +156,7 @@ func (suite *BackupDeleteSharePointIntegrationSuite) SetupSuite() {
// some tests require an existing backup // some tests require an existing backup
sel := selectors.NewSharePointBackup(sites) sel := selectors.NewSharePointBackup(sites)
sel.Include(sel.Libraries(sites, selectors.Any())) sel.Include(sel.Libraries(selectors.Any()))
suite.backupOp, err = suite.repo.NewBackup(ctx, sel.Selector) suite.backupOp, err = suite.repo.NewBackup(ctx, sel.Selector)
require.NoError(t, suite.backupOp.Run(ctx)) require.NoError(t, suite.backupOp.Run(ctx))

View File

@ -189,15 +189,7 @@ func (suite *SharePointSuite) TestSharePointBackupCreateSelectors() {
sel, err := sharePointBackupCreateSelectors(ctx, test.site, test.weburl, gc) sel, err := sharePointBackupCreateSelectors(ctx, test.site, test.weburl, gc)
require.NoError(t, err) require.NoError(t, err)
scopes := sel.Scopes() assert.ElementsMatch(t, test.expect, sel.DiscreteResourceOwners())
assert.Len(t, scopes, test.expectScopesLen)
if test.expectScopesLen == 0 {
return
}
targetSites := scopes[0].Get(selectors.SharePointSite)
assert.ElementsMatch(t, test.expect, targetSites)
}) })
} }
} }

View File

@ -200,14 +200,9 @@ func connectS3Cmd(cmd *cobra.Command, args []string) error {
} }
func s3Overrides() map[string]string { func s3Overrides() map[string]string {
var (
prvM365 = account.ProviderM365.String()
prvS3 = storage.ProviderS3.String()
)
return map[string]string{ return map[string]string{
config.AccountProviderTypeKey: prvM365, config.AccountProviderTypeKey: account.ProviderM365.String(),
config.StorageProviderTypeKey: prvS3, config.StorageProviderTypeKey: storage.ProviderS3.String(),
storage.Bucket: bucket, storage.Bucket: bucket,
storage.Endpoint: endpoint, storage.Endpoint: endpoint,
storage.Prefix: prefix, storage.Prefix: prefix,

View File

@ -12,7 +12,6 @@ import (
"github.com/alcionai/corso/src/internal/common" "github.com/alcionai/corso/src/internal/common"
"github.com/alcionai/corso/src/pkg/control" "github.com/alcionai/corso/src/pkg/control"
"github.com/alcionai/corso/src/pkg/repository" "github.com/alcionai/corso/src/pkg/repository"
"github.com/alcionai/corso/src/pkg/selectors"
) )
// exchange bucket info from flags // exchange bucket info from flags
@ -221,7 +220,7 @@ func restoreExchangeCmd(cmd *cobra.Command, args []string) error {
// if no selector flags were specified, get all data in the service. // if no selector flags were specified, get all data in the service.
if len(sel.Scopes()) == 0 { if len(sel.Scopes()) == 0 {
sel.Include(sel.Users(selectors.Any())) sel.Include(sel.AllData())
} }
restoreDest := control.DefaultRestoreDestination(common.SimpleDateTime) restoreDest := control.DefaultRestoreDestination(common.SimpleDateTime)

View File

@ -90,16 +90,13 @@ func (suite *RestoreExchangeIntegrationSuite) SetupSuite() {
switch set { switch set {
case email: case email:
scopes = sel.MailFolders(users, []string{exchange.DefaultMailFolder}, selectors.PrefixMatch()) scopes = sel.MailFolders([]string{exchange.DefaultMailFolder}, selectors.PrefixMatch())
case contacts: case contacts:
scopes = sel.ContactFolders( scopes = sel.ContactFolders([]string{exchange.DefaultContactFolder}, selectors.PrefixMatch())
users,
[]string{exchange.DefaultContactFolder},
selectors.PrefixMatch())
case events: case events:
scopes = sel.EventCalendars(users, []string{exchange.DefaultCalendar}, selectors.PrefixMatch()) scopes = sel.EventCalendars([]string{exchange.DefaultCalendar}, selectors.PrefixMatch())
} }
sel.Include(scopes) sel.Include(scopes)

View File

@ -12,7 +12,6 @@ import (
"github.com/alcionai/corso/src/internal/common" "github.com/alcionai/corso/src/internal/common"
"github.com/alcionai/corso/src/pkg/control" "github.com/alcionai/corso/src/pkg/control"
"github.com/alcionai/corso/src/pkg/repository" "github.com/alcionai/corso/src/pkg/repository"
"github.com/alcionai/corso/src/pkg/selectors"
) )
var ( var (
@ -158,7 +157,7 @@ func restoreOneDriveCmd(cmd *cobra.Command, args []string) error {
// if no selector flags were specified, get all data in the service. // if no selector flags were specified, get all data in the service.
if len(sel.Scopes()) == 0 { if len(sel.Scopes()) == 0 {
sel.Include(sel.Users(selectors.Any())) sel.Include(sel.AllData())
} }
restoreDest := control.DefaultRestoreDestination(common.SimpleDateTimeOneDrive) restoreDest := control.DefaultRestoreDestination(common.SimpleDateTimeOneDrive)

View File

@ -12,7 +12,6 @@ import (
"github.com/alcionai/corso/src/internal/common" "github.com/alcionai/corso/src/internal/common"
"github.com/alcionai/corso/src/pkg/control" "github.com/alcionai/corso/src/pkg/control"
"github.com/alcionai/corso/src/pkg/repository" "github.com/alcionai/corso/src/pkg/repository"
"github.com/alcionai/corso/src/pkg/selectors"
) )
var ( var (
@ -159,7 +158,7 @@ func restoreSharePointCmd(cmd *cobra.Command, args []string) error {
// if no selector flags were specified, get all data in the service. // if no selector flags were specified, get all data in the service.
if len(sel.Scopes()) == 0 { if len(sel.Scopes()) == 0 {
sel.Include(sel.Sites(selectors.Any())) sel.Include(sel.AllData())
} }
restoreDest := control.DefaultRestoreDestination(common.SimpleDateTimeOneDrive) restoreDest := control.DefaultRestoreDestination(common.SimpleDateTimeOneDrive)

View File

@ -53,7 +53,7 @@ type ExchangeOpts struct {
// to act as a wildcard. // to act as a wildcard.
func AddExchangeInclude( func AddExchangeInclude(
sel *selectors.ExchangeRestore, sel *selectors.ExchangeRestore,
resource, folders, items []string, folders, items []string,
eisc selectors.ExchangeItemScopeConstructor, eisc selectors.ExchangeItemScopeConstructor,
) { ) {
lf, li := len(folders), len(items) lf, li := len(folders), len(items)
@ -64,10 +64,6 @@ func AddExchangeInclude(
return return
} }
if len(resource) == 0 {
resource = selectors.Any()
}
if li == 0 { if li == 0 {
items = selectors.Any() items = selectors.Any()
} }
@ -75,11 +71,11 @@ func AddExchangeInclude(
containsFolders, prefixFolders := splitFoldersIntoContainsAndPrefix(folders) containsFolders, prefixFolders := splitFoldersIntoContainsAndPrefix(folders)
if len(containsFolders) > 0 { if len(containsFolders) > 0 {
sel.Include(eisc(resource, containsFolders, items)) sel.Include(eisc(containsFolders, items))
} }
if len(prefixFolders) > 0 { if len(prefixFolders) > 0 {
sel.Include(eisc(resource, prefixFolders, items, selectors.PrefixMatch())) sel.Include(eisc(prefixFolders, items, selectors.PrefixMatch()))
} }
} }
@ -141,7 +137,7 @@ func IncludeExchangeRestoreDataSelectors(opts ExchangeOpts) *selectors.ExchangeR
lev, lec := len(opts.Event), len(opts.EventCalendar) lev, lec := len(opts.Event), len(opts.EventCalendar)
// either scope the request to a set of users // either scope the request to a set of users
if lc+lcf+le+lef+lev+lec == 0 { if lc+lcf+le+lef+lev+lec == 0 {
sel.Include(sel.Users(users)) sel.Include(sel.AllData())
return sel return sel
} }
@ -149,9 +145,9 @@ func IncludeExchangeRestoreDataSelectors(opts ExchangeOpts) *selectors.ExchangeR
opts.EmailFolder = trimFolderSlash(opts.EmailFolder) opts.EmailFolder = trimFolderSlash(opts.EmailFolder)
// or add selectors for each type of data // or add selectors for each type of data
AddExchangeInclude(sel, users, opts.ContactFolder, opts.Contact, sel.Contacts) AddExchangeInclude(sel, opts.ContactFolder, opts.Contact, sel.Contacts)
AddExchangeInclude(sel, users, opts.EmailFolder, opts.Email, sel.Mails) AddExchangeInclude(sel, opts.EmailFolder, opts.Email, sel.Mails)
AddExchangeInclude(sel, users, opts.EventCalendar, opts.Event, sel.Events) AddExchangeInclude(sel, opts.EventCalendar, opts.Event, sel.Events)
return sel return sel
} }

View File

@ -370,7 +370,7 @@ func (suite *ExchangeUtilsSuite) TestAddExchangeInclude() {
suite.T().Run(test.name, func(t *testing.T) { suite.T().Run(test.name, func(t *testing.T) {
sel := selectors.NewExchangeRestore(nil) sel := selectors.NewExchangeRestore(nil)
// no return, mutates sel as a side effect // no return, mutates sel as a side effect
utils.AddExchangeInclude(sel, test.resources, test.folders, test.items, eisc) utils.AddExchangeInclude(sel, test.folders, test.items, eisc)
assert.Len(t, sel.Includes, test.expectIncludeLen) assert.Len(t, sel.Includes, test.expectIncludeLen)
}) })
} }

View File

@ -83,7 +83,7 @@ func IncludeOneDriveRestoreDataSelectors(opts OneDriveOpts) *selectors.OneDriveR
// only use the inclusion if either a path or item name // only use the inclusion if either a path or item name
// is specified // is specified
if lp+ln == 0 { if lp+ln == 0 {
sel.Include(sel.Users(opts.Users)) sel.Include(sel.AllData())
return sel return sel
} }
@ -97,11 +97,11 @@ func IncludeOneDriveRestoreDataSelectors(opts OneDriveOpts) *selectors.OneDriveR
containsFolders, prefixFolders := splitFoldersIntoContainsAndPrefix(opts.Paths) containsFolders, prefixFolders := splitFoldersIntoContainsAndPrefix(opts.Paths)
if len(containsFolders) > 0 { if len(containsFolders) > 0 {
sel.Include(sel.Items(users, containsFolders, opts.Names)) sel.Include(sel.Items(containsFolders, opts.Names))
} }
if len(prefixFolders) > 0 { if len(prefixFolders) > 0 {
sel.Include(sel.Items(users, prefixFolders, opts.Names, selectors.PrefixMatch())) sel.Include(sel.Items(prefixFolders, opts.Names, selectors.PrefixMatch()))
} }
return sel return sel

View File

@ -68,7 +68,7 @@ func IncludeSharePointRestoreDataSelectors(opts SharePointOpts) *selectors.Share
sel := selectors.NewSharePointRestore(sites) sel := selectors.NewSharePointRestore(sites)
if lp+li+lwu+slp+sli == 0 { if lp+li+lwu+slp+sli == 0 {
sel.Include(sel.Sites(sites)) sel.Include(sel.AllData())
return sel return sel
} }
@ -81,11 +81,11 @@ func IncludeSharePointRestoreDataSelectors(opts SharePointOpts) *selectors.Share
containsFolders, prefixFolders := splitFoldersIntoContainsAndPrefix(opts.LibraryPaths) containsFolders, prefixFolders := splitFoldersIntoContainsAndPrefix(opts.LibraryPaths)
if len(containsFolders) > 0 { if len(containsFolders) > 0 {
sel.Include(sel.LibraryItems(sites, containsFolders, opts.LibraryItems)) sel.Include(sel.LibraryItems(containsFolders, opts.LibraryItems))
} }
if len(prefixFolders) > 0 { if len(prefixFolders) > 0 {
sel.Include(sel.LibraryItems(sites, prefixFolders, opts.LibraryItems, selectors.PrefixMatch())) sel.Include(sel.LibraryItems(prefixFolders, opts.LibraryItems, selectors.PrefixMatch()))
} }
} }
@ -98,11 +98,11 @@ func IncludeSharePointRestoreDataSelectors(opts SharePointOpts) *selectors.Share
containsFolders, prefixFolders := splitFoldersIntoContainsAndPrefix(opts.ListPaths) containsFolders, prefixFolders := splitFoldersIntoContainsAndPrefix(opts.ListPaths)
if len(containsFolders) > 0 { if len(containsFolders) > 0 {
sel.Include(sel.ListItems(opts.Sites, containsFolders, opts.ListItems)) sel.Include(sel.ListItems(containsFolders, opts.ListItems))
} }
if len(prefixFolders) > 0 { if len(prefixFolders) > 0 {
sel.Include(sel.ListItems(opts.Sites, prefixFolders, opts.ListItems, selectors.PrefixMatch())) sel.Include(sel.ListItems(prefixFolders, opts.ListItems, selectors.PrefixMatch()))
} }
} }

View File

@ -106,14 +106,18 @@ func verifyBackupInputs(sels selectors.Selector, userPNs, siteIDs []string) erro
ids = siteIDs ids = siteIDs
} }
// verify resourceOwners resourceOwner := strings.ToLower(sels.DiscreteOwner)
normROs := map[string]struct{}{}
var found bool
for _, id := range ids { for _, id := range ids {
normROs[strings.ToLower(id)] = struct{}{} if strings.ToLower(id) == resourceOwner {
found = true
break
}
} }
if _, ok := normROs[strings.ToLower(sels.DiscreteOwner)]; !ok { if !found {
return fmt.Errorf("resource owner [%s] not found within tenant", sels.DiscreteOwner) return fmt.Errorf("resource owner [%s] not found within tenant", sels.DiscreteOwner)
} }

View File

@ -70,7 +70,7 @@ func (suite *ConnectorDataCollectionIntegrationSuite) TestExchangeDataCollection
name: suite.user + " Email", name: suite.user + " Email",
getSelector: func(t *testing.T) selectors.Selector { getSelector: func(t *testing.T) selectors.Selector {
sel := selectors.NewExchangeBackup(selUsers) sel := selectors.NewExchangeBackup(selUsers)
sel.Include(sel.MailFolders(selUsers, []string{exchange.DefaultMailFolder}, selectors.PrefixMatch())) sel.Include(sel.MailFolders([]string{exchange.DefaultMailFolder}, selectors.PrefixMatch()))
sel.DiscreteOwner = suite.user sel.DiscreteOwner = suite.user
return sel.Selector return sel.Selector
}, },
@ -79,7 +79,7 @@ func (suite *ConnectorDataCollectionIntegrationSuite) TestExchangeDataCollection
name: suite.user + " Contacts", name: suite.user + " Contacts",
getSelector: func(t *testing.T) selectors.Selector { getSelector: func(t *testing.T) selectors.Selector {
sel := selectors.NewExchangeBackup(selUsers) sel := selectors.NewExchangeBackup(selUsers)
sel.Include(sel.ContactFolders(selUsers, []string{exchange.DefaultContactFolder}, selectors.PrefixMatch())) sel.Include(sel.ContactFolders([]string{exchange.DefaultContactFolder}, selectors.PrefixMatch()))
sel.DiscreteOwner = suite.user sel.DiscreteOwner = suite.user
return sel.Selector return sel.Selector
}, },
@ -88,7 +88,7 @@ func (suite *ConnectorDataCollectionIntegrationSuite) TestExchangeDataCollection
// name: suite.user + " Events", // name: suite.user + " Events",
// getSelector: func(t *testing.T) selectors.Selector { // getSelector: func(t *testing.T) selectors.Selector {
// sel := selectors.NewExchangeBackup(selUsers) // sel := selectors.NewExchangeBackup(selUsers)
// sel.Include(sel.EventCalendars(selUsers, []string{exchange.DefaultCalendar}, selectors.PrefixMatch())) // sel.Include(sel.EventCalendars([]string{exchange.DefaultCalendar}, selectors.PrefixMatch()))
// sel.DiscreteOwner = suite.user // sel.DiscreteOwner = suite.user
// return sel.Selector // return sel.Selector
// }, // },
@ -146,7 +146,7 @@ func (suite *ConnectorDataCollectionIntegrationSuite) TestDataCollections_invali
name: "invalid exchange backup user", name: "invalid exchange backup user",
getSelector: func(t *testing.T) selectors.Selector { getSelector: func(t *testing.T) selectors.Selector {
sel := selectors.NewExchangeBackup(owners) sel := selectors.NewExchangeBackup(owners)
sel.Include(sel.MailFolders(owners, selectors.Any())) sel.Include(sel.MailFolders(selectors.Any()))
return sel.Selector return sel.Selector
}, },
}, },
@ -154,7 +154,7 @@ func (suite *ConnectorDataCollectionIntegrationSuite) TestDataCollections_invali
name: "Invalid onedrive backup user", name: "Invalid onedrive backup user",
getSelector: func(t *testing.T) selectors.Selector { getSelector: func(t *testing.T) selectors.Selector {
sel := selectors.NewOneDriveBackup(owners) sel := selectors.NewOneDriveBackup(owners)
sel.Include(sel.Folders(owners, selectors.Any())) sel.Include(sel.Folders(selectors.Any()))
return sel.Selector return sel.Selector
}, },
}, },
@ -162,7 +162,7 @@ func (suite *ConnectorDataCollectionIntegrationSuite) TestDataCollections_invali
name: "Invalid sharepoint backup site", name: "Invalid sharepoint backup site",
getSelector: func(t *testing.T) selectors.Selector { getSelector: func(t *testing.T) selectors.Selector {
sel := selectors.NewSharePointBackup(owners) sel := selectors.NewSharePointBackup(owners)
sel.Include(sel.Libraries(owners, selectors.Any())) sel.Include(sel.Libraries(selectors.Any()))
return sel.Selector return sel.Selector
}, },
}, },
@ -170,7 +170,7 @@ func (suite *ConnectorDataCollectionIntegrationSuite) TestDataCollections_invali
name: "missing exchange backup user", name: "missing exchange backup user",
getSelector: func(t *testing.T) selectors.Selector { getSelector: func(t *testing.T) selectors.Selector {
sel := selectors.NewExchangeBackup(owners) sel := selectors.NewExchangeBackup(owners)
sel.Include(sel.MailFolders(owners, selectors.Any())) sel.Include(sel.MailFolders(selectors.Any()))
sel.DiscreteOwner = "" sel.DiscreteOwner = ""
return sel.Selector return sel.Selector
}, },
@ -179,7 +179,7 @@ func (suite *ConnectorDataCollectionIntegrationSuite) TestDataCollections_invali
name: "missing onedrive backup user", name: "missing onedrive backup user",
getSelector: func(t *testing.T) selectors.Selector { getSelector: func(t *testing.T) selectors.Selector {
sel := selectors.NewOneDriveBackup(owners) sel := selectors.NewOneDriveBackup(owners)
sel.Include(sel.Folders(owners, selectors.Any())) sel.Include(sel.Folders(selectors.Any()))
sel.DiscreteOwner = "" sel.DiscreteOwner = ""
return sel.Selector return sel.Selector
}, },
@ -188,7 +188,7 @@ func (suite *ConnectorDataCollectionIntegrationSuite) TestDataCollections_invali
name: "missing sharepoint backup site", name: "missing sharepoint backup site",
getSelector: func(t *testing.T) selectors.Selector { getSelector: func(t *testing.T) selectors.Selector {
sel := selectors.NewSharePointBackup(owners) sel := selectors.NewSharePointBackup(owners)
sel.Include(sel.Libraries(owners, selectors.Any())) sel.Include(sel.Libraries(selectors.Any()))
sel.DiscreteOwner = "" sel.DiscreteOwner = ""
return sel.Selector return sel.Selector
}, },
@ -223,9 +223,7 @@ func (suite *ConnectorDataCollectionIntegrationSuite) TestSharePointDataCollecti
name: "Libraries", name: "Libraries",
getSelector: func() selectors.Selector { getSelector: func() selectors.Selector {
sel := selectors.NewSharePointBackup(selSites) sel := selectors.NewSharePointBackup(selSites)
sel.Include(sel.Libraries(selSites, selectors.Any())) sel.Include(sel.Libraries(selectors.Any()))
sel.DiscreteOwner = suite.site
return sel.Selector return sel.Selector
}, },
}, },
@ -234,9 +232,7 @@ func (suite *ConnectorDataCollectionIntegrationSuite) TestSharePointDataCollecti
expected: 0, expected: 0,
getSelector: func() selectors.Selector { getSelector: func() selectors.Selector {
sel := selectors.NewSharePointBackup(selSites) sel := selectors.NewSharePointBackup(selSites)
sel.Include(sel.Lists(selSites, selectors.Any())) sel.Include(sel.Lists(selectors.Any()))
sel.DiscreteOwner = suite.site
return sel.Selector return sel.Selector
}, },
}, },
@ -330,12 +326,7 @@ func (suite *ConnectorCreateSharePointCollectionIntegrationSuite) TestCreateShar
comparator: assert.Equal, comparator: assert.Equal,
sel: func() selectors.Selector { sel: func() selectors.Selector {
sel := selectors.NewSharePointBackup(siteIDs) sel := selectors.NewSharePointBackup(siteIDs)
sel.Include(sel.Libraries( sel.Include(sel.Libraries([]string{"foo"}, selectors.PrefixMatch()))
siteIDs,
[]string{"foo"},
selectors.PrefixMatch(),
))
return sel.Selector return sel.Selector
}, },
}, },
@ -344,11 +335,7 @@ func (suite *ConnectorCreateSharePointCollectionIntegrationSuite) TestCreateShar
comparator: assert.Less, comparator: assert.Less,
sel: func() selectors.Selector { sel: func() selectors.Selector {
sel := selectors.NewSharePointBackup(siteIDs) sel := selectors.NewSharePointBackup(siteIDs)
sel.Include(sel.Lists( sel.Include(sel.Lists(selectors.Any(), selectors.PrefixMatch()))
siteIDs,
selectors.Any(),
selectors.PrefixMatch(), // without this option a SEG Fault occurs
))
return sel.Selector return sel.Selector
}, },

View File

@ -246,7 +246,6 @@ func (suite *DataCollectionsIntegrationSuite) TestMailFetch() {
{ {
name: "Folder Iterative Check Mail", name: "Folder Iterative Check Mail",
scope: selectors.NewExchangeBackup(users).MailFolders( scope: selectors.NewExchangeBackup(users).MailFolders(
users,
[]string{DefaultMailFolder}, []string{DefaultMailFolder},
selectors.PrefixMatch(), selectors.PrefixMatch(),
)[0], )[0],
@ -303,7 +302,6 @@ func (suite *DataCollectionsIntegrationSuite) TestDelta() {
{ {
name: "Mail", name: "Mail",
scope: selectors.NewExchangeBackup(users).MailFolders( scope: selectors.NewExchangeBackup(users).MailFolders(
[]string{userID},
[]string{DefaultMailFolder}, []string{DefaultMailFolder},
selectors.PrefixMatch(), selectors.PrefixMatch(),
)[0], )[0],
@ -311,7 +309,6 @@ func (suite *DataCollectionsIntegrationSuite) TestDelta() {
{ {
name: "Contacts", name: "Contacts",
scope: selectors.NewExchangeBackup(users).ContactFolders( scope: selectors.NewExchangeBackup(users).ContactFolders(
[]string{userID},
[]string{DefaultContactFolder}, []string{DefaultContactFolder},
selectors.PrefixMatch(), selectors.PrefixMatch(),
)[0], )[0],
@ -391,7 +388,7 @@ func (suite *DataCollectionsIntegrationSuite) TestMailSerializationRegression()
require.NoError(t, err) require.NoError(t, err)
sel := selectors.NewExchangeBackup(users) sel := selectors.NewExchangeBackup(users)
sel.Include(sel.MailFolders(users, []string{DefaultMailFolder}, selectors.PrefixMatch())) sel.Include(sel.MailFolders([]string{DefaultMailFolder}, selectors.PrefixMatch()))
collections, err := createCollections( collections, err := createCollections(
ctx, ctx,
@ -451,7 +448,6 @@ func (suite *DataCollectionsIntegrationSuite) TestContactSerializationRegression
{ {
name: "Default Contact Folder", name: "Default Contact Folder",
scope: selectors.NewExchangeBackup(users).ContactFolders( scope: selectors.NewExchangeBackup(users).ContactFolders(
users,
[]string{DefaultContactFolder}, []string{DefaultContactFolder},
selectors.PrefixMatch())[0], selectors.PrefixMatch())[0],
}, },
@ -528,7 +524,6 @@ func (suite *DataCollectionsIntegrationSuite) TestEventsSerializationRegression(
name: "Default Event Calendar", name: "Default Event Calendar",
expected: DefaultCalendar, expected: DefaultCalendar,
scope: selectors.NewExchangeBackup(users).EventCalendars( scope: selectors.NewExchangeBackup(users).EventCalendars(
users,
[]string{DefaultCalendar}, []string{DefaultCalendar},
selectors.PrefixMatch())[0], selectors.PrefixMatch())[0],
}, },
@ -536,7 +531,6 @@ func (suite *DataCollectionsIntegrationSuite) TestEventsSerializationRegression(
name: "Birthday Calendar", name: "Birthday Calendar",
expected: "Birthdays", expected: "Birthdays",
scope: selectors.NewExchangeBackup(users).EventCalendars( scope: selectors.NewExchangeBackup(users).EventCalendars(
users,
[]string{"Birthdays"}, []string{"Birthdays"},
selectors.PrefixMatch())[0], selectors.PrefixMatch())[0],
}, },

View File

@ -216,8 +216,8 @@ func (suite *DisconnectedGraphConnectorSuite) TestVerifyBackupInputs() {
name: "Valid Single User", name: "Valid Single User",
checkError: assert.NoError, checkError: assert.NoError,
getSelector: func(t *testing.T) selectors.Selector { getSelector: func(t *testing.T) selectors.Selector {
sel := selectors.NewExchangeBackup([]string{"bobkelso@someHospital.org"}) sel := selectors.NewExchangeBackup([]string{"bobKelso@someHospital.org"})
sel.Include(sel.MailFolders([]string{"bobkelso@someHospital.org"}, selectors.Any())) sel.Include(sel.MailFolders(selectors.Any()))
return sel.Selector return sel.Selector
}, },
}, },
@ -226,11 +226,20 @@ func (suite *DisconnectedGraphConnectorSuite) TestVerifyBackupInputs() {
checkError: assert.Error, checkError: assert.Error,
getSelector: func(t *testing.T) selectors.Selector { getSelector: func(t *testing.T) selectors.Selector {
sel := selectors.NewExchangeBackup([]string{"bobkelso@someHospital.org", "janitor@someHospital.org"}) sel := selectors.NewExchangeBackup([]string{"bobkelso@someHospital.org", "janitor@someHospital.org"})
sel.Include(sel.MailFolders([]string{"bobkelso@someHospital.org", "janitor@someHospital.org"}, selectors.Any())) sel.Include(sel.MailFolders(selectors.Any()))
sel.DiscreteOwner = "janitor@someHospital.org" sel.DiscreteOwner = "janitor@someHospital.org"
return sel.Selector return sel.Selector
}, },
}, },
{
name: "Invalid discrete owner",
checkError: assert.Error,
getSelector: func(t *testing.T) selectors.Selector {
sel := selectors.NewOneDriveBackup([]string{"janitor@someHospital.org"})
sel.Include(sel.AllData())
return sel.Selector
},
},
} }
for _, test := range tests { for _, test := range tests {
@ -257,19 +266,19 @@ func (suite *DisconnectedGraphConnectorSuite) TestVerifyBackupInputs_allServices
checkError: assert.NoError, checkError: assert.NoError,
excludes: func(t *testing.T) selectors.Selector { excludes: func(t *testing.T) selectors.Selector {
sel := selectors.NewOneDriveBackup([]string{"elliotReid@someHospital.org", "foo@SomeCompany.org"}) sel := selectors.NewOneDriveBackup([]string{"elliotReid@someHospital.org", "foo@SomeCompany.org"})
sel.Exclude(sel.Folders([]string{"elliotReid@someHospital.org"}, selectors.Any())) sel.Exclude(sel.Folders(selectors.Any()))
sel.DiscreteOwner = "elliotReid@someHospital.org" sel.DiscreteOwner = "elliotReid@someHospital.org"
return sel.Selector return sel.Selector
}, },
filters: func(t *testing.T) selectors.Selector { filters: func(t *testing.T) selectors.Selector {
sel := selectors.NewOneDriveBackup([]string{"elliotReid@someHospital.org", "foo@SomeCompany.org"}) sel := selectors.NewOneDriveBackup([]string{"elliotReid@someHospital.org", "foo@SomeCompany.org"})
sel.Filter(sel.Folders([]string{"elliotReid@someHospital.org"}, selectors.Any())) sel.Filter(sel.Folders(selectors.Any()))
sel.DiscreteOwner = "elliotReid@someHospital.org" sel.DiscreteOwner = "elliotReid@someHospital.org"
return sel.Selector return sel.Selector
}, },
includes: func(t *testing.T) selectors.Selector { includes: func(t *testing.T) selectors.Selector {
sel := selectors.NewOneDriveBackup([]string{"elliotReid@someHospital.org", "foo@SomeCompany.org"}) sel := selectors.NewOneDriveBackup([]string{"elliotReid@someHospital.org", "foo@SomeCompany.org"})
sel.Include(sel.Folders([]string{"elliotReid@someHospital.org"}, selectors.Any())) sel.Include(sel.Folders(selectors.Any()))
sel.DiscreteOwner = "elliotReid@someHospital.org" sel.DiscreteOwner = "elliotReid@someHospital.org"
return sel.Selector return sel.Selector
}, },
@ -279,17 +288,17 @@ func (suite *DisconnectedGraphConnectorSuite) TestVerifyBackupInputs_allServices
checkError: assert.Error, checkError: assert.Error,
excludes: func(t *testing.T) selectors.Selector { excludes: func(t *testing.T) selectors.Selector {
sel := selectors.NewOneDriveBackup([]string{"foo@SomeCompany.org"}) sel := selectors.NewOneDriveBackup([]string{"foo@SomeCompany.org"})
sel.Exclude(sel.Folders([]string{"foo@SomeCompany.org"}, selectors.Any())) sel.Exclude(sel.Folders(selectors.Any()))
return sel.Selector return sel.Selector
}, },
filters: func(t *testing.T) selectors.Selector { filters: func(t *testing.T) selectors.Selector {
sel := selectors.NewOneDriveBackup([]string{"foo@SomeCompany.org"}) sel := selectors.NewOneDriveBackup([]string{"foo@SomeCompany.org"})
sel.Filter(sel.Folders([]string{"foo@SomeCompany.org"}, selectors.Any())) sel.Filter(sel.Folders(selectors.Any()))
return sel.Selector return sel.Selector
}, },
includes: func(t *testing.T) selectors.Selector { includes: func(t *testing.T) selectors.Selector {
sel := selectors.NewOneDriveBackup([]string{"foo@SomeCompany.org"}) sel := selectors.NewOneDriveBackup([]string{"foo@SomeCompany.org"})
sel.Include(sel.Folders([]string{"foo@SomeCompany.org"}, selectors.Any())) sel.Include(sel.Folders(selectors.Any()))
return sel.Selector return sel.Selector
}, },
}, },
@ -298,20 +307,20 @@ func (suite *DisconnectedGraphConnectorSuite) TestVerifyBackupInputs_allServices
checkError: assert.NoError, checkError: assert.NoError,
excludes: func(t *testing.T) selectors.Selector { excludes: func(t *testing.T) selectors.Selector {
sel := selectors.NewSharePointBackup([]string{"abc.site.foo", "bar.site.baz"}) sel := selectors.NewSharePointBackup([]string{"abc.site.foo", "bar.site.baz"})
sel.Exclude(sel.Sites([]string{"abc.site.foo", "bar.site.baz"}))
sel.DiscreteOwner = "abc.site.foo" sel.DiscreteOwner = "abc.site.foo"
sel.Exclude(sel.AllData())
return sel.Selector return sel.Selector
}, },
filters: func(t *testing.T) selectors.Selector { filters: func(t *testing.T) selectors.Selector {
sel := selectors.NewSharePointBackup([]string{"abc.site.foo", "bar.site.baz"}) sel := selectors.NewSharePointBackup([]string{"abc.site.foo", "bar.site.baz"})
sel.Filter(sel.Sites([]string{"abc.site.foo", "bar.site.baz"}))
sel.DiscreteOwner = "abc.site.foo" sel.DiscreteOwner = "abc.site.foo"
sel.Filter(sel.AllData())
return sel.Selector return sel.Selector
}, },
includes: func(t *testing.T) selectors.Selector { includes: func(t *testing.T) selectors.Selector {
sel := selectors.NewSharePointBackup([]string{"abc.site.foo", "bar.site.baz"}) sel := selectors.NewSharePointBackup([]string{"abc.site.foo", "bar.site.baz"})
sel.Include(sel.Sites([]string{"abc.site.foo", "bar.site.baz"}))
sel.DiscreteOwner = "abc.site.foo" sel.DiscreteOwner = "abc.site.foo"
sel.Include(sel.AllData())
return sel.Selector return sel.Selector
}, },
}, },
@ -320,20 +329,17 @@ func (suite *DisconnectedGraphConnectorSuite) TestVerifyBackupInputs_allServices
checkError: assert.Error, checkError: assert.Error,
excludes: func(t *testing.T) selectors.Selector { excludes: func(t *testing.T) selectors.Selector {
sel := selectors.NewSharePointBackup([]string{"fnords.smarfs.brawnhilda"}) sel := selectors.NewSharePointBackup([]string{"fnords.smarfs.brawnhilda"})
sel.Exclude(sel.Sites([]string{"fnords.smarfs.brawnhilda"})) sel.Exclude(sel.AllData())
sel.DiscreteOwner = "fnords.smarfs.brawnhilda"
return sel.Selector return sel.Selector
}, },
filters: func(t *testing.T) selectors.Selector { filters: func(t *testing.T) selectors.Selector {
sel := selectors.NewSharePointBackup([]string{"fnords.smarfs.brawnhilda"}) sel := selectors.NewSharePointBackup([]string{"fnords.smarfs.brawnhilda"})
sel.Filter(sel.Sites([]string{"fnords.smarfs.brawnhilda"})) sel.Filter(sel.AllData())
sel.DiscreteOwner = "fnords.smarfs.brawnhilda"
return sel.Selector return sel.Selector
}, },
includes: func(t *testing.T) selectors.Selector { includes: func(t *testing.T) selectors.Selector {
sel := selectors.NewSharePointBackup([]string{"fnords.smarfs.brawnhilda"}) sel := selectors.NewSharePointBackup([]string{"fnords.smarfs.brawnhilda"})
sel.Include(sel.Sites([]string{"fnords.smarfs.brawnhilda"})) sel.Include(sel.AllData())
sel.DiscreteOwner = "fnords.smarfs.brawnhilda"
return sel.Selector return sel.Selector
}, },
}, },

View File

@ -798,7 +798,6 @@ func makeExchangeBackupSel(
} }
toInclude = append(toInclude, builder( toInclude = append(toInclude, builder(
[]string{d.resourceOwner},
[]string{d.dest}, []string{d.dest},
selectors.PrefixMatch(), selectors.PrefixMatch(),
)) ))
@ -826,7 +825,6 @@ func makeOneDriveBackupSel(
sel := selectors.NewOneDriveBackup(nil) sel := selectors.NewOneDriveBackup(nil)
toInclude = append(toInclude, sel.Folders( toInclude = append(toInclude, sel.Folders(
[]string{d.resourceOwner},
[]string{d.dest}, []string{d.dest},
selectors.PrefixMatch(), selectors.PrefixMatch(),
)) ))

View File

@ -83,7 +83,7 @@ func (suite *OneDriveCollectionsSuite) TestGetCanonicalPath() {
} }
func (suite *OneDriveCollectionsSuite) TestUpdateCollections() { func (suite *OneDriveCollectionsSuite) TestUpdateCollections() {
anyFolder := (&selectors.OneDriveBackup{}).Folders(selectors.Any(), selectors.Any())[0] anyFolder := (&selectors.OneDriveBackup{}).Folders(selectors.Any())[0]
const ( const (
tenant = "tenant" tenant = "tenant"
@ -181,7 +181,7 @@ func (suite *OneDriveCollectionsSuite) TestUpdateCollections() {
driveItem("fileInFolder2", testBaseDrivePath+folderSub+folder, true, false, false), driveItem("fileInFolder2", testBaseDrivePath+folderSub+folder, true, false, false),
driveItem("fileInPackage", testBaseDrivePath+pkg, true, false, false), driveItem("fileInPackage", testBaseDrivePath+pkg, true, false, false),
}, },
scope: (&selectors.OneDriveBackup{}).Folders(selectors.Any(), []string{"folder"})[0], scope: (&selectors.OneDriveBackup{}).Folders([]string{"folder"})[0],
expect: assert.NoError, expect: assert.NoError,
expectedCollectionPaths: append( expectedCollectionPaths: append(
expectedPathAsSlice( expectedPathAsSlice(
@ -214,7 +214,7 @@ func (suite *OneDriveCollectionsSuite) TestUpdateCollections() {
driveItem("fileInPackage", testBaseDrivePath+pkg, true, false, false), driveItem("fileInPackage", testBaseDrivePath+pkg, true, false, false),
}, },
scope: (&selectors.OneDriveBackup{}). scope: (&selectors.OneDriveBackup{}).
Folders(selectors.Any(), []string{"/folder/subfolder"}, selectors.PrefixMatch())[0], Folders([]string{"/folder/subfolder"}, selectors.PrefixMatch())[0],
expect: assert.NoError, expect: assert.NoError,
expectedCollectionPaths: expectedPathAsSlice( expectedCollectionPaths: expectedPathAsSlice(
suite.T(), suite.T(),
@ -237,7 +237,7 @@ func (suite *OneDriveCollectionsSuite) TestUpdateCollections() {
driveItem("fileInSubfolder", testBaseDrivePath+folderSub, true, false, false), driveItem("fileInSubfolder", testBaseDrivePath+folderSub, true, false, false),
driveItem("fileInPackage", testBaseDrivePath+pkg, true, false, false), driveItem("fileInPackage", testBaseDrivePath+pkg, true, false, false),
}, },
scope: (&selectors.OneDriveBackup{}).Folders(selectors.Any(), []string{"folder/subfolder"})[0], scope: (&selectors.OneDriveBackup{}).Folders([]string{"folder/subfolder"})[0],
expect: assert.NoError, expect: assert.NoError,
expectedCollectionPaths: expectedPathAsSlice( expectedCollectionPaths: expectedPathAsSlice(
suite.T(), suite.T(),

View File

@ -144,7 +144,7 @@ func (suite *OneDriveSuite) TestOneDriveNewCollections() {
service := loadTestService(t) service := loadTestService(t)
scope := selectors. scope := selectors.
NewOneDriveBackup([]string{test.user}). NewOneDriveBackup([]string{test.user}).
Users([]string{test.user})[0] AllData()[0]
odcs, err := NewCollections( odcs, err := NewCollections(
creds.AzureTenantID, creds.AzureTenantID,
test.user, test.user,

View File

@ -58,7 +58,6 @@ func DataCollections(
serv, serv,
tenantID, tenantID,
site, site,
scope,
su, su,
ctrlOpts) ctrlOpts)
if err != nil { if err != nil {
@ -90,13 +89,11 @@ func collectLists(
ctx context.Context, ctx context.Context,
serv graph.Servicer, serv graph.Servicer,
tenantID, siteID string, tenantID, siteID string,
scope selectors.SharePointScope,
updater statusUpdater, updater statusUpdater,
ctrlOpts control.Options, ctrlOpts control.Options,
) ([]data.Collection, error) { ) ([]data.Collection, error) {
logger.Ctx(ctx).With("site", siteID).Debug("Creating SharePoint List Collections") logger.Ctx(ctx).With("site", siteID).Debug("Creating SharePoint List Collections")
if scope.Matches(selectors.SharePointSite, siteID) {
spcs := make([]data.Collection, 0) spcs := make([]data.Collection, 0)
tuples, err := preFetchLists(ctx, serv, siteID) tuples, err := preFetchLists(ctx, serv, siteID)
@ -122,9 +119,6 @@ func collectLists(
} }
return spcs, nil return spcs, nil
}
return nil, nil
} }
// collectLibraries constructs a onedrive Collections struct and Get()s // collectLibraries constructs a onedrive Collections struct and Get()s

View File

@ -46,7 +46,7 @@ func TestSharePointLibrariesSuite(t *testing.T) {
} }
func (suite *SharePointLibrariesSuite) TestUpdateCollections() { func (suite *SharePointLibrariesSuite) TestUpdateCollections() {
anyFolder := (&selectors.SharePointBackup{}).Libraries(selectors.Any(), selectors.Any())[0] anyFolder := (&selectors.SharePointBackup{}).Libraries(selectors.Any())[0]
const ( const (
tenant = "tenant" tenant = "tenant"

View File

@ -515,7 +515,7 @@ func (suite *BackupOpIntegrationSuite) TestBackup_Run_exchange() {
name: "Mail", name: "Mail",
selector: func() *selectors.ExchangeBackup { selector: func() *selectors.ExchangeBackup {
sel := selectors.NewExchangeBackup(users) sel := selectors.NewExchangeBackup(users)
sel.Include(sel.MailFolders(users, []string{exchange.DefaultMailFolder}, selectors.PrefixMatch())) sel.Include(sel.MailFolders([]string{exchange.DefaultMailFolder}, selectors.PrefixMatch()))
sel.DiscreteOwner = suite.user sel.DiscreteOwner = suite.user
return sel return sel
@ -529,12 +529,7 @@ func (suite *BackupOpIntegrationSuite) TestBackup_Run_exchange() {
name: "Contacts", name: "Contacts",
selector: func() *selectors.ExchangeBackup { selector: func() *selectors.ExchangeBackup {
sel := selectors.NewExchangeBackup(users) sel := selectors.NewExchangeBackup(users)
sel.Include(sel.ContactFolders( sel.Include(sel.ContactFolders([]string{exchange.DefaultContactFolder}, selectors.PrefixMatch()))
users,
[]string{exchange.DefaultContactFolder},
selectors.PrefixMatch()))
sel.DiscreteOwner = suite.user
return sel return sel
}, },
resourceOwner: suite.user, resourceOwner: suite.user,
@ -546,9 +541,7 @@ func (suite *BackupOpIntegrationSuite) TestBackup_Run_exchange() {
name: "Calendar Events", name: "Calendar Events",
selector: func() *selectors.ExchangeBackup { selector: func() *selectors.ExchangeBackup {
sel := selectors.NewExchangeBackup(users) sel := selectors.NewExchangeBackup(users)
sel.Include(sel.EventCalendars(users, []string{exchange.DefaultCalendar}, selectors.PrefixMatch())) sel.Include(sel.EventCalendars([]string{exchange.DefaultCalendar}, selectors.PrefixMatch()))
sel.DiscreteOwner = suite.user
return sel return sel
}, },
resourceOwner: suite.user, resourceOwner: suite.user,
@ -755,8 +748,8 @@ func (suite *BackupOpIntegrationSuite) TestBackup_Run_exchangeIncrementals() {
containers := []string{container1, container2, container3, containerRename} containers := []string{container1, container2, container3, containerRename}
sel := selectors.NewExchangeBackup(users) sel := selectors.NewExchangeBackup(users)
sel.Include( sel.Include(
sel.MailFolders(users, containers, selectors.PrefixMatch()), sel.MailFolders(containers, selectors.PrefixMatch()),
sel.ContactFolders(users, containers, selectors.PrefixMatch()), sel.ContactFolders(containers, selectors.PrefixMatch()),
) )
bo, _, kw, ms, closer := prepNewTestBackupOp(t, ctx, mb, sel.Selector, ffs) bo, _, kw, ms, closer := prepNewTestBackupOp(t, ctx, mb, sel.Selector, ffs)
@ -1015,7 +1008,7 @@ func (suite *BackupOpIntegrationSuite) TestBackup_Run_oneDrive() {
sel = selectors.NewOneDriveBackup([]string{m365UserID}) sel = selectors.NewOneDriveBackup([]string{m365UserID})
) )
sel.Include(sel.Users([]string{m365UserID})) sel.Include(sel.AllData())
bo, _, _, _, closer := prepNewTestBackupOp(t, ctx, mb, sel.Selector, control.FeatureFlags{}) bo, _, _, _, closer := prepNewTestBackupOp(t, ctx, mb, sel.Selector, control.FeatureFlags{})
defer closer() defer closer()
@ -1037,7 +1030,7 @@ func (suite *BackupOpIntegrationSuite) TestBackup_Run_sharePoint() {
sel = selectors.NewSharePointBackup([]string{suite.site}) sel = selectors.NewSharePointBackup([]string{suite.site})
) )
sel.Include(sel.Sites([]string{suite.site})) sel.Include(sel.AllData())
bo, _, _, _, closer := prepNewTestBackupOp(t, ctx, mb, sel.Selector, control.FeatureFlags{}) bo, _, _, _, closer := prepNewTestBackupOp(t, ctx, mb, sel.Selector, control.FeatureFlags{})
defer closer() defer closer()

View File

@ -180,9 +180,9 @@ func (suite *RestoreOpIntegrationSuite) SetupSuite() {
bsel := selectors.NewExchangeBackup(users) bsel := selectors.NewExchangeBackup(users)
bsel.DiscreteOwner = m365UserID bsel.DiscreteOwner = m365UserID
bsel.Include( bsel.Include(
bsel.MailFolders(users, []string{exchange.DefaultMailFolder}, selectors.PrefixMatch()), bsel.MailFolders([]string{exchange.DefaultMailFolder}, selectors.PrefixMatch()),
bsel.ContactFolders(users, []string{exchange.DefaultContactFolder}, selectors.PrefixMatch()), bsel.ContactFolders([]string{exchange.DefaultContactFolder}, selectors.PrefixMatch()),
bsel.EventCalendars(users, []string{exchange.DefaultCalendar}, selectors.PrefixMatch()), bsel.EventCalendars([]string{exchange.DefaultCalendar}, selectors.PrefixMatch()),
) )
bo, err := NewBackupOperation( bo, err := NewBackupOperation(
@ -267,7 +267,7 @@ func (suite *RestoreOpIntegrationSuite) TestRestore_Run() {
users := []string{tester.M365UserID(t)} users := []string{tester.M365UserID(t)}
rsel := selectors.NewExchangeRestore(users) rsel := selectors.NewExchangeRestore(users)
rsel.Include(rsel.Users(users)) rsel.Include(rsel.AllData())
dest := tester.DefaultTestRestoreDestination() dest := tester.DefaultTestRestoreDestination()
mb := evmock.NewBus() mb := evmock.NewBus()
@ -309,7 +309,7 @@ func (suite *RestoreOpIntegrationSuite) TestRestore_Run_ErrorNoResults() {
t := suite.T() t := suite.T()
rsel := selectors.NewExchangeRestore(selectors.None()) rsel := selectors.NewExchangeRestore(selectors.None())
rsel.Include(rsel.Users(selectors.None())) rsel.Include(rsel.AllData())
dest := tester.DefaultTestRestoreDestination() dest := tester.DefaultTestRestoreDestination()
mb := evmock.NewBus() mb := evmock.NewBus()

View File

@ -26,7 +26,7 @@ func TestBackupSuite(t *testing.T) {
func stubBackup(t time.Time) backup.Backup { func stubBackup(t time.Time) backup.Backup {
sel := selectors.NewExchangeBackup(selectors.Any()) sel := selectors.NewExchangeBackup(selectors.Any())
sel.Include(sel.Users(selectors.Any())) sel.Include(sel.AllData())
return backup.Backup{ return backup.Backup{
BaseModel: model.BaseModel{ BaseModel: model.BaseModel{

View File

@ -396,9 +396,9 @@ func (suite *RepositoryLoadTestExchangeSuite) TestExchange() {
defer flush() defer flush()
bsel := selectors.NewExchangeBackup(suite.usersUnderTest) bsel := selectors.NewExchangeBackup(suite.usersUnderTest)
bsel.Include(bsel.MailFolders(suite.usersUnderTest, selectors.Any())) bsel.Include(bsel.MailFolders(selectors.Any()))
bsel.Include(bsel.ContactFolders(suite.usersUnderTest, selectors.Any())) bsel.Include(bsel.ContactFolders(selectors.Any()))
bsel.Include(bsel.EventCalendars(suite.usersUnderTest, selectors.Any())) bsel.Include(bsel.EventCalendars(selectors.Any()))
sel := bsel.Selector sel := bsel.Selector
runLoadTest( runLoadTest(
@ -444,9 +444,9 @@ func (suite *RepositoryIndividualLoadTestExchangeSuite) TestExchange() {
defer flush() defer flush()
bsel := selectors.NewExchangeBackup(suite.usersUnderTest) bsel := selectors.NewExchangeBackup(suite.usersUnderTest)
bsel.Include(bsel.MailFolders(suite.usersUnderTest, selectors.Any())) bsel.Include(bsel.MailFolders(selectors.Any()))
bsel.Include(bsel.ContactFolders(suite.usersUnderTest, selectors.Any())) bsel.Include(bsel.ContactFolders(selectors.Any()))
bsel.Include(bsel.EventCalendars(suite.usersUnderTest, selectors.Any())) bsel.Include(bsel.EventCalendars(selectors.Any()))
sel := bsel.Selector sel := bsel.Selector
runLoadTest( runLoadTest(
@ -494,7 +494,7 @@ func (suite *RepositoryLoadTestOneDriveSuite) TestOneDrive() {
defer flush() defer flush()
bsel := selectors.NewOneDriveBackup(suite.usersUnderTest) bsel := selectors.NewOneDriveBackup(suite.usersUnderTest)
bsel.Include(bsel.Users(suite.usersUnderTest)) bsel.Include(bsel.AllData())
sel := bsel.Selector sel := bsel.Selector
runLoadTest( runLoadTest(
@ -538,7 +538,7 @@ func (suite *RepositoryIndividualLoadTestOneDriveSuite) TestOneDrive() {
defer flush() defer flush()
bsel := selectors.NewOneDriveBackup(suite.usersUnderTest) bsel := selectors.NewOneDriveBackup(suite.usersUnderTest)
bsel.Include(bsel.Users(suite.usersUnderTest)) bsel.Include(bsel.AllData())
sel := bsel.Selector sel := bsel.Selector
runLoadTest( runLoadTest(
@ -586,7 +586,7 @@ func (suite *RepositoryLoadTestSharePointSuite) TestSharePoint() {
defer flush() defer flush()
bsel := selectors.NewSharePointBackup(suite.sitesUnderTest) bsel := selectors.NewSharePointBackup(suite.sitesUnderTest)
bsel.Include(bsel.Sites(suite.sitesUnderTest)) bsel.Include(bsel.AllData())
sel := bsel.Selector sel := bsel.Selector
runLoadTest( runLoadTest(
@ -630,7 +630,7 @@ func (suite *RepositoryIndividualLoadTestSharePointSuite) TestSharePoint() {
defer flush() defer flush()
bsel := selectors.NewSharePointBackup(suite.sitesUnderTest) bsel := selectors.NewSharePointBackup(suite.sitesUnderTest)
bsel.Include(bsel.Sites(suite.sitesUnderTest)) bsel.Include(bsel.AllData())
sel := bsel.Selector sel := bsel.Selector
runLoadTest( runLoadTest(

View File

@ -66,19 +66,19 @@ func Example_includeFoldersAndItems() {
// structures and individual items below. Higher level scopes will automatically // structures and individual items below. Higher level scopes will automatically
// involve all descendant data in the hierarchy. // involve all descendant data in the hierarchy.
// Users will select all Exchange data owned by the specified user. // AllData will select all Exchange data owned by the users specified
seb.Users([]string{"foo-user-id"}) // in the selector.
seb.AllData()
// Lower level Scopes are described on a per-data-type basis. This scope will // Lower level Scopes are described on a per-data-type basis. This scope will
// select all email in the Inbox folder, for all users in the tenant. // select all email in the Inbox folder, for all users in the tenant.
seb.MailFolders(selectors.Any(), []string{"Inbox"}) seb.MailFolders([]string{"Inbox"})
// Folder-level scopes will, by default, include every folder whose name matches // Folder-level scopes will, by default, include every folder whose name matches
// the provided value, regardless of its position in the hierarchy. If you want // the provided value, regardless of its position in the hierarchy. If you want
// to restrict the scope to a specific path, you can use the PrefixMatch option. // to restrict the scope to a specific path, you can use the PrefixMatch option.
// This scope selects all data in /foolder, but will skip /other/foolder. // This scope selects all data in /foolder, but will skip /other/foolder.
seb.MailFolders( seb.MailFolders(
selectors.Any(),
[]string{"foolder"}, []string{"foolder"},
selectors.PrefixMatch()) selectors.PrefixMatch())
@ -86,7 +86,6 @@ func Example_includeFoldersAndItems() {
// selection for users and folders when specifying an item, but these ids are // selection for users and folders when specifying an item, but these ids are
// usually unique, and have a low chance of collision. // usually unique, and have a low chance of collision.
seb.Mails( seb.Mails(
selectors.Any(),
selectors.Any(), selectors.Any(),
[]string{"item-id-1", "item-id-2"}, []string{"item-id-1", "item-id-2"},
) )
@ -114,11 +113,6 @@ func Example_filters() {
// But you can still make a compound filter by adding each scope individually. // But you can still make a compound filter by adding each scope individually.
ser.MailSubject("the answer to life, the universe, and everything"), ser.MailSubject("the answer to life, the universe, and everything"),
) )
// Selectors can specify both Filter and Inclusion scopes. Now, not only will the
// data only include emails matching the filters above, it will only include emails
// owned by this one user.
ser.Include(ser.Users([]string{"foo-user-id"}))
} }
var ( var (
@ -155,7 +149,7 @@ func Example_reduceDetails() {
// We haven't added any scopes to our selector yet, so none of the data is retained. // We haven't added any scopes to our selector yet, so none of the data is retained.
fmt.Println("Before adding scopes:", len(filteredDetails.Entries)) fmt.Println("Before adding scopes:", len(filteredDetails.Entries))
ser.Include(ser.Mails([]string{"your-user-id"}, []string{"example"}, []string{"xyz"})) ser.Include(ser.Mails([]string{"example"}, []string{"xyz"}))
ser.Filter(ser.MailSubject("the answer to life")) ser.Filter(ser.MailSubject("the answer to life"))
// Now that we've selected our data, we should find a result. // Now that we've selected our data, we should find a result.
@ -174,11 +168,7 @@ func Example_scopeMatching() {
NewExchangeBackup( NewExchangeBackup(
[]string{"your-user-id", "foo-user-id", "bar-user-id"}, []string{"your-user-id", "foo-user-id", "bar-user-id"},
). ).
Mails( Mails([]string{"Inbox"}, selectors.Any())[0]
[]string{"id-1"},
[]string{"Inbox"},
selectors.Any(),
)[0]
// To compare data against a scope, you need to specify the category of data, // To compare data against a scope, you need to specify the category of data,
// and input the value to check. // and input the value to check.
@ -186,8 +176,8 @@ func Example_scopeMatching() {
fmt.Println("Matches the mail folder 'inbox':", result) fmt.Println("Matches the mail folder 'inbox':", result)
// Non-matching values will return false. // Non-matching values will return false.
result = scope.Matches(selectors.ExchangeUser, "id-42") result = scope.Matches(selectors.ExchangeMailFolder, "Archive")
fmt.Println("Matches the user by id 'id-42':", result) fmt.Println("Matches the mail folder by display name 'Archive':", result)
// If you specify a category that doesn't belong to the expected // If you specify a category that doesn't belong to the expected
// data type, the result is always false, even if the underlying // data type, the result is always false, even if the underlying
@ -201,7 +191,7 @@ func Example_scopeMatching() {
fmt.Println("Scope Category:", cat) fmt.Println("Scope Category:", cat)
// Output: Matches the mail folder 'inbox': true // Output: Matches the mail folder 'inbox': true
// Matches the user by id 'id-42': false // Matches the mail folder by display name 'Archive': false
// Matches the contact by id 'id-1': false // Matches the contact by id 'id-1': false
// Scope Category: ExchangeMail // Scope Category: ExchangeMail
} }

View File

@ -209,7 +209,7 @@ func (s *exchange) DiscreteScopes(userPNs []string) []ExchangeScope {
return ss return ss
} }
type ExchangeItemScopeConstructor func([]string, []string, []string, ...option) []ExchangeScope type ExchangeItemScopeConstructor func([]string, []string, ...option) []ExchangeScope
// ------------------- // -------------------
// Scope Factories // Scope Factories
@ -219,12 +219,12 @@ type ExchangeItemScopeConstructor func([]string, []string, []string, ...option)
// 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]
// options are only applied to the folder scopes. // options are only applied to the folder scopes.
func (s *exchange) Contacts(users, folders, contacts []string, opts ...option) []ExchangeScope { func (s *exchange) Contacts(folders, contacts []string, opts ...option) []ExchangeScope {
scopes := []ExchangeScope{} scopes := []ExchangeScope{}
scopes = append( scopes = append(
scopes, scopes,
makeScope[ExchangeScope](ExchangeContact, users, contacts). makeScope[ExchangeScope](ExchangeContact, contacts).
set(ExchangeContactFolder, folders, opts...), set(ExchangeContactFolder, folders, opts...),
) )
@ -236,7 +236,7 @@ func (s *exchange) Contacts(users, folders, contacts []string, opts ...option) [
// 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]
// options are only applied to the folder scopes. // options are only applied to the folder scopes.
func (s *exchange) ContactFolders(users, folders []string, opts ...option) []ExchangeScope { func (s *exchange) ContactFolders(folders []string, opts ...option) []ExchangeScope {
var ( var (
scopes = []ExchangeScope{} scopes = []ExchangeScope{}
os = append([]option{pathComparator()}, opts...) os = append([]option{pathComparator()}, opts...)
@ -244,7 +244,7 @@ func (s *exchange) ContactFolders(users, folders []string, opts ...option) []Exc
scopes = append( scopes = append(
scopes, scopes,
makeScope[ExchangeScope](ExchangeContactFolder, users, folders, os...), makeScope[ExchangeScope](ExchangeContactFolder, folders, os...),
) )
return scopes return scopes
@ -255,12 +255,12 @@ func (s *exchange) ContactFolders(users, folders []string, opts ...option) []Exc
// 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]
// options are only applied to the folder scopes. // options are only applied to the folder scopes.
func (s *exchange) Events(users, calendars, events []string, opts ...option) []ExchangeScope { func (s *exchange) Events(calendars, events []string, opts ...option) []ExchangeScope {
scopes := []ExchangeScope{} scopes := []ExchangeScope{}
scopes = append( scopes = append(
scopes, scopes,
makeScope[ExchangeScope](ExchangeEvent, users, events). makeScope[ExchangeScope](ExchangeEvent, events).
set(ExchangeEventCalendar, calendars, opts...), set(ExchangeEventCalendar, calendars, opts...),
) )
@ -273,7 +273,7 @@ func (s *exchange) Events(users, calendars, events []string, opts ...option) []E
// 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]
// options are only applied to the folder scopes. // options are only applied to the folder scopes.
func (s *exchange) EventCalendars(users, events []string, opts ...option) []ExchangeScope { func (s *exchange) EventCalendars(events []string, opts ...option) []ExchangeScope {
var ( var (
scopes = []ExchangeScope{} scopes = []ExchangeScope{}
os = append([]option{pathComparator()}, opts...) os = append([]option{pathComparator()}, opts...)
@ -281,7 +281,7 @@ func (s *exchange) EventCalendars(users, events []string, opts ...option) []Exch
scopes = append( scopes = append(
scopes, scopes,
makeScope[ExchangeScope](ExchangeEventCalendar, users, events, os...), makeScope[ExchangeScope](ExchangeEventCalendar, events, os...),
) )
return scopes return scopes
@ -292,12 +292,12 @@ func (s *exchange) EventCalendars(users, events []string, opts ...option) []Exch
// 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]
// options are only applied to the folder scopes. // options are only applied to the folder scopes.
func (s *exchange) Mails(users, folders, mails []string, opts ...option) []ExchangeScope { func (s *exchange) Mails(folders, mails []string, opts ...option) []ExchangeScope {
scopes := []ExchangeScope{} scopes := []ExchangeScope{}
scopes = append( scopes = append(
scopes, scopes,
makeScope[ExchangeScope](ExchangeMail, users, mails). makeScope[ExchangeScope](ExchangeMail, mails).
set(ExchangeMailFolder, folders, opts...), set(ExchangeMailFolder, folders, opts...),
) )
@ -309,7 +309,7 @@ func (s *exchange) Mails(users, folders, mails []string, opts ...option) []Excha
// 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]
// options are only applied to the folder scopes. // options are only applied to the folder scopes.
func (s *exchange) MailFolders(users, folders []string, opts ...option) []ExchangeScope { func (s *exchange) MailFolders(folders []string, opts ...option) []ExchangeScope {
var ( var (
scopes = []ExchangeScope{} scopes = []ExchangeScope{}
os = append([]option{pathComparator()}, opts...) os = append([]option{pathComparator()}, opts...)
@ -317,24 +317,24 @@ func (s *exchange) MailFolders(users, folders []string, opts ...option) []Exchan
scopes = append( scopes = append(
scopes, scopes,
makeScope[ExchangeScope](ExchangeMailFolder, users, folders, os...), makeScope[ExchangeScope](ExchangeMailFolder, folders, os...),
) )
return scopes return scopes
} }
// Produces one or more exchange contact user scopes. // Retrieves all exchange data.
// Each user id generates three scopes, one for each data type: contact, event, and mail. // Each user id generates three scopes, one for each data type: contact, event, and mail.
// 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 (s *exchange) Users(users []string) []ExchangeScope { func (s *exchange) AllData() []ExchangeScope {
scopes := []ExchangeScope{} scopes := []ExchangeScope{}
scopes = append(scopes, scopes = append(scopes,
makeScope[ExchangeScope](ExchangeContactFolder, users, Any()), makeScope[ExchangeScope](ExchangeContactFolder, Any()),
makeScope[ExchangeScope](ExchangeEventCalendar, users, Any()), makeScope[ExchangeScope](ExchangeEventCalendar, Any()),
makeScope[ExchangeScope](ExchangeMailFolder, users, Any()), makeScope[ExchangeScope](ExchangeMailFolder, Any()),
) )
return scopes return scopes
@ -529,15 +529,15 @@ const (
// exchangeLeafProperties describes common metadata of the leaf categories // exchangeLeafProperties describes common metadata of the leaf categories
var exchangeLeafProperties = map[categorizer]leafProperty{ var exchangeLeafProperties = map[categorizer]leafProperty{
ExchangeContact: { ExchangeContact: {
pathKeys: []categorizer{ExchangeUser, ExchangeContactFolder, ExchangeContact}, pathKeys: []categorizer{ExchangeContactFolder, ExchangeContact},
pathType: path.ContactsCategory, pathType: path.ContactsCategory,
}, },
ExchangeEvent: { ExchangeEvent: {
pathKeys: []categorizer{ExchangeUser, ExchangeEventCalendar, ExchangeEvent}, pathKeys: []categorizer{ExchangeEventCalendar, ExchangeEvent},
pathType: path.EventsCategory, pathType: path.EventsCategory,
}, },
ExchangeMail: { ExchangeMail: {
pathKeys: []categorizer{ExchangeUser, ExchangeMailFolder, ExchangeMail}, pathKeys: []categorizer{ExchangeMailFolder, ExchangeMail},
pathType: path.EmailCategory, pathType: path.EmailCategory,
}, },
ExchangeUser: { // the root category must be represented, even though it isn't a leaf ExchangeUser: { // the root category must be represented, even though it isn't a leaf
@ -618,7 +618,6 @@ func (ec exchangeCategory) pathValues(p path.Path) map[categorizer]string {
} }
return map[categorizer]string{ return map[categorizer]string{
ExchangeUser: p.ResourceOwner(),
folderCat: p.Folder(), folderCat: p.Folder(),
itemCat: p.Item(), itemCat: p.Item(),
} }

View File

@ -68,7 +68,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Exclude_Contacts() {
) )
sel := NewExchangeBackup([]string{user}) sel := NewExchangeBackup([]string{user})
sel.Exclude(sel.Contacts([]string{user}, []string{folder}, []string{c1, c2})) sel.Exclude(sel.Contacts([]string{folder}, []string{c1, c2}))
scopes := sel.Excludes scopes := sel.Excludes
require.Len(t, scopes, 1) require.Len(t, scopes, 1)
@ -76,7 +76,6 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Exclude_Contacts() {
t, t,
ExchangeScope(scopes[0]), ExchangeScope(scopes[0]),
map[categorizer]string{ map[categorizer]string{
ExchangeUser: user,
ExchangeContactFolder: folder, ExchangeContactFolder: folder,
ExchangeContact: join(c1, c2), ExchangeContact: join(c1, c2),
}, },
@ -94,7 +93,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Include_Contacts() {
) )
sel := NewExchangeBackup([]string{user}) sel := NewExchangeBackup([]string{user})
sel.Include(sel.Contacts([]string{user}, []string{folder}, []string{c1, c2})) sel.Include(sel.Contacts([]string{folder}, []string{c1, c2}))
scopes := sel.Includes scopes := sel.Includes
require.Len(t, scopes, 1) require.Len(t, scopes, 1)
@ -102,7 +101,6 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Include_Contacts() {
t, t,
ExchangeScope(scopes[0]), ExchangeScope(scopes[0]),
map[categorizer]string{ map[categorizer]string{
ExchangeUser: user,
ExchangeContactFolder: folder, ExchangeContactFolder: folder,
ExchangeContact: join(c1, c2), ExchangeContact: join(c1, c2),
}, },
@ -121,7 +119,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Exclude_ContactFolders(
) )
sel := NewExchangeBackup([]string{user}) sel := NewExchangeBackup([]string{user})
sel.Exclude(sel.ContactFolders([]string{user}, []string{f1, f2})) sel.Exclude(sel.ContactFolders([]string{f1, f2}))
scopes := sel.Excludes scopes := sel.Excludes
require.Len(t, scopes, 1) require.Len(t, scopes, 1)
@ -129,7 +127,6 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Exclude_ContactFolders(
t, t,
ExchangeScope(scopes[0]), ExchangeScope(scopes[0]),
map[categorizer]string{ map[categorizer]string{
ExchangeUser: user,
ExchangeContactFolder: join(f1, f2), ExchangeContactFolder: join(f1, f2),
ExchangeContact: AnyTgt, ExchangeContact: AnyTgt,
}, },
@ -146,7 +143,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Include_ContactFolders(
) )
sel := NewExchangeBackup([]string{user}) sel := NewExchangeBackup([]string{user})
sel.Include(sel.ContactFolders([]string{user}, []string{f1, f2})) sel.Include(sel.ContactFolders([]string{f1, f2}))
scopes := sel.Includes scopes := sel.Includes
require.Len(t, scopes, 1) require.Len(t, scopes, 1)
@ -154,7 +151,6 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Include_ContactFolders(
t, t,
ExchangeScope(scopes[0]), ExchangeScope(scopes[0]),
map[categorizer]string{ map[categorizer]string{
ExchangeUser: user,
ExchangeContactFolder: join(f1, f2), ExchangeContactFolder: join(f1, f2),
ExchangeContact: AnyTgt, ExchangeContact: AnyTgt,
}, },
@ -174,7 +170,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Exclude_Events() {
) )
sel := NewExchangeBackup([]string{user}) sel := NewExchangeBackup([]string{user})
sel.Exclude(sel.Events([]string{user}, []string{c1}, []string{e1, e2})) sel.Exclude(sel.Events([]string{c1}, []string{e1, e2}))
scopes := sel.Excludes scopes := sel.Excludes
require.Len(t, scopes, 1) require.Len(t, scopes, 1)
@ -182,7 +178,6 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Exclude_Events() {
t, t,
ExchangeScope(scopes[0]), ExchangeScope(scopes[0]),
map[categorizer]string{ map[categorizer]string{
ExchangeUser: user,
ExchangeEventCalendar: c1, ExchangeEventCalendar: c1,
ExchangeEvent: join(e1, e2), ExchangeEvent: join(e1, e2),
}, },
@ -199,7 +194,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Exclude_EventCalendars(
) )
sel := NewExchangeBackup([]string{user}) sel := NewExchangeBackup([]string{user})
sel.Exclude(sel.EventCalendars([]string{user}, []string{c1, c2})) sel.Exclude(sel.EventCalendars([]string{c1, c2}))
scopes := sel.Excludes scopes := sel.Excludes
require.Len(t, scopes, 1) require.Len(t, scopes, 1)
@ -207,7 +202,6 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Exclude_EventCalendars(
t, t,
ExchangeScope(scopes[0]), ExchangeScope(scopes[0]),
map[categorizer]string{ map[categorizer]string{
ExchangeUser: user,
ExchangeEventCalendar: join(c1, c2), ExchangeEventCalendar: join(c1, c2),
ExchangeEvent: AnyTgt, ExchangeEvent: AnyTgt,
}, },
@ -225,7 +219,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Include_Events() {
) )
sel := NewExchangeBackup([]string{user}) sel := NewExchangeBackup([]string{user})
sel.Include(sel.Events([]string{user}, []string{c1}, []string{e1, e2})) sel.Include(sel.Events([]string{c1}, []string{e1, e2}))
scopes := sel.Includes scopes := sel.Includes
require.Len(t, scopes, 1) require.Len(t, scopes, 1)
@ -233,7 +227,6 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Include_Events() {
t, t,
ExchangeScope(scopes[0]), ExchangeScope(scopes[0]),
map[categorizer]string{ map[categorizer]string{
ExchangeUser: user,
ExchangeEventCalendar: c1, ExchangeEventCalendar: c1,
ExchangeEvent: join(e1, e2), ExchangeEvent: join(e1, e2),
}, },
@ -250,7 +243,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Include_EventCalendars(
) )
sel := NewExchangeBackup([]string{user}) sel := NewExchangeBackup([]string{user})
sel.Include(sel.EventCalendars([]string{user}, []string{c1, c2})) sel.Include(sel.EventCalendars([]string{c1, c2}))
scopes := sel.Includes scopes := sel.Includes
require.Len(t, scopes, 1) require.Len(t, scopes, 1)
@ -258,7 +251,6 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Include_EventCalendars(
t, t,
ExchangeScope(scopes[0]), ExchangeScope(scopes[0]),
map[categorizer]string{ map[categorizer]string{
ExchangeUser: user,
ExchangeEventCalendar: join(c1, c2), ExchangeEventCalendar: join(c1, c2),
ExchangeEvent: AnyTgt, ExchangeEvent: AnyTgt,
}, },
@ -276,7 +268,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Exclude_Mails() {
) )
sel := NewExchangeBackup([]string{user}) sel := NewExchangeBackup([]string{user})
sel.Exclude(sel.Mails([]string{user}, []string{folder}, []string{m1, m2})) sel.Exclude(sel.Mails([]string{folder}, []string{m1, m2}))
scopes := sel.Excludes scopes := sel.Excludes
require.Len(t, scopes, 1) require.Len(t, scopes, 1)
@ -284,7 +276,6 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Exclude_Mails() {
t, t,
ExchangeScope(scopes[0]), ExchangeScope(scopes[0]),
map[categorizer]string{ map[categorizer]string{
ExchangeUser: user,
ExchangeMailFolder: folder, ExchangeMailFolder: folder,
ExchangeMail: join(m1, m2), ExchangeMail: join(m1, m2),
}, },
@ -302,7 +293,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Include_Mails() {
) )
sel := NewExchangeBackup([]string{user}) sel := NewExchangeBackup([]string{user})
sel.Include(sel.Mails([]string{user}, []string{folder}, []string{m1, m2})) sel.Include(sel.Mails([]string{folder}, []string{m1, m2}))
scopes := sel.Includes scopes := sel.Includes
require.Len(t, scopes, 1) require.Len(t, scopes, 1)
@ -310,7 +301,6 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Include_Mails() {
t, t,
ExchangeScope(scopes[0]), ExchangeScope(scopes[0]),
map[categorizer]string{ map[categorizer]string{
ExchangeUser: user,
ExchangeMailFolder: folder, ExchangeMailFolder: folder,
ExchangeMail: join(m1, m2), ExchangeMail: join(m1, m2),
}, },
@ -329,7 +319,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Exclude_MailFolders() {
) )
sel := NewExchangeBackup([]string{user}) sel := NewExchangeBackup([]string{user})
sel.Exclude(sel.MailFolders([]string{user}, []string{f1, f2})) sel.Exclude(sel.MailFolders([]string{f1, f2}))
scopes := sel.Excludes scopes := sel.Excludes
require.Len(t, scopes, 1) require.Len(t, scopes, 1)
@ -337,7 +327,6 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Exclude_MailFolders() {
t, t,
ExchangeScope(scopes[0]), ExchangeScope(scopes[0]),
map[categorizer]string{ map[categorizer]string{
ExchangeUser: user,
ExchangeMailFolder: join(f1, f2), ExchangeMailFolder: join(f1, f2),
ExchangeMail: AnyTgt, ExchangeMail: AnyTgt,
}, },
@ -354,7 +343,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Include_MailFolders() {
) )
sel := NewExchangeBackup([]string{user}) sel := NewExchangeBackup([]string{user})
sel.Include(sel.MailFolders([]string{user}, []string{f1, f2})) sel.Include(sel.MailFolders([]string{f1, f2}))
scopes := sel.Includes scopes := sel.Includes
require.Len(t, scopes, 1) require.Len(t, scopes, 1)
@ -362,7 +351,6 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Include_MailFolders() {
t, t,
ExchangeScope(scopes[0]), ExchangeScope(scopes[0]),
map[categorizer]string{ map[categorizer]string{
ExchangeUser: user,
ExchangeMailFolder: join(f1, f2), ExchangeMailFolder: join(f1, f2),
ExchangeMail: AnyTgt, ExchangeMail: AnyTgt,
}, },
@ -371,7 +359,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Include_MailFolders() {
assert.Equal(t, sel.Scopes()[0].Category(), ExchangeMailFolder) assert.Equal(t, sel.Scopes()[0].Category(), ExchangeMailFolder)
} }
func (suite *ExchangeSelectorSuite) TestExchangeSelector_Exclude_Users() { func (suite *ExchangeSelectorSuite) TestExchangeSelector_Exclude_AllData() {
t := suite.T() t := suite.T()
const ( const (
@ -380,17 +368,11 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Exclude_Users() {
) )
sel := NewExchangeBackup([]string{u1, u2}) sel := NewExchangeBackup([]string{u1, u2})
sel.Exclude(sel.Users([]string{u1, u2})) sel.Exclude(sel.AllData())
scopes := sel.Excludes scopes := sel.Excludes
require.Len(t, scopes, 3) require.Len(t, scopes, 3)
for _, sc := range scopes { for _, sc := range scopes {
scopeMustHave(
t,
ExchangeScope(sc),
map[categorizer]string{ExchangeUser: join(u1, u2)},
)
if sc[scopeKeyCategory].Compare(ExchangeContactFolder.String()) { if sc[scopeKeyCategory].Compare(ExchangeContactFolder.String()) {
scopeMustHave( scopeMustHave(
t, t,
@ -425,7 +407,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Exclude_Users() {
} }
} }
func (suite *ExchangeSelectorSuite) TestExchangeSelector_Include_Users() { func (suite *ExchangeSelectorSuite) TestExchangeSelector_Include_AllData() {
t := suite.T() t := suite.T()
const ( const (
@ -434,17 +416,11 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Include_Users() {
) )
sel := NewExchangeBackup([]string{u1, u2}) sel := NewExchangeBackup([]string{u1, u2})
sel.Include(sel.Users([]string{u1, u2})) sel.Include(sel.AllData())
scopes := sel.Includes scopes := sel.Includes
require.Len(t, scopes, 3) require.Len(t, scopes, 3)
for _, sc := range scopes { for _, sc := range scopes {
scopeMustHave(
t,
ExchangeScope(sc),
map[categorizer]string{ExchangeUser: join(u1, u2)},
)
if sc[scopeKeyCategory].Compare(ExchangeContactFolder.String()) { if sc[scopeKeyCategory].Compare(ExchangeContactFolder.String()) {
scopeMustHave( scopeMustHave(
t, t,
@ -481,7 +457,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Include_Users() {
func (suite *ExchangeSelectorSuite) TestExchangeBackup_Scopes() { func (suite *ExchangeSelectorSuite) TestExchangeBackup_Scopes() {
eb := NewExchangeBackup(Any()) eb := NewExchangeBackup(Any())
eb.Include(eb.Users(Any())) eb.Include(eb.AllData())
scopes := eb.Scopes() scopes := eb.Scopes()
assert.Len(suite.T(), scopes, 3) assert.Len(suite.T(), scopes, 3)
@ -489,7 +465,6 @@ func (suite *ExchangeSelectorSuite) TestExchangeBackup_Scopes() {
for _, sc := range scopes { for _, sc := range scopes {
cat := sc.Category() cat := sc.Category()
suite.T().Run(cat.String(), func(t *testing.T) { suite.T().Run(cat.String(), func(t *testing.T) {
assert.True(t, sc.IsAny(ExchangeUser))
switch sc.Category() { switch sc.Category() {
case ExchangeContactFolder: case ExchangeContactFolder:
assert.True(t, sc.IsAny(ExchangeContact)) assert.True(t, sc.IsAny(ExchangeContact))
@ -534,14 +509,15 @@ func (suite *ExchangeSelectorSuite) TestExchangeBackup_DiscreteScopes() {
for _, test := range table { for _, test := range table {
suite.T().Run(test.name, func(t *testing.T) { suite.T().Run(test.name, func(t *testing.T) {
eb := NewExchangeBackup(test.include) // todo: remove discreteScopes
eb.Include(eb.Users(test.include)) // eb := NewExchangeBackup(test.include)
// eb.Include(eb.AllData())
scopes := eb.DiscreteScopes(test.discrete) // scopes := eb.DiscreteScopes(test.discrete)
for _, sc := range scopes { // for _, sc := range scopes {
users := sc.Get(ExchangeUser) // users := sc.Get(ExchangeUser)
assert.Equal(t, test.expect, users) // assert.Equal(t, test.expect, users)
} // }
}) })
} }
} }
@ -626,7 +602,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeScope_IncludesCategory() {
func (suite *ExchangeSelectorSuite) TestExchangeScope_Get() { func (suite *ExchangeSelectorSuite) TestExchangeScope_Get() {
eb := NewExchangeBackup(Any()) eb := NewExchangeBackup(Any())
eb.Include(eb.Users(Any())) eb.Include(eb.AllData())
scopes := eb.Scopes() scopes := eb.Scopes()
@ -636,12 +612,10 @@ func (suite *ExchangeSelectorSuite) TestExchangeScope_Get() {
ExchangeEvent, ExchangeEvent,
ExchangeMail, ExchangeMail,
ExchangeMailFolder, ExchangeMailFolder,
ExchangeUser,
} }
for _, test := range table { for _, test := range table {
suite.T().Run(test.String(), func(t *testing.T) { suite.T().Run(test.String(), func(t *testing.T) {
for _, sc := range scopes { for _, sc := range scopes {
assert.Equal(t, Any(), sc.Get(ExchangeUser))
switch sc.Category() { switch sc.Category() {
case ExchangeContactFolder: case ExchangeContactFolder:
assert.Equal(t, Any(), sc.Get(ExchangeContact)) assert.Equal(t, Any(), sc.Get(ExchangeContact))
@ -790,28 +764,24 @@ func (suite *ExchangeSelectorSuite) TestExchangeScope_MatchesPath() {
shortRef string shortRef string
expect assert.BoolAssertionFunc expect assert.BoolAssertionFunc
}{ }{
{"all user's items", es.Users(Any()), "", assert.True}, {"all items", es.AllData(), "", assert.True},
{"no user's items", es.Users(None()), "", assert.True}, {"all folders", es.MailFolders(Any()), "", assert.True},
{"matching user", es.Users([]string{usr}), "", assert.True}, {"no folders", es.MailFolders(None()), "", assert.False},
{"non-matching user", es.Users([]string{"smarf"}), "", assert.True}, {"matching folder", es.MailFolders([]string{fld1}), "", assert.True},
{"one of multiple users", es.Users([]string{"smarf", usr}), "", assert.True}, {"incomplete matching folder", es.MailFolders([]string{"mail"}), "", assert.False},
{"all folders", es.MailFolders(Any(), Any()), "", assert.True}, {"non-matching folder", es.MailFolders([]string{"smarf"}), "", assert.False},
{"no folders", es.MailFolders(Any(), None()), "", assert.False}, {"non-matching folder substring", es.MailFolders([]string{fld1 + "_suffix"}), "", assert.False},
{"matching folder", es.MailFolders(Any(), []string{fld1}), "", assert.True}, {"matching folder prefix", es.MailFolders([]string{fld1}, PrefixMatch()), "", assert.True},
{"incomplete matching folder", es.MailFolders(Any(), []string{"mail"}), "", assert.False}, {"incomplete folder prefix", es.MailFolders([]string{"mail"}, PrefixMatch()), "", assert.False},
{"non-matching folder", es.MailFolders(Any(), []string{"smarf"}), "", assert.False}, {"matching folder substring", es.MailFolders([]string{"Folder"}), "", assert.False},
{"non-matching folder substring", es.MailFolders(Any(), []string{fld1 + "_suffix"}), "", assert.False}, {"one of multiple folders", es.MailFolders([]string{"smarf", fld2}), "", assert.True},
{"matching folder prefix", es.MailFolders(Any(), []string{fld1}, PrefixMatch()), "", assert.True}, {"all mail", es.Mails(Any(), Any()), "", assert.True},
{"incomplete folder prefix", es.MailFolders(Any(), []string{"mail"}, PrefixMatch()), "", assert.False}, {"no mail", es.Mails(Any(), None()), "", assert.False},
{"matching folder substring", es.MailFolders(Any(), []string{"Folder"}), "", assert.False}, {"matching mail", es.Mails(Any(), []string{mail}), "", assert.True},
{"one of multiple folders", es.MailFolders(Any(), []string{"smarf", fld2}), "", assert.True}, {"non-matching mail", es.Mails(Any(), []string{"smarf"}), "", assert.False},
{"all mail", es.Mails(Any(), Any(), Any()), "", assert.True}, {"one of multiple mails", es.Mails(Any(), []string{"smarf", mail}), "", assert.True},
{"no mail", es.Mails(Any(), Any(), None()), "", assert.False}, {"mail short ref", es.Mails(Any(), []string{short}), short, assert.True},
{"matching mail", es.Mails(Any(), Any(), []string{mail}), "", assert.True}, {"non-leaf short ref", es.Mails([]string{short}, []string{"foo"}), short, assert.False},
{"non-matching mail", es.Mails(Any(), Any(), []string{"smarf"}), "", assert.False},
{"one of multiple mails", es.Mails(Any(), Any(), []string{"smarf", mail}), "", assert.True},
{"mail short ref", es.Mails(Any(), Any(), []string{short}), short, assert.True},
{"non-leaf short ref", es.Mails([]string{short}, []string{short}, []string{"foo"}), short, assert.False},
} }
for _, test := range table { for _, test := range table {
suite.T().Run(test.name, func(t *testing.T) { suite.T().Run(test.name, func(t *testing.T) {
@ -839,7 +809,6 @@ func (suite *ExchangeSelectorSuite) TestIdPath() {
ExchangeContact, ExchangeContact,
stubPath(suite.T(), "uid", []string{"cFld", "cid"}, path.ContactsCategory), stubPath(suite.T(), "uid", []string{"cFld", "cid"}, path.ContactsCategory),
map[exchangeCategory]string{ map[exchangeCategory]string{
ExchangeUser: "uid",
ExchangeContactFolder: "cFld", ExchangeContactFolder: "cFld",
ExchangeContact: "cid", ExchangeContact: "cid",
}, },
@ -848,7 +817,6 @@ func (suite *ExchangeSelectorSuite) TestIdPath() {
ExchangeEvent, ExchangeEvent,
stubPath(suite.T(), "uid", []string{"eCld", "eid"}, path.EventsCategory), stubPath(suite.T(), "uid", []string{"eCld", "eid"}, path.EventsCategory),
map[exchangeCategory]string{ map[exchangeCategory]string{
ExchangeUser: "uid",
ExchangeEventCalendar: "eCld", ExchangeEventCalendar: "eCld",
ExchangeEvent: "eid", ExchangeEvent: "eid",
}, },
@ -857,7 +825,6 @@ func (suite *ExchangeSelectorSuite) TestIdPath() {
ExchangeMail, ExchangeMail,
stubPath(suite.T(), "uid", []string{"mFld", "mid"}, path.EmailCategory), stubPath(suite.T(), "uid", []string{"mFld", "mid"}, path.EmailCategory),
map[exchangeCategory]string{ map[exchangeCategory]string{
ExchangeUser: "uid",
ExchangeMailFolder: "mFld", ExchangeMailFolder: "mFld",
ExchangeMail: "mid", ExchangeMail: "mid",
}, },
@ -923,7 +890,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeRestore_Reduce() {
makeDeets(), makeDeets(),
func() *ExchangeRestore { func() *ExchangeRestore {
er := NewExchangeRestore(Any()) er := NewExchangeRestore(Any())
er.Include(er.Users(Any())) er.Include(er.AllData())
return er return er
}, },
[]string{}, []string{},
@ -933,7 +900,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeRestore_Reduce() {
makeDeets(contact), makeDeets(contact),
func() *ExchangeRestore { func() *ExchangeRestore {
er := NewExchangeRestore(Any()) er := NewExchangeRestore(Any())
er.Include(er.Users(Any())) er.Include(er.AllData())
return er return er
}, },
arr(contact), arr(contact),
@ -943,7 +910,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeRestore_Reduce() {
makeDeets(event), makeDeets(event),
func() *ExchangeRestore { func() *ExchangeRestore {
er := NewExchangeRestore(Any()) er := NewExchangeRestore(Any())
er.Include(er.Users(Any())) er.Include(er.AllData())
return er return er
}, },
arr(event), arr(event),
@ -953,7 +920,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeRestore_Reduce() {
makeDeets(mail), makeDeets(mail),
func() *ExchangeRestore { func() *ExchangeRestore {
er := NewExchangeRestore(Any()) er := NewExchangeRestore(Any())
er.Include(er.Users(Any())) er.Include(er.AllData())
return er return er
}, },
arr(mail), arr(mail),
@ -963,7 +930,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeRestore_Reduce() {
makeDeets(contact, event, mail), makeDeets(contact, event, mail),
func() *ExchangeRestore { func() *ExchangeRestore {
er := NewExchangeRestore(Any()) er := NewExchangeRestore(Any())
er.Include(er.Users(Any())) er.Include(er.AllData())
return er return er
}, },
arr(contact, event, mail), arr(contact, event, mail),
@ -973,7 +940,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeRestore_Reduce() {
makeDeets(contact, event, mail), makeDeets(contact, event, mail),
func() *ExchangeRestore { func() *ExchangeRestore {
er := NewExchangeRestore([]string{"uid"}) er := NewExchangeRestore([]string{"uid"})
er.Include(er.Contacts([]string{"uid"}, []string{"cfld"}, []string{"cid"})) er.Include(er.Contacts([]string{"cfld"}, []string{"cid"}))
return er return er
}, },
arr(contact), arr(contact),
@ -983,7 +950,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeRestore_Reduce() {
makeDeets(contactInSubFolder, contact, event, mail), makeDeets(contactInSubFolder, contact, event, mail),
func() *ExchangeRestore { func() *ExchangeRestore {
er := NewExchangeRestore([]string{"uid"}) er := NewExchangeRestore([]string{"uid"})
er.Include(er.ContactFolders([]string{"uid"}, []string{"cfld1/cfld2"})) er.Include(er.ContactFolders([]string{"cfld1/cfld2"}))
return er return er
}, },
arr(contactInSubFolder), arr(contactInSubFolder),
@ -993,7 +960,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeRestore_Reduce() {
makeDeets(contactInSubFolder, contact, event, mail), makeDeets(contactInSubFolder, contact, event, mail),
func() *ExchangeRestore { func() *ExchangeRestore {
er := NewExchangeRestore([]string{"uid"}) er := NewExchangeRestore([]string{"uid"})
er.Include(er.ContactFolders([]string{"uid"}, []string{"cfld1/cfld2"}, PrefixMatch())) er.Include(er.ContactFolders([]string{"cfld1/cfld2"}, PrefixMatch()))
return er return er
}, },
arr(contactInSubFolder), arr(contactInSubFolder),
@ -1003,7 +970,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeRestore_Reduce() {
makeDeets(contactInSubFolder, contact, event, mail), makeDeets(contactInSubFolder, contact, event, mail),
func() *ExchangeRestore { func() *ExchangeRestore {
er := NewExchangeRestore([]string{"uid"}) er := NewExchangeRestore([]string{"uid"})
er.Include(er.ContactFolders([]string{"uid"}, []string{"cfld2"})) er.Include(er.ContactFolders([]string{"cfld2"}))
return er return er
}, },
arr(contactInSubFolder), arr(contactInSubFolder),
@ -1013,7 +980,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeRestore_Reduce() {
makeDeets(contact, event, mail), makeDeets(contact, event, mail),
func() *ExchangeRestore { func() *ExchangeRestore {
er := NewExchangeRestore([]string{"uid"}) er := NewExchangeRestore([]string{"uid"})
er.Include(er.Events([]string{"uid"}, []string{"ecld"}, []string{"eid"})) er.Include(er.Events([]string{"ecld"}, []string{"eid"}))
return er return er
}, },
arr(event), arr(event),
@ -1023,7 +990,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeRestore_Reduce() {
makeDeets(contact, event, mail), makeDeets(contact, event, mail),
func() *ExchangeRestore { func() *ExchangeRestore {
er := NewExchangeRestore([]string{"uid"}) er := NewExchangeRestore([]string{"uid"})
er.Include(er.Mails([]string{"uid"}, []string{"mfld"}, []string{"mid"})) er.Include(er.Mails([]string{"mfld"}, []string{"mid"}))
return er return er
}, },
arr(mail), arr(mail),
@ -1033,8 +1000,8 @@ func (suite *ExchangeSelectorSuite) TestExchangeRestore_Reduce() {
makeDeets(contact, event, mail), makeDeets(contact, event, mail),
func() *ExchangeRestore { func() *ExchangeRestore {
er := NewExchangeRestore(Any()) er := NewExchangeRestore(Any())
er.Include(er.Users(Any())) er.Include(er.AllData())
er.Exclude(er.Contacts([]string{"uid"}, []string{"cfld"}, []string{"cid"})) er.Exclude(er.Contacts([]string{"cfld"}, []string{"cid"}))
return er return er
}, },
arr(event, mail), arr(event, mail),
@ -1044,8 +1011,8 @@ func (suite *ExchangeSelectorSuite) TestExchangeRestore_Reduce() {
makeDeets(contact, event, mail), makeDeets(contact, event, mail),
func() *ExchangeRestore { func() *ExchangeRestore {
er := NewExchangeRestore(Any()) er := NewExchangeRestore(Any())
er.Include(er.Users(Any())) er.Include(er.AllData())
er.Exclude(er.Events([]string{"uid"}, []string{"ecld"}, []string{"eid"})) er.Exclude(er.Events([]string{"ecld"}, []string{"eid"}))
return er return er
}, },
arr(contact, mail), arr(contact, mail),
@ -1055,8 +1022,8 @@ func (suite *ExchangeSelectorSuite) TestExchangeRestore_Reduce() {
makeDeets(contact, event, mail), makeDeets(contact, event, mail),
func() *ExchangeRestore { func() *ExchangeRestore {
er := NewExchangeRestore(Any()) er := NewExchangeRestore(Any())
er.Include(er.Users(Any())) er.Include(er.AllData())
er.Exclude(er.Mails([]string{"uid"}, []string{"mfld"}, []string{"mid"})) er.Exclude(er.Mails([]string{"mfld"}, []string{"mid"}))
return er return er
}, },
arr(contact, event), arr(contact, event),
@ -1072,7 +1039,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeRestore_Reduce() {
}(), }(),
func() *ExchangeRestore { func() *ExchangeRestore {
er := NewExchangeRestore(Any()) er := NewExchangeRestore(Any())
er.Include(er.Users(Any())) er.Include(er.AllData())
er.Filter(er.MailSubject("subj")) er.Filter(er.MailSubject("subj"))
return er return er
}, },
@ -1093,7 +1060,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeRestore_Reduce() {
}(), }(),
func() *ExchangeRestore { func() *ExchangeRestore {
er := NewExchangeRestore(Any()) er := NewExchangeRestore(Any())
er.Include(er.Users(Any())) er.Include(er.AllData())
er.Filter(er.MailSubject("subj")) er.Filter(er.MailSubject("subj"))
return er return er
}, },
@ -1116,10 +1083,10 @@ func (suite *ExchangeSelectorSuite) TestExchangeRestore_Reduce() {
func (suite *ExchangeSelectorSuite) TestScopesByCategory() { func (suite *ExchangeSelectorSuite) TestScopesByCategory() {
var ( var (
es = NewExchangeRestore(Any()) es = NewExchangeRestore(Any())
users = es.Users(Any()) allData = es.AllData()
contacts = es.ContactFolders(Any(), Any()) contacts = es.ContactFolders(Any())
events = es.Events(Any(), Any(), Any()) events = es.EventCalendars(Any())
mail = es.MailFolders(Any(), Any()) mail = es.MailFolders(Any())
) )
type expect struct { type expect struct {
@ -1152,11 +1119,10 @@ func (suite *ExchangeSelectorSuite) TestScopesByCategory() {
scopes input scopes input
expect expect expect expect
}{ }{
{"users: one of each", makeInput(users), expect{1, 1, 1}},
{"contacts only", makeInput(contacts), expect{1, 0, 0}}, {"contacts only", makeInput(contacts), expect{1, 0, 0}},
{"events only", makeInput(events), expect{0, 1, 0}}, {"events only", makeInput(events), expect{0, 1, 0}},
{"mail only", makeInput(mail), expect{0, 0, 1}}, {"mail only", makeInput(mail), expect{0, 0, 1}},
{"all", makeInput(users, contacts, events, mail), expect{2, 2, 2}}, {"all", makeInput(allData, contacts, events, mail), expect{2, 2, 2}},
} }
for _, test := range table { for _, test := range table {
suite.T().Run(test.name, func(t *testing.T) { suite.T().Run(test.name, func(t *testing.T) {
@ -1179,11 +1145,10 @@ func (suite *ExchangeSelectorSuite) TestPasses() {
var ( var (
es = NewExchangeRestore(Any()) // TODO: move into test and compose with each test value es = NewExchangeRestore(Any()) // TODO: move into test and compose with each test value
anyUser = setScopesToDefault(es.Users(Any())) otherMail = setScopesToDefault(es.Mails(Any(), []string{"smarf"}))
noUser = setScopesToDefault(es.Users(None())) mail = setScopesToDefault(es.Mails(Any(), []string{mid}))
mail = setScopesToDefault(es.Mails(Any(), Any(), []string{mid})) noMail = setScopesToDefault(es.Mails(Any(), None()))
otherMail = setScopesToDefault(es.Mails(Any(), Any(), []string{"smarf"})) allMail = setScopesToDefault(es.Mails(Any(), Any()))
noMail = setScopesToDefault(es.Mails(Any(), Any(), None()))
pth = stubPath(suite.T(), "user", []string{"folder", mid}, path.EmailCategory) pth = stubPath(suite.T(), "user", []string{"folder", mid}, path.EmailCategory)
) )
@ -1193,23 +1158,15 @@ func (suite *ExchangeSelectorSuite) TestPasses() {
expect assert.BoolAssertionFunc expect assert.BoolAssertionFunc
}{ }{
{"empty", nil, nil, nil, assert.False}, {"empty", nil, nil, nil, assert.False},
{"in Any", nil, nil, anyUser, assert.True},
{"in None", nil, nil, noUser, assert.True},
{"in Mail", nil, nil, mail, assert.True}, {"in Mail", nil, nil, mail, assert.True},
{"in Other", nil, nil, otherMail, assert.False}, {"in Other", nil, nil, otherMail, assert.False},
{"in no Mail", nil, nil, noMail, assert.False}, {"in no Mail", nil, nil, noMail, assert.False},
{"ex Any", anyUser, nil, anyUser, assert.False}, {"ex None filter mail", allMail, mail, nil, assert.False},
{"ex Any filter", anyUser, anyUser, nil, assert.False}, {"ex Mail", mail, nil, allMail, assert.False},
{"ex None", noUser, nil, anyUser, assert.False}, {"ex Other", otherMail, nil, allMail, assert.True},
{"ex None filter mail", noUser, mail, nil, assert.False},
{"ex None filter any user", noUser, anyUser, nil, assert.False},
{"ex Mail", mail, nil, anyUser, assert.False},
{"ex Other", otherMail, nil, anyUser, assert.True},
{"in and ex Mail", mail, nil, mail, assert.False}, {"in and ex Mail", mail, nil, mail, assert.False},
{"filter Any", nil, anyUser, nil, assert.False}, {"filter Mail", nil, mail, allMail, assert.True},
{"filter None", nil, noUser, anyUser, assert.False}, {"filter Other", nil, otherMail, allMail, assert.False},
{"filter Mail", nil, mail, anyUser, assert.True},
{"filter Other", nil, otherMail, anyUser, assert.False},
} }
for _, test := range table { for _, test := range table {
suite.T().Run(test.name, func(t *testing.T) { suite.T().Run(test.name, func(t *testing.T) {
@ -1230,12 +1187,11 @@ func (suite *ExchangeSelectorSuite) TestContains() {
var ( var (
es = NewExchangeRestore(Any()) // TODO: move into test and compose with each test value es = NewExchangeRestore(Any()) // TODO: move into test and compose with each test value
anyUser = setScopesToDefault(es.Users(Any())) noMail = setScopesToDefault(es.Mails(None(), None()))
noMail = setScopesToDefault(es.Mails(None(), None(), None())) does = setScopesToDefault(es.Mails(Any(), []string{target}))
does = setScopesToDefault(es.Mails(Any(), Any(), []string{target})) doesNot = setScopesToDefault(es.Mails(Any(), []string{"smarf"}))
doesNot = setScopesToDefault(es.Mails(Any(), Any(), []string{"smarf"})) wrongType = setScopesToDefault(es.Contacts(Any(), Any()))
wrongType = setScopesToDefault(es.Contacts(Any(), Any(), Any())) wrongTypeGoodTarget = setScopesToDefault(es.Contacts(Any(), Any()))
wrongTypeGoodTarget = setScopesToDefault(es.Contacts(Any(), Any(), Any()))
) )
table := []struct { table := []struct {
@ -1243,7 +1199,6 @@ func (suite *ExchangeSelectorSuite) TestContains() {
scopes []ExchangeScope scopes []ExchangeScope
expect assert.BoolAssertionFunc expect assert.BoolAssertionFunc
}{ }{
{"any user", anyUser, assert.True},
{"no mail", noMail, assert.False}, {"no mail", noMail, assert.False},
{"does contain", does, assert.True}, {"does contain", does, assert.True},
{"does not contain", doesNot, assert.False}, {"does not contain", doesNot, assert.False},
@ -1267,10 +1222,8 @@ func (suite *ExchangeSelectorSuite) TestContains() {
func (suite *ExchangeSelectorSuite) TestIsAny() { func (suite *ExchangeSelectorSuite) TestIsAny() {
var ( var (
es = NewExchangeRestore(Any()) // TODO: move into test and compose with each test value es = NewExchangeRestore(Any()) // TODO: move into test and compose with each test value
anyUser = setScopesToDefault(es.Users(Any())) specificMail = setScopesToDefault(es.Mails(Any(), []string{"email"}))
noUser = setScopesToDefault(es.Users(None())) anyMail = setScopesToDefault(es.Mails(Any(), Any()))
specificMail = setScopesToDefault(es.Mails(Any(), Any(), []string{"email"}))
anyMail = setScopesToDefault(es.Mails(Any(), Any(), Any()))
) )
table := []struct { table := []struct {
@ -1279,8 +1232,6 @@ func (suite *ExchangeSelectorSuite) TestIsAny() {
cat exchangeCategory cat exchangeCategory
expect assert.BoolAssertionFunc expect assert.BoolAssertionFunc
}{ }{
{"any user", anyUser, ExchangeUser, assert.True},
{"no user", noUser, ExchangeUser, assert.False},
{"specific mail", specificMail, ExchangeMail, assert.False}, {"specific mail", specificMail, ExchangeMail, assert.False},
{"any mail", anyMail, ExchangeMail, assert.True}, {"any mail", anyMail, ExchangeMail, assert.True},
{"wrong category", anyMail, ExchangeEvent, assert.False}, {"wrong category", anyMail, ExchangeEvent, assert.False},
@ -1324,19 +1275,16 @@ func (suite *ExchangeSelectorSuite) TestExchangeCategory_PathValues() {
contactPath := stubPath(t, "user", []string{"cfolder", "contactitem"}, path.ContactsCategory) contactPath := stubPath(t, "user", []string{"cfolder", "contactitem"}, path.ContactsCategory)
contactMap := map[categorizer]string{ contactMap := map[categorizer]string{
ExchangeUser: contactPath.ResourceOwner(),
ExchangeContactFolder: contactPath.Folder(), ExchangeContactFolder: contactPath.Folder(),
ExchangeContact: contactPath.Item(), ExchangeContact: contactPath.Item(),
} }
eventPath := stubPath(t, "user", []string{"ecalendar", "eventitem"}, path.EventsCategory) eventPath := stubPath(t, "user", []string{"ecalendar", "eventitem"}, path.EventsCategory)
eventMap := map[categorizer]string{ eventMap := map[categorizer]string{
ExchangeUser: eventPath.ResourceOwner(),
ExchangeEventCalendar: eventPath.Folder(), ExchangeEventCalendar: eventPath.Folder(),
ExchangeEvent: eventPath.Item(), ExchangeEvent: eventPath.Item(),
} }
mailPath := stubPath(t, "user", []string{"mfolder", "mailitem"}, path.EmailCategory) mailPath := stubPath(t, "user", []string{"mfolder", "mailitem"}, path.EmailCategory)
mailMap := map[categorizer]string{ mailMap := map[categorizer]string{
ExchangeUser: mailPath.ResourceOwner(),
ExchangeMailFolder: mailPath.Folder(), ExchangeMailFolder: mailPath.Folder(),
ExchangeMail: mailPath.Item(), ExchangeMail: mailPath.Item(),
} }
@ -1358,9 +1306,9 @@ func (suite *ExchangeSelectorSuite) TestExchangeCategory_PathValues() {
} }
func (suite *ExchangeSelectorSuite) TestExchangeCategory_PathKeys() { func (suite *ExchangeSelectorSuite) TestExchangeCategory_PathKeys() {
contact := []categorizer{ExchangeUser, ExchangeContactFolder, ExchangeContact} contact := []categorizer{ExchangeContactFolder, ExchangeContact}
event := []categorizer{ExchangeUser, ExchangeEventCalendar, ExchangeEvent} event := []categorizer{ExchangeEventCalendar, ExchangeEvent}
mail := []categorizer{ExchangeUser, ExchangeMailFolder, ExchangeMail} mail := []categorizer{ExchangeMailFolder, ExchangeMail}
user := []categorizer{ExchangeUser} user := []categorizer{ExchangeUser}
var empty []categorizer var empty []categorizer

View File

@ -205,15 +205,15 @@ func (s *oneDrive) DiscreteScopes(userPNs []string) []OneDriveScope {
// ------------------- // -------------------
// Scope Factories // Scope Factories
// Produces one or more OneDrive user scopes. // Retrieves all OneDrive data.
// One scope is created per user entry. // One scope is created per user entry.
// 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 (s *oneDrive) Users(users []string) []OneDriveScope { func (s *oneDrive) AllData() []OneDriveScope {
scopes := []OneDriveScope{} scopes := []OneDriveScope{}
scopes = append(scopes, makeScope[OneDriveScope](OneDriveFolder, users, Any())) scopes = append(scopes, makeScope[OneDriveScope](OneDriveFolder, Any()))
return scopes return scopes
} }
@ -223,7 +223,7 @@ func (s *oneDrive) Users(users []string) []OneDriveScope {
// 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]
// options are only applied to the folder scopes. // options are only applied to the folder scopes.
func (s *oneDrive) Folders(users, folders []string, opts ...option) []OneDriveScope { func (s *oneDrive) Folders(folders []string, opts ...option) []OneDriveScope {
var ( var (
scopes = []OneDriveScope{} scopes = []OneDriveScope{}
os = append([]option{pathComparator()}, opts...) os = append([]option{pathComparator()}, opts...)
@ -231,7 +231,7 @@ func (s *oneDrive) Folders(users, folders []string, opts ...option) []OneDriveSc
scopes = append( scopes = append(
scopes, scopes,
makeScope[OneDriveScope](OneDriveFolder, users, folders, os...), makeScope[OneDriveScope](OneDriveFolder, folders, os...),
) )
return scopes return scopes
@ -242,12 +242,12 @@ func (s *oneDrive) Folders(users, folders []string, opts ...option) []OneDriveSc
// 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]
// options are only applied to the folder scopes. // options are only applied to the folder scopes.
func (s *oneDrive) Items(users, folders, items []string, opts ...option) []OneDriveScope { func (s *oneDrive) Items(folders, items []string, opts ...option) []OneDriveScope {
scopes := []OneDriveScope{} scopes := []OneDriveScope{}
scopes = append( scopes = append(
scopes, scopes,
makeScope[OneDriveScope](OneDriveItem, users, items). makeScope[OneDriveScope](OneDriveItem, items).
set(OneDriveFolder, folders, opts...), set(OneDriveFolder, folders, opts...),
) )
@ -341,7 +341,7 @@ const (
// oneDriveLeafProperties describes common metadata of the leaf categories // oneDriveLeafProperties describes common metadata of the leaf categories
var oneDriveLeafProperties = map[categorizer]leafProperty{ var oneDriveLeafProperties = map[categorizer]leafProperty{
OneDriveItem: { OneDriveItem: {
pathKeys: []categorizer{OneDriveUser, OneDriveFolder, OneDriveItem}, pathKeys: []categorizer{OneDriveFolder, OneDriveItem},
pathType: path.FilesCategory, pathType: path.FilesCategory,
}, },
OneDriveUser: { // the root category must be represented, even though it isn't a leaf OneDriveUser: { // the root category must be represented, even though it isn't a leaf
@ -401,7 +401,6 @@ func (c oneDriveCategory) pathValues(p path.Path) map[categorizer]string {
folder := path.Builder{}.Append(p.Folders()...).PopFront().PopFront().PopFront().String() folder := path.Builder{}.Append(p.Folders()...).PopFront().PopFront().PopFront().String()
return map[categorizer]string{ return map[categorizer]string{
OneDriveUser: p.ResourceOwner(),
OneDriveFolder: folder, OneDriveFolder: folder,
OneDriveItem: p.Item(), OneDriveItem: p.Item(),
} }

View File

@ -69,41 +69,34 @@ func (suite *OneDriveSelectorSuite) TestOneDriveBackup_DiscreteScopes() {
for _, test := range table { for _, test := range table {
suite.T().Run(test.name, func(t *testing.T) { suite.T().Run(test.name, func(t *testing.T) {
eb := NewOneDriveBackup(test.include) // todo: remove discreteScopes
eb.Include(eb.Users(test.include)) // eb := NewOneDriveBackup(test.include)
// eb.Include(eb.AllData())
scopes := eb.DiscreteScopes(test.discrete) // scopes := eb.DiscreteScopes(test.discrete)
for _, sc := range scopes { // for _, sc := range scopes {
users := sc.Get(OneDriveUser) // users := sc.Get(OneDriveUser)
assert.Equal(t, test.expect, users) // assert.Equal(t, test.expect, users)
} // }
}) })
} }
} }
func (suite *OneDriveSelectorSuite) TestOneDriveSelector_Users() { func (suite *OneDriveSelectorSuite) TestOneDriveSelector_AllData() {
t := suite.T() t := suite.T()
const (
u1 = "u1"
u2 = "u2"
)
var ( var (
users = []string{u1, u2} users = []string{"u1", "u2"}
sel = NewOneDriveBackup(users) sel = NewOneDriveBackup(users)
userScopes = sel.Users(users) allScopes = sel.AllData()
) )
for _, scope := range userScopes { assert.ElementsMatch(t, users, sel.DiscreteResourceOwners())
// Scope value is either u1 or u2
assert.Contains(t, join(u1, u2), scope[OneDriveUser.String()].Target)
}
// Initialize the selector Include, Exclude, Filter // Initialize the selector Include, Exclude, Filter
sel.Exclude(userScopes) sel.Exclude(allScopes)
sel.Include(userScopes) sel.Include(allScopes)
sel.Filter(userScopes) sel.Filter(allScopes)
table := []struct { table := []struct {
name string name string
@ -117,14 +110,20 @@ func (suite *OneDriveSelectorSuite) TestOneDriveSelector_Users() {
suite.T().Run(test.name, func(t *testing.T) { suite.T().Run(test.name, func(t *testing.T) {
require.Len(t, test.scopesToCheck, 1) require.Len(t, test.scopesToCheck, 1)
for _, scope := range test.scopesToCheck { for _, scope := range test.scopesToCheck {
// Scope value is u1,u2 scopeMustHave(
assert.Contains(t, join(u1, u2), scope[OneDriveUser.String()].Target) t,
OneDriveScope(scope),
map[categorizer]string{
OneDriveItem: AnyTgt,
OneDriveFolder: AnyTgt,
},
)
} }
}) })
} }
} }
func (suite *OneDriveSelectorSuite) TestOneDriveSelector_Include_Users() { func (suite *OneDriveSelectorSuite) TestOneDriveSelector_Include_AllData() {
t := suite.T() t := suite.T()
const ( const (
@ -135,10 +134,10 @@ func (suite *OneDriveSelectorSuite) TestOneDriveSelector_Include_Users() {
var ( var (
users = []string{u1, u2} users = []string{u1, u2}
sel = NewOneDriveBackup(users) sel = NewOneDriveBackup(users)
userScopes = sel.Users(users) allScopes = sel.AllData()
) )
sel.Include(userScopes) sel.Include(allScopes)
scopes := sel.Includes scopes := sel.Includes
require.Len(t, scopes, 1) require.Len(t, scopes, 1)
@ -146,12 +145,15 @@ func (suite *OneDriveSelectorSuite) TestOneDriveSelector_Include_Users() {
scopeMustHave( scopeMustHave(
t, t,
OneDriveScope(sc), OneDriveScope(sc),
map[categorizer]string{OneDriveUser: join(u1, u2)}, map[categorizer]string{
OneDriveItem: AnyTgt,
OneDriveFolder: AnyTgt,
},
) )
} }
} }
func (suite *OneDriveSelectorSuite) TestOneDriveSelector_Exclude_Users() { func (suite *OneDriveSelectorSuite) TestOneDriveSelector_Exclude_AllData() {
t := suite.T() t := suite.T()
const ( const (
@ -162,10 +164,10 @@ func (suite *OneDriveSelectorSuite) TestOneDriveSelector_Exclude_Users() {
var ( var (
users = []string{u1, u2} users = []string{u1, u2}
sel = NewOneDriveBackup(users) sel = NewOneDriveBackup(users)
userScopes = sel.Users(users) allScopes = sel.AllData()
) )
sel.Exclude(userScopes) sel.Exclude(allScopes)
scopes := sel.Excludes scopes := sel.Excludes
require.Len(t, scopes, 1) require.Len(t, scopes, 1)
@ -173,7 +175,10 @@ func (suite *OneDriveSelectorSuite) TestOneDriveSelector_Exclude_Users() {
scopeMustHave( scopeMustHave(
t, t,
OneDriveScope(sc), OneDriveScope(sc),
map[categorizer]string{OneDriveUser: join(u1, u2)}, map[categorizer]string{
OneDriveItem: AnyTgt,
OneDriveFolder: AnyTgt,
},
) )
} }
} }
@ -248,7 +253,7 @@ func (suite *OneDriveSelectorSuite) TestOneDriveRestore_Reduce() {
deets, deets,
func() *OneDriveRestore { func() *OneDriveRestore {
odr := NewOneDriveRestore(Any()) odr := NewOneDriveRestore(Any())
odr.Include(odr.Users(Any())) odr.Include(odr.AllData())
return odr return odr
}, },
arr(file, file2, file3), arr(file, file2, file3),
@ -258,7 +263,7 @@ func (suite *OneDriveSelectorSuite) TestOneDriveRestore_Reduce() {
deets, deets,
func() *OneDriveRestore { func() *OneDriveRestore {
odr := NewOneDriveRestore(Any()) odr := NewOneDriveRestore(Any())
odr.Include(odr.Items(Any(), Any(), []string{"file2"})) odr.Include(odr.Items(Any(), []string{"file2"}))
return odr return odr
}, },
arr(file2), arr(file2),
@ -268,7 +273,7 @@ func (suite *OneDriveSelectorSuite) TestOneDriveRestore_Reduce() {
deets, deets,
func() *OneDriveRestore { func() *OneDriveRestore {
odr := NewOneDriveRestore([]string{"uid"}) odr := NewOneDriveRestore([]string{"uid"})
odr.Include(odr.Folders([]string{"uid"}, []string{"folderA/folderB", "folderA/folderC"})) odr.Include(odr.Folders([]string{"folderA/folderB", "folderA/folderC"}))
return odr return odr
}, },
arr(file, file2), arr(file, file2),
@ -295,7 +300,6 @@ func (suite *OneDriveSelectorSuite) TestOneDriveCategory_PathValues() {
require.NoError(t, err) require.NoError(t, err)
expected := map[categorizer]string{ expected := map[categorizer]string{
OneDriveUser: "user",
OneDriveFolder: "dir1/dir2", OneDriveFolder: "dir1/dir2",
OneDriveItem: "file", OneDriveItem: "file",
} }

View File

@ -161,7 +161,7 @@ type (
// makeScope produces a well formatted, typed scope that ensures all base values are populated. // makeScope produces a well formatted, typed scope that ensures all base values are populated.
func makeScope[T scopeT]( func makeScope[T scopeT](
cat categorizer, cat categorizer,
resources, vs []string, vs []string,
opts ...option, opts ...option,
) T { ) T {
sc := &scopeConfig{} sc := &scopeConfig{}
@ -171,7 +171,6 @@ func makeScope[T scopeT](
scopeKeyCategory: filters.Identity(cat.String()), scopeKeyCategory: filters.Identity(cat.String()),
scopeKeyDataType: filters.Identity(cat.leafCat().String()), scopeKeyDataType: filters.Identity(cat.leafCat().String()),
cat.String(): filterize(*sc, vs...), cat.String(): filterize(*sc, vs...),
cat.rootCat().String(): filterize(scopeConfig{}, resources...),
} }
return s return s
@ -326,14 +325,14 @@ func reduce[T scopeT, C categoryT](
continue continue
} }
passed := passes( e, f, i := excls[dc], filts[dc], incls[dc]
dc,
dc.pathValues(repoPath), // at least one filter or inclusion must be presentt
*ent, if len(f)+len(i) == 0 {
excls[dc], continue
filts[dc], }
incls[dc],
) passed := passes(dc, dc.pathValues(repoPath), *ent, e, f, i)
if passed { if passed {
ents = append(ents, *ent) ents = append(ents, *ent)
} }

View File

@ -98,7 +98,18 @@ type Selector struct {
// A record of the resource owners matched by this selector. // A record of the resource owners matched by this selector.
ResourceOwners filters.Filter `json:"resourceOwners,omitempty"` ResourceOwners filters.Filter `json:"resourceOwners,omitempty"`
// The single resource owner used by the selector after splitting. // The single resource owner being observed by the selector.
// Selectors are constructed by passing in a list of ResourceOwners,
// and those owners represent the "total" data that should be operated
// across all corso operations. But any single operation (backup,restore,
// etc) will only observe a single user at a time, and that user is
// represented by this value.
//
// If the constructor is passed a len=1 list of owners, this value is
// automatically matched to that entry. For lists with more than one
// owner, the user is expected to call SplitByResourceOwner(), and
// iterate over the results, where each one will populate this field
// with a different owner.
DiscreteOwner string `json:"discreteOwner,omitempty"` DiscreteOwner string `json:"discreteOwner,omitempty"`
// A slice of exclusion scopes. Exclusions apply globally to all // A slice of exclusion scopes. Exclusions apply globally to all
@ -114,7 +125,7 @@ type Selector struct {
// helper for specific selector instance constructors. // helper for specific selector instance constructors.
func newSelector(s service, resourceOwners []string) Selector { func newSelector(s service, resourceOwners []string) Selector {
var owner string var owner string
if len(resourceOwners) == 1 { if len(resourceOwners) == 1 && resourceOwners[0] != AnyTgt {
owner = resourceOwners[0] owner = resourceOwners[0]
} }
@ -312,6 +323,7 @@ func selectorAsIface[T any](s Selector) (T, error) {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
type Printable struct { type Printable struct {
ResourceOwners []string `json:"resourceOwners"`
Service string `json:"service"` Service string `json:"service"`
Excludes map[string][]string `json:"excludes,omitempty"` Excludes map[string][]string `json:"excludes,omitempty"`
Filters map[string][]string `json:"filters,omitempty"` Filters map[string][]string `json:"filters,omitempty"`
@ -335,6 +347,7 @@ func (s Selector) ToPrintable() Printable {
// toPrintable creates the minimized display of a selector, formatted for human readability. // toPrintable creates the minimized display of a selector, formatted for human readability.
func toPrintable[T scopeT](s Selector) Printable { func toPrintable[T scopeT](s Selector) Printable {
return Printable{ return Printable{
ResourceOwners: s.DiscreteResourceOwners(),
Service: s.Service.String(), Service: s.Service.String(),
Excludes: toResourceTypeMap[T](s.Excludes), Excludes: toResourceTypeMap[T](s.Excludes),
Filters: toResourceTypeMap[T](s.Filters), Filters: toResourceTypeMap[T](s.Filters),
@ -349,33 +362,30 @@ func toPrintable[T scopeT](s Selector) Printable {
// Resource refers to the top-level entity in the service. User for Exchange, // Resource refers to the top-level entity in the service. User for Exchange,
// Site for sharepoint, etc. // Site for sharepoint, etc.
func (p Printable) Resources() string { func (p Printable) Resources() string {
s := resourcesShortFormat(p.Includes) s := resourcesShortFormat(p.ResourceOwners)
if len(s) == 0 {
s = resourcesShortFormat(p.Filters)
}
if len(s) == 0 { if len(s) == 0 {
s = "None" s = "None"
} }
if s == AnyTgt {
s = "All"
}
return s return s
} }
// returns a string with the resources in the map. Shortened to the first resource key, // returns a string with the resources in the map. Shortened to the first resource key,
// plus, if more exist, " (len-1 more)" // plus, if more exist, " (len-1 more)"
func resourcesShortFormat(m map[string][]string) string { func resourcesShortFormat(ros []string) string {
var s string switch len(ros) {
case 0:
for k := range m { return ""
s = k case 1:
break return ros[0]
default:
return fmt.Sprintf("%s (%d more)", ros[0], len(ros)-1)
} }
if len(s) > 0 && len(m) > 1 {
s = fmt.Sprintf("%s (%d more)", s, len(m)-1)
}
return s
} }
// Transforms the slice to a single map. // Transforms the slice to a single map.

View File

@ -36,11 +36,7 @@ func (suite *SelectorReduceSuite) TestReduce() {
name: "ExchangeAllMail", name: "ExchangeAllMail",
selFunc: func() selectors.Reducer { selFunc: func() selectors.Reducer {
sel := selectors.NewExchangeRestore(selectors.Any()) sel := selectors.NewExchangeRestore(selectors.Any())
sel.Include(sel.Mails( sel.Include(sel.Mails(selectors.Any(), selectors.Any()))
selectors.Any(),
selectors.Any(),
selectors.Any(),
))
return sel return sel
}, },
@ -51,7 +47,6 @@ func (suite *SelectorReduceSuite) TestReduce() {
selFunc: func() selectors.Reducer { selFunc: func() selectors.Reducer {
sel := selectors.NewExchangeRestore(selectors.Any()) sel := selectors.NewExchangeRestore(selectors.Any())
sel.Include(sel.MailFolders( sel.Include(sel.MailFolders(
selectors.Any(),
[]string{testdata.ExchangeEmailInboxPath.Folder()}, []string{testdata.ExchangeEmailInboxPath.Folder()},
)) ))
@ -75,7 +70,6 @@ func (suite *SelectorReduceSuite) TestReduce() {
sel := selectors.NewExchangeRestore(selectors.Any()) sel := selectors.NewExchangeRestore(selectors.Any())
sel.Filter(sel.MailSender("a-person")) sel.Filter(sel.MailSender("a-person"))
sel.Exclude(sel.Mails( sel.Exclude(sel.Mails(
selectors.Any(),
selectors.Any(), selectors.Any(),
[]string{testdata.ExchangeEmailItemPath2.ShortRef()}, []string{testdata.ExchangeEmailItemPath2.ShortRef()},
)) ))
@ -114,7 +108,6 @@ func (suite *SelectorReduceSuite) TestReduce() {
selFunc: func() selectors.Reducer { selFunc: func() selectors.Reducer {
sel := selectors.NewExchangeRestore(selectors.Any()) sel := selectors.NewExchangeRestore(selectors.Any())
sel.Include(sel.Mails( sel.Include(sel.Mails(
selectors.Any(),
selectors.Any(), selectors.Any(),
[]string{testdata.ExchangeEmailItemPath1.Item()}, []string{testdata.ExchangeEmailItemPath1.Item()},
)) ))
@ -128,7 +121,6 @@ func (suite *SelectorReduceSuite) TestReduce() {
selFunc: func() selectors.Reducer { selFunc: func() selectors.Reducer {
sel := selectors.NewExchangeRestore(selectors.Any()) sel := selectors.NewExchangeRestore(selectors.Any())
sel.Include(sel.Mails( sel.Include(sel.Mails(
selectors.Any(),
selectors.Any(), selectors.Any(),
[]string{testdata.ExchangeEmailItemPath1.ShortRef()}, []string{testdata.ExchangeEmailItemPath1.ShortRef()},
)) ))
@ -144,7 +136,6 @@ func (suite *SelectorReduceSuite) TestReduce() {
sel.Include(sel.Events( sel.Include(sel.Events(
selectors.Any(), selectors.Any(),
selectors.Any(), selectors.Any(),
selectors.Any(),
)) ))
sel.Filter(sel.MailSubject("foo")) sel.Filter(sel.MailSubject("foo"))
@ -167,9 +158,7 @@ func (suite *SelectorReduceSuite) TestReduce() {
name: "ExchangeAll", name: "ExchangeAll",
selFunc: func() selectors.Reducer { selFunc: func() selectors.Reducer {
sel := selectors.NewExchangeRestore(selectors.Any()) sel := selectors.NewExchangeRestore(selectors.Any())
sel.Include(sel.Users( sel.Include(sel.AllData())
selectors.Any(),
))
return sel return sel
}, },
@ -187,7 +176,6 @@ func (suite *SelectorReduceSuite) TestReduce() {
selFunc: func() selectors.Reducer { selFunc: func() selectors.Reducer {
sel := selectors.NewExchangeRestore(selectors.Any()) sel := selectors.NewExchangeRestore(selectors.Any())
sel.Include(sel.MailFolders( sel.Include(sel.MailFolders(
selectors.Any(),
[]string{testdata.ExchangeEmailBasePath.Folder()}, []string{testdata.ExchangeEmailBasePath.Folder()},
)) ))
@ -203,7 +191,6 @@ func (suite *SelectorReduceSuite) TestReduce() {
selFunc: func() selectors.Reducer { selFunc: func() selectors.Reducer {
sel := selectors.NewExchangeRestore(selectors.Any()) sel := selectors.NewExchangeRestore(selectors.Any())
sel.Include(sel.MailFolders( sel.Include(sel.MailFolders(
selectors.Any(),
[]string{testdata.ExchangeEmailBasePath.Folder()}, []string{testdata.ExchangeEmailBasePath.Folder()},
selectors.PrefixMatch(), // force prefix matching selectors.PrefixMatch(), // force prefix matching
)) ))
@ -217,7 +204,6 @@ func (suite *SelectorReduceSuite) TestReduce() {
selFunc: func() selectors.Reducer { selFunc: func() selectors.Reducer {
sel := selectors.NewExchangeRestore(selectors.Any()) sel := selectors.NewExchangeRestore(selectors.Any())
sel.Include(sel.MailFolders( sel.Include(sel.MailFolders(
selectors.Any(),
[]string{testdata.ExchangeEmailInboxPath.Folder()}, []string{testdata.ExchangeEmailInboxPath.Folder()},
)) ))
@ -230,7 +216,6 @@ func (suite *SelectorReduceSuite) TestReduce() {
selFunc: func() selectors.Reducer { selFunc: func() selectors.Reducer {
sel := selectors.NewExchangeRestore(selectors.Any()) sel := selectors.NewExchangeRestore(selectors.Any())
sel.Include(sel.ContactFolders( sel.Include(sel.ContactFolders(
selectors.Any(),
[]string{testdata.ExchangeContactsBasePath.Folder()}, []string{testdata.ExchangeContactsBasePath.Folder()},
)) ))
@ -243,7 +228,6 @@ func (suite *SelectorReduceSuite) TestReduce() {
selFunc: func() selectors.Reducer { selFunc: func() selectors.Reducer {
sel := selectors.NewExchangeRestore(selectors.Any()) sel := selectors.NewExchangeRestore(selectors.Any())
sel.Include(sel.ContactFolders( sel.Include(sel.ContactFolders(
selectors.Any(),
[]string{testdata.ExchangeContactsRootPath.Folder()}, []string{testdata.ExchangeContactsRootPath.Folder()},
)) ))
@ -257,7 +241,6 @@ func (suite *SelectorReduceSuite) TestReduce() {
selFunc: func() selectors.Reducer { selFunc: func() selectors.Reducer {
sel := selectors.NewExchangeRestore(selectors.Any()) sel := selectors.NewExchangeRestore(selectors.Any())
sel.Include(sel.EventCalendars( sel.Include(sel.EventCalendars(
selectors.Any(),
[]string{testdata.ExchangeEventsBasePath.Folder()}, []string{testdata.ExchangeEventsBasePath.Folder()},
)) ))
@ -270,7 +253,6 @@ func (suite *SelectorReduceSuite) TestReduce() {
selFunc: func() selectors.Reducer { selFunc: func() selectors.Reducer {
sel := selectors.NewExchangeRestore(selectors.Any()) sel := selectors.NewExchangeRestore(selectors.Any())
sel.Include(sel.EventCalendars( sel.Include(sel.EventCalendars(
selectors.Any(),
[]string{testdata.ExchangeEventsRootPath.Folder()}, []string{testdata.ExchangeEventsRootPath.Folder()},
)) ))
@ -282,10 +264,6 @@ func (suite *SelectorReduceSuite) TestReduce() {
for _, test := range table { for _, test := range table {
suite.T().Run(test.name, func(t *testing.T) { suite.T().Run(test.name, func(t *testing.T) {
test := test
t.Parallel()
output := test.selFunc().Reduce(ctx, allDetails) output := test.selFunc().Reduce(ctx, allDetails)
assert.ElementsMatch(t, test.expected, output.Entries) assert.ElementsMatch(t, test.expected, output.Entries)
}) })

View File

@ -71,15 +71,10 @@ func (suite *SelectorSuite) TestPrintable_IncludedResources() {
for _, test := range table { for _, test := range table {
suite.T().Run(test.name, func(t *testing.T) { suite.T().Run(test.name, func(t *testing.T) {
sel := stubSelector(test.resourceOwners) sel := stubSelector(test.resourceOwners)
p := sel.Printable()
res := p.Resources()
assert.Equal(t, "All", res, "stub starts out as an all-pass")
stubWithResource := func(resource string) scope { stubWithResource := func(resource string) scope {
ss := stubScope("") ss := stubScope("")
ss[rootCatStub.String()] = filterize(scopeConfig{}, resource) ss[rootCatStub.String()] = filterize(scopeConfig{}, resource)
return scope(ss) return scope(ss)
} }
@ -90,11 +85,6 @@ func (suite *SelectorSuite) TestPrintable_IncludedResources() {
sel.Includes = append(sel.Includes, stubWithResource(ro)) sel.Includes = append(sel.Includes, stubWithResource(ro))
sel.Filters = append(sel.Filters, stubWithResource(ro)) sel.Filters = append(sel.Filters, stubWithResource(ro))
} }
p = sel.Printable()
res = p.Resources()
assert.True(t, test.expect(res), test.reason)
}) })
} }
} }

View File

@ -233,13 +233,13 @@ func (s *SharePointRestore) WebURL(urlSuffixes []string, opts ...option) []Share
// 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 (s *sharePoint) Sites(sites []string) []SharePointScope { func (s *sharePoint) AllData() []SharePointScope {
scopes := []SharePointScope{} scopes := []SharePointScope{}
scopes = append( scopes = append(
scopes, scopes,
makeScope[SharePointScope](SharePointLibrary, sites, Any()), makeScope[SharePointScope](SharePointLibrary, Any()),
makeScope[SharePointScope](SharePointList, sites, Any()), makeScope[SharePointScope](SharePointList, Any()),
) )
return scopes return scopes
@ -249,13 +249,13 @@ func (s *sharePoint) Sites(sites []string) []SharePointScope {
// 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]
// Any empty slice defaults to [selectors.None] // Any empty slice defaults to [selectors.None]
func (s *sharePoint) Lists(sites, lists []string, opts ...option) []SharePointScope { func (s *sharePoint) Lists(lists []string, opts ...option) []SharePointScope {
var ( var (
scopes = []SharePointScope{} scopes = []SharePointScope{}
os = append([]option{pathComparator()}, opts...) os = append([]option{pathComparator()}, opts...)
) )
scopes = append(scopes, makeScope[SharePointScope](SharePointList, sites, lists, os...)) scopes = append(scopes, makeScope[SharePointScope](SharePointList, lists, os...))
return scopes return scopes
} }
@ -265,12 +265,12 @@ func (s *sharePoint) Lists(sites, lists []string, opts ...option) []SharePointSc
// 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]
// options are only applied to the list scopes. // options are only applied to the list scopes.
func (s *sharePoint) ListItems(sites, lists, items []string, opts ...option) []SharePointScope { func (s *sharePoint) ListItems(lists, items []string, opts ...option) []SharePointScope {
scopes := []SharePointScope{} scopes := []SharePointScope{}
scopes = append( scopes = append(
scopes, scopes,
makeScope[SharePointScope](SharePointListItem, sites, items). makeScope[SharePointScope](SharePointListItem, items).
set(SharePointList, lists, opts...), set(SharePointList, lists, opts...),
) )
@ -281,7 +281,7 @@ func (s *sharePoint) ListItems(sites, lists, items []string, opts ...option) []S
// 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 (s *sharePoint) Libraries(sites, libraries []string, opts ...option) []SharePointScope { func (s *sharePoint) Libraries(libraries []string, opts ...option) []SharePointScope {
var ( var (
scopes = []SharePointScope{} scopes = []SharePointScope{}
os = append([]option{pathComparator()}, opts...) os = append([]option{pathComparator()}, opts...)
@ -289,7 +289,7 @@ func (s *sharePoint) Libraries(sites, libraries []string, opts ...option) []Shar
scopes = append( scopes = append(
scopes, scopes,
makeScope[SharePointScope](SharePointLibrary, sites, libraries, os...), makeScope[SharePointScope](SharePointLibrary, libraries, os...),
) )
return scopes return scopes
@ -300,12 +300,12 @@ func (s *sharePoint) Libraries(sites, libraries []string, opts ...option) []Shar
// 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]
// options are only applied to the library scopes. // options are only applied to the library scopes.
func (s *sharePoint) LibraryItems(sites, libraries, items []string, opts ...option) []SharePointScope { func (s *sharePoint) LibraryItems(libraries, items []string, opts ...option) []SharePointScope {
scopes := []SharePointScope{} scopes := []SharePointScope{}
scopes = append( scopes = append(
scopes, scopes,
makeScope[SharePointScope](SharePointLibraryItem, sites, items). makeScope[SharePointScope](SharePointLibraryItem, items).
set(SharePointLibrary, libraries, opts...), set(SharePointLibrary, libraries, opts...),
) )
@ -343,7 +343,7 @@ const (
// sharePointLeafProperties describes common metadata of the leaf categories // sharePointLeafProperties describes common metadata of the leaf categories
var sharePointLeafProperties = map[categorizer]leafProperty{ var sharePointLeafProperties = map[categorizer]leafProperty{
SharePointLibraryItem: { SharePointLibraryItem: {
pathKeys: []categorizer{SharePointSite, SharePointLibrary, SharePointLibraryItem}, pathKeys: []categorizer{SharePointLibrary, SharePointLibraryItem},
pathType: path.LibrariesCategory, pathType: path.LibrariesCategory,
}, },
SharePointSite: { // the root category must be represented, even though it isn't a leaf SharePointSite: { // the root category must be represented, even though it isn't a leaf
@ -413,7 +413,6 @@ func (c sharePointCategory) pathValues(p path.Path) map[categorizer]string {
} }
return map[categorizer]string{ return map[categorizer]string{
SharePointSite: p.ResourceOwner(),
folderCat: p.Folder(), folderCat: p.Folder(),
itemCat: p.Item(), itemCat: p.Item(),
} }

View File

@ -67,33 +67,28 @@ func (suite *SharePointSelectorSuite) TestSharePointBackup_DiscreteScopes() {
for _, test := range table { for _, test := range table {
suite.T().Run(test.name, func(t *testing.T) { suite.T().Run(test.name, func(t *testing.T) {
eb := NewSharePointBackup(test.include) // todo: remove discreteScopes
eb.Include(eb.Sites(test.include)) // eb := NewSharePointBackup(test.include)
// eb.Include(eb.AllData())
scopes := eb.DiscreteScopes(test.discrete) // scopes := eb.DiscreteScopes(test.discrete)
for _, sc := range scopes { // for _, sc := range scopes {
sites := sc.Get(SharePointSite) // sites := sc.Get(SharePointSite)
assert.Equal(t, test.expect, sites) // assert.Equal(t, test.expect, sites)
} // }
}) })
} }
} }
func (suite *SharePointSelectorSuite) TestSharePointSelector_Sites() { func (suite *SharePointSelectorSuite) TestSharePointSelector_AllData() {
t := suite.T() t := suite.T()
const ( sites := []string{"s1", "s2"}
s1 = "s1"
s2 = "s2"
)
sel := NewSharePointBackup([]string{s1, s2}) sel := NewSharePointBackup(sites)
siteScopes := sel.Sites([]string{s1, s2}) siteScopes := sel.AllData()
for _, scope := range siteScopes { assert.ElementsMatch(t, sites, sel.DiscreteResourceOwners())
// Scope value is either s1 or s2
assert.Contains(t, join(s1, s2), scope[SharePointSite.String()].Target)
}
// Initialize the selector Include, Exclude, Filter // Initialize the selector Include, Exclude, Filter
sel.Exclude(siteScopes) sel.Exclude(siteScopes)
@ -109,14 +104,38 @@ func (suite *SharePointSelectorSuite) TestSharePointSelector_Sites() {
{"Filter Scopes", sel.Filters}, {"Filter Scopes", sel.Filters},
} }
for _, test := range table { for _, test := range table {
suite.T().Run(test.name, func(t *testing.T) {
require.Len(t, test.scopesToCheck, 2) require.Len(t, test.scopesToCheck, 2)
for _, scope := range test.scopesToCheck { for _, scope := range test.scopesToCheck {
// Scope value is s1,s2 var (
assert.Contains(t, join(s1, s2), scope[SharePointSite.String()].Target) spsc = SharePointScope(scope)
cat = spsc.Category()
)
suite.T().Run(test.name+"-"+cat.String(), func(t *testing.T) {
switch cat {
case SharePointLibraryItem:
scopeMustHave(
t,
spsc,
map[categorizer]string{
SharePointLibraryItem: AnyTgt,
SharePointLibrary: AnyTgt,
},
)
case SharePointListItem:
scopeMustHave(
t,
spsc,
map[categorizer]string{
SharePointListItem: AnyTgt,
SharePointList: AnyTgt,
},
)
} }
}) })
} }
}
} }
func (suite *SharePointSelectorSuite) TestSharePointSelector_Include_WebURLs() { func (suite *SharePointSelectorSuite) TestSharePointSelector_Include_WebURLs() {
@ -198,52 +217,6 @@ func (suite *SharePointSelectorSuite) TestSharePointSelector_Exclude_WebURLs() {
} }
} }
// TestSharePointselector_Include_Sites ensures that the scopes of
// SharePoint Libraries & SharePoint Lists are created.
func (suite *SharePointSelectorSuite) TestSharePointSelector_Include_Sites() {
t := suite.T()
const (
s1 = "s1"
s2 = "s2"
)
sel := NewSharePointBackup([]string{s1, s2})
sel.Include(sel.Sites([]string{s1, s2}))
scopes := sel.Includes
require.Len(t, scopes, 2)
for _, sc := range scopes {
scopeMustHave(
t,
SharePointScope(sc),
map[categorizer]string{SharePointSite: join(s1, s2)},
)
}
}
func (suite *SharePointSelectorSuite) TestSharePointSelector_Exclude_Sites() {
t := suite.T()
const (
s1 = "s1"
s2 = "s2"
)
sel := NewSharePointBackup([]string{s1, s2})
sel.Exclude(sel.Sites([]string{s1, s2}))
scopes := sel.Excludes
require.Len(t, scopes, 2)
for _, sc := range scopes {
scopeMustHave(
t,
SharePointScope(sc),
map[categorizer]string{SharePointSite: join(s1, s2)},
)
}
}
func (suite *SharePointSelectorSuite) TestNewSharePointRestore() { func (suite *SharePointSelectorSuite) TestNewSharePointRestore() {
t := suite.T() t := suite.T()
or := NewSharePointRestore(nil) or := NewSharePointRestore(nil)
@ -314,7 +287,7 @@ func (suite *SharePointSelectorSuite) TestSharePointRestore_Reduce() {
deets: deets, deets: deets,
makeSelector: func() *SharePointRestore { makeSelector: func() *SharePointRestore {
odr := NewSharePointRestore(Any()) odr := NewSharePointRestore(Any())
odr.Include(odr.Sites(Any())) odr.Include(odr.AllData())
return odr return odr
}, },
expect: arr(item, item2, item3), expect: arr(item, item2, item3),
@ -324,7 +297,7 @@ func (suite *SharePointSelectorSuite) TestSharePointRestore_Reduce() {
deets: deets, deets: deets,
makeSelector: func() *SharePointRestore { makeSelector: func() *SharePointRestore {
odr := NewSharePointRestore(Any()) odr := NewSharePointRestore(Any())
odr.Include(odr.LibraryItems(Any(), Any(), []string{"item2"})) odr.Include(odr.LibraryItems(Any(), []string{"item2"}))
return odr return odr
}, },
expect: arr(item2), expect: arr(item2),
@ -334,7 +307,7 @@ func (suite *SharePointSelectorSuite) TestSharePointRestore_Reduce() {
deets: deets, deets: deets,
makeSelector: func() *SharePointRestore { makeSelector: func() *SharePointRestore {
odr := NewSharePointRestore([]string{"sid"}) odr := NewSharePointRestore([]string{"sid"})
odr.Include(odr.Libraries([]string{"sid"}, []string{"folderA/folderB", "folderA/folderC"})) odr.Include(odr.Libraries([]string{"folderA/folderB", "folderA/folderC"}))
return odr return odr
}, },
expect: arr(item, item2), expect: arr(item, item2),
@ -354,10 +327,8 @@ func (suite *SharePointSelectorSuite) TestSharePointRestore_Reduce() {
} }
func (suite *SharePointSelectorSuite) TestSharePointCategory_PathValues() { func (suite *SharePointSelectorSuite) TestSharePointCategory_PathValues() {
t := suite.T()
pathBuilder := path.Builder{}.Append("dir1", "dir2", "item") pathBuilder := path.Builder{}.Append("dir1", "dir2", "item")
ten := "tenant"
site := "site"
table := []struct { table := []struct {
name string name string
sc sharePointCategory sc sharePointCategory
@ -367,7 +338,6 @@ func (suite *SharePointSelectorSuite) TestSharePointCategory_PathValues() {
name: "SharePoint Libraries", name: "SharePoint Libraries",
sc: SharePointLibraryItem, sc: SharePointLibraryItem,
expected: map[categorizer]string{ expected: map[categorizer]string{
SharePointSite: site,
SharePointLibrary: "dir1/dir2", SharePointLibrary: "dir1/dir2",
SharePointLibraryItem: "item", SharePointLibraryItem: "item",
}, },
@ -376,7 +346,6 @@ func (suite *SharePointSelectorSuite) TestSharePointCategory_PathValues() {
name: "SharePoint Lists", name: "SharePoint Lists",
sc: SharePointListItem, sc: SharePointListItem,
expected: map[categorizer]string{ expected: map[categorizer]string{
SharePointSite: site,
SharePointList: "dir1/dir2", SharePointList: "dir1/dir2",
SharePointListItem: "item", SharePointListItem: "item",
}, },
@ -384,10 +353,10 @@ func (suite *SharePointSelectorSuite) TestSharePointCategory_PathValues() {
} }
for _, test := range table { for _, test := range table {
t.Run(test.name, func(t *testing.T) { suite.T().Run(test.name, func(t *testing.T) {
itemPath, err := pathBuilder.ToDataLayerSharePointPath( itemPath, err := pathBuilder.ToDataLayerSharePointPath(
ten, "tenant",
site, "site",
test.sc.PathType(), test.sc.PathType(),
true, true,
) )