From 23b90f9bec2b034ead683a73f1d3ff8f42579672 Mon Sep 17 00:00:00 2001 From: Keepers Date: Wed, 8 Mar 2023 16:51:49 -0700 Subject: [PATCH] selectors use mulit-value short-refs (#2736) With onedrive storage file names being changed from the file display name to the file id, we need a more granular form of indentification when using selectors to choose which values count as matchable fields. This change modifies the selector PathValues to return slices of strings for each category instead of a single string, and the reducer matches on any. This will allow each service to decide what values are considered equivalent (id, shortRef, a value inside the info, etc) for each property. --- #### Does this PR need a docs update or release note? - [x] :no_entry: No #### Type of change - [x] :sunflower: Feature #### Issue(s) * #2708 #### Test Plan - [x] :zap: Unit test --- src/pkg/selectors/exchange.go | 21 +++--- src/pkg/selectors/exchange_test.go | 54 ++++++++++------ src/pkg/selectors/helpers_test.go | 18 +++--- src/pkg/selectors/onedrive.go | 25 +++----- src/pkg/selectors/onedrive_test.go | 14 ++-- src/pkg/selectors/scopes.go | 96 ++++++++++------------------ src/pkg/selectors/scopes_test.go | 20 +++--- src/pkg/selectors/sharepoint.go | 27 ++++---- src/pkg/selectors/sharepoint_test.go | 25 +++++--- 9 files changed, 139 insertions(+), 161 deletions(-) diff --git a/src/pkg/selectors/exchange.go b/src/pkg/selectors/exchange.go index d048bab97..415c4106e 100644 --- a/src/pkg/selectors/exchange.go +++ b/src/pkg/selectors/exchange.go @@ -580,7 +580,7 @@ func (ec exchangeCategory) isLeaf() bool { // Example: // [tenantID, service, userPN, category, mailFolder, mailID] // => {exchMailFolder: mailFolder, exchMail: mailID} -func (ec exchangeCategory) pathValues(repo, location path.Path) (map[categorizer]string, map[categorizer]string) { +func (ec exchangeCategory) pathValues(repo path.Path, ent details.DetailsEntry) map[categorizer][]string { var folderCat, itemCat categorizer switch ec { @@ -594,24 +594,19 @@ func (ec exchangeCategory) pathValues(repo, location path.Path) (map[categorizer folderCat, itemCat = ExchangeMailFolder, ExchangeMail default: - return map[categorizer]string{}, map[categorizer]string{} + return map[categorizer][]string{} } - rv := map[categorizer]string{ - folderCat: repo.Folder(false), - itemCat: repo.Item(), + result := map[categorizer][]string{ + folderCat: {repo.Folder(false)}, + itemCat: {repo.Item(), ent.ShortRef}, } - lv := map[categorizer]string{} - - if location != nil { - lv = map[categorizer]string{ - folderCat: location.Folder(false), - itemCat: location.Item(), - } + if len(ent.LocationRef) > 0 { + result[folderCat] = append(result[folderCat], ent.LocationRef) } - return rv, lv + return result } // pathKeys returns the path keys recognized by the receiver's leaf type. diff --git a/src/pkg/selectors/exchange_test.go b/src/pkg/selectors/exchange_test.go index b18563fe5..817b3ee25 100644 --- a/src/pkg/selectors/exchange_test.go +++ b/src/pkg/selectors/exchange_test.go @@ -1,6 +1,7 @@ package selectors import ( + "strings" "testing" "time" @@ -716,9 +717,14 @@ func (suite *ExchangeSelectorSuite) TestExchangeScope_MatchesPath() { var ( repo = stubPath(suite.T(), usr, []string{fID1, fID2, mail}, path.EmailCategory) - loc = stubPath(suite.T(), usr, []string{fld1, fld2, mail}, path.EmailCategory) + loc = strings.Join([]string{fld1, fld2, mail}, "/") short = "thisisahashofsomekind" es = NewExchangeRestore(Any()) + ent = details.DetailsEntry{ + RepoRef: repo.String(), + ShortRef: short, + LocationRef: loc, + } ) table := []struct { @@ -758,12 +764,12 @@ func (suite *ExchangeSelectorSuite) TestExchangeScope_MatchesPath() { scopes := setScopesToDefault(test.scope) var aMatch bool for _, scope := range scopes { - repoVals, locVals := ExchangeMail.pathValues(repo, loc) - if matchesPathValues(scope, ExchangeMail, repoVals, short) { + pvs := ExchangeMail.pathValues(repo, ent) + if matchesPathValues(scope, ExchangeMail, pvs) { aMatch = true break } - if matchesPathValues(scope, ExchangeMail, locVals, short) { + if matchesPathValues(scope, ExchangeMail, pvs) { aMatch = true break } @@ -1313,7 +1319,10 @@ func (suite *ExchangeSelectorSuite) TestPasses() { mail = setScopesToDefault(es.Mails(Any(), []string{mid})) noMail = setScopesToDefault(es.Mails(Any(), None())) allMail = setScopesToDefault(es.Mails(Any(), Any())) - pth = stubPath(suite.T(), "user", []string{"folder", mid}, path.EmailCategory) + repo = stubPath(suite.T(), "user", []string{"folder", mid}, path.EmailCategory) + ent = details.DetailsEntry{ + RepoRef: repo.String(), + } ) table := []struct { @@ -1336,12 +1345,11 @@ func (suite *ExchangeSelectorSuite) TestPasses() { suite.Run(test.name, func() { t := suite.T() - repoVals, locVals := cat.pathValues(pth, pth) + pvs := cat.pathValues(repo, ent) result := passes( cat, - repoVals, - locVals, + pvs, entry, test.excludes, test.filters, @@ -1447,25 +1455,25 @@ func (suite *ExchangeSelectorSuite) TestExchangeCategory_PathValues() { t := suite.T() contactPath := stubPath(t, "user", []string{"cfolder", "contactitem"}, path.ContactsCategory) - contactMap := map[categorizer]string{ - ExchangeContactFolder: contactPath.Folder(false), - ExchangeContact: contactPath.Item(), + contactMap := map[categorizer][]string{ + ExchangeContactFolder: {contactPath.Folder(false)}, + ExchangeContact: {contactPath.Item(), "short"}, } eventPath := stubPath(t, "user", []string{"ecalendar", "eventitem"}, path.EventsCategory) - eventMap := map[categorizer]string{ - ExchangeEventCalendar: eventPath.Folder(false), - ExchangeEvent: eventPath.Item(), + eventMap := map[categorizer][]string{ + ExchangeEventCalendar: {eventPath.Folder(false)}, + ExchangeEvent: {eventPath.Item(), "short"}, } mailPath := stubPath(t, "user", []string{"mfolder", "mailitem"}, path.EmailCategory) - mailMap := map[categorizer]string{ - ExchangeMailFolder: mailPath.Folder(false), - ExchangeMail: mailPath.Item(), + mailMap := map[categorizer][]string{ + ExchangeMailFolder: {mailPath.Folder(false)}, + ExchangeMail: {mailPath.Item(), "short"}, } table := []struct { cat exchangeCategory path path.Path - expect map[categorizer]string + expect map[categorizer][]string }{ {ExchangeContact, contactPath, contactMap}, {ExchangeEvent, eventPath, eventMap}, @@ -1473,9 +1481,13 @@ func (suite *ExchangeSelectorSuite) TestExchangeCategory_PathValues() { } for _, test := range table { suite.T().Run(string(test.cat), func(t *testing.T) { - r, l := test.cat.pathValues(test.path, test.path) - assert.Equal(t, test.expect, r) - assert.Equal(t, test.expect, l) + ent := details.DetailsEntry{ + RepoRef: test.path.String(), + ShortRef: "short", + } + + pvs := test.cat.pathValues(test.path, ent) + assert.Equal(t, test.expect, pvs) }) } } diff --git a/src/pkg/selectors/helpers_test.go b/src/pkg/selectors/helpers_test.go index 5ab0360e5..88e19fe71 100644 --- a/src/pkg/selectors/helpers_test.go +++ b/src/pkg/selectors/helpers_test.go @@ -55,13 +55,11 @@ func (mc mockCategorizer) isLeaf() bool { return mc == leafCatStub } -func (mc mockCategorizer) pathValues(repo, location path.Path) (map[categorizer]string, map[categorizer]string) { - pv := map[categorizer]string{ - rootCatStub: "root", - leafCatStub: "leaf", +func (mc mockCategorizer) pathValues(repo path.Path, ent details.DetailsEntry) map[categorizer][]string { + return map[categorizer][]string{ + rootCatStub: {"root"}, + leafCatStub: {"leaf"}, } - - return pv, pv } func (mc mockCategorizer) pathKeys() []categorizer { @@ -77,10 +75,10 @@ func (mc mockCategorizer) PathType() path.CategoryType { } } -func stubPathValues() map[categorizer]string { - return map[categorizer]string{ - rootCatStub: rootCatStub.String(), - leafCatStub: leafCatStub.String(), +func stubPathValues() map[categorizer][]string { + return map[categorizer][]string{ + rootCatStub: {rootCatStub.String()}, + leafCatStub: {leafCatStub.String()}, } } diff --git a/src/pkg/selectors/onedrive.go b/src/pkg/selectors/onedrive.go index f9cc037ea..dde3b9784 100644 --- a/src/pkg/selectors/onedrive.go +++ b/src/pkg/selectors/onedrive.go @@ -65,7 +65,7 @@ func (s Selector) ToOneDriveBackup() (*OneDriveBackup, error) { } func (s OneDriveBackup) SplitByResourceOwner(users []string) []OneDriveBackup { - sels := splitByResourceOwner[ExchangeScope](s.Selector, users, OneDriveUser) + sels := splitByResourceOwner[OneDriveScope](s.Selector, users, OneDriveUser) ss := make([]OneDriveBackup, 0, len(sels)) for _, sel := range sels { @@ -99,7 +99,7 @@ func (s Selector) ToOneDriveRestore() (*OneDriveRestore, error) { } func (s OneDriveRestore) SplitByResourceOwner(users []string) []OneDriveRestore { - sels := splitByResourceOwner[ExchangeScope](s.Selector, users, ExchangeUser) + sels := splitByResourceOwner[OneDriveScope](s.Selector, users, OneDriveUser) ss := make([]OneDriveRestore, 0, len(sels)) for _, sel := range sels { @@ -376,25 +376,20 @@ func (c oneDriveCategory) isLeaf() bool { // Example: // [tenantID, service, userPN, category, folder, fileID] // => {odFolder: folder, odFileID: fileID} -func (c oneDriveCategory) pathValues(repo, location path.Path) (map[categorizer]string, map[categorizer]string) { +func (c oneDriveCategory) pathValues(repo path.Path, ent details.DetailsEntry) map[categorizer][]string { // Ignore `drives//root:` for folder comparison rFld := path.Builder{}.Append(repo.Folders()...).PopFront().PopFront().PopFront().String() - rv := map[categorizer]string{ - OneDriveFolder: rFld, - OneDriveItem: repo.Item(), + + result := map[categorizer][]string{ + OneDriveFolder: {rFld}, + OneDriveItem: {repo.Item(), ent.ShortRef}, } - lv := map[categorizer]string{} - - if location != nil { - lFld := path.Builder{}.Append(location.Folders()...).PopFront().PopFront().PopFront().String() - lv = map[categorizer]string{ - OneDriveFolder: lFld, - OneDriveItem: location.Item(), - } + if len(ent.LocationRef) > 0 { + result[OneDriveFolder] = append(result[OneDriveFolder], ent.LocationRef) } - return rv, lv + return result } // pathKeys returns the path keys recognized by the receiver's leaf type. diff --git a/src/pkg/selectors/onedrive_test.go b/src/pkg/selectors/onedrive_test.go index 6423ca2a7..61a00533a 100644 --- a/src/pkg/selectors/onedrive_test.go +++ b/src/pkg/selectors/onedrive_test.go @@ -261,14 +261,18 @@ func (suite *OneDriveSelectorSuite) TestOneDriveCategory_PathValues() { filePath, err := pathBuilder.ToDataLayerOneDrivePath("tenant", "user", true) require.NoError(t, err) - expected := map[categorizer]string{ - OneDriveFolder: "dir1/dir2", - OneDriveItem: "file", + expected := map[categorizer][]string{ + OneDriveFolder: {"dir1/dir2"}, + OneDriveItem: {"file", "short"}, } - r, l := OneDriveItem.pathValues(filePath, filePath) + ent := details.DetailsEntry{ + RepoRef: filePath.String(), + ShortRef: "short", + } + + r := OneDriveItem.pathValues(filePath, ent) assert.Equal(t, expected, r) - assert.Equal(t, expected, l) } func (suite *OneDriveSelectorSuite) TestOneDriveScope_MatchesInfo() { diff --git a/src/pkg/selectors/scopes.go b/src/pkg/selectors/scopes.go index 6b7d45c89..32076f049 100644 --- a/src/pkg/selectors/scopes.go +++ b/src/pkg/selectors/scopes.go @@ -88,7 +88,7 @@ type ( // folderCat: folder, // itemCat: itemID, // } - pathValues(path.Path, path.Path) (map[categorizer]string, map[categorizer]string) + pathValues(path.Path, details.DetailsEntry) map[categorizer][]string // pathKeys produces a list of categorizers that can be used as keys in the pathValues // map. The combination of the two funcs generically interprets the context of the @@ -212,6 +212,20 @@ func matches[T scopeT, C categoryT](s T, cat C, inpt string) bool { return s[cat.String()].Compare(inpt) } +// matchesAny returns true if the category is included in the scope's +// data type, and any one of the input strings passes the scope's filter. +func matchesAny[T scopeT, C categoryT](s T, cat C, inpts []string) bool { + if !typeAndCategoryMatches(cat, s.categorizer()) { + return false + } + + if len(inpts) == 0 { + return false + } + + return s[cat.String()].CompareAny(inpts...) +} + // getCategory returns the scope's category value. // if s is a filter-type scope, returns the filter category. func getCategory[T scopeT](s T) string { @@ -297,6 +311,8 @@ func reduce[T scopeT, C categoryT]( return nil } + el := errs.Local() + // if a DiscreteOwner is specified, only match details for that owner. matchesResourceOwner := s.ResourceOwners if len(s.DiscreteOwner) > 0 { @@ -314,35 +330,10 @@ func reduce[T scopeT, C categoryT]( for _, ent := range deets.Items() { repoPath, err := path.FromDataLayerPath(ent.RepoRef, true) if err != nil { - errs.AddRecoverable(clues.Wrap(err, "transforming repoRef to path").WithClues(ctx)) + el.AddRecoverable(clues.Wrap(err, "transforming repoRef to path").WithClues(ctx)) continue } - var locationPath path.Path - - // if the details entry has a locationRef specified, use those folders in place - // of the repoRef folders, so that scopes can match against the display names - // instead of container IDs. - if len(ent.LocationRef) > 0 { - pb, err := path.Builder{}.SplitUnescapeAppend(ent.LocationRef) - if err != nil { - errs.AddRecoverable(clues.Wrap(err, "transforming locationRef to path").WithClues(ctx)) - continue - } - - locationPath, err = pb.Append(repoPath.Item()). - ToDataLayerPath( - repoPath.Tenant(), - repoPath.ResourceOwner(), - repoPath.Service(), - repoPath.Category(), - true) - if err != nil { - errs.AddRecoverable(clues.Wrap(err, "transforming locationRef to path").WithClues(ctx)) - continue - } - } - // first check, every entry needs to match the selector's resource owners. if !matchesResourceOwner.Compare(repoPath.ResourceOwner()) { continue @@ -360,9 +351,9 @@ func reduce[T scopeT, C categoryT]( continue } - rv, lv := dc.pathValues(repoPath, locationPath) + pv := dc.pathValues(repoPath, *ent) - passed := passes(dc, rv, lv, *ent, e, f, i) + passed := passes(dc, pv, *ent, e, f, i) if passed { ents = append(ents, *ent) } @@ -407,7 +398,7 @@ func scopesByCategory[T scopeT, C categoryT]( // if the path is included, passes filters, and not excluded. func passes[T scopeT, C categoryT]( cat C, - repoValues, locationValues map[categorizer]string, + pathValues map[categorizer][]string, entry details.DetailsEntry, excs, filts, incs []T, ) bool { @@ -423,7 +414,7 @@ func passes[T scopeT, C categoryT]( var included bool for _, inc := range incs { - if matchesEntry(inc, cat, repoValues, locationValues, entry) { + if matchesEntry(inc, cat, pathValues, entry) { included = true break } @@ -436,14 +427,14 @@ func passes[T scopeT, C categoryT]( // all filters must pass for _, filt := range filts { - if !matchesEntry(filt, cat, repoValues, locationValues, entry) { + if !matchesEntry(filt, cat, pathValues, entry) { return false } } // any matching exclusion means failure for _, exc := range excs { - if matchesEntry(exc, cat, repoValues, locationValues, entry) { + if matchesEntry(exc, cat, pathValues, entry) { return false } } @@ -456,7 +447,7 @@ func passes[T scopeT, C categoryT]( func matchesEntry[T scopeT, C categoryT]( sc T, cat C, - repoValues, locationValues map[categorizer]string, + pathValues map[categorizer][]string, entry details.DetailsEntry, ) bool { // filterCategory requires matching against service-specific info values @@ -464,11 +455,7 @@ func matchesEntry[T scopeT, C categoryT]( return sc.matchesInfo(entry.ItemInfo) } - if len(locationValues) > 0 && matchesPathValues(sc, cat, locationValues, entry.ShortRef) { - return true - } - - return matchesPathValues(sc, cat, repoValues, entry.ShortRef) + return matchesPathValues(sc, cat, pathValues) } // matchesPathValues will check whether the pathValues have matching entries @@ -479,8 +466,7 @@ func matchesEntry[T scopeT, C categoryT]( func matchesPathValues[T scopeT, C categoryT]( sc T, cat C, - pathValues map[categorizer]string, - shortRef string, + pathValues map[categorizer][]string, ) bool { for _, c := range cat.pathKeys() { // resourceOwners are now checked at the beginning of the reduction. @@ -488,12 +474,6 @@ func matchesPathValues[T scopeT, C categoryT]( continue } - // the pathValues must have an entry for the given categorizer - pathVal, ok := pathValues[c] - if !ok { - return false - } - cc := c.(C) if isNoneTarget(sc, cc) { @@ -505,23 +485,13 @@ func matchesPathValues[T scopeT, C categoryT]( continue } - var ( - match bool - isLeaf = c.isLeaf() - ) - - switch { - // Leaf category - the scope can match either the path value (the item ID itself), - // or the shortRef hash representing the item. - case isLeaf && len(shortRef) > 0: - match = matches(sc, cc, pathVal) || matches(sc, cc, shortRef) - - // all other categories (root, folder, etc) just need to pass the filter - default: - match = matches(sc, cc, pathVal) + // the pathValues must have an entry for the given categorizer + pathVals, ok := pathValues[c] + if !ok || len(pathVals) == 0 { + return false } - if !match { + if !matchesAny(sc, cc, pathVals) { return false } } @@ -530,7 +500,7 @@ func matchesPathValues[T scopeT, C categoryT]( } // --------------------------------------------------------------------------- -// categorizer funcs +// helper funcs // --------------------------------------------------------------------------- // categoryMatches returns true if: diff --git a/src/pkg/selectors/scopes_test.go b/src/pkg/selectors/scopes_test.go index 8d5e0517e..80b94b06f 100644 --- a/src/pkg/selectors/scopes_test.go +++ b/src/pkg/selectors/scopes_test.go @@ -354,10 +354,14 @@ func (suite *SelectorScopesSuite) TestScopesByCategory() { } func (suite *SelectorScopesSuite) TestPasses() { - cat := rootCatStub - pth := stubPath(suite.T(), "uid", []string{"fld"}, path.EventsCategory) - repoVals, locVals := cat.pathValues(pth, pth) - entry := details.DetailsEntry{} + var ( + cat = rootCatStub + pth = stubPath(suite.T(), "uid", []string{"fld"}, path.EventsCategory) + entry = details.DetailsEntry{ + RepoRef: pth.String(), + } + pvs = cat.pathValues(pth, entry) + ) for _, test := range reduceTestTable { suite.Run(test.name, func() { @@ -369,8 +373,7 @@ func (suite *SelectorScopesSuite) TestPasses() { incl := toMockScope(sel.Includes) result := passes( cat, - repoVals, - locVals, + pvs, entry, excl, filt, incl) test.expectPasses(t, result) @@ -394,7 +397,6 @@ func toMockScope(sc []scope) []mockScope { func (suite *SelectorScopesSuite) TestMatchesPathValues() { cat := rootCatStub - pvs := stubPathValues() short := "brunheelda" table := []struct { @@ -440,12 +442,14 @@ func (suite *SelectorScopesSuite) TestMatchesPathValues() { for _, test := range table { suite.Run(test.name, func() { t := suite.T() + pvs := stubPathValues() + pvs[leafCatStub] = append(pvs[leafCatStub], test.shortRef) sc := stubScope("") sc[rootCatStub.String()] = filterize(scopeConfig{}, test.rootVal) sc[leafCatStub.String()] = filterize(scopeConfig{}, test.leafVal) - test.expect(t, matchesPathValues(sc, cat, pvs, test.shortRef)) + test.expect(t, matchesPathValues(sc, cat, pvs)) }) } } diff --git a/src/pkg/selectors/sharepoint.go b/src/pkg/selectors/sharepoint.go index c0407f75a..f7cfc47e2 100644 --- a/src/pkg/selectors/sharepoint.go +++ b/src/pkg/selectors/sharepoint.go @@ -65,7 +65,7 @@ func (s Selector) ToSharePointBackup() (*SharePointBackup, error) { } func (s SharePointBackup) SplitByResourceOwner(sites []string) []SharePointBackup { - sels := splitByResourceOwner[ExchangeScope](s.Selector, sites, SharePointSite) + sels := splitByResourceOwner[SharePointScope](s.Selector, sites, SharePointSite) ss := make([]SharePointBackup, 0, len(sels)) for _, sel := range sels { @@ -98,8 +98,8 @@ func (s Selector) ToSharePointRestore() (*SharePointRestore, error) { return &src, nil } -func (s SharePointRestore) SplitByResourceOwner(users []string) []SharePointRestore { - sels := splitByResourceOwner[ExchangeScope](s.Selector, users, ExchangeUser) +func (s SharePointRestore) SplitByResourceOwner(sites []string) []SharePointRestore { + sels := splitByResourceOwner[SharePointScope](s.Selector, sites, SharePointSite) ss := make([]SharePointRestore, 0, len(sels)) for _, sel := range sels { @@ -476,7 +476,7 @@ func (c sharePointCategory) isLeaf() bool { // Example: // [tenantID, service, siteID, category, folder, itemID] // => {spFolder: folder, spItemID: itemID} -func (c sharePointCategory) pathValues(repo, location path.Path) (map[categorizer]string, map[categorizer]string) { +func (c sharePointCategory) pathValues(repo path.Path, ent details.DetailsEntry) map[categorizer][]string { var folderCat, itemCat categorizer switch c { @@ -487,24 +487,19 @@ func (c sharePointCategory) pathValues(repo, location path.Path) (map[categorize case SharePointPage, SharePointPageFolder: folderCat, itemCat = SharePointPageFolder, SharePointPage default: - return map[categorizer]string{}, map[categorizer]string{} + return map[categorizer][]string{} } - rv := map[categorizer]string{ - folderCat: repo.Folder(false), - itemCat: repo.Item(), + result := map[categorizer][]string{ + folderCat: {repo.Folder(false)}, + itemCat: {repo.Item(), ent.ShortRef}, } - lv := map[categorizer]string{} - - if location != nil { - lv = map[categorizer]string{ - folderCat: location.Folder(false), - itemCat: location.Item(), - } + if len(ent.LocationRef) > 0 { + result[folderCat] = append(result[folderCat], ent.LocationRef) } - return rv, lv + return result } // pathKeys returns the path keys recognized by the receiver's leaf type. diff --git a/src/pkg/selectors/sharepoint_test.go b/src/pkg/selectors/sharepoint_test.go index a7b3aa701..ffc7a9ec8 100644 --- a/src/pkg/selectors/sharepoint_test.go +++ b/src/pkg/selectors/sharepoint_test.go @@ -326,22 +326,22 @@ func (suite *SharePointSelectorSuite) TestSharePointCategory_PathValues() { table := []struct { name string sc sharePointCategory - expected map[categorizer]string + expected map[categorizer][]string }{ { name: "SharePoint Libraries", sc: SharePointLibraryItem, - expected: map[categorizer]string{ - SharePointLibrary: "dir1/dir2", - SharePointLibraryItem: "item", + expected: map[categorizer][]string{ + SharePointLibrary: {"dir1/dir2"}, + SharePointLibraryItem: {"item", "short"}, }, }, { name: "SharePoint Lists", sc: SharePointListItem, - expected: map[categorizer]string{ - SharePointList: "dir1/dir2", - SharePointListItem: "item", + expected: map[categorizer][]string{ + SharePointList: {"dir1/dir2"}, + SharePointListItem: {"item", "short"}, }, }, } @@ -356,9 +356,14 @@ func (suite *SharePointSelectorSuite) TestSharePointCategory_PathValues() { test.sc.PathType(), true) require.NoError(t, err) - r, l := test.sc.pathValues(itemPath, itemPath) - assert.Equal(t, test.expected, r) - assert.Equal(t, test.expected, l) + + ent := details.DetailsEntry{ + RepoRef: itemPath.String(), + ShortRef: "short", + } + + pv := test.sc.pathValues(itemPath, ent) + assert.Equal(t, test.expected, pv) }) } }