utilize shorthash in selector sels (#854)
## Description The details entry shorthash can be treated as equal to the leaf item ID. This adds support to the selector reduce step to compare the leaf val to either the path item ID or the shortHash. ## Type of change - [x] 🌻 Feature ## Issue(s) * closes #572 ## Test Plan - [ ] 💪 Manual - [x] ⚡ Unit test - [x] 💚 E2E
This commit is contained in:
parent
a368570e20
commit
ed52a07e2f
@ -551,6 +551,11 @@ func (ec exchangeCategory) unknownCat() categorizer {
|
||||
return ExchangeCategoryUnknown
|
||||
}
|
||||
|
||||
// isLeaf is true if the category is a mail, event, or contact category.
|
||||
func (ec exchangeCategory) isLeaf() bool {
|
||||
return ec == ec.leafCat()
|
||||
}
|
||||
|
||||
// pathValues transforms a path to a map of identified properties.
|
||||
//
|
||||
// Example:
|
||||
@ -692,7 +697,7 @@ func (s ExchangeScope) matchesEntry(
|
||||
entry details.DetailsEntry,
|
||||
) bool {
|
||||
// matchesPathValues can be handled generically, thanks to SCIENCE.
|
||||
return matchesPathValues(s, cat.(exchangeCategory), pathValues) || s.matchesInfo(entry.Exchange)
|
||||
return matchesPathValues(s, cat.(exchangeCategory), pathValues, entry.ShortRef) || s.matchesInfo(entry.Exchange)
|
||||
}
|
||||
|
||||
// matchesInfo handles the standard behavior when comparing a scope and an ExchangeFilter
|
||||
|
||||
@ -779,30 +779,34 @@ func (suite *ExchangeSelectorSuite) TestExchangeScope_MatchesPath() {
|
||||
)
|
||||
|
||||
var (
|
||||
pth = stubPath(suite.T(), usr, []string{fld, mail}, path.EmailCategory)
|
||||
es = NewExchangeRestore()
|
||||
pth = stubPath(suite.T(), usr, []string{fld, mail}, path.EmailCategory)
|
||||
short = "thisisahashofsomekind"
|
||||
es = NewExchangeRestore()
|
||||
)
|
||||
|
||||
table := []struct {
|
||||
name string
|
||||
scope []ExchangeScope
|
||||
expect assert.BoolAssertionFunc
|
||||
name string
|
||||
scope []ExchangeScope
|
||||
shortRef string
|
||||
expect assert.BoolAssertionFunc
|
||||
}{
|
||||
{"all user's items", es.Users(Any()), assert.True},
|
||||
{"no user's items", es.Users(None()), assert.False},
|
||||
{"matching user", es.Users([]string{usr}), assert.True},
|
||||
{"non-matching user", es.Users([]string{"smarf"}), assert.False},
|
||||
{"one of multiple users", es.Users([]string{"smarf", usr}), assert.True},
|
||||
{"all folders", es.MailFolders(Any(), Any()), assert.True},
|
||||
{"no folders", es.MailFolders(Any(), None()), assert.False},
|
||||
{"matching folder", es.MailFolders(Any(), []string{fld}), assert.True},
|
||||
{"non-matching folder", es.MailFolders(Any(), []string{"smarf"}), assert.False},
|
||||
{"one of multiple folders", es.MailFolders(Any(), []string{"smarf", fld}), assert.True},
|
||||
{"all mail", es.Mails(Any(), Any(), Any()), assert.True},
|
||||
{"no mail", es.Mails(Any(), Any(), None()), assert.False},
|
||||
{"matching mail", es.Mails(Any(), Any(), []string{mail}), assert.True},
|
||||
{"non-matching mail", es.Mails(Any(), Any(), []string{"smarf"}), assert.False},
|
||||
{"one of multiple mails", es.Mails(Any(), Any(), []string{"smarf", mail}), assert.True},
|
||||
{"all user's items", es.Users(Any()), "", assert.True},
|
||||
{"no user's items", es.Users(None()), "", assert.False},
|
||||
{"matching user", es.Users([]string{usr}), "", assert.True},
|
||||
{"non-matching user", es.Users([]string{"smarf"}), "", assert.False},
|
||||
{"one of multiple users", es.Users([]string{"smarf", usr}), "", assert.True},
|
||||
{"all folders", es.MailFolders(Any(), Any()), "", assert.True},
|
||||
{"no folders", es.MailFolders(Any(), None()), "", assert.False},
|
||||
{"matching folder", es.MailFolders(Any(), []string{fld}), "", assert.True},
|
||||
{"non-matching folder", es.MailFolders(Any(), []string{"smarf"}), "", assert.False},
|
||||
{"one of multiple folders", es.MailFolders(Any(), []string{"smarf", fld}), "", assert.True},
|
||||
{"all mail", es.Mails(Any(), Any(), Any()), "", assert.True},
|
||||
{"no mail", es.Mails(Any(), Any(), None()), "", assert.False},
|
||||
{"matching mail", es.Mails(Any(), Any(), []string{mail}), "", assert.True},
|
||||
{"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 {
|
||||
suite.T().Run(test.name, func(t *testing.T) {
|
||||
@ -810,7 +814,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeScope_MatchesPath() {
|
||||
var aMatch bool
|
||||
for _, scope := range scopes {
|
||||
pv := ExchangeMail.pathValues(pth)
|
||||
if matchesPathValues(scope, ExchangeMail, pv) {
|
||||
if matchesPathValues(scope, ExchangeMail, pv, short) {
|
||||
aMatch = true
|
||||
break
|
||||
}
|
||||
@ -1072,7 +1076,8 @@ func (suite *ExchangeSelectorSuite) TestScopesByCategory() {
|
||||
}
|
||||
|
||||
func (suite *ExchangeSelectorSuite) TestPasses() {
|
||||
deets := details.DetailsEntry{}
|
||||
short := "thisisahashofsomekind"
|
||||
entry := details.DetailsEntry{ShortRef: short}
|
||||
|
||||
const (
|
||||
mid = "mailID"
|
||||
@ -1118,7 +1123,7 @@ func (suite *ExchangeSelectorSuite) TestPasses() {
|
||||
result := passes(
|
||||
cat,
|
||||
cat.pathValues(pth),
|
||||
deets,
|
||||
entry,
|
||||
test.excludes,
|
||||
test.filters,
|
||||
test.includes)
|
||||
|
||||
@ -47,6 +47,10 @@ func (mc mockCategorizer) unknownCat() categorizer {
|
||||
return unknownCatStub
|
||||
}
|
||||
|
||||
func (mc mockCategorizer) isLeaf() bool {
|
||||
return mc == leafCatStub
|
||||
}
|
||||
|
||||
func (mc mockCategorizer) pathValues(pth path.Path) map[categorizer]string {
|
||||
return map[categorizer]string{rootCatStub: "stub"}
|
||||
}
|
||||
|
||||
@ -183,6 +183,11 @@ func (c oneDriveCategory) unknownCat() categorizer {
|
||||
return OneDriveCategoryUnknown
|
||||
}
|
||||
|
||||
// isLeaf is true if the category is a mail, event, or contact category.
|
||||
func (c oneDriveCategory) isLeaf() bool {
|
||||
return c == c.leafCat()
|
||||
}
|
||||
|
||||
// pathValues transforms a path to a map of identified properties.
|
||||
//
|
||||
// Example:
|
||||
@ -271,7 +276,7 @@ func (s OneDriveScope) matchesEntry(
|
||||
entry details.DetailsEntry,
|
||||
) bool {
|
||||
// matchesPathValues can be handled generically, thanks to SCIENCE.
|
||||
return matchesPathValues(s, cat.(oneDriveCategory), pathValues) || s.matchesInfo(entry.OneDrive)
|
||||
return matchesPathValues(s, cat.(oneDriveCategory), pathValues, entry.ShortRef) || s.matchesInfo(entry.OneDrive)
|
||||
}
|
||||
|
||||
// matchesInfo handles the standard behavior when comparing a scope and an oneDriveInfo
|
||||
|
||||
@ -32,6 +32,10 @@ type (
|
||||
// unknownType returns the unknown category value
|
||||
unknownCat() categorizer
|
||||
|
||||
// isLeaf returns true if the category is one of the leaf categories.
|
||||
// eg: in a resourceOwner/folder/item structure, the item is the leaf.
|
||||
isLeaf() bool
|
||||
|
||||
// pathValues should produce a map of category:string pairs populated by extracting
|
||||
// values out of the path.Path struct.
|
||||
//
|
||||
@ -205,7 +209,6 @@ func isAnyTarget[T scopeT, C categoryT](s T, cat C) bool {
|
||||
|
||||
// reduce filters the entries in the details to only those that match the
|
||||
// inclusions, filters, and exclusions in the selector.
|
||||
//
|
||||
func reduce[T scopeT, C categoryT](
|
||||
ctx context.Context,
|
||||
deets *details.Details,
|
||||
@ -337,6 +340,7 @@ func matchesPathValues[T scopeT, C categoryT](
|
||||
sc T,
|
||||
cat C,
|
||||
pathValues map[categorizer]string,
|
||||
shortRef string,
|
||||
) bool {
|
||||
// if scope specifies a filter category,
|
||||
// path checking is automatically skipped.
|
||||
@ -362,7 +366,12 @@ func matchesPathValues[T scopeT, C categoryT](
|
||||
// all parts of the scope must match
|
||||
cc := c.(C)
|
||||
if !isAnyTarget(sc, cc) {
|
||||
if filters.NotContains(join(scopeVals...)).Compare(pathVal) {
|
||||
notMatch := filters.NotContains(join(scopeVals...))
|
||||
if c.isLeaf() && len(shortRef) > 0 {
|
||||
if notMatch.Compare(pathVal) && notMatch.Compare(shortRef) {
|
||||
return false
|
||||
}
|
||||
} else if notMatch.Compare(pathVal) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
@ -301,12 +301,15 @@ func toMockScope(sc []scope) []mockScope {
|
||||
func (suite *SelectorScopesSuite) TestMatchesPathValues() {
|
||||
cat := rootCatStub
|
||||
pvs := stubPathValues()
|
||||
short := "brunheelda"
|
||||
|
||||
table := []struct {
|
||||
name string
|
||||
rootVal string
|
||||
leafVal string
|
||||
expect assert.BoolAssertionFunc
|
||||
name string
|
||||
cat mockCategorizer
|
||||
rootVal string
|
||||
leafVal string
|
||||
shortRef string
|
||||
expect assert.BoolAssertionFunc
|
||||
}{
|
||||
{
|
||||
name: "matching values",
|
||||
@ -332,6 +335,20 @@ func (suite *SelectorScopesSuite) TestMatchesPathValues() {
|
||||
leafVal: "smarf",
|
||||
expect: assert.False,
|
||||
},
|
||||
{
|
||||
name: "leaf matches shortRef",
|
||||
rootVal: rootCatStub.String(),
|
||||
leafVal: short,
|
||||
shortRef: short,
|
||||
expect: assert.True,
|
||||
},
|
||||
{
|
||||
name: "root matches shortRef",
|
||||
rootVal: short,
|
||||
leafVal: leafCatStub.String(),
|
||||
shortRef: short,
|
||||
expect: assert.False,
|
||||
},
|
||||
}
|
||||
for _, test := range table {
|
||||
suite.T().Run(test.name, func(t *testing.T) {
|
||||
@ -339,7 +356,7 @@ func (suite *SelectorScopesSuite) TestMatchesPathValues() {
|
||||
sc[rootCatStub.String()] = filterize(test.rootVal)
|
||||
sc[leafCatStub.String()] = filterize(test.leafVal)
|
||||
|
||||
test.expect(t, matchesPathValues(sc, cat, pvs))
|
||||
test.expect(t, matchesPathValues(sc, cat, pvs, test.shortRef))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user