From 6e0b9183b4f263ed24949ee519c1dc43e93f721c Mon Sep 17 00:00:00 2001 From: ashmrtn Date: Tue, 21 Feb 2023 08:39:48 -0800 Subject: [PATCH] OneDrive test framework (#2533) ## Description Major changes: * OneDrive files now store the lookup key in the first few bytes of the file and then the file data. This allows the test framework to continue working even when we switch to using item IDs as names * Create a framework to create the data necessary for testing. This framework uses something akin to the builder pattern and automatically adds files to the collection if they should appear in that version. For example, trying to add a metadata file to a backup version that didn't have metadata files will result in a noop. Adding files will also add the metadata to the aux file set Long term this will hopefully make ensuring compatibility between OneDrive versions easier because only a few places in the code need to be updated to support another version. It also allows easy ranges over different versions via for-loop ## Does this PR need a docs update or release note? - [ ] :white_check_mark: Yes, it's included - [ ] :clock1: Yes, but in a later PR - [x] :no_entry: No ## Type of change - [ ] :sunflower: Feature - [ ] :bug: Bugfix - [ ] :world_map: Documentation - [x] :robot: Test - [ ] :computer: CI/Deployment - [ ] :broom: Tech Debt/Cleanup ## Issue(s) * #1535 ## Test Plan - [ ] :muscle: Manual - [x] :zap: Unit test - [ ] :green_heart: E2E --- .../connector/graph_connector_helper_test.go | 86 +- .../graph_connector_onedrive_test.go | 1192 +++++++++-------- 2 files changed, 719 insertions(+), 559 deletions(-) diff --git a/src/internal/connector/graph_connector_helper_test.go b/src/internal/connector/graph_connector_helper_test.go index 82fc38e59..a3adae175 100644 --- a/src/internal/connector/graph_connector_helper_test.go +++ b/src/internal/connector/graph_connector_helper_test.go @@ -191,7 +191,6 @@ type restoreBackupInfo struct { } type restoreBackupInfoMultiVersion struct { - name string service path.ServiceType collectionsLatest []colInfo collectionsPrevious []colInfo @@ -707,43 +706,78 @@ func compareOneDriveItem( item data.Stream, restorePermissions bool, ) { - name := item.UUID() - - expectedData := expected[item.UUID()] - if !assert.NotNil(t, expectedData, "unexpected file with name %s", item.UUID()) { - return - } - buf, err := io.ReadAll(item.ToReader()) if !assert.NoError(t, err) { return } - if !strings.HasSuffix(name, onedrive.MetaFileSuffix) && !strings.HasSuffix(name, onedrive.DirMetaFileSuffix) { - // OneDrive data items are just byte buffers of the data. Nothing special to - // interpret. May need to do chunked comparisons in the future if we test - // large item equality. - assert.Equal(t, expectedData, buf) + name := item.UUID() + if strings.HasSuffix(name, onedrive.MetaFileSuffix) || + strings.HasSuffix(name, onedrive.DirMetaFileSuffix) { + var ( + itemMeta onedrive.Metadata + expectedMeta onedrive.Metadata + ) + + err = json.Unmarshal(buf, &itemMeta) + if !assert.NoErrorf(t, err, "unmarshalling retrieved metadata for file %s", name) { + return + } + + expectedData := expected[name] + if !assert.NotNil( + t, + expectedData, + "unexpected metadata file with name %s", + name, + ) { + return + } + + err = json.Unmarshal(expectedData, &expectedMeta) + if !assert.NoError(t, err, "unmarshalling expected metadata") { + return + } + + // Only compare file names if we're using a version that expects them to be + // set. + if len(expectedMeta.FileName) > 0 { + assert.Equal(t, expectedMeta.FileName, itemMeta.FileName) + } + + if !restorePermissions { + assert.Equal(t, 0, len(itemMeta.Permissions)) + return + } + + testElementsMatch( + t, + expectedMeta.Permissions, + itemMeta.Permissions, + permissionEqual, + ) + return } - var ( - itemMeta onedrive.Metadata - expectedMeta onedrive.Metadata - ) + var fileData testOneDriveData - err = json.Unmarshal(buf, &itemMeta) - assert.Nil(t, err) - - err = json.Unmarshal(expectedData, &expectedMeta) - assert.Nil(t, err) - - if !restorePermissions { - assert.Equal(t, 0, len(itemMeta.Permissions)) + err = json.Unmarshal(buf, &fileData) + if !assert.NoErrorf(t, err, "unmarshalling file data for file %s", name) { return } - testElementsMatch(t, expectedMeta.Permissions, itemMeta.Permissions, permissionEqual) + expectedData := expected[fileData.FileName] + if !assert.NotNil(t, expectedData, "unexpected file with name %s", name) { + return + } + + // OneDrive data items are just byte buffers of the data. Nothing special to + // interpret. May need to do chunked comparisons in the future if we test + // large item equality. + // Compare against the version with the file name embedded because that's what + // the auto-generated expected data has. + assert.Equal(t, expectedData, buf) } func compareItem( diff --git a/src/internal/connector/graph_connector_onedrive_test.go b/src/internal/connector/graph_connector_onedrive_test.go index e86042194..104b0f7cd 100644 --- a/src/internal/connector/graph_connector_onedrive_test.go +++ b/src/internal/connector/graph_connector_onedrive_test.go @@ -3,9 +3,12 @@ package connector import ( "encoding/base64" "encoding/json" + "fmt" "strings" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" "github.com/alcionai/corso/src/internal/connector/graph" @@ -17,32 +20,66 @@ import ( "github.com/alcionai/corso/src/pkg/path" ) -func getTestMetaJSON(t *testing.T, user string, roles []string) []byte { - id := base64.StdEncoding.EncodeToString([]byte(user + strings.Join(roles, "+"))) - testMeta := onedrive.Metadata{Permissions: []onedrive.UserPermission{ - {ID: id, Roles: roles, Email: user}, - }} - - testMetaJSON, err := json.Marshal(testMeta) - if err != nil { - t.Fatal("unable to marshall test permissions", err) +func getMetadata(fileName, user string, roles []string) onedrive.Metadata { + if len(user) == 0 || len(roles) == 0 { + return onedrive.Metadata{FileName: fileName} } - return testMetaJSON + id := base64.StdEncoding.EncodeToString([]byte(user + strings.Join(roles, "+"))) + testMeta := onedrive.Metadata{ + FileName: fileName, + Permissions: []onedrive.UserPermission{ + {ID: id, Roles: roles, Email: user}, + }, + } + + return testMeta } -func onedriveItemWithData(name string, itemData []byte) itemInfo { +type testOneDriveData struct { + FileName string `json:"fileName,omitempty"` + Data []byte `json:"data,omitempty"` +} + +func onedriveItemWithData( + t *testing.T, + name, lookupKey string, + fileData []byte, +) itemInfo { + t.Helper() + + content := testOneDriveData{ + FileName: lookupKey, + Data: fileData, + } + + serialized, err := json.Marshal(content) + require.NoError(t, err) + return itemInfo{ name: name, - data: itemData, - lookupKey: name, + data: serialized, + lookupKey: lookupKey, } } -func onedriveFileWithMetadata(baseName string, fileData, metadata []byte) []itemInfo { - return []itemInfo{ - onedriveItemWithData(baseName+onedrive.DataFileSuffix, fileData), - onedriveItemWithData(baseName+onedrive.MetaFileSuffix, metadata), +func onedriveMetadata( + t *testing.T, + fileName, itemID string, + user string, + roles []string, +) itemInfo { + t.Helper() + + testMeta := getMetadata(fileName, user, roles) + + testMetaJSON, err := json.Marshal(testMeta) + require.NoError(t, err, "marshalling metadata") + + return itemInfo{ + name: itemID, + data: testMetaJSON, + lookupKey: itemID, } } @@ -79,10 +116,9 @@ func (suite *GraphConnectorOneDriveIntegrationSuite) SetupSuite() { } var ( - fileEmptyPerms = onedriveItemWithData( - "test-file.txt"+onedrive.MetaFileSuffix, - []byte("{}"), - ) + fileName = "test-file.txt" + folderAName = "folder-a" + folderBName = "b" fileAData = []byte(strings.Repeat("a", 33)) fileBData = []byte(strings.Repeat("b", 65)) @@ -90,65 +126,189 @@ var ( fileDData = []byte(strings.Repeat("d", 257)) fileEData = []byte(strings.Repeat("e", 257)) - fileAEmptyPerms = []itemInfo{ - onedriveItemWithData( - "test-file.txt"+onedrive.DataFileSuffix, - fileAData, - ), - fileEmptyPerms, - } - - fileBEmptyPerms = []itemInfo{ - onedriveItemWithData( - "test-file.txt"+onedrive.DataFileSuffix, - fileBData, - ), - fileEmptyPerms, - } - - fileCEmptyPerms = []itemInfo{ - onedriveItemWithData( - "test-file.txt"+onedrive.DataFileSuffix, - fileCData, - ), - fileEmptyPerms, - } - - fileDEmptyPerms = []itemInfo{ - onedriveItemWithData( - "test-file.txt"+onedrive.DataFileSuffix, - fileDData, - ), - fileEmptyPerms, - } - - fileEEmptyPerms = []itemInfo{ - onedriveItemWithData( - "test-file.txt"+onedrive.DataFileSuffix, - fileEData, - ), - fileEmptyPerms, - } - - folderAEmptyPerms = []itemInfo{ - onedriveItemWithData("folder-a"+onedrive.DirMetaFileSuffix, []byte("{}")), - } - - folderBEmptyPerms = []itemInfo{ - onedriveItemWithData("b"+onedrive.DirMetaFileSuffix, []byte("{}")), - } + writePerm = []string{"write"} + readPerm = []string{"read"} ) -func withItems(items ...[]itemInfo) []itemInfo { - res := []itemInfo{} - for _, i := range items { - res = append(res, i...) +func newOneDriveCollection( + t *testing.T, + pathElements []string, + backupVersion int, +) *onedriveCollection { + return &onedriveCollection{ + pathElements: pathElements, + backupVersion: backupVersion, + t: t, + } +} + +type onedriveCollection struct { + pathElements []string + items []itemInfo + aux []itemInfo + backupVersion int + t *testing.T +} + +func (c onedriveCollection) collection() colInfo { + return colInfo{ + pathElements: c.pathElements, + category: path.FilesCategory, + items: c.items, + auxItems: c.aux, + } +} + +func (c *onedriveCollection) withFile( + name string, + fileData []byte, + user string, + roles []string, +) *onedriveCollection { + switch c.backupVersion { + case 0: + // Lookups will occur using the most recent version of things so we need + // the embedded file name to match that. + c.items = append(c.items, onedriveItemWithData( + c.t, + name, + name+onedrive.DataFileSuffix, + fileData)) + + case 1: + fallthrough + case 2: + c.items = append(c.items, onedriveItemWithData( + c.t, + name+onedrive.DataFileSuffix, + name+onedrive.DataFileSuffix, + fileData)) + + metadata := onedriveMetadata( + c.t, + "", + name+onedrive.MetaFileSuffix, + user, + roles) + c.items = append(c.items, metadata) + c.aux = append(c.aux, metadata) + + default: + assert.FailNowf(c.t, "bad backup version", "version %d", c.backupVersion) + } + + return c +} + +func (c *onedriveCollection) withFolder( + name string, + user string, + roles []string, +) *onedriveCollection { + switch c.backupVersion { + case 0: + return c + + case 1: + fallthrough + case 2: + c.items = append( + c.items, + onedriveMetadata( + c.t, + "", + name+onedrive.DirMetaFileSuffix, + user, + roles), + ) + + default: + assert.FailNowf(c.t, "bad backup version", "version %d", c.backupVersion) + } + + return c +} + +// withPermissions adds permissions to the folder represented by this +// onedriveCollection. +func (c *onedriveCollection) withPermissions( + user string, + roles []string, +) *onedriveCollection { + // These versions didn't store permissions for the folder or didn't store them + // in the folder's collection. + if c.backupVersion < 3 { + return c + } + + name := c.pathElements[len(c.pathElements)-1] + + if name == "root:" { + return c + } + + c.items = append( + c.items, + onedriveMetadata( + c.t, + name, + name+onedrive.DirMetaFileSuffix, + user, + roles), + ) + + return c +} + +type permData struct { + user string + roles []string +} + +type itemData struct { + name string + data []byte + perms permData +} + +type onedriveColInfo struct { + pathElements []string + perms permData + files []itemData + folders []itemData +} + +type onedriveTest struct { + name string + // Version this test first be run for. Will run from + // [startVersion, backup.Version] inclusive. + startVersion int + cols []onedriveColInfo +} + +func testDataForInfo(t *testing.T, cols []onedriveColInfo, backupVersion int) []colInfo { + var res []colInfo + + for _, c := range cols { + onedriveCol := newOneDriveCollection(t, c.pathElements, backupVersion) + + for _, f := range c.files { + onedriveCol.withFile(f.name, f.data, f.perms.user, f.perms.roles) + } + + for _, d := range c.folders { + onedriveCol.withFolder(d.name, d.perms.user, d.perms.roles) + } + + onedriveCol.withPermissions(c.perms.user, c.perms.roles) + + res = append(res, onedriveCol.collection()) } return res } -func (suite *GraphConnectorOneDriveIntegrationSuite) TestRestoreAndBackup() { +func (suite *GraphConnectorOneDriveIntegrationSuite) TestRestoreAndBackup_MultipleFilesAndFolders() { ctx, flush := tester.NewContext() defer flush() @@ -160,55 +320,146 @@ func (suite *GraphConnectorOneDriveIntegrationSuite) TestRestoreAndBackup() { suite.user, ) - table := []restoreBackupInfo{ + rootPath := []string{ + "drives", + driveID, + "root:", + } + folderAPath := []string{ + "drives", + driveID, + "root:", + folderAName, + } + subfolderBPath := []string{ + "drives", + driveID, + "root:", + folderAName, + folderBName, + } + subfolderAPath := []string{ + "drives", + driveID, + "root:", + folderAName, + folderBName, + folderAName, + } + folderBPath := []string{ + "drives", + driveID, + "root:", + folderBName, + } + + table := []onedriveTest{ { - name: "OneDriveFoldersAndFilesWithMetadata", - service: path.OneDriveService, - resource: Users, - collections: []colInfo{ + name: "WithMetadata", + startVersion: 1, + cols: []onedriveColInfo{ { - pathElements: []string{ - "drives", - driveID, - "root:", + pathElements: rootPath, + files: []itemData{ + { + name: fileName, + data: fileAData, + perms: permData{ + user: suite.secondaryUser, + roles: writePerm, + }, + }, }, - category: path.FilesCategory, - items: withItems( - onedriveFileWithMetadata( - "test-file.txt", - fileAData, - getTestMetaJSON(suite.T(), suite.secondaryUser, []string{"write"}), - ), - []itemInfo{onedriveItemWithData( - "b"+onedrive.DirMetaFileSuffix, - getTestMetaJSON(suite.T(), suite.secondaryUser, []string{"read"}), - )}, - ), - auxItems: []itemInfo{ - onedriveItemWithData( - "test-file.txt"+onedrive.MetaFileSuffix, - getTestMetaJSON(suite.T(), suite.secondaryUser, []string{"write"}), - ), + folders: []itemData{ + { + name: folderBName, + perms: permData{ + user: suite.secondaryUser, + roles: readPerm, + }, + }, }, }, { - pathElements: []string{ - "drives", - driveID, - "root:", - "b", + pathElements: folderBPath, + files: []itemData{ + { + name: fileName, + data: fileEData, + perms: permData{ + user: suite.secondaryUser, + roles: readPerm, + }, + }, }, - category: path.FilesCategory, - items: onedriveFileWithMetadata( - "test-file.txt", - fileEData, - getTestMetaJSON(suite.T(), suite.secondaryUser, []string{"read"}), - ), - auxItems: []itemInfo{ - onedriveItemWithData( - "test-file.txt"+onedrive.MetaFileSuffix, - getTestMetaJSON(suite.T(), suite.secondaryUser, []string{"read"}), - ), + }, + }, + }, + { + name: "NoMetadata", + startVersion: 0, + cols: []onedriveColInfo{ + { + pathElements: rootPath, + files: []itemData{ + { + name: fileName, + data: fileAData, + }, + }, + folders: []itemData{ + { + name: folderAName, + }, + { + name: folderBName, + }, + }, + }, + { + pathElements: folderAPath, + files: []itemData{ + { + name: fileName, + data: fileBData, + }, + }, + folders: []itemData{ + { + name: folderBName, + }, + }, + }, + { + pathElements: subfolderBPath, + files: []itemData{ + { + name: fileName, + data: fileCData, + }, + }, + folders: []itemData{ + { + name: folderAName, + }, + }, + }, + { + pathElements: subfolderAPath, + files: []itemData{ + { + name: fileName, + data: fileDData, + }, + }, + }, + { + pathElements: folderBPath, + files: []itemData{ + { + name: fileName, + data: fileEData, + }, }, }, }, @@ -216,214 +467,34 @@ func (suite *GraphConnectorOneDriveIntegrationSuite) TestRestoreAndBackup() { } for _, test := range table { - suite.T().Run(test.name, func(t *testing.T) { - runRestoreBackupTest( - t, - suite.acct, - test, - suite.connector.tenant, - []string{suite.user}, - control.Options{ - RestorePermissions: true, - ToggleFeatures: control.Toggles{EnablePermissionsBackup: true}, - }, - ) - }) - } -} + expected := testDataForInfo(suite.T(), test.cols, backup.Version) -func (suite *GraphConnectorOneDriveIntegrationSuite) TestRestoreAndBackup_Versions() { - ctx, flush := tester.NewContext() - defer flush() + for version := test.startVersion; version <= backup.Version; version++ { + suite.T().Run(fmt.Sprintf("%s_Version%d", test.name, version), func(t *testing.T) { + input := testDataForInfo(t, test.cols, version) - // Get the default drive ID for the test user. - driveID := mustGetDefaultDriveID( - suite.T(), - ctx, - suite.connector.Service, - suite.user, - ) + testData := restoreBackupInfoMultiVersion{ + service: path.OneDriveService, + resource: Users, + backupVersion: version, + countMeta: version == 0, + collectionsPrevious: input, + collectionsLatest: expected, + } - collectionsLatest := []colInfo{ - { - pathElements: []string{ - "drives", - driveID, - "root:", - }, - category: path.FilesCategory, - items: withItems( - fileAEmptyPerms, - folderAEmptyPerms, - folderBEmptyPerms, - ), - auxItems: []itemInfo{fileEmptyPerms}, - }, - { - pathElements: []string{ - "drives", - driveID, - "root:", - "folder-a", - }, - category: path.FilesCategory, - items: withItems(fileBEmptyPerms, folderBEmptyPerms), - auxItems: []itemInfo{fileEmptyPerms}, - }, - { - pathElements: []string{ - "drives", - driveID, - "root:", - "folder-a", - "b", - }, - category: path.FilesCategory, - items: withItems(fileCEmptyPerms, folderAEmptyPerms), - auxItems: []itemInfo{fileEmptyPerms}, - }, - { - pathElements: []string{ - "drives", - driveID, - "root:", - "folder-a", - "b", - "folder-a", - }, - category: path.FilesCategory, - items: fileDEmptyPerms, - auxItems: []itemInfo{fileEmptyPerms}, - }, - { - pathElements: []string{ - "drives", - driveID, - "root:", - "b", - }, - category: path.FilesCategory, - items: fileEEmptyPerms, - auxItems: []itemInfo{fileEmptyPerms}, - }, - } - - table := []restoreBackupInfoMultiVersion{ - { - name: "OneDriveMultipleFoldersAndFiles_Version0", - service: path.OneDriveService, - resource: Users, - backupVersion: 0, // The OG version ;) - countMeta: true, - - collectionsPrevious: []colInfo{ - { - pathElements: []string{ - "drives", - driveID, - "root:", + runRestoreBackupTestVersions( + t, + suite.acct, + testData, + suite.connector.tenant, + []string{suite.user}, + control.Options{ + RestorePermissions: true, + ToggleFeatures: control.Toggles{EnablePermissionsBackup: true}, }, - category: path.FilesCategory, - items: []itemInfo{ - onedriveItemWithData( - "test-file.txt", - fileAData, - ), - }, - }, - { - pathElements: []string{ - "drives", - driveID, - "root:", - "folder-a", - }, - category: path.FilesCategory, - items: []itemInfo{ - onedriveItemWithData( - "test-file.txt", - fileBData, - ), - }, - }, - { - pathElements: []string{ - "drives", - driveID, - "root:", - "folder-a", - "b", - }, - category: path.FilesCategory, - items: []itemInfo{ - onedriveItemWithData( - "test-file.txt", - fileCData, - ), - }, - }, - { - pathElements: []string{ - "drives", - driveID, - "root:", - "folder-a", - "b", - "folder-a", - }, - category: path.FilesCategory, - items: []itemInfo{ - onedriveItemWithData( - "test-file.txt", - fileDData, - ), - }, - }, - { - pathElements: []string{ - "drives", - driveID, - "root:", - "b", - }, - category: path.FilesCategory, - items: []itemInfo{ - onedriveItemWithData( - "test-file.txt", - fileEData, - ), - }, - }, - }, - - collectionsLatest: collectionsLatest, - }, - - { - name: "OneDriveMultipleFoldersAndFiles_Version1", - service: path.OneDriveService, - resource: Users, - backupVersion: 1, - countMeta: false, - collectionsPrevious: collectionsLatest, - collectionsLatest: collectionsLatest, - }, - } - - for _, test := range table { - suite.T().Run(test.name, func(t *testing.T) { - runRestoreBackupTestVersions( - t, - suite.acct, - test, - suite.connector.tenant, - []string{suite.user}, - control.Options{ - RestorePermissions: true, - ToggleFeatures: control.Toggles{EnablePermissionsBackup: true}, - }, - ) - }) + ) + }) + } } } @@ -439,185 +510,220 @@ func (suite *GraphConnectorOneDriveIntegrationSuite) TestPermissionsRestoreAndBa suite.user, ) - var ( - fileAWritePerms = onedriveFileWithMetadata( - "test-file.txt", - fileAData, - getTestMetaJSON(suite.T(), suite.secondaryUser, []string{"write"}), - ) + rootPath := []string{ + "drives", + driveID, + "root:", + } + folderPath := []string{ + "drives", + driveID, + "root:", + folderBName, + } - fileEReadPerms = onedriveFileWithMetadata( - "test-file.txt", - fileEData, - getTestMetaJSON(suite.T(), suite.secondaryUser, []string{"read"}), - ) + startVersion := 1 - folderBReadPerms = []itemInfo{onedriveItemWithData( - "b"+onedrive.DirMetaFileSuffix, - getTestMetaJSON(suite.T(), suite.secondaryUser, []string{"read"}), - )} - - fileWritePerms = onedriveItemWithData( - "test-file.txt"+onedrive.MetaFileSuffix, - getTestMetaJSON(suite.T(), suite.secondaryUser, []string{"write"}), - ) - - fileReadPerms = onedriveItemWithData( - "test-file.txt"+onedrive.MetaFileSuffix, - getTestMetaJSON(suite.T(), suite.secondaryUser, []string{"read"}), - ) - ) - - table := []restoreBackupInfo{ + table := []onedriveTest{ { - name: "FilePermissionsRestore", - service: path.OneDriveService, - resource: Users, - collections: []colInfo{ + name: "FilePermissionsRestore", + startVersion: startVersion, + cols: []onedriveColInfo{ { - pathElements: []string{ - "drives", - driveID, - "root:", + pathElements: rootPath, + files: []itemData{ + { + name: fileName, + data: fileAData, + perms: permData{ + user: suite.secondaryUser, + roles: writePerm, + }, + }, }, - category: path.FilesCategory, - items: fileAWritePerms, - auxItems: []itemInfo{fileWritePerms}, }, }, }, - { - name: "FileInsideFolderPermissionsRestore", - service: path.OneDriveService, - resource: Users, - collections: []colInfo{ + name: "FileInsideFolderPermissionsRestore", + startVersion: startVersion, + cols: []onedriveColInfo{ { - pathElements: []string{ - "drives", - driveID, - "root:", + pathElements: rootPath, + files: []itemData{ + { + name: fileName, + data: fileAData, + }, + }, + folders: []itemData{ + { + name: folderBName, + }, }, - category: path.FilesCategory, - items: withItems(fileAEmptyPerms, folderBEmptyPerms), - auxItems: []itemInfo{fileEmptyPerms}, }, { - pathElements: []string{ - "drives", - driveID, - "root:", - "b", + pathElements: folderPath, + files: []itemData{ + { + name: fileName, + data: fileEData, + perms: permData{ + user: suite.secondaryUser, + roles: readPerm, + }, + }, }, - category: path.FilesCategory, - items: fileEReadPerms, - auxItems: []itemInfo{fileReadPerms}, }, }, }, - { - name: "FileAndFolderPermissionsRestore", - service: path.OneDriveService, - resource: Users, - collections: []colInfo{ + name: "FilesAndFolderPermissionsRestore", + startVersion: startVersion, + cols: []onedriveColInfo{ { - pathElements: []string{ - "drives", - driveID, - "root:", + pathElements: rootPath, + files: []itemData{ + { + name: fileName, + data: fileAData, + perms: permData{ + user: suite.secondaryUser, + roles: writePerm, + }, + }, + }, + folders: []itemData{ + { + name: folderBName, + perms: permData{ + user: suite.secondaryUser, + roles: readPerm, + }, + }, }, - category: path.FilesCategory, - items: withItems(fileAWritePerms, folderBReadPerms), - auxItems: []itemInfo{fileWritePerms}, }, { - pathElements: []string{ - "drives", - driveID, - "root:", - "b", + pathElements: folderPath, + files: []itemData{ + { + name: fileName, + data: fileEData, + perms: permData{ + user: suite.secondaryUser, + roles: readPerm, + }, + }, + }, + perms: permData{ + user: suite.secondaryUser, + roles: readPerm, }, - category: path.FilesCategory, - items: fileEReadPerms, - auxItems: []itemInfo{fileReadPerms}, }, }, }, - { - name: "FileAndFolderSeparatePermissionsRestore", - service: path.OneDriveService, - resource: Users, - collections: []colInfo{ + name: "FilesAndFolderSeparatePermissionsRestore", + startVersion: startVersion, + cols: []onedriveColInfo{ { - pathElements: []string{ - "drives", - driveID, - "root:", + pathElements: rootPath, + folders: []itemData{ + { + name: folderBName, + perms: permData{ + user: suite.secondaryUser, + roles: readPerm, + }, + }, }, - category: path.FilesCategory, - items: folderBReadPerms, }, { - pathElements: []string{ - "drives", - driveID, - "root:", - "b", + pathElements: folderPath, + files: []itemData{ + { + name: fileName, + data: fileEData, + perms: permData{ + user: suite.secondaryUser, + roles: writePerm, + }, + }, + }, + perms: permData{ + user: suite.secondaryUser, + roles: readPerm, }, - category: path.FilesCategory, - items: fileAWritePerms, - auxItems: []itemInfo{fileWritePerms}, }, }, }, - { - name: "FolderAndNoChildPermissionsRestore", - service: path.OneDriveService, - resource: Users, - collections: []colInfo{ + name: "FolderAndNoChildPermissionsRestore", + startVersion: startVersion, + cols: []onedriveColInfo{ { - pathElements: []string{ - "drives", - driveID, - "root:", + pathElements: rootPath, + folders: []itemData{ + { + name: folderBName, + perms: permData{ + user: suite.secondaryUser, + roles: readPerm, + }, + }, }, - category: path.FilesCategory, - items: folderBReadPerms, }, { - pathElements: []string{ - "drives", - driveID, - "root:", - "b", + pathElements: folderPath, + files: []itemData{ + { + name: fileName, + data: fileEData, + }, + }, + perms: permData{ + user: suite.secondaryUser, + roles: readPerm, }, - category: path.FilesCategory, - items: fileEEmptyPerms, - auxItems: []itemInfo{fileEmptyPerms}, }, }, }, } for _, test := range table { - suite.T().Run(test.name, func(t *testing.T) { - runRestoreBackupTest(t, - suite.acct, - test, - suite.connector.tenant, - []string{suite.user}, - control.Options{ - RestorePermissions: true, - ToggleFeatures: control.Toggles{EnablePermissionsBackup: true}, - }, - ) - }) + expected := testDataForInfo(suite.T(), test.cols, backup.Version) + + for version := test.startVersion; version <= backup.Version; version++ { + suite.T().Run(fmt.Sprintf("%s_Version%d", test.name, version), func(t *testing.T) { + input := testDataForInfo(t, test.cols, version) + + testData := restoreBackupInfoMultiVersion{ + service: path.OneDriveService, + resource: Users, + backupVersion: version, + countMeta: version == 0, + collectionsPrevious: input, + collectionsLatest: expected, + } + + runRestoreBackupTestVersions( + t, + suite.acct, + testData, + suite.connector.tenant, + []string{suite.user}, + control.Options{ + RestorePermissions: true, + ToggleFeatures: control.Toggles{EnablePermissionsBackup: true}, + }, + ) + }) + } } } +// TODO(ashmrtn): What this test is supposed to do needs investigated. It +// doesn't seem to do what it says. func (suite *GraphConnectorOneDriveIntegrationSuite) TestPermissionsBackupAndNoRestore() { ctx, flush := tester.NewContext() defer flush() @@ -630,29 +736,27 @@ func (suite *GraphConnectorOneDriveIntegrationSuite) TestPermissionsBackupAndNoR suite.user, ) - table := []restoreBackupInfo{ + startVersion := 1 + + table := []onedriveTest{ { - name: "FilePermissionsRestore", - service: path.OneDriveService, - resource: Users, - collections: []colInfo{ + startVersion: startVersion, + cols: []onedriveColInfo{ { pathElements: []string{ "drives", driveID, "root:", }, - category: path.FilesCategory, - items: onedriveFileWithMetadata( - "test-file.txt", - fileAData, - getTestMetaJSON(suite.T(), suite.secondaryUser, []string{"write"}), - ), - auxItems: []itemInfo{ - onedriveItemWithData( - "test-file.txt"+onedrive.MetaFileSuffix, - getTestMetaJSON(suite.T(), suite.secondaryUser, []string{"write"}), - ), + files: []itemData{ + { + name: fileName, + data: fileAData, + perms: permData{ + user: suite.secondaryUser, + roles: writePerm, + }, + }, }, }, }, @@ -660,19 +764,34 @@ func (suite *GraphConnectorOneDriveIntegrationSuite) TestPermissionsBackupAndNoR } for _, test := range table { - suite.T().Run(test.name, func(t *testing.T) { - runRestoreBackupTest( - t, - suite.acct, - test, - suite.connector.tenant, - []string{suite.user}, - control.Options{ - RestorePermissions: true, - ToggleFeatures: control.Toggles{EnablePermissionsBackup: true}, - }, - ) - }) + expected := testDataForInfo(suite.T(), test.cols, backup.Version) + + for version := test.startVersion; version <= backup.Version; version++ { + suite.T().Run(fmt.Sprintf("Version%d", version), func(t *testing.T) { + input := testDataForInfo(t, test.cols, version) + + testData := restoreBackupInfoMultiVersion{ + service: path.OneDriveService, + resource: Users, + backupVersion: version, + countMeta: version == 0, + collectionsPrevious: input, + collectionsLatest: expected, + } + + runRestoreBackupTestVersions( + t, + suite.acct, + testData, + suite.connector.tenant, + []string{suite.user}, + control.Options{ + RestorePermissions: true, + ToggleFeatures: control.Toggles{EnablePermissionsBackup: true}, + }, + ) + }) + } } } @@ -695,81 +814,88 @@ func (suite *GraphConnectorOneDriveIntegrationSuite) TestPermissionsRestoreAndNo backupVersion: backup.Version, countMeta: false, collectionsPrevious: []colInfo{ - { - pathElements: []string{ + newOneDriveCollection( + suite.T(), + []string{ "drives", driveID, "root:", }, - category: path.FilesCategory, - items: withItems( - onedriveFileWithMetadata( - "test-file.txt", - fileAData, - getTestMetaJSON(t, suite.secondaryUser, []string{"write"}), - ), - []itemInfo{onedriveItemWithData( - "b"+onedrive.DirMetaFileSuffix, - getTestMetaJSON(t, suite.secondaryUser, []string{"read"}), - )}, - ), - auxItems: []itemInfo{ - onedriveItemWithData( - "test-file.txt"+onedrive.MetaFileSuffix, - getTestMetaJSON(t, suite.secondaryUser, []string{"write"}), - ), - }, - }, - { - pathElements: []string{ + backup.Version, + ). + withFile( + fileName, + fileAData, + suite.secondaryUser, + writePerm, + ). + withFolder( + folderBName, + suite.secondaryUser, + readPerm, + ). + collection(), + newOneDriveCollection( + suite.T(), + []string{ "drives", driveID, "root:", - "b", + folderBName, }, - category: path.FilesCategory, - items: onedriveFileWithMetadata( - "test-file.txt", + backup.Version, + ). + withFile( + fileName, fileEData, - getTestMetaJSON(t, suite.secondaryUser, []string{"read"}), - ), - auxItems: []itemInfo{ - onedriveItemWithData( - "test-file.txt"+onedrive.MetaFileSuffix, - getTestMetaJSON(t, suite.secondaryUser, []string{"read"}), - ), - }, - }, + suite.secondaryUser, + readPerm, + ). + withPermissions( + suite.secondaryUser, + readPerm, + ). + collection(), }, collectionsLatest: []colInfo{ - { - pathElements: []string{ + newOneDriveCollection( + suite.T(), + []string{ "drives", driveID, "root:", }, - category: path.FilesCategory, - items: withItems( - fileAEmptyPerms, - folderBEmptyPerms, - ), - auxItems: []itemInfo{ - fileEmptyPerms, - }, - }, - { - pathElements: []string{ + backup.Version, + ). + withFile( + fileName, + fileAData, + "", + nil, + ). + withFolder( + folderBName, + "", + nil, + ). + collection(), + newOneDriveCollection( + suite.T(), + []string{ "drives", driveID, "root:", - "b", + folderBName, }, - category: path.FilesCategory, - items: fileEEmptyPerms, - auxItems: []itemInfo{ - fileEmptyPerms, - }, - }, + backup.Version, + ). + withFile( + fileName, + fileEData, + "", + nil, + ). + collection(), }, }