corso/src/pkg/selectors/onedrive_test.go
ashmrtn 754e14d7a6
Don't use RepoRef in selector reduction (#3236)
A few high-level things of note:
* things will no longer match on folder ID. Folder IDs weren't displayed
  to the user via CLI and SDK consumers have no insight into folder IDs
  so this shouldn't be an issue
* OneDrive and SharePoint match on ParentPath (derived from
  LocationRef). ParentPath *does not* include root: in the path

Not matching on folder ID should be the only user-visible change in
this PR

First commit contains the required logic changes. All other changes
are test updates

---

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

- [ ]  Yes, it's included
- [ ] 🕐 Yes, but in a later PR
- [x]  No

#### Type of change

- [ ] 🌻 Feature
- [ ] 🐛 Bugfix
- [ ] 🗺️ Documentation
- [x] 🤖 Supportability/Tests
- [ ] 💻 CI/Deployment
- [ ] 🧹 Tech Debt/Cleanup

#### Issue(s)

* closes #3194

#### Test Plan

- [ ] 💪 Manual
- [x]  Unit test
- [ ] 💚 E2E
2023-04-27 22:01:34 +00:00

454 lines
11 KiB
Go

package selectors
import (
"testing"
"time"
"github.com/alcionai/clues"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
"github.com/alcionai/corso/src/internal/common"
"github.com/alcionai/corso/src/internal/tester"
"github.com/alcionai/corso/src/pkg/backup/details"
"github.com/alcionai/corso/src/pkg/fault"
"github.com/alcionai/corso/src/pkg/path"
)
type OneDriveSelectorSuite struct {
tester.Suite
}
func TestOneDriveSelectorSuite(t *testing.T) {
suite.Run(t, &OneDriveSelectorSuite{Suite: tester.NewUnitSuite(t)})
}
func (suite *OneDriveSelectorSuite) TestNewOneDriveBackup() {
t := suite.T()
ob := NewOneDriveBackup(Any())
assert.Equal(t, ob.Service, ServiceOneDrive)
assert.NotZero(t, ob.Scopes())
}
func (suite *OneDriveSelectorSuite) TestToOneDriveBackup() {
t := suite.T()
ob := NewOneDriveBackup(Any())
s := ob.Selector
ob, err := s.ToOneDriveBackup()
require.NoError(t, err, clues.ToCore(err))
assert.Equal(t, ob.Service, ServiceOneDrive)
assert.NotZero(t, ob.Scopes())
}
func (suite *OneDriveSelectorSuite) TestOneDriveSelector_AllData() {
t := suite.T()
var (
users = []string{"u1", "u2"}
sel = NewOneDriveBackup(users)
allScopes = sel.AllData()
)
assert.ElementsMatch(t, users, sel.DiscreteResourceOwners())
// Initialize the selector Include, Exclude, Filter
sel.Exclude(allScopes)
sel.Include(allScopes)
sel.Filter(allScopes)
table := []struct {
name string
scopesToCheck []scope
}{
{"Include Scopes", sel.Includes},
{"Exclude Scopes", sel.Excludes},
{"info scopes", sel.Filters},
}
for _, test := range table {
suite.Run(test.name, func() {
t := suite.T()
require.Len(t, test.scopesToCheck, 1)
for _, scope := range test.scopesToCheck {
scopeMustHave(
t,
OneDriveScope(scope),
map[categorizer][]string{
OneDriveItem: Any(),
OneDriveFolder: Any(),
},
)
}
})
}
}
func (suite *OneDriveSelectorSuite) TestOneDriveSelector_Include_AllData() {
t := suite.T()
const (
u1 = "u1"
u2 = "u2"
)
var (
users = []string{u1, u2}
sel = NewOneDriveBackup(users)
allScopes = sel.AllData()
)
sel.Include(allScopes)
scopes := sel.Includes
require.Len(t, scopes, 1)
for _, sc := range scopes {
scopeMustHave(
t,
OneDriveScope(sc),
map[categorizer][]string{
OneDriveItem: Any(),
OneDriveFolder: Any(),
},
)
}
}
func (suite *OneDriveSelectorSuite) TestOneDriveSelector_Exclude_AllData() {
t := suite.T()
const (
u1 = "u1"
u2 = "u2"
)
var (
users = []string{u1, u2}
sel = NewOneDriveBackup(users)
allScopes = sel.AllData()
)
sel.Exclude(allScopes)
scopes := sel.Excludes
require.Len(t, scopes, 1)
for _, sc := range scopes {
scopeMustHave(
t,
OneDriveScope(sc),
map[categorizer][]string{
OneDriveItem: Any(),
OneDriveFolder: Any(),
},
)
}
}
func (suite *OneDriveSelectorSuite) TestNewOneDriveRestore() {
t := suite.T()
or := NewOneDriveRestore(Any())
assert.Equal(t, or.Service, ServiceOneDrive)
assert.NotZero(t, or.Scopes())
}
func (suite *OneDriveSelectorSuite) TestToOneDriveRestore() {
t := suite.T()
eb := NewOneDriveRestore(Any())
s := eb.Selector
or, err := s.ToOneDriveRestore()
require.NoError(t, err, clues.ToCore(err))
assert.Equal(t, or.Service, ServiceOneDrive)
assert.NotZero(t, or.Scopes())
}
func (suite *OneDriveSelectorSuite) TestOneDriveRestore_Reduce() {
var (
file = stubRepoRef(
path.OneDriveService,
path.FilesCategory,
"uid",
"drive/driveID/root:/folderA.d/folderB.d",
"file")
fileParent = "folderA/folderB"
file2 = stubRepoRef(
path.OneDriveService,
path.FilesCategory,
"uid",
"drive/driveID/root:/folderA.d/folderC.d",
"file2")
fileParent2 = "folderA/folderC"
file3 = stubRepoRef(
path.OneDriveService,
path.FilesCategory,
"uid",
"drive/driveID/root:/folderD.d/folderE.d",
"file3")
fileParent3 = "folderD/folderE"
)
deets := &details.Details{
DetailsModel: details.DetailsModel{
Entries: []details.DetailsEntry{
{
RepoRef: file,
ItemRef: "file",
ItemInfo: details.ItemInfo{
OneDrive: &details.OneDriveInfo{
ItemType: details.OneDriveItem,
ItemName: "fileName",
ParentPath: fileParent,
},
},
},
{
RepoRef: file2,
ItemRef: "file2",
ItemInfo: details.ItemInfo{
OneDrive: &details.OneDriveInfo{
ItemType: details.OneDriveItem,
ItemName: "fileName2",
ParentPath: fileParent2,
},
},
},
{
RepoRef: file3,
// item ref intentionally blank to assert fallback case
ItemInfo: details.ItemInfo{
OneDrive: &details.OneDriveInfo{
ItemType: details.OneDriveItem,
ItemName: "fileName3",
ParentPath: fileParent3,
},
},
},
},
},
}
arr := func(s ...string) []string {
return s
}
table := []struct {
name string
makeSelector func() *OneDriveRestore
expect []string
cfg Config
}{
{
name: "all",
makeSelector: func() *OneDriveRestore {
odr := NewOneDriveRestore(Any())
odr.Include(odr.AllData())
return odr
},
expect: arr(file, file2, file3),
},
{
name: "only match file",
makeSelector: func() *OneDriveRestore {
odr := NewOneDriveRestore(Any())
odr.Include(odr.Items(Any(), []string{"file2"}))
return odr
},
expect: arr(file2),
},
{
name: "id doesn't match name",
makeSelector: func() *OneDriveRestore {
odr := NewOneDriveRestore(Any())
odr.Include(odr.Items(Any(), []string{"file2"}))
return odr
},
expect: []string{},
cfg: Config{OnlyMatchItemNames: true},
},
{
name: "only match file name",
makeSelector: func() *OneDriveRestore {
odr := NewOneDriveRestore(Any())
odr.Include(odr.Items(Any(), []string{"fileName2"}))
return odr
},
expect: arr(file2),
cfg: Config{OnlyMatchItemNames: true},
},
{
name: "name doesn't match id",
makeSelector: func() *OneDriveRestore {
odr := NewOneDriveRestore(Any())
odr.Include(odr.Items(Any(), []string{"fileName2"}))
return odr
},
expect: []string{},
},
{
name: "only match folder",
makeSelector: func() *OneDriveRestore {
odr := NewOneDriveRestore([]string{"uid"})
odr.Include(odr.Folders([]string{"folderA/folderB", "folderA/folderC"}))
return odr
},
expect: arr(file, file2),
},
}
for _, test := range table {
suite.Run(test.name, func() {
t := suite.T()
ctx, flush := tester.NewContext()
defer flush()
sel := test.makeSelector()
sel.Configure(test.cfg)
results := sel.Reduce(ctx, deets, fault.New(true))
paths := results.Paths()
assert.Equal(t, test.expect, paths)
})
}
}
func (suite *OneDriveSelectorSuite) TestOneDriveCategory_PathValues() {
t := suite.T()
fileName := "file"
fileID := fileName + "-id"
shortRef := "short"
elems := []string{"drive", "driveID", "root:", "dir1.d", "dir2.d", fileID}
filePath, err := path.Build("tenant", "user", path.OneDriveService, path.FilesCategory, true, elems...)
require.NoError(t, err, clues.ToCore(err))
fileLoc := path.Builder{}.Append("dir1", "dir2")
table := []struct {
name string
pathElems []string
expected map[categorizer][]string
cfg Config
}{
{
name: "items",
pathElems: elems,
expected: map[categorizer][]string{
OneDriveFolder: {"dir1/dir2"},
OneDriveItem: {fileID, shortRef},
},
cfg: Config{},
},
{
name: "items w/ name",
pathElems: elems,
expected: map[categorizer][]string{
OneDriveFolder: {"dir1/dir2"},
OneDriveItem: {fileName, shortRef},
},
cfg: Config{OnlyMatchItemNames: true},
},
}
for _, test := range table {
suite.Run(test.name, func() {
t := suite.T()
itemPath, err := path.Build(
"tenant",
"site",
path.OneDriveService,
path.FilesCategory,
true,
test.pathElems...)
require.NoError(t, err, clues.ToCore(err))
ent := details.DetailsEntry{
RepoRef: filePath.String(),
ShortRef: shortRef,
ItemRef: fileID,
ItemInfo: details.ItemInfo{
OneDrive: &details.OneDriveInfo{
ItemName: fileName,
ParentPath: fileLoc.String(),
},
},
}
pv, err := OneDriveItem.pathValues(itemPath, ent, test.cfg)
require.NoError(t, err)
assert.Equal(t, test.expected, pv)
})
}
}
func (suite *OneDriveSelectorSuite) TestOneDriveScope_MatchesInfo() {
ods := NewOneDriveRestore(Any())
var (
epoch = time.Time{}
now = time.Now()
future = now.Add(1 * time.Minute)
)
itemInfo := details.ItemInfo{
OneDrive: &details.OneDriveInfo{
ItemType: details.OneDriveItem,
ParentPath: "folder1/folder2",
ItemName: "file1",
Size: 10,
Owner: "user@email.com",
Created: now,
Modified: now,
},
}
table := []struct {
name string
scope []OneDriveScope
expect assert.BoolAssertionFunc
}{
{"file create after the epoch", ods.CreatedAfter(common.FormatTime(epoch)), assert.True},
{"file create after now", ods.CreatedAfter(common.FormatTime(now)), assert.False},
{"file create after later", ods.CreatedAfter(common.FormatTime(future)), assert.False},
{"file create before future", ods.CreatedBefore(common.FormatTime(future)), assert.True},
{"file create before now", ods.CreatedBefore(common.FormatTime(now)), assert.False},
{"file create before epoch", ods.CreatedBefore(common.FormatTime(now)), assert.False},
{"file modified after the epoch", ods.ModifiedAfter(common.FormatTime(epoch)), assert.True},
{"file modified after now", ods.ModifiedAfter(common.FormatTime(now)), assert.False},
{"file modified after later", ods.ModifiedAfter(common.FormatTime(future)), assert.False},
{"file modified before future", ods.ModifiedBefore(common.FormatTime(future)), assert.True},
{"file modified before now", ods.ModifiedBefore(common.FormatTime(now)), assert.False},
{"file modified before epoch", ods.ModifiedBefore(common.FormatTime(now)), assert.False},
}
for _, test := range table {
suite.Run(test.name, func() {
t := suite.T()
scopes := setScopesToDefault(test.scope)
for _, scope := range scopes {
test.expect(t, scope.matchesInfo(itemInfo))
}
})
}
}
func (suite *OneDriveSelectorSuite) TestCategory_PathType() {
table := []struct {
cat oneDriveCategory
pathType path.CategoryType
}{
{OneDriveCategoryUnknown, path.UnknownCategory},
{OneDriveUser, path.UnknownCategory},
{OneDriveItem, path.FilesCategory},
{OneDriveFolder, path.FilesCategory},
{FileInfoCreatedAfter, path.FilesCategory},
{FileInfoCreatedBefore, path.FilesCategory},
{FileInfoModifiedAfter, path.FilesCategory},
{FileInfoModifiedBefore, path.FilesCategory},
}
for _, test := range table {
suite.Run(test.cat.String(), func() {
assert.Equal(suite.T(), test.pathType, test.cat.PathType())
})
}
}