Issue-556 introduce discreteScopes in selector handling (#635)

Graph may have an easier time parsing scopes if the root
user is discretely identified, as opposed to being a wildcard.
DiscreteScopes() automatically handles replacement of
scopes matching Any() user with the set of user provided
discrete IDs.
This commit is contained in:
Keepers 2022-08-23 15:56:24 -06:00 committed by GitHub
parent 3b9c8e284c
commit 2d88e59cd0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 166 additions and 28 deletions

View File

@ -143,6 +143,13 @@ func (s *exchange) Scopes() []ExchangeScope {
return scopes[ExchangeScope](s.Selector)
}
// DiscreteScopes retrieves the list of exchangeScopes in the selector.
// If any Include scope's User category is set to Any, replaces that
// scope's value with the list of userIDs instead.
func (s *exchange) DiscreteScopes(userIDs []string) []ExchangeScope {
return discreteScopes[ExchangeScope](s.Selector, ExchangeUser, userIDs)
}
// -------------------
// Scope Factories

View File

@ -373,27 +373,69 @@ func (suite *ExchangeSourceSuite) TestExchangeDestination_GetOrDefault() {
}
}
var allScopesExceptUnknown = scope{
ExchangeContact.String(): AnyTgt,
ExchangeContactFolder.String(): AnyTgt,
ExchangeEvent.String(): AnyTgt,
ExchangeMail.String(): AnyTgt,
ExchangeMailFolder.String(): AnyTgt,
ExchangeUser.String(): AnyTgt,
}
func (suite *ExchangeSourceSuite) TestExchangeBackup_Scopes() {
eb := NewExchangeBackup()
eb.Includes = []scope{allScopesExceptUnknown}
// todo: swap the above for this
// eb := NewExchangeBackup().IncludeUsers(AnyTgt)
eb.Include(eb.Users(Any()))
scopes := eb.Scopes()
assert.Len(suite.T(), scopes, 1)
assert.Equal(
suite.T(),
allScopesExceptUnknown,
scope(scopes[0]))
assert.Len(suite.T(), scopes, 3)
for _, sc := range scopes {
cat := sc.Category()
suite.T().Run(cat.String(), func(t *testing.T) {
assert.True(t, sc.IsAny(ExchangeUser))
switch sc.Category() {
case ExchangeContactFolder:
assert.True(t, sc.IsAny(ExchangeContact))
assert.True(t, sc.IsAny(ExchangeContactFolder))
case ExchangeEvent:
assert.True(t, sc.IsAny(ExchangeEvent))
case ExchangeMailFolder:
assert.True(t, sc.IsAny(ExchangeMail))
assert.True(t, sc.IsAny(ExchangeMailFolder))
}
})
}
}
func (suite *ExchangeSourceSuite) TestExchangeBackup_DiscreteScopes() {
usrs := []string{"u1", "u2"}
table := []struct {
name string
include []string
discrete []string
expect []string
}{
{
name: "any user",
include: Any(),
discrete: usrs,
expect: usrs,
},
{
name: "discrete user",
include: []string{"u3"},
discrete: usrs,
expect: []string{"u3"},
},
{
name: "nil discrete slice",
include: Any(),
discrete: nil,
expect: Any(),
},
}
for _, test := range table {
suite.T().Run(test.name, func(t *testing.T) {
eb := NewExchangeBackup()
eb.Include(eb.Users(test.include))
scopes := eb.DiscreteScopes(test.discrete)
for _, sc := range scopes {
users := sc.Get(ExchangeUser)
assert.Equal(t, test.expect, users)
}
})
}
}
func (suite *ExchangeSourceSuite) TestExchangeScope_Category() {
@ -461,11 +503,9 @@ func (suite *ExchangeSourceSuite) TestExchangeScope_IncludesCategory() {
func (suite *ExchangeSourceSuite) TestExchangeScope_Get() {
eb := NewExchangeBackup()
eb.Includes = []scope{allScopesExceptUnknown}
// todo: swap the above for this
// eb := NewExchangeBackup().IncludeUsers(AnyTgt)
eb.Include(eb.Users(Any()))
scope := eb.Scopes()[0]
scopes := eb.Scopes()
table := []exchangeCategory{
ExchangeContact,
@ -476,15 +516,22 @@ func (suite *ExchangeSourceSuite) TestExchangeScope_Get() {
ExchangeUser,
}
assert.Equal(
suite.T(),
None(),
scope.Get(ExchangeCategoryUnknown))
expect := Any()
for _, test := range table {
suite.T().Run(test.String(), func(t *testing.T) {
assert.Equal(t, expect, scope.Get(test))
for _, sc := range scopes {
assert.Equal(t, Any(), sc.Get(ExchangeUser))
switch sc.Category() {
case ExchangeContactFolder:
assert.Equal(t, Any(), sc.Get(ExchangeContact))
assert.Equal(t, Any(), sc.Get(ExchangeContactFolder))
case ExchangeEvent:
assert.Equal(t, Any(), sc.Get(ExchangeEvent))
case ExchangeMailFolder:
assert.Equal(t, Any(), sc.Get(ExchangeMail))
assert.Equal(t, Any(), sc.Get(ExchangeMailFolder))
}
assert.Equal(t, None(), sc.Get(ExchangeCategoryUnknown))
}
})
}
}

View File

@ -121,6 +121,13 @@ func (s *onedrive) Scopes() []OneDriveScope {
return scopes[OneDriveScope](s.Selector)
}
// DiscreteScopes retrieves the list of onedriveScopes in the selector.
// If any Include scope's User category is set to Any, replaces that
// scope's value with the list of userIDs instead.
func (s *onedrive) DiscreteScopes(userIDs []string) []OneDriveScope {
return discreteScopes[OneDriveScope](s.Selector, OneDriveUser, userIDs)
}
// ---------------------------------------------------------------------------
// Categories
// ---------------------------------------------------------------------------

View File

@ -33,6 +33,47 @@ func (suite *OnedriveSourceSuite) TestToOnedriveBackup() {
assert.NotZero(t, ob.Scopes())
}
func (suite *OnedriveSourceSuite) TestOnedriveBackup_DiscreteScopes() {
usrs := []string{"u1", "u2"}
table := []struct {
name string
include []string
discrete []string
expect []string
}{
{
name: "any user",
include: Any(),
discrete: usrs,
expect: usrs,
},
{
name: "discrete user",
include: []string{"u3"},
discrete: usrs,
expect: []string{"u3"},
},
{
name: "nil discrete slice",
include: Any(),
discrete: nil,
expect: Any(),
},
}
for _, test := range table {
suite.T().Run(test.name, func(t *testing.T) {
eb := NewOneDriveBackup()
eb.Include(eb.Users(test.include))
scopes := eb.DiscreteScopes(test.discrete)
for _, sc := range scopes {
users := sc.Get(OneDriveUser)
assert.Equal(t, test.expect, users)
}
})
}
}
func (suite *OnedriveSourceSuite) TestOnedriveSelector_Users() {
t := suite.T()
sel := NewOneDriveBackup()

View File

@ -132,6 +132,42 @@ func scopes[T scopeT](s Selector) []T {
return scopes
}
// discreteScopes retrieves the list of scopes in the selector.
// for any scope in the `Includes` set, if scope.IsAny(rootCat),
// then that category's value is replaced with the provided set of
// discrete identifiers.
// If discreteIDs is an empty slice, returns the normal scopes(s).
// future TODO: if Includes is nil, return filters.
func discreteScopes[T scopeT, C categoryT](
s Selector,
rootCat C,
discreteIDs []string,
) []T {
sl := []T{}
jdid := join(discreteIDs...)
if len(jdid) == 0 {
return scopes[T](s)
}
for _, v := range s.Includes {
t := T(v)
if isAnyTarget(t, rootCat) {
w := T{}
for k, v := range t {
w[k] = v
}
set(w, rootCat, jdid)
t = w
}
sl = append(sl, t)
}
return sl
}
// ---------------------------------------------------------------------------
// Printing Selectors for Human Reading
// ---------------------------------------------------------------------------