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
|
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.
|
// pathValues transforms a path to a map of identified properties.
|
||||||
//
|
//
|
||||||
// Example:
|
// Example:
|
||||||
@ -692,7 +697,7 @@ func (s ExchangeScope) matchesEntry(
|
|||||||
entry details.DetailsEntry,
|
entry details.DetailsEntry,
|
||||||
) bool {
|
) bool {
|
||||||
// matchesPathValues can be handled generically, thanks to SCIENCE.
|
// 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
|
// matchesInfo handles the standard behavior when comparing a scope and an ExchangeFilter
|
||||||
|
|||||||
@ -779,30 +779,34 @@ func (suite *ExchangeSelectorSuite) TestExchangeScope_MatchesPath() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
pth = stubPath(suite.T(), usr, []string{fld, mail}, path.EmailCategory)
|
pth = stubPath(suite.T(), usr, []string{fld, mail}, path.EmailCategory)
|
||||||
es = NewExchangeRestore()
|
short = "thisisahashofsomekind"
|
||||||
|
es = NewExchangeRestore()
|
||||||
)
|
)
|
||||||
|
|
||||||
table := []struct {
|
table := []struct {
|
||||||
name string
|
name string
|
||||||
scope []ExchangeScope
|
scope []ExchangeScope
|
||||||
expect assert.BoolAssertionFunc
|
shortRef string
|
||||||
|
expect assert.BoolAssertionFunc
|
||||||
}{
|
}{
|
||||||
{"all user's items", es.Users(Any()), assert.True},
|
{"all user's items", es.Users(Any()), "", assert.True},
|
||||||
{"no user's items", es.Users(None()), assert.False},
|
{"no user's items", es.Users(None()), "", assert.False},
|
||||||
{"matching user", es.Users([]string{usr}), assert.True},
|
{"matching user", es.Users([]string{usr}), "", assert.True},
|
||||||
{"non-matching user", es.Users([]string{"smarf"}), assert.False},
|
{"non-matching user", es.Users([]string{"smarf"}), "", assert.False},
|
||||||
{"one of multiple users", es.Users([]string{"smarf", usr}), assert.True},
|
{"one of multiple users", es.Users([]string{"smarf", usr}), "", assert.True},
|
||||||
{"all folders", es.MailFolders(Any(), Any()), assert.True},
|
{"all folders", es.MailFolders(Any(), Any()), "", assert.True},
|
||||||
{"no folders", es.MailFolders(Any(), None()), assert.False},
|
{"no folders", es.MailFolders(Any(), None()), "", assert.False},
|
||||||
{"matching folder", es.MailFolders(Any(), []string{fld}), assert.True},
|
{"matching folder", es.MailFolders(Any(), []string{fld}), "", assert.True},
|
||||||
{"non-matching folder", es.MailFolders(Any(), []string{"smarf"}), assert.False},
|
{"non-matching folder", es.MailFolders(Any(), []string{"smarf"}), "", assert.False},
|
||||||
{"one of multiple folders", es.MailFolders(Any(), []string{"smarf", fld}), assert.True},
|
{"one of multiple folders", es.MailFolders(Any(), []string{"smarf", fld}), "", assert.True},
|
||||||
{"all mail", es.Mails(Any(), Any(), Any()), assert.True},
|
{"all mail", es.Mails(Any(), Any(), Any()), "", assert.True},
|
||||||
{"no mail", es.Mails(Any(), Any(), None()), assert.False},
|
{"no mail", es.Mails(Any(), Any(), None()), "", assert.False},
|
||||||
{"matching mail", es.Mails(Any(), Any(), []string{mail}), assert.True},
|
{"matching mail", es.Mails(Any(), Any(), []string{mail}), "", assert.True},
|
||||||
{"non-matching mail", es.Mails(Any(), Any(), []string{"smarf"}), 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},
|
{"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) {
|
||||||
@ -810,7 +814,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeScope_MatchesPath() {
|
|||||||
var aMatch bool
|
var aMatch bool
|
||||||
for _, scope := range scopes {
|
for _, scope := range scopes {
|
||||||
pv := ExchangeMail.pathValues(pth)
|
pv := ExchangeMail.pathValues(pth)
|
||||||
if matchesPathValues(scope, ExchangeMail, pv) {
|
if matchesPathValues(scope, ExchangeMail, pv, short) {
|
||||||
aMatch = true
|
aMatch = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -1072,7 +1076,8 @@ func (suite *ExchangeSelectorSuite) TestScopesByCategory() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (suite *ExchangeSelectorSuite) TestPasses() {
|
func (suite *ExchangeSelectorSuite) TestPasses() {
|
||||||
deets := details.DetailsEntry{}
|
short := "thisisahashofsomekind"
|
||||||
|
entry := details.DetailsEntry{ShortRef: short}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
mid = "mailID"
|
mid = "mailID"
|
||||||
@ -1118,7 +1123,7 @@ func (suite *ExchangeSelectorSuite) TestPasses() {
|
|||||||
result := passes(
|
result := passes(
|
||||||
cat,
|
cat,
|
||||||
cat.pathValues(pth),
|
cat.pathValues(pth),
|
||||||
deets,
|
entry,
|
||||||
test.excludes,
|
test.excludes,
|
||||||
test.filters,
|
test.filters,
|
||||||
test.includes)
|
test.includes)
|
||||||
|
|||||||
@ -47,6 +47,10 @@ func (mc mockCategorizer) unknownCat() categorizer {
|
|||||||
return unknownCatStub
|
return unknownCatStub
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (mc mockCategorizer) isLeaf() bool {
|
||||||
|
return mc == leafCatStub
|
||||||
|
}
|
||||||
|
|
||||||
func (mc mockCategorizer) pathValues(pth path.Path) map[categorizer]string {
|
func (mc mockCategorizer) pathValues(pth path.Path) map[categorizer]string {
|
||||||
return map[categorizer]string{rootCatStub: "stub"}
|
return map[categorizer]string{rootCatStub: "stub"}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -183,6 +183,11 @@ func (c oneDriveCategory) unknownCat() categorizer {
|
|||||||
return OneDriveCategoryUnknown
|
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.
|
// pathValues transforms a path to a map of identified properties.
|
||||||
//
|
//
|
||||||
// Example:
|
// Example:
|
||||||
@ -271,7 +276,7 @@ func (s OneDriveScope) matchesEntry(
|
|||||||
entry details.DetailsEntry,
|
entry details.DetailsEntry,
|
||||||
) bool {
|
) bool {
|
||||||
// matchesPathValues can be handled generically, thanks to SCIENCE.
|
// 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
|
// matchesInfo handles the standard behavior when comparing a scope and an oneDriveInfo
|
||||||
|
|||||||
@ -32,6 +32,10 @@ type (
|
|||||||
// unknownType returns the unknown category value
|
// unknownType returns the unknown category value
|
||||||
unknownCat() categorizer
|
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
|
// pathValues should produce a map of category:string pairs populated by extracting
|
||||||
// values out of the path.Path struct.
|
// 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
|
// reduce filters the entries in the details to only those that match the
|
||||||
// inclusions, filters, and exclusions in the selector.
|
// inclusions, filters, and exclusions in the selector.
|
||||||
//
|
|
||||||
func reduce[T scopeT, C categoryT](
|
func reduce[T scopeT, C categoryT](
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
deets *details.Details,
|
deets *details.Details,
|
||||||
@ -337,6 +340,7 @@ func matchesPathValues[T scopeT, C categoryT](
|
|||||||
sc T,
|
sc T,
|
||||||
cat C,
|
cat C,
|
||||||
pathValues map[categorizer]string,
|
pathValues map[categorizer]string,
|
||||||
|
shortRef string,
|
||||||
) bool {
|
) bool {
|
||||||
// if scope specifies a filter category,
|
// if scope specifies a filter category,
|
||||||
// path checking is automatically skipped.
|
// path checking is automatically skipped.
|
||||||
@ -362,7 +366,12 @@ func matchesPathValues[T scopeT, C categoryT](
|
|||||||
// all parts of the scope must match
|
// all parts of the scope must match
|
||||||
cc := c.(C)
|
cc := c.(C)
|
||||||
if !isAnyTarget(sc, cc) {
|
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
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -301,12 +301,15 @@ func toMockScope(sc []scope) []mockScope {
|
|||||||
func (suite *SelectorScopesSuite) TestMatchesPathValues() {
|
func (suite *SelectorScopesSuite) TestMatchesPathValues() {
|
||||||
cat := rootCatStub
|
cat := rootCatStub
|
||||||
pvs := stubPathValues()
|
pvs := stubPathValues()
|
||||||
|
short := "brunheelda"
|
||||||
|
|
||||||
table := []struct {
|
table := []struct {
|
||||||
name string
|
name string
|
||||||
rootVal string
|
cat mockCategorizer
|
||||||
leafVal string
|
rootVal string
|
||||||
expect assert.BoolAssertionFunc
|
leafVal string
|
||||||
|
shortRef string
|
||||||
|
expect assert.BoolAssertionFunc
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "matching values",
|
name: "matching values",
|
||||||
@ -332,6 +335,20 @@ func (suite *SelectorScopesSuite) TestMatchesPathValues() {
|
|||||||
leafVal: "smarf",
|
leafVal: "smarf",
|
||||||
expect: assert.False,
|
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 {
|
for _, test := range table {
|
||||||
suite.T().Run(test.name, func(t *testing.T) {
|
suite.T().Run(test.name, func(t *testing.T) {
|
||||||
@ -339,7 +356,7 @@ func (suite *SelectorScopesSuite) TestMatchesPathValues() {
|
|||||||
sc[rootCatStub.String()] = filterize(test.rootVal)
|
sc[rootCatStub.String()] = filterize(test.rootVal)
|
||||||
sc[leafCatStub.String()] = filterize(test.leafVal)
|
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