From f28c6e53d44208661a82a7810ba6c3e1a0003f1f Mon Sep 17 00:00:00 2001 From: ashmrtn Date: Fri, 19 May 2023 18:41:37 -0700 Subject: [PATCH] Add tests for older versions of backup details data (#3454) Add tests for older backup details versions including things like: * SharePoint using OneDriveItem type * not having LocationRef * not having ItemRef * folder names in RepoRef * file names in RepoRef Recommend viewing with ignore whitespace changes --- #### 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: Supportability/Tests - [ ] :computer: CI/Deployment - [ ] :broom: Tech Debt/Cleanup #### Issue(s) * #3269 #### Test Plan - [ ] :muscle: Manual - [x] :zap: Unit test - [ ] :green_heart: E2E --- src/cli/backup/exchange_test.go | 35 +- src/cli/backup/onedrive_test.go | 35 +- src/cli/backup/sharepoint_test.go | 35 +- src/cli/utils/testdata/opts.go | 1022 ++++++++++++------ src/pkg/backup/details/testdata/testdata.go | 1030 +++++++++++++++---- src/pkg/selectors/selectors_reduce_test.go | 241 ++++- 6 files changed, 1808 insertions(+), 590 deletions(-) diff --git a/src/cli/backup/exchange_test.go b/src/cli/backup/exchange_test.go index d8d4f9e68..dd3d12766 100644 --- a/src/cli/backup/exchange_test.go +++ b/src/cli/backup/exchange_test.go @@ -1,6 +1,7 @@ package backup import ( + "fmt" "testing" "github.com/alcionai/clues" @@ -13,6 +14,8 @@ import ( "github.com/alcionai/corso/src/cli/utils" "github.com/alcionai/corso/src/cli/utils/testdata" "github.com/alcionai/corso/src/internal/tester" + "github.com/alcionai/corso/src/internal/version" + dtd "github.com/alcionai/corso/src/pkg/backup/details/testdata" ) type ExchangeUnitSuite struct { @@ -275,18 +278,26 @@ func (suite *ExchangeUnitSuite) TestExchangeBackupDetailsSelectors() { ctx, flush := tester.NewContext() defer flush() - for _, test := range testdata.ExchangeOptionDetailLookups { - suite.Run(test.Name, func() { - t := suite.T() + for v := 0; v <= version.Backup; v++ { + suite.Run(fmt.Sprintf("version%d", v), func() { + for _, test := range testdata.ExchangeOptionDetailLookups { + suite.Run(test.Name, func() { + t := suite.T() - output, err := runDetailsExchangeCmd( - ctx, - test.BackupGetter, - "backup-ID", - test.Opts, - false) - assert.NoError(t, err, clues.ToCore(err)) - assert.ElementsMatch(t, test.Expected, output.Entries) + bg := testdata.VersionedBackupGetter{ + Details: dtd.GetDetailsSetForVersion(t, v), + } + + output, err := runDetailsExchangeCmd( + ctx, + bg, + "backup-ID", + test.Opts(t, v), + false) + assert.NoError(t, err, clues.ToCore(err)) + assert.ElementsMatch(t, test.Expected(t, v), output.Entries) + }) + } }) } } @@ -303,7 +314,7 @@ func (suite *ExchangeUnitSuite) TestExchangeBackupDetailsSelectorsBadFormats() { ctx, test.BackupGetter, "backup-ID", - test.Opts, + test.Opts(t, version.Backup), false) assert.Error(t, err, clues.ToCore(err)) assert.Empty(t, output) diff --git a/src/cli/backup/onedrive_test.go b/src/cli/backup/onedrive_test.go index dd9d6586b..27720fa74 100644 --- a/src/cli/backup/onedrive_test.go +++ b/src/cli/backup/onedrive_test.go @@ -1,6 +1,7 @@ package backup import ( + "fmt" "testing" "github.com/alcionai/clues" @@ -13,6 +14,8 @@ import ( "github.com/alcionai/corso/src/cli/utils" "github.com/alcionai/corso/src/cli/utils/testdata" "github.com/alcionai/corso/src/internal/tester" + "github.com/alcionai/corso/src/internal/version" + dtd "github.com/alcionai/corso/src/pkg/backup/details/testdata" ) type OneDriveUnitSuite struct { @@ -137,18 +140,26 @@ func (suite *OneDriveUnitSuite) TestOneDriveBackupDetailsSelectors() { ctx, flush := tester.NewContext() defer flush() - for _, test := range testdata.OneDriveOptionDetailLookups { - suite.Run(test.Name, func() { - t := suite.T() + for v := 0; v <= version.Backup; v++ { + suite.Run(fmt.Sprintf("version%d", v), func() { + for _, test := range testdata.OneDriveOptionDetailLookups { + suite.Run(test.Name, func() { + t := suite.T() - output, err := runDetailsOneDriveCmd( - ctx, - test.BackupGetter, - "backup-ID", - test.Opts, - false) - assert.NoError(t, err, clues.ToCore(err)) - assert.ElementsMatch(t, test.Expected, output.Entries) + bg := testdata.VersionedBackupGetter{ + Details: dtd.GetDetailsSetForVersion(t, v), + } + + output, err := runDetailsOneDriveCmd( + ctx, + bg, + "backup-ID", + test.Opts(t, v), + false) + assert.NoError(t, err, clues.ToCore(err)) + assert.ElementsMatch(t, test.Expected(t, v), output.Entries) + }) + } }) } } @@ -165,7 +176,7 @@ func (suite *OneDriveUnitSuite) TestOneDriveBackupDetailsSelectorsBadFormats() { ctx, test.BackupGetter, "backup-ID", - test.Opts, + test.Opts(t, version.Backup), false) assert.Error(t, err, clues.ToCore(err)) assert.Empty(t, output) diff --git a/src/cli/backup/sharepoint_test.go b/src/cli/backup/sharepoint_test.go index 70b132897..ba355da82 100644 --- a/src/cli/backup/sharepoint_test.go +++ b/src/cli/backup/sharepoint_test.go @@ -1,6 +1,7 @@ package backup import ( + "fmt" "testing" "github.com/alcionai/clues" @@ -14,6 +15,8 @@ import ( "github.com/alcionai/corso/src/cli/utils/testdata" "github.com/alcionai/corso/src/internal/common/idname" "github.com/alcionai/corso/src/internal/tester" + "github.com/alcionai/corso/src/internal/version" + dtd "github.com/alcionai/corso/src/pkg/backup/details/testdata" "github.com/alcionai/corso/src/pkg/selectors" ) @@ -256,18 +259,26 @@ func (suite *SharePointUnitSuite) TestSharePointBackupDetailsSelectors() { ctx, flush := tester.NewContext() defer flush() - for _, test := range testdata.SharePointOptionDetailLookups { - suite.Run(test.Name, func() { - t := suite.T() + for v := 0; v <= version.Backup; v++ { + suite.Run(fmt.Sprintf("version%d", v), func() { + for _, test := range testdata.SharePointOptionDetailLookups { + suite.Run(test.Name, func() { + t := suite.T() - output, err := runDetailsSharePointCmd( - ctx, - test.BackupGetter, - "backup-ID", - test.Opts, - false) - assert.NoError(t, err, clues.ToCore(err)) - assert.ElementsMatch(t, test.Expected, output.Entries) + bg := testdata.VersionedBackupGetter{ + Details: dtd.GetDetailsSetForVersion(t, v), + } + + output, err := runDetailsSharePointCmd( + ctx, + bg, + "backup-ID", + test.Opts(t, v), + false) + assert.NoError(t, err, clues.ToCore(err)) + assert.ElementsMatch(t, test.Expected(t, v), output.Entries) + }) + } }) } } @@ -284,7 +295,7 @@ func (suite *SharePointUnitSuite) TestSharePointBackupDetailsSelectorsBadFormats ctx, test.BackupGetter, "backup-ID", - test.Opts, + test.Opts(t, version.Backup), false) assert.Error(t, err, clues.ToCore(err)) assert.Empty(t, output) diff --git a/src/cli/utils/testdata/opts.go b/src/cli/utils/testdata/opts.go index 8bbb35a58..614434c11 100644 --- a/src/cli/utils/testdata/opts.go +++ b/src/cli/utils/testdata/opts.go @@ -2,6 +2,7 @@ package testdata import ( "context" + "testing" "time" "github.com/alcionai/clues" @@ -13,15 +14,16 @@ import ( "github.com/alcionai/corso/src/pkg/backup/details/testdata" "github.com/alcionai/corso/src/pkg/fault" ftd "github.com/alcionai/corso/src/pkg/fault/testdata" + "github.com/alcionai/corso/src/pkg/path" "github.com/alcionai/corso/src/pkg/selectors" "github.com/alcionai/corso/src/pkg/store" ) type ExchangeOptionsTest struct { Name string - Opts utils.ExchangeOpts + Opts func(t *testing.T, wantedVersion int) utils.ExchangeOpts BackupGetter *MockBackupGetter - Expected []details.Entry + Expected func(t *testing.T, wantedVersion int) []details.Entry } var ( @@ -32,92 +34,112 @@ var ( BadExchangeOptionsFormats = []ExchangeOptionsTest{ { Name: "BadEmailReceiveAfter", - Opts: utils.ExchangeOpts{ - EmailReceivedAfter: "foo", - Populated: utils.PopulatedFlags{ - utils.EmailReceivedAfterFN: struct{}{}, - }, + Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts { + return utils.ExchangeOpts{ + EmailReceivedAfter: "foo", + Populated: utils.PopulatedFlags{ + utils.EmailReceivedAfterFN: struct{}{}, + }, + } }, }, { Name: "EmptyEmailReceiveAfter", - Opts: utils.ExchangeOpts{ - EmailReceivedAfter: "", - Populated: utils.PopulatedFlags{ - utils.EmailReceivedAfterFN: struct{}{}, - }, + Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts { + return utils.ExchangeOpts{ + EmailReceivedAfter: "", + Populated: utils.PopulatedFlags{ + utils.EmailReceivedAfterFN: struct{}{}, + }, + } }, }, { Name: "BadEmailReceiveBefore", - Opts: utils.ExchangeOpts{ - EmailReceivedBefore: "foo", - Populated: utils.PopulatedFlags{ - utils.EmailReceivedBeforeFN: struct{}{}, - }, + Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts { + return utils.ExchangeOpts{ + EmailReceivedBefore: "foo", + Populated: utils.PopulatedFlags{ + utils.EmailReceivedBeforeFN: struct{}{}, + }, + } }, }, { Name: "EmptyEmailReceiveBefore", - Opts: utils.ExchangeOpts{ - EmailReceivedBefore: "", - Populated: utils.PopulatedFlags{ - utils.EmailReceivedBeforeFN: struct{}{}, - }, + Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts { + return utils.ExchangeOpts{ + EmailReceivedBefore: "", + Populated: utils.PopulatedFlags{ + utils.EmailReceivedBeforeFN: struct{}{}, + }, + } }, }, { Name: "BadEventRecurs", - Opts: utils.ExchangeOpts{ - EventRecurs: "foo", - Populated: utils.PopulatedFlags{ - utils.EventRecursFN: struct{}{}, - }, + Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts { + return utils.ExchangeOpts{ + EventRecurs: "foo", + Populated: utils.PopulatedFlags{ + utils.EventRecursFN: struct{}{}, + }, + } }, }, { Name: "EmptyEventRecurs", - Opts: utils.ExchangeOpts{ - EventRecurs: "", - Populated: utils.PopulatedFlags{ - utils.EventRecursFN: struct{}{}, - }, + Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts { + return utils.ExchangeOpts{ + EventRecurs: "", + Populated: utils.PopulatedFlags{ + utils.EventRecursFN: struct{}{}, + }, + } }, }, { Name: "BadEventStartsAfter", - Opts: utils.ExchangeOpts{ - EventStartsAfter: "foo", - Populated: utils.PopulatedFlags{ - utils.EventStartsAfterFN: struct{}{}, - }, + Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts { + return utils.ExchangeOpts{ + EventStartsAfter: "foo", + Populated: utils.PopulatedFlags{ + utils.EventStartsAfterFN: struct{}{}, + }, + } }, }, { Name: "EmptyEventStartsAfter", - Opts: utils.ExchangeOpts{ - EventStartsAfter: "", - Populated: utils.PopulatedFlags{ - utils.EventStartsAfterFN: struct{}{}, - }, + Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts { + return utils.ExchangeOpts{ + EventStartsAfter: "", + Populated: utils.PopulatedFlags{ + utils.EventStartsAfterFN: struct{}{}, + }, + } }, }, { Name: "BadEventStartsBefore", - Opts: utils.ExchangeOpts{ - EventStartsBefore: "foo", - Populated: utils.PopulatedFlags{ - utils.EventStartsBeforeFN: struct{}{}, - }, + Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts { + return utils.ExchangeOpts{ + EventStartsBefore: "foo", + Populated: utils.PopulatedFlags{ + utils.EventStartsBeforeFN: struct{}{}, + }, + } }, }, { Name: "EmptyEventStartsBefore", - Opts: utils.ExchangeOpts{ - EventStartsBefore: "", - Populated: utils.PopulatedFlags{ - utils.EventStartsBeforeFN: struct{}{}, - }, + Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts { + return utils.ExchangeOpts{ + EventStartsBefore: "", + Populated: utils.PopulatedFlags{ + utils.EventStartsBeforeFN: struct{}{}, + }, + } }, }, } @@ -128,130 +150,274 @@ var ( // configured to return the full dataset listed in selectors/testdata. ExchangeOptionDetailLookups = []ExchangeOptionsTest{ { - Name: "Emails", - Expected: testdata.ExchangeEmailItems, - Opts: utils.ExchangeOpts{ - Email: selectors.Any(), + Name: "Emails", + Expected: func(t *testing.T, wantedVersion int) []details.Entry { + return testdata.GetItemsForVersion( + t, + path.ExchangeService, + path.EmailCategory, + wantedVersion, + -1) + }, + Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts { + return utils.ExchangeOpts{ + Email: selectors.Any(), + } }, }, { - Name: "EmailsFolderPrefixMatch", - Expected: testdata.ExchangeEmailItems, - Opts: utils.ExchangeOpts{ - EmailFolder: []string{testdata.ExchangeEmailInboxPath.FolderLocation()}, + Name: "EmailsFolderPrefixMatch", + Expected: func(t *testing.T, wantedVersion int) []details.Entry { + return testdata.GetItemsForVersion( + t, + path.ExchangeService, + path.EmailCategory, + wantedVersion, + -1) + }, + Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts { + return utils.ExchangeOpts{ + EmailFolder: []string{testdata.ExchangeEmailInboxPath.FolderLocation()}, + } }, }, { - Name: "EmailsFolderPrefixMatchTrailingSlash", - Expected: testdata.ExchangeEmailItems, - Opts: utils.ExchangeOpts{ - EmailFolder: []string{testdata.ExchangeEmailInboxPath.FolderLocation() + "/"}, + Name: "EmailsFolderPrefixMatchTrailingSlash", + Expected: func(t *testing.T, wantedVersion int) []details.Entry { + return testdata.GetItemsForVersion( + t, + path.ExchangeService, + path.EmailCategory, + wantedVersion, + -1) + }, + Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts { + return utils.ExchangeOpts{ + EmailFolder: []string{testdata.ExchangeEmailInboxPath.FolderLocation() + "/"}, + } }, }, { Name: "EmailsFolderWithSlashPrefixMatch", - Expected: []details.Entry{ - testdata.ExchangeEmailItems[1], - testdata.ExchangeEmailItems[2], + Expected: func(t *testing.T, wantedVersion int) []details.Entry { + return testdata.GetItemsForVersion( + t, + path.ExchangeService, + path.EmailCategory, + wantedVersion, + 1, 2) }, - Opts: utils.ExchangeOpts{ - EmailFolder: []string{testdata.ExchangeEmailBasePath2.FolderLocation()}, + Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts { + return utils.ExchangeOpts{ + EmailFolder: []string{testdata.ExchangeEmailBasePath2.FolderLocation()}, + } }, }, { Name: "EmailsFolderWithSlashPrefixMatchTrailingSlash", - Expected: []details.Entry{ - testdata.ExchangeEmailItems[1], - testdata.ExchangeEmailItems[2], + Expected: func(t *testing.T, wantedVersion int) []details.Entry { + return testdata.GetItemsForVersion( + t, + path.ExchangeService, + path.EmailCategory, + wantedVersion, + 1, 2) }, - Opts: utils.ExchangeOpts{ - EmailFolder: []string{testdata.ExchangeEmailBasePath2.FolderLocation() + "/"}, + Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts { + return utils.ExchangeOpts{ + EmailFolder: []string{testdata.ExchangeEmailBasePath2.FolderLocation() + "/"}, + } }, }, { Name: "EmailsBySubject", - Expected: []details.Entry{ - testdata.ExchangeEmailItems[0], - testdata.ExchangeEmailItems[1], + Expected: func(t *testing.T, wantedVersion int) []details.Entry { + return testdata.GetItemsForVersion( + t, + path.ExchangeService, + path.EmailCategory, + wantedVersion, + 0, 1) }, - Opts: utils.ExchangeOpts{ - EmailSender: "a-person", + Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts { + return utils.ExchangeOpts{ + EmailSender: "a-person", + } }, }, { Name: "AllExchange", - Expected: append( - append( + Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts { + return utils.ExchangeOpts{} + }, + Expected: func(t *testing.T, wantedVersion int) []details.Entry { + return append( append( - []details.Entry{}, - testdata.ExchangeEmailItems..., - ), - testdata.ExchangeContactsItems..., - ), - testdata.ExchangeEventsItems..., - ), - }, - { - Name: "MailReceivedTime", - Expected: []details.Entry{testdata.ExchangeEmailItems[0]}, - Opts: utils.ExchangeOpts{ - EmailReceivedBefore: dttm.Format(testdata.Time1.Add(time.Second)), + testdata.GetItemsForVersion( + t, + path.ExchangeService, + path.EmailCategory, + wantedVersion, + -1), + testdata.GetItemsForVersion( + t, + path.ExchangeService, + path.EventsCategory, + wantedVersion, + -1)...), + testdata.GetItemsForVersion( + t, + path.ExchangeService, + path.ContactsCategory, + wantedVersion, + -1)...) }, }, { - Name: "MailShortRef", - Expected: []details.Entry{testdata.ExchangeEmailItems[0]}, - Opts: utils.ExchangeOpts{ - Email: []string{testdata.ExchangeEmailItemPath1.RR.ShortRef()}, + Name: "MailReceivedTime", + Expected: func(t *testing.T, wantedVersion int) []details.Entry { + return testdata.GetItemsForVersion( + t, + path.ExchangeService, + path.EmailCategory, + wantedVersion, + 0) + }, + Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts { + return utils.ExchangeOpts{ + EmailReceivedBefore: dttm.Format(testdata.Time1.Add(time.Second)), + } + }, + }, + { + Name: "MailShortRef", + Expected: func(t *testing.T, wantedVersion int) []details.Entry { + return testdata.GetItemsForVersion( + t, + path.ExchangeService, + path.EmailCategory, + wantedVersion, + 0) + }, + Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts { + deets := testdata.GetDeetsForVersion( + t, + path.ExchangeService, + path.EmailCategory, + wantedVersion) + + return utils.ExchangeOpts{ + Email: []string{deets[0].ShortRef}, + } }, }, { Name: "BadMailItemRef", // no matches are expected, since exchange ItemRefs // are not matched when using the CLI's selectors. - Expected: []details.Entry{}, - Opts: utils.ExchangeOpts{ - Email: []string{testdata.ExchangeEmailItems[0].ItemRef}, + Expected: func(t *testing.T, wantedVersion int) []details.Entry { + return []details.Entry{} + }, + Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts { + deets := testdata.GetDeetsForVersion( + t, + path.ExchangeService, + path.EmailCategory, + wantedVersion) + + return utils.ExchangeOpts{ + Email: []string{deets[0].ItemRef}, + } }, }, { Name: "MultipleMailShortRef", - Expected: []details.Entry{ - testdata.ExchangeEmailItems[0], - testdata.ExchangeEmailItems[1], + Expected: func(t *testing.T, wantedVersion int) []details.Entry { + return testdata.GetItemsForVersion( + t, + path.ExchangeService, + path.EmailCategory, + wantedVersion, + 0, 1) }, - Opts: utils.ExchangeOpts{ - Email: []string{ - testdata.ExchangeEmailItemPath1.RR.ShortRef(), - testdata.ExchangeEmailItemPath2.RR.ShortRef(), - }, + Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts { + deets := testdata.GetDeetsForVersion( + t, + path.ExchangeService, + path.EmailCategory, + wantedVersion) + + return utils.ExchangeOpts{ + Email: []string{ + deets[0].ShortRef, + deets[1].ShortRef, + }, + } }, }, { - Name: "AllEventsAndMailWithSubject", - Expected: []details.Entry{testdata.ExchangeEmailItems[0]}, - Opts: utils.ExchangeOpts{ - EmailSubject: "foo", - Event: selectors.Any(), + Name: "AllEventsAndMailWithSubject", + Expected: func(t *testing.T, wantedVersion int) []details.Entry { + return testdata.GetItemsForVersion( + t, + path.ExchangeService, + path.EmailCategory, + wantedVersion, + 0) + }, + Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts { + return utils.ExchangeOpts{ + EmailSubject: "foo", + Event: selectors.Any(), + } }, }, { - Name: "EventsAndMailWithSubject", - Expected: []details.Entry{}, - Opts: utils.ExchangeOpts{ - EmailSubject: "foo", - EventSubject: "foo", + Name: "EventsAndMailWithSubject", + Expected: func(t *testing.T, wantedVersion int) []details.Entry { + return []details.Entry{} + }, + Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts { + return utils.ExchangeOpts{ + EmailSubject: "foo", + EventSubject: "foo", + } }, }, { Name: "EventsAndMailByShortRef", - Expected: []details.Entry{ - testdata.ExchangeEmailItems[0], - testdata.ExchangeEventsItems[0], + Expected: func(t *testing.T, wantedVersion int) []details.Entry { + return append( + testdata.GetItemsForVersion( + t, + path.ExchangeService, + path.EmailCategory, + wantedVersion, + 0), + testdata.GetItemsForVersion( + t, + path.ExchangeService, + path.EventsCategory, + wantedVersion, + 0)...) }, - Opts: utils.ExchangeOpts{ - Email: []string{testdata.ExchangeEmailItemPath1.RR.ShortRef()}, - Event: []string{testdata.ExchangeEventsItemPath1.RR.ShortRef()}, + Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts { + emailDeets := testdata.GetDeetsForVersion( + t, + path.ExchangeService, + path.EmailCategory, + wantedVersion) + + eventDeets := testdata.GetDeetsForVersion( + t, + path.ExchangeService, + path.EventsCategory, + wantedVersion) + + return utils.ExchangeOpts{ + Email: []string{emailDeets[0].ShortRef}, + Event: []string{eventDeets[0].ShortRef}, + } }, }, } @@ -259,9 +425,9 @@ var ( type OneDriveOptionsTest struct { Name string - Opts utils.OneDriveOpts + Opts func(t *testing.T, wantedVersion int) utils.OneDriveOpts BackupGetter *MockBackupGetter - Expected []details.Entry + Expected func(t *testing.T, wantedVersion int) []details.Entry } var ( @@ -271,75 +437,91 @@ var ( BadOneDriveOptionsFormats = []OneDriveOptionsTest{ { Name: "BadFileCreatedAfter", - Opts: utils.OneDriveOpts{ - Users: selectors.Any(), - FileCreatedAfter: "foo", - Populated: utils.PopulatedFlags{ - utils.FileCreatedAfterFN: struct{}{}, - }, + Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts { + return utils.OneDriveOpts{ + Users: selectors.Any(), + FileCreatedAfter: "foo", + Populated: utils.PopulatedFlags{ + utils.FileCreatedAfterFN: struct{}{}, + }, + } }, }, { Name: "EmptyFileCreatedAfter", - Opts: utils.OneDriveOpts{ - FileCreatedAfter: "", - Populated: utils.PopulatedFlags{ - utils.FileCreatedAfterFN: struct{}{}, - }, + Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts { + return utils.OneDriveOpts{ + FileCreatedAfter: "", + Populated: utils.PopulatedFlags{ + utils.FileCreatedAfterFN: struct{}{}, + }, + } }, }, { Name: "BadFileCreatedBefore", - Opts: utils.OneDriveOpts{ - FileCreatedBefore: "foo", - Populated: utils.PopulatedFlags{ - utils.FileCreatedBeforeFN: struct{}{}, - }, + Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts { + return utils.OneDriveOpts{ + FileCreatedBefore: "foo", + Populated: utils.PopulatedFlags{ + utils.FileCreatedBeforeFN: struct{}{}, + }, + } }, }, { Name: "EmptyFileCreatedBefore", - Opts: utils.OneDriveOpts{ - FileCreatedBefore: "", - Populated: utils.PopulatedFlags{ - utils.FileCreatedBeforeFN: struct{}{}, - }, + Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts { + return utils.OneDriveOpts{ + FileCreatedBefore: "", + Populated: utils.PopulatedFlags{ + utils.FileCreatedBeforeFN: struct{}{}, + }, + } }, }, { Name: "BadFileModifiedAfter", - Opts: utils.OneDriveOpts{ - FileModifiedAfter: "foo", - Populated: utils.PopulatedFlags{ - utils.FileModifiedAfterFN: struct{}{}, - }, + Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts { + return utils.OneDriveOpts{ + FileModifiedAfter: "foo", + Populated: utils.PopulatedFlags{ + utils.FileModifiedAfterFN: struct{}{}, + }, + } }, }, { Name: "EmptyFileModifiedAfter", - Opts: utils.OneDriveOpts{ - FileModifiedAfter: "", - Populated: utils.PopulatedFlags{ - utils.FileModifiedAfterFN: struct{}{}, - }, + Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts { + return utils.OneDriveOpts{ + FileModifiedAfter: "", + Populated: utils.PopulatedFlags{ + utils.FileModifiedAfterFN: struct{}{}, + }, + } }, }, { Name: "BadFileModifiedBefore", - Opts: utils.OneDriveOpts{ - FileModifiedBefore: "foo", - Populated: utils.PopulatedFlags{ - utils.FileModifiedBeforeFN: struct{}{}, - }, + Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts { + return utils.OneDriveOpts{ + FileModifiedBefore: "foo", + Populated: utils.PopulatedFlags{ + utils.FileModifiedBeforeFN: struct{}{}, + }, + } }, }, { Name: "EmptyFileModifiedBefore", - Opts: utils.OneDriveOpts{ - FileModifiedBefore: "", - Populated: utils.PopulatedFlags{ - utils.FileModifiedBeforeFN: struct{}{}, - }, + Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts { + return utils.OneDriveOpts{ + FileModifiedBefore: "", + Populated: utils.PopulatedFlags{ + utils.FileModifiedBeforeFN: struct{}{}, + }, + } }, }, } @@ -350,96 +532,203 @@ var ( // configured to return the full dataset listed in selectors/testdata. OneDriveOptionDetailLookups = []OneDriveOptionsTest{ { - Name: "AllFiles", - Expected: testdata.OneDriveItems, - Opts: utils.OneDriveOpts{ - FolderPath: selectors.Any(), + Name: "AllFiles", + Expected: func(t *testing.T, wantedVersion int) []details.Entry { + return testdata.GetItemsForVersion( + t, + path.OneDriveService, + path.FilesCategory, + wantedVersion, + -1) + }, + Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts { + return utils.OneDriveOpts{ + FolderPath: selectors.Any(), + } }, }, { - Name: "FilesWithSingleSlash", - Expected: testdata.OneDriveItems, - Opts: utils.OneDriveOpts{ - FolderPath: []string{"/"}, + Name: "FilesWithSingleSlash", + Expected: func(t *testing.T, wantedVersion int) []details.Entry { + return testdata.GetItemsForVersion( + t, + path.OneDriveService, + path.FilesCategory, + wantedVersion, + -1) + }, + Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts { + return utils.OneDriveOpts{ + FolderPath: []string{"/"}, + } }, }, { - Name: "FolderPrefixMatch", - Expected: testdata.OneDriveItems, - Opts: utils.OneDriveOpts{ - FolderPath: []string{testdata.OneDriveFolderFolder}, + Name: "FolderPrefixMatch", + Expected: func(t *testing.T, wantedVersion int) []details.Entry { + return testdata.GetItemsForVersion( + t, + path.OneDriveService, + path.FilesCategory, + wantedVersion, + -1) + }, + Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts { + return utils.OneDriveOpts{ + FolderPath: []string{testdata.OneDriveFolderFolder}, + } }, }, { - Name: "FolderPrefixMatchTrailingSlash", - Expected: testdata.OneDriveItems, - Opts: utils.OneDriveOpts{ - FolderPath: []string{testdata.OneDriveFolderFolder + "/"}, + Name: "FolderPrefixMatchTrailingSlash", + Expected: func(t *testing.T, wantedVersion int) []details.Entry { + return testdata.GetItemsForVersion( + t, + path.OneDriveService, + path.FilesCategory, + wantedVersion, + -1) + }, + Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts { + return utils.OneDriveOpts{ + FolderPath: []string{testdata.OneDriveFolderFolder + "/"}, + } }, }, { - Name: "FolderPrefixMatchTrailingSlash", - Expected: testdata.OneDriveItems, - Opts: utils.OneDriveOpts{ - FolderPath: []string{testdata.OneDriveFolderFolder + "/"}, + Name: "FolderPrefixMatchTrailingSlash", + Expected: func(t *testing.T, wantedVersion int) []details.Entry { + return testdata.GetItemsForVersion( + t, + path.OneDriveService, + path.FilesCategory, + wantedVersion, + -1) + }, + Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts { + return utils.OneDriveOpts{ + FolderPath: []string{testdata.OneDriveFolderFolder + "/"}, + } }, }, { - Name: "FolderRepoRefMatchesNothing", - Expected: []details.Entry{}, - Opts: utils.OneDriveOpts{ - FolderPath: []string{testdata.OneDriveFolderPath.RR.Folder(true)}, + Name: "FolderRepoRefMatchesNothing", + Expected: func(t *testing.T, wantedVersion int) []details.Entry { + return []details.Entry{} + }, + Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts { + return utils.OneDriveOpts{ + FolderPath: []string{testdata.OneDriveFolderPath.RR.Folder(true)}, + } }, }, { Name: "ShortRef", - Expected: []details.Entry{ - testdata.OneDriveItems[0], - testdata.OneDriveItems[1], + Expected: func(t *testing.T, wantedVersion int) []details.Entry { + return testdata.GetItemsForVersion( + t, + path.OneDriveService, + path.FilesCategory, + wantedVersion, + 0, 1) }, - Opts: utils.OneDriveOpts{ - FileName: []string{ - testdata.OneDriveItems[0].ShortRef, - testdata.OneDriveItems[1].ShortRef, - }, + Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts { + deets := testdata.GetDeetsForVersion( + t, + path.OneDriveService, + path.FilesCategory, + wantedVersion) + + return utils.OneDriveOpts{ + FileName: []string{ + deets[0].ShortRef, + deets[1].ShortRef, + }, + } }, }, { - Name: "SingleItem", - Expected: []details.Entry{testdata.OneDriveItems[0]}, - Opts: utils.OneDriveOpts{ - FileName: []string{ - testdata.OneDriveItems[0].OneDrive.ItemName, - }, + Name: "SingleItem", + Expected: func(t *testing.T, wantedVersion int) []details.Entry { + return testdata.GetItemsForVersion( + t, + path.OneDriveService, + path.FilesCategory, + wantedVersion, + 0) + }, + Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts { + deets := testdata.GetDeetsForVersion( + t, + path.OneDriveService, + path.FilesCategory, + wantedVersion) + + return utils.OneDriveOpts{ + FileName: []string{ + deets[0].OneDrive.ItemName, + }, + } }, }, { Name: "MultipleItems", - Expected: []details.Entry{ - testdata.OneDriveItems[0], - testdata.OneDriveItems[1], + Expected: func(t *testing.T, wantedVersion int) []details.Entry { + return testdata.GetItemsForVersion( + t, + path.OneDriveService, + path.FilesCategory, + wantedVersion, + 0, 1) }, - Opts: utils.OneDriveOpts{ - FileName: []string{ - testdata.OneDriveItems[0].OneDrive.ItemName, - testdata.OneDriveItems[1].OneDrive.ItemName, - }, + Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts { + deets := testdata.GetDeetsForVersion( + t, + path.OneDriveService, + path.FilesCategory, + wantedVersion) + + return utils.OneDriveOpts{ + FileName: []string{ + deets[0].OneDrive.ItemName, + deets[1].OneDrive.ItemName, + }, + } }, }, { - Name: "ItemRefMatchesNothing", - Expected: []details.Entry{}, - Opts: utils.OneDriveOpts{ - FileName: []string{ - testdata.OneDriveItems[0].ItemRef, - }, + Name: "ItemRefMatchesNothing", + Expected: func(t *testing.T, wantedVersion int) []details.Entry { + return []details.Entry{} + }, + Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts { + deets := testdata.GetDeetsForVersion( + t, + path.OneDriveService, + path.FilesCategory, + wantedVersion) + + return utils.OneDriveOpts{ + FileName: []string{ + deets[0].ItemRef, + }, + } }, }, { - Name: "CreatedBefore", - Expected: []details.Entry{testdata.OneDriveItems[1]}, - Opts: utils.OneDriveOpts{ - FileCreatedBefore: dttm.Format(testdata.Time1.Add(time.Second)), + Name: "CreatedBefore", + Expected: func(t *testing.T, wantedVersion int) []details.Entry { + return testdata.GetItemsForVersion( + t, + path.OneDriveService, + path.FilesCategory, + wantedVersion, + 1) + }, + Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts { + return utils.OneDriveOpts{ + FileCreatedBefore: dttm.Format(testdata.Time1.Add(time.Second)), + } }, }, } @@ -447,9 +736,9 @@ var ( type SharePointOptionsTest struct { Name string - Opts utils.SharePointOpts + Opts func(t *testing.T, wantedVersion int) utils.SharePointOpts BackupGetter *MockBackupGetter - Expected []details.Entry + Expected func(t *testing.T, wantedVersion int) []details.Entry } var ( @@ -457,24 +746,28 @@ var ( // cause errors about the format of the input flag. Mocks are configured to // allow the system to run if it doesn't throw an error on formatting. BadSharePointOptionsFormats = []SharePointOptionsTest{ - // { - // Name: "BadFileCreatedBefore", - // Opts: utils.OneDriveOpts{ - // FileCreatedBefore: "foo", - // Populated: utils.PopulatedFlags{ - // utils.FileCreatedBeforeFN: struct{}{}, - // }, - // }, - // }, - // { - // Name: "EmptyFileCreatedBefore", - // Opts: utils.OneDriveOpts{ - // FileCreatedBefore: "", - // Populated: utils.PopulatedFlags{ - // utils.FileCreatedBeforeFN: struct{}{}, - // }, - // }, - // }, + //{ + // Name: "BadFileCreatedBefore", + // Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts { + // return utils.SharePointOpts{ + // FileCreatedBefore: "foo", + // Populated: utils.PopulatedFlags{ + // utils.FileCreatedBeforeFN: struct{}{}, + // }, + // } + // }, + //}, + //{ + // Name: "EmptyFileCreatedBefore", + // Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts { + // return utils.SharePointOpts{ + // FileCreatedBefore: "", + // Populated: utils.PopulatedFlags{ + // utils.FileCreatedBeforeFN: struct{}{}, + // }, + // } + // }, + //}, } // SharePointOptionDetailLookups contains flag inputs and expected results for @@ -483,98 +776,205 @@ var ( // configured to return the full dataset listed in selectors/testdata. SharePointOptionDetailLookups = []SharePointOptionsTest{ { - Name: "AllLibraryItems", - Expected: testdata.SharePointLibraryItems, - Opts: utils.SharePointOpts{ - FolderPath: selectors.Any(), + Name: "AllLibraryItems", + Expected: func(t *testing.T, wantedVersion int) []details.Entry { + return testdata.GetItemsForVersion( + t, + path.SharePointService, + path.LibrariesCategory, + wantedVersion, + -1) + }, + Opts: func(t *testing.T, wantedVersion int) utils.SharePointOpts { + return utils.SharePointOpts{ + FolderPath: selectors.Any(), + } }, }, { - Name: "LibraryItemsWithSingleSlash", - Expected: testdata.SharePointLibraryItems, - Opts: utils.SharePointOpts{ - FolderPath: []string{"/"}, + Name: "LibraryItemsWithSingleSlash", + Expected: func(t *testing.T, wantedVersion int) []details.Entry { + return testdata.GetItemsForVersion( + t, + path.SharePointService, + path.LibrariesCategory, + wantedVersion, + -1) + }, + Opts: func(t *testing.T, wantedVersion int) utils.SharePointOpts { + return utils.SharePointOpts{ + FolderPath: []string{"/"}, + } }, }, { - Name: "FolderPrefixMatch", - Expected: testdata.SharePointLibraryItems, - Opts: utils.SharePointOpts{ - FolderPath: []string{testdata.SharePointLibraryFolder}, + Name: "FolderPrefixMatch", + Expected: func(t *testing.T, wantedVersion int) []details.Entry { + return testdata.GetItemsForVersion( + t, + path.SharePointService, + path.LibrariesCategory, + wantedVersion, + -1) + }, + Opts: func(t *testing.T, wantedVersion int) utils.SharePointOpts { + return utils.SharePointOpts{ + FolderPath: []string{testdata.SharePointLibraryFolder}, + } }, }, { - Name: "FolderPrefixMatchTrailingSlash", - Expected: testdata.SharePointLibraryItems, - Opts: utils.SharePointOpts{ - FolderPath: []string{testdata.SharePointLibraryFolder + "/"}, + Name: "FolderPrefixMatchTrailingSlash", + Expected: func(t *testing.T, wantedVersion int) []details.Entry { + return testdata.GetItemsForVersion( + t, + path.SharePointService, + path.LibrariesCategory, + wantedVersion, + -1) + }, + Opts: func(t *testing.T, wantedVersion int) utils.SharePointOpts { + return utils.SharePointOpts{ + FolderPath: []string{testdata.SharePointLibraryFolder + "/"}, + } }, }, { - Name: "FolderPrefixMatchTrailingSlash", - Expected: testdata.SharePointLibraryItems, - Opts: utils.SharePointOpts{ - FolderPath: []string{testdata.SharePointLibraryFolder + "/"}, + Name: "FolderPrefixMatchTrailingSlash", + Expected: func(t *testing.T, wantedVersion int) []details.Entry { + return testdata.GetItemsForVersion( + t, + path.SharePointService, + path.LibrariesCategory, + wantedVersion, + -1) + }, + Opts: func(t *testing.T, wantedVersion int) utils.SharePointOpts { + return utils.SharePointOpts{ + FolderPath: []string{testdata.SharePointLibraryFolder + "/"}, + } }, }, { - Name: "FolderRepoRefMatchesNothing", - Expected: []details.Entry{}, - Opts: utils.SharePointOpts{ - FolderPath: []string{testdata.SharePointLibraryPath.RR.Folder(true)}, + Name: "FolderRepoRefMatchesNothing", + Expected: func(t *testing.T, wantedVersion int) []details.Entry { + return []details.Entry{} + }, + Opts: func(t *testing.T, wantedVersion int) utils.SharePointOpts { + return utils.SharePointOpts{ + FolderPath: []string{testdata.SharePointLibraryPath.RR.Folder(true)}, + } }, }, { Name: "ShortRef", - Expected: []details.Entry{ - testdata.SharePointLibraryItems[0], - testdata.SharePointLibraryItems[1], + Expected: func(t *testing.T, wantedVersion int) []details.Entry { + return testdata.GetItemsForVersion( + t, + path.SharePointService, + path.LibrariesCategory, + wantedVersion, + 0, 1) }, - Opts: utils.SharePointOpts{ - FileName: []string{ - testdata.SharePointLibraryItems[0].ShortRef, - testdata.SharePointLibraryItems[1].ShortRef, - }, + Opts: func(t *testing.T, wantedVersion int) utils.SharePointOpts { + deets := testdata.GetDeetsForVersion( + t, + path.SharePointService, + path.LibrariesCategory, + wantedVersion) + + return utils.SharePointOpts{ + FileName: []string{ + deets[0].ShortRef, + deets[1].ShortRef, + }, + } }, }, { - Name: "SingleItem", - Expected: []details.Entry{testdata.SharePointLibraryItems[0]}, - Opts: utils.SharePointOpts{ - FileName: []string{ - testdata.SharePointLibraryItems[0].SharePoint.ItemName, - }, + Name: "SingleItem", + Expected: func(t *testing.T, wantedVersion int) []details.Entry { + return testdata.GetItemsForVersion( + t, + path.SharePointService, + path.LibrariesCategory, + wantedVersion, + 0) + }, + Opts: func(t *testing.T, wantedVersion int) utils.SharePointOpts { + deets := testdata.GetDeetsForVersion( + t, + path.SharePointService, + path.LibrariesCategory, + wantedVersion) + + return utils.SharePointOpts{ + FileName: []string{ + deets[0].SharePoint.ItemName, + }, + } }, }, { Name: "MultipleItems", - Expected: []details.Entry{ - testdata.SharePointLibraryItems[0], - testdata.SharePointLibraryItems[1], + Expected: func(t *testing.T, wantedVersion int) []details.Entry { + return testdata.GetItemsForVersion( + t, + path.SharePointService, + path.LibrariesCategory, + wantedVersion, + 0, 1) }, - Opts: utils.SharePointOpts{ - FileName: []string{ - testdata.SharePointLibraryItems[0].SharePoint.ItemName, - testdata.SharePointLibraryItems[1].SharePoint.ItemName, - }, + Opts: func(t *testing.T, wantedVersion int) utils.SharePointOpts { + deets := testdata.GetDeetsForVersion( + t, + path.SharePointService, + path.LibrariesCategory, + wantedVersion) + + return utils.SharePointOpts{ + FileName: []string{ + deets[0].SharePoint.ItemName, + deets[1].SharePoint.ItemName, + }, + } }, }, { - Name: "ItemRefMatchesNothing", - Expected: []details.Entry{}, - Opts: utils.SharePointOpts{ - FileName: []string{ - testdata.SharePointLibraryItems[0].ItemRef, - }, + Name: "ItemRefMatchesNothing", + Expected: func(t *testing.T, wantedVersion int) []details.Entry { + return []details.Entry{} + }, + Opts: func(t *testing.T, wantedVersion int) utils.SharePointOpts { + deets := testdata.GetDeetsForVersion( + t, + path.SharePointService, + path.LibrariesCategory, + wantedVersion) + + return utils.SharePointOpts{ + FileName: []string{ + deets[0].ItemRef, + }, + } }, }, - // { - // Name: "CreatedBefore", - // Expected: []details.DetailsEntry{testdata.SharePointLibraryItems[1]}, - // Opts: utils.SharePointOpts{ - // FileCreatedBefore: dttm.Format(testdata.Time1.Add(time.Second)), - // }, - // }, + //{ + // Name: "CreatedBefore", + // Expected: func(t *testing.T, wantedVersion int) []details.DetailsEntry { + // return testdata.GetItemsForVersion( + // t, + // path.SharePointService, + // path.LibrariesCategory, + // wantedVersion, + // 1) + // }, + // Opts: func(t *testing.T, wantedVersion int) utils.SharePointOpts { + // return utils.SharePointOpts{ + // FileCreatedBefore: dttm.Format(testdata.Time1.Add(time.Second)), + // } + // }, + //}, } ) @@ -611,10 +1011,6 @@ func (bg *MockBackupGetter) GetBackupDetails( ctx context.Context, backupID string, ) (*details.Details, *backup.Backup, *fault.Bus) { - if bg == nil { - return testdata.GetDetailsSet(), nil, fault.New(true) - } - return nil, nil, fault.New(false).Fail(clues.New("unexpected call to mock")) } @@ -629,3 +1025,15 @@ func (bg *MockBackupGetter) GetBackupErrors( return nil, nil, fault.New(false).Fail(clues.New("unexpected call to mock")) } + +type VersionedBackupGetter struct { + *MockBackupGetter + Details *details.Details +} + +func (bg VersionedBackupGetter) GetBackupDetails( + ctx context.Context, + backupID string, +) (*details.Details, *backup.Backup, *fault.Bus) { + return bg.Details, nil, fault.New(true) +} diff --git a/src/pkg/backup/details/testdata/testdata.go b/src/pkg/backup/details/testdata/testdata.go index 0d98ec7df..a929c141c 100644 --- a/src/pkg/backup/details/testdata/testdata.go +++ b/src/pkg/backup/details/testdata/testdata.go @@ -2,8 +2,13 @@ package testdata import ( "strings" + "testing" "time" + "github.com/stretchr/testify/require" + "golang.org/x/exp/slices" + + "github.com/alcionai/corso/src/internal/version" "github.com/alcionai/corso/src/pkg/backup/details" "github.com/alcionai/corso/src/pkg/path" ) @@ -88,6 +93,28 @@ func (p repoRefAndLocRef) FolderLocation() string { return p.Loc.Append(strings.TrimSuffix(lastElem, folderSuffix)).String() } +// locationAsRepoRef returns a path.Path where the LocationRef is used for the +// folder path instead of the id-based path elements. This is useful for +// generating paths for older versions of Corso. +func (p repoRefAndLocRef) locationAsRepoRef() path.Path { + tmp := p.Loc + if len(p.ItemLocation()) > 0 { + tmp = tmp.Append(p.ItemLocation()) + } + + res, err := tmp.ToDataLayerPath( + p.RR.Tenant(), + p.RR.ResourceOwner(), + p.RR.Service(), + p.RR.Category(), + len(p.ItemLocation()) > 0) + if err != nil { + panic(err) + } + + return res +} + func mustPathRep(ref string, isItem bool) repoRefAndLocRef { res := repoRefAndLocRef{} tmp := mustParsePath(ref, isItem) @@ -145,49 +172,141 @@ var ( ExchangeEmailItemPath2 = ExchangeEmailBasePath2.MustAppend(ItemName2, true) ExchangeEmailItemPath3 = ExchangeEmailBasePath3.MustAppend(ItemName3, true) - ExchangeEmailItems = []details.Entry{ - { - RepoRef: ExchangeEmailItemPath1.RR.String(), - ShortRef: ExchangeEmailItemPath1.RR.ShortRef(), - ParentRef: ExchangeEmailItemPath1.RR.ToBuilder().Dir().ShortRef(), - ItemRef: ExchangeEmailItemPath1.ItemLocation(), - LocationRef: ExchangeEmailItemPath1.Loc.String(), - ItemInfo: details.ItemInfo{ - Exchange: &details.ExchangeInfo{ - ItemType: details.ExchangeMail, - Sender: "a-person", - Subject: "foo", - Received: Time1, + // These all represent the same set of items however, the different versions + // have varying amounts of information. + exchangeEmailItemsByVersion = map[int][]details.Entry{ + version.All8MigrateUserPNToID: { + { + RepoRef: ExchangeEmailItemPath1.RR.String(), + ShortRef: ExchangeEmailItemPath1.RR.ShortRef(), + ParentRef: ExchangeEmailItemPath1.RR.ToBuilder().Dir().ShortRef(), + ItemRef: ExchangeEmailItemPath1.ItemLocation(), + LocationRef: ExchangeEmailItemPath1.Loc.String(), + ItemInfo: details.ItemInfo{ + Exchange: &details.ExchangeInfo{ + ItemType: details.ExchangeMail, + Sender: "a-person", + Subject: "foo", + Received: Time1, + }, + }, + }, + { + RepoRef: ExchangeEmailItemPath2.RR.String(), + ShortRef: ExchangeEmailItemPath2.RR.ShortRef(), + ParentRef: ExchangeEmailItemPath2.RR.ToBuilder().Dir().ShortRef(), + ItemRef: ExchangeEmailItemPath2.ItemLocation(), + LocationRef: ExchangeEmailItemPath2.Loc.String(), + ItemInfo: details.ItemInfo{ + Exchange: &details.ExchangeInfo{ + ItemType: details.ExchangeMail, + Sender: "a-person", + Subject: "bar", + Received: Time2, + }, + }, + }, + { + RepoRef: ExchangeEmailItemPath3.RR.String(), + ShortRef: ExchangeEmailItemPath3.RR.ShortRef(), + ParentRef: ExchangeEmailItemPath3.RR.ToBuilder().Dir().ShortRef(), + ItemRef: ExchangeEmailItemPath3.ItemLocation(), + LocationRef: ExchangeEmailItemPath3.Loc.String(), + ItemInfo: details.ItemInfo{ + Exchange: &details.ExchangeInfo{ + ItemType: details.ExchangeMail, + Sender: "another-person", + Subject: "baz", + Received: Time2, + }, }, }, }, - { - RepoRef: ExchangeEmailItemPath2.RR.String(), - ShortRef: ExchangeEmailItemPath2.RR.ShortRef(), - ParentRef: ExchangeEmailItemPath2.RR.ToBuilder().Dir().ShortRef(), - ItemRef: ExchangeEmailItemPath2.ItemLocation(), - LocationRef: ExchangeEmailItemPath2.Loc.String(), - ItemInfo: details.ItemInfo{ - Exchange: &details.ExchangeInfo{ - ItemType: details.ExchangeMail, - Sender: "a-person", - Subject: "bar", - Received: Time2, + version.OneDrive7LocationRef: { + { + RepoRef: ExchangeEmailItemPath1.locationAsRepoRef().String(), + ShortRef: ExchangeEmailItemPath1.locationAsRepoRef().ShortRef(), + ParentRef: ExchangeEmailItemPath1.locationAsRepoRef().ToBuilder().Dir().ShortRef(), + ItemRef: ExchangeEmailItemPath1.ItemLocation(), + LocationRef: ExchangeEmailItemPath1.Loc.String(), + ItemInfo: details.ItemInfo{ + Exchange: &details.ExchangeInfo{ + ItemType: details.ExchangeMail, + Sender: "a-person", + Subject: "foo", + Received: Time1, + }, + }, + }, + { + RepoRef: ExchangeEmailItemPath2.locationAsRepoRef().String(), + ShortRef: ExchangeEmailItemPath2.locationAsRepoRef().ShortRef(), + ParentRef: ExchangeEmailItemPath2.locationAsRepoRef().ToBuilder().Dir().ShortRef(), + ItemRef: ExchangeEmailItemPath2.ItemLocation(), + LocationRef: ExchangeEmailItemPath2.Loc.String(), + ItemInfo: details.ItemInfo{ + Exchange: &details.ExchangeInfo{ + ItemType: details.ExchangeMail, + Sender: "a-person", + Subject: "bar", + Received: Time2, + }, + }, + }, + { + RepoRef: ExchangeEmailItemPath3.locationAsRepoRef().String(), + ShortRef: ExchangeEmailItemPath3.locationAsRepoRef().ShortRef(), + ParentRef: ExchangeEmailItemPath3.locationAsRepoRef().ToBuilder().Dir().ShortRef(), + ItemRef: ExchangeEmailItemPath3.ItemLocation(), + LocationRef: ExchangeEmailItemPath3.Loc.String(), + ItemInfo: details.ItemInfo{ + Exchange: &details.ExchangeInfo{ + ItemType: details.ExchangeMail, + Sender: "another-person", + Subject: "baz", + Received: Time2, + }, }, }, }, - { - RepoRef: ExchangeEmailItemPath3.RR.String(), - ShortRef: ExchangeEmailItemPath3.RR.ShortRef(), - ParentRef: ExchangeEmailItemPath3.RR.ToBuilder().Dir().ShortRef(), - ItemRef: ExchangeEmailItemPath3.ItemLocation(), - LocationRef: ExchangeEmailItemPath3.Loc.String(), - ItemInfo: details.ItemInfo{ - Exchange: &details.ExchangeInfo{ - ItemType: details.ExchangeMail, - Sender: "another-person", - Subject: "baz", - Received: Time2, + 0: { + { + RepoRef: ExchangeEmailItemPath1.locationAsRepoRef().String(), + ShortRef: ExchangeEmailItemPath1.locationAsRepoRef().ShortRef(), + ParentRef: ExchangeEmailItemPath1.locationAsRepoRef().ToBuilder().Dir().ShortRef(), + ItemInfo: details.ItemInfo{ + Exchange: &details.ExchangeInfo{ + ItemType: details.ExchangeMail, + Sender: "a-person", + Subject: "foo", + Received: Time1, + }, + }, + }, + { + RepoRef: ExchangeEmailItemPath2.locationAsRepoRef().String(), + ShortRef: ExchangeEmailItemPath2.locationAsRepoRef().ShortRef(), + ParentRef: ExchangeEmailItemPath2.locationAsRepoRef().ToBuilder().Dir().ShortRef(), + ItemInfo: details.ItemInfo{ + Exchange: &details.ExchangeInfo{ + ItemType: details.ExchangeMail, + Sender: "a-person", + Subject: "bar", + Received: Time2, + }, + }, + }, + { + RepoRef: ExchangeEmailItemPath3.locationAsRepoRef().String(), + ShortRef: ExchangeEmailItemPath3.locationAsRepoRef().ShortRef(), + ParentRef: ExchangeEmailItemPath3.locationAsRepoRef().ToBuilder().Dir().ShortRef(), + ItemInfo: details.ItemInfo{ + Exchange: &details.ExchangeInfo{ + ItemType: details.ExchangeMail, + Sender: "another-person", + Subject: "baz", + Received: Time2, + }, }, }, }, @@ -199,30 +318,84 @@ var ( ExchangeContactsItemPath1 = ExchangeContactsBasePath.MustAppend(ItemName1, true) ExchangeContactsItemPath2 = ExchangeContactsBasePath2.MustAppend(ItemName2, true) - ExchangeContactsItems = []details.Entry{ - { - RepoRef: ExchangeContactsItemPath1.RR.String(), - ShortRef: ExchangeContactsItemPath1.RR.ShortRef(), - ParentRef: ExchangeContactsItemPath1.RR.ToBuilder().Dir().ShortRef(), - ItemRef: ExchangeContactsItemPath1.ItemLocation(), - LocationRef: ExchangeContactsItemPath1.Loc.String(), - ItemInfo: details.ItemInfo{ - Exchange: &details.ExchangeInfo{ - ItemType: details.ExchangeContact, - ContactName: "a-person", + exchangeContactsItemsByVersion = map[int][]details.Entry{ + version.All8MigrateUserPNToID: { + { + RepoRef: ExchangeContactsItemPath1.RR.String(), + ShortRef: ExchangeContactsItemPath1.RR.ShortRef(), + ParentRef: ExchangeContactsItemPath1.RR.ToBuilder().Dir().ShortRef(), + ItemRef: ExchangeContactsItemPath1.ItemLocation(), + LocationRef: ExchangeContactsItemPath1.Loc.String(), + ItemInfo: details.ItemInfo{ + Exchange: &details.ExchangeInfo{ + ItemType: details.ExchangeContact, + ContactName: "a-person", + }, + }, + }, + { + RepoRef: ExchangeContactsItemPath2.RR.String(), + ShortRef: ExchangeContactsItemPath2.RR.ShortRef(), + ParentRef: ExchangeContactsItemPath2.RR.ToBuilder().Dir().ShortRef(), + ItemRef: ExchangeContactsItemPath2.ItemLocation(), + LocationRef: ExchangeContactsItemPath2.Loc.String(), + ItemInfo: details.ItemInfo{ + Exchange: &details.ExchangeInfo{ + ItemType: details.ExchangeContact, + ContactName: "another-person", + }, }, }, }, - { - RepoRef: ExchangeContactsItemPath2.RR.String(), - ShortRef: ExchangeContactsItemPath2.RR.ShortRef(), - ParentRef: ExchangeContactsItemPath2.RR.ToBuilder().Dir().ShortRef(), - ItemRef: ExchangeContactsItemPath2.ItemLocation(), - LocationRef: ExchangeContactsItemPath2.Loc.String(), - ItemInfo: details.ItemInfo{ - Exchange: &details.ExchangeInfo{ - ItemType: details.ExchangeContact, - ContactName: "another-person", + version.OneDrive7LocationRef: { + { + RepoRef: ExchangeContactsItemPath1.locationAsRepoRef().String(), + ShortRef: ExchangeContactsItemPath1.locationAsRepoRef().ShortRef(), + ParentRef: ExchangeContactsItemPath1.locationAsRepoRef().ToBuilder().Dir().ShortRef(), + ItemRef: ExchangeContactsItemPath1.ItemLocation(), + LocationRef: ExchangeContactsItemPath1.Loc.String(), + ItemInfo: details.ItemInfo{ + Exchange: &details.ExchangeInfo{ + ItemType: details.ExchangeContact, + ContactName: "a-person", + }, + }, + }, + { + RepoRef: ExchangeContactsItemPath2.locationAsRepoRef().String(), + ShortRef: ExchangeContactsItemPath2.locationAsRepoRef().ShortRef(), + ParentRef: ExchangeContactsItemPath2.locationAsRepoRef().ToBuilder().Dir().ShortRef(), + ItemRef: ExchangeContactsItemPath2.ItemLocation(), + LocationRef: ExchangeContactsItemPath2.Loc.String(), + ItemInfo: details.ItemInfo{ + Exchange: &details.ExchangeInfo{ + ItemType: details.ExchangeContact, + ContactName: "another-person", + }, + }, + }, + }, + 0: { + { + RepoRef: ExchangeContactsItemPath1.locationAsRepoRef().String(), + ShortRef: ExchangeContactsItemPath1.locationAsRepoRef().ShortRef(), + ParentRef: ExchangeContactsItemPath1.locationAsRepoRef().ToBuilder().Dir().ShortRef(), + ItemInfo: details.ItemInfo{ + Exchange: &details.ExchangeInfo{ + ItemType: details.ExchangeContact, + ContactName: "a-person", + }, + }, + }, + { + RepoRef: ExchangeContactsItemPath2.locationAsRepoRef().String(), + ShortRef: ExchangeContactsItemPath2.locationAsRepoRef().ShortRef(), + ParentRef: ExchangeContactsItemPath2.locationAsRepoRef().ToBuilder().Dir().ShortRef(), + ItemInfo: details.ItemInfo{ + Exchange: &details.ExchangeInfo{ + ItemType: details.ExchangeContact, + ContactName: "another-person", + }, }, }, }, @@ -233,36 +406,100 @@ var ( ExchangeEventsItemPath1 = ExchangeEventsBasePath.MustAppend(ItemName1, true) ExchangeEventsItemPath2 = ExchangeEventsBasePath2.MustAppend(ItemName2, true) - ExchangeEventsItems = []details.Entry{ - { - RepoRef: ExchangeEventsItemPath1.RR.String(), - ShortRef: ExchangeEventsItemPath1.RR.ShortRef(), - ParentRef: ExchangeEventsItemPath1.RR.ToBuilder().Dir().ShortRef(), - ItemRef: ExchangeEventsItemPath1.ItemLocation(), - LocationRef: ExchangeEventsItemPath1.Loc.String(), - ItemInfo: details.ItemInfo{ - Exchange: &details.ExchangeInfo{ - ItemType: details.ExchangeEvent, - Organizer: "a-person", - Subject: "foo", - EventStart: Time1, - EventRecurs: false, + exchangeEventsItemsByVersion = map[int][]details.Entry{ + version.All8MigrateUserPNToID: { + { + RepoRef: ExchangeEventsItemPath1.RR.String(), + ShortRef: ExchangeEventsItemPath1.RR.ShortRef(), + ParentRef: ExchangeEventsItemPath1.RR.ToBuilder().Dir().ShortRef(), + ItemRef: ExchangeEventsItemPath1.ItemLocation(), + LocationRef: ExchangeEventsItemPath1.Loc.String(), + ItemInfo: details.ItemInfo{ + Exchange: &details.ExchangeInfo{ + ItemType: details.ExchangeEvent, + Organizer: "a-person", + Subject: "foo", + EventStart: Time1, + EventRecurs: false, + }, + }, + }, + { + RepoRef: ExchangeEventsItemPath2.RR.String(), + ShortRef: ExchangeEventsItemPath2.RR.ShortRef(), + ParentRef: ExchangeEventsItemPath2.RR.ToBuilder().Dir().ShortRef(), + ItemRef: ExchangeEventsItemPath2.ItemLocation(), + LocationRef: ExchangeEventsItemPath2.Loc.String(), + ItemInfo: details.ItemInfo{ + Exchange: &details.ExchangeInfo{ + ItemType: details.ExchangeEvent, + Organizer: "a-person", + Subject: "foo", + EventStart: Time2, + EventRecurs: true, + }, }, }, }, - { - RepoRef: ExchangeEventsItemPath2.RR.String(), - ShortRef: ExchangeEventsItemPath2.RR.ShortRef(), - ParentRef: ExchangeEventsItemPath2.RR.ToBuilder().Dir().ShortRef(), - ItemRef: ExchangeEventsItemPath2.ItemLocation(), - LocationRef: ExchangeEventsItemPath2.Loc.String(), - ItemInfo: details.ItemInfo{ - Exchange: &details.ExchangeInfo{ - ItemType: details.ExchangeEvent, - Organizer: "a-person", - Subject: "foo", - EventStart: Time2, - EventRecurs: true, + 2: { + { + RepoRef: ExchangeEventsItemPath1.RR.String(), + ShortRef: ExchangeEventsItemPath1.RR.ShortRef(), + ParentRef: ExchangeEventsItemPath1.RR.ToBuilder().Dir().ShortRef(), + LocationRef: ExchangeEventsItemPath1.Loc.String(), + ItemInfo: details.ItemInfo{ + Exchange: &details.ExchangeInfo{ + ItemType: details.ExchangeEvent, + Organizer: "a-person", + Subject: "foo", + EventStart: Time1, + EventRecurs: false, + }, + }, + }, + { + RepoRef: ExchangeEventsItemPath2.RR.String(), + ShortRef: ExchangeEventsItemPath2.RR.ShortRef(), + ParentRef: ExchangeEventsItemPath2.RR.ToBuilder().Dir().ShortRef(), + LocationRef: ExchangeEventsItemPath2.Loc.String(), + ItemInfo: details.ItemInfo{ + Exchange: &details.ExchangeInfo{ + ItemType: details.ExchangeEvent, + Organizer: "a-person", + Subject: "foo", + EventStart: Time2, + EventRecurs: true, + }, + }, + }, + }, + 0: { + { + RepoRef: ExchangeEventsItemPath1.locationAsRepoRef().String(), + ShortRef: ExchangeEventsItemPath1.locationAsRepoRef().ShortRef(), + ParentRef: ExchangeEventsItemPath1.locationAsRepoRef().ToBuilder().Dir().ShortRef(), + ItemInfo: details.ItemInfo{ + Exchange: &details.ExchangeInfo{ + ItemType: details.ExchangeEvent, + Organizer: "a-person", + Subject: "foo", + EventStart: Time1, + EventRecurs: false, + }, + }, + }, + { + RepoRef: ExchangeEventsItemPath2.locationAsRepoRef().String(), + ShortRef: ExchangeEventsItemPath2.locationAsRepoRef().ShortRef(), + ParentRef: ExchangeEventsItemPath2.locationAsRepoRef().ToBuilder().Dir().ShortRef(), + ItemInfo: details.ItemInfo{ + Exchange: &details.ExchangeInfo{ + ItemType: details.ExchangeEvent, + Organizer: "a-person", + Subject: "foo", + EventStart: Time2, + EventRecurs: true, + }, }, }, }, @@ -281,58 +518,213 @@ var ( OneDriveParentFolder1 = OneDriveBasePath1.Loc.PopFront().String() OneDriveParentFolder2 = OneDriveBasePath2.Loc.PopFront().String() - OneDriveItems = []details.Entry{ - { - RepoRef: OneDriveItemPath1.RR.String(), - ShortRef: OneDriveItemPath1.RR.ShortRef(), - ParentRef: OneDriveItemPath1.RR.ToBuilder().Dir().ShortRef(), - ItemRef: OneDriveItemPath1.ItemLocation(), - LocationRef: OneDriveItemPath1.Loc.String(), - ItemInfo: details.ItemInfo{ - OneDrive: &details.OneDriveInfo{ - ItemType: details.OneDriveItem, - ParentPath: OneDriveFolderFolder, - ItemName: OneDriveItemPath1.ItemLocation() + "name", - Size: int64(23), - Owner: UserEmail1, - Created: Time2, - Modified: Time4, + oneDriveItemsByVersion = map[int][]details.Entry{ + version.All8MigrateUserPNToID: { + { + RepoRef: OneDriveItemPath1.locationAsRepoRef().String(), + ShortRef: OneDriveItemPath1.locationAsRepoRef().ShortRef(), + ParentRef: OneDriveItemPath1.locationAsRepoRef().ToBuilder().Dir().ShortRef(), + ItemRef: OneDriveItemPath1.ItemLocation(), + LocationRef: OneDriveItemPath1.Loc.String(), + ItemInfo: details.ItemInfo{ + OneDrive: &details.OneDriveInfo{ + ItemType: details.OneDriveItem, + ParentPath: OneDriveFolderFolder, + ItemName: OneDriveItemPath1.ItemLocation() + "name", + Size: int64(23), + Owner: UserEmail1, + Created: Time2, + Modified: Time4, + }, + }, + }, + { + RepoRef: OneDriveItemPath2.locationAsRepoRef().String(), + ShortRef: OneDriveItemPath2.locationAsRepoRef().ShortRef(), + ParentRef: OneDriveItemPath2.locationAsRepoRef().ToBuilder().Dir().ShortRef(), + ItemRef: OneDriveItemPath2.ItemLocation(), + LocationRef: OneDriveItemPath2.Loc.String(), + ItemInfo: details.ItemInfo{ + OneDrive: &details.OneDriveInfo{ + ItemType: details.OneDriveItem, + ParentPath: OneDriveParentFolder1, + ItemName: OneDriveItemPath2.ItemLocation() + "name", + Size: int64(42), + Owner: UserEmail1, + Created: Time1, + Modified: Time3, + }, + }, + }, + { + RepoRef: OneDriveItemPath3.locationAsRepoRef().String(), + ShortRef: OneDriveItemPath3.locationAsRepoRef().ShortRef(), + ParentRef: OneDriveItemPath3.locationAsRepoRef().ToBuilder().Dir().ShortRef(), + ItemRef: OneDriveItemPath3.ItemLocation(), + LocationRef: OneDriveItemPath3.Loc.String(), + ItemInfo: details.ItemInfo{ + OneDrive: &details.OneDriveInfo{ + ItemType: details.OneDriveItem, + ParentPath: OneDriveParentFolder2, + ItemName: OneDriveItemPath3.ItemLocation() + "name", + Size: int64(19), + Owner: UserEmail2, + Created: Time2, + Modified: Time4, + }, }, }, }, - { - RepoRef: OneDriveItemPath2.RR.String(), - ShortRef: OneDriveItemPath2.RR.ShortRef(), - ParentRef: OneDriveItemPath2.RR.ToBuilder().Dir().ShortRef(), - ItemRef: OneDriveItemPath2.ItemLocation(), - LocationRef: OneDriveItemPath2.Loc.String(), - ItemInfo: details.ItemInfo{ - OneDrive: &details.OneDriveInfo{ - ItemType: details.OneDriveItem, - ParentPath: OneDriveParentFolder1, - ItemName: OneDriveItemPath2.ItemLocation() + "name", - Size: int64(42), - Owner: UserEmail1, - Created: Time1, - Modified: Time3, + version.OneDrive7LocationRef: { + { + RepoRef: OneDriveItemPath1.locationAsRepoRef().String(), + ShortRef: OneDriveItemPath1.locationAsRepoRef().ShortRef(), + ParentRef: OneDriveItemPath1.locationAsRepoRef().ToBuilder().Dir().ShortRef(), + LocationRef: OneDriveItemPath1.Loc.String(), + ItemInfo: details.ItemInfo{ + OneDrive: &details.OneDriveInfo{ + ItemType: details.OneDriveItem, + ParentPath: OneDriveFolderFolder, + ItemName: OneDriveItemPath1.ItemLocation() + "name", + Size: int64(23), + Owner: UserEmail1, + Created: Time2, + Modified: Time4, + }, + }, + }, + { + RepoRef: OneDriveItemPath2.locationAsRepoRef().String(), + ShortRef: OneDriveItemPath2.locationAsRepoRef().ShortRef(), + ParentRef: OneDriveItemPath2.locationAsRepoRef().ToBuilder().Dir().ShortRef(), + LocationRef: OneDriveItemPath2.Loc.String(), + ItemInfo: details.ItemInfo{ + OneDrive: &details.OneDriveInfo{ + ItemType: details.OneDriveItem, + ParentPath: OneDriveParentFolder1, + ItemName: OneDriveItemPath2.ItemLocation() + "name", + Size: int64(42), + Owner: UserEmail1, + Created: Time1, + Modified: Time3, + }, + }, + }, + { + RepoRef: OneDriveItemPath3.locationAsRepoRef().String(), + ShortRef: OneDriveItemPath3.locationAsRepoRef().ShortRef(), + ParentRef: OneDriveItemPath3.locationAsRepoRef().ToBuilder().Dir().ShortRef(), + LocationRef: OneDriveItemPath3.Loc.String(), + ItemInfo: details.ItemInfo{ + OneDrive: &details.OneDriveInfo{ + ItemType: details.OneDriveItem, + ParentPath: OneDriveParentFolder2, + ItemName: OneDriveItemPath3.ItemLocation() + "name", + Size: int64(19), + Owner: UserEmail2, + Created: Time2, + Modified: Time4, + }, }, }, }, - { - RepoRef: OneDriveItemPath3.RR.String(), - ShortRef: OneDriveItemPath3.RR.ShortRef(), - ParentRef: OneDriveItemPath3.RR.ToBuilder().Dir().ShortRef(), - ItemRef: OneDriveItemPath3.ItemLocation(), - LocationRef: OneDriveItemPath3.Loc.String(), - ItemInfo: details.ItemInfo{ - OneDrive: &details.OneDriveInfo{ - ItemType: details.OneDriveItem, - ParentPath: OneDriveParentFolder2, - ItemName: OneDriveItemPath3.ItemLocation() + "name", - Size: int64(19), - Owner: UserEmail2, - Created: Time2, - Modified: Time4, + version.OneDrive6NameInMeta: { + { + RepoRef: OneDriveItemPath1.locationAsRepoRef().String(), + ShortRef: OneDriveItemPath1.locationAsRepoRef().ShortRef(), + ParentRef: OneDriveItemPath1.locationAsRepoRef().ToBuilder().Dir().ShortRef(), + ItemInfo: details.ItemInfo{ + OneDrive: &details.OneDriveInfo{ + ItemType: details.OneDriveItem, + ParentPath: OneDriveFolderFolder, + ItemName: OneDriveItemPath1.ItemLocation() + "name", + Size: int64(23), + Owner: UserEmail1, + Created: Time2, + Modified: Time4, + }, + }, + }, + { + RepoRef: OneDriveItemPath2.locationAsRepoRef().String(), + ShortRef: OneDriveItemPath2.locationAsRepoRef().ShortRef(), + ParentRef: OneDriveItemPath2.locationAsRepoRef().ToBuilder().Dir().ShortRef(), + ItemInfo: details.ItemInfo{ + OneDrive: &details.OneDriveInfo{ + ItemType: details.OneDriveItem, + ParentPath: OneDriveParentFolder1, + ItemName: OneDriveItemPath2.ItemLocation() + "name", + Size: int64(42), + Owner: UserEmail1, + Created: Time1, + Modified: Time3, + }, + }, + }, + { + RepoRef: OneDriveItemPath3.locationAsRepoRef().String(), + ShortRef: OneDriveItemPath3.locationAsRepoRef().ShortRef(), + ParentRef: OneDriveItemPath3.locationAsRepoRef().ToBuilder().Dir().ShortRef(), + ItemInfo: details.ItemInfo{ + OneDrive: &details.OneDriveInfo{ + ItemType: details.OneDriveItem, + ParentPath: OneDriveParentFolder2, + ItemName: OneDriveItemPath3.ItemLocation() + "name", + Size: int64(19), + Owner: UserEmail2, + Created: Time2, + Modified: Time4, + }, + }, + }, + }, + 0: { + { + RepoRef: OneDriveItemPath1.locationAsRepoRef().String() + "name", + ShortRef: OneDriveItemPath1.locationAsRepoRef().ShortRef(), + ParentRef: OneDriveItemPath1.locationAsRepoRef().ToBuilder().Dir().ShortRef(), + ItemInfo: details.ItemInfo{ + OneDrive: &details.OneDriveInfo{ + ItemType: details.OneDriveItem, + ParentPath: OneDriveFolderFolder, + ItemName: OneDriveItemPath1.ItemLocation() + "name", + Size: int64(23), + Owner: UserEmail1, + Created: Time2, + Modified: Time4, + }, + }, + }, + { + RepoRef: OneDriveItemPath2.locationAsRepoRef().String() + "name", + ShortRef: OneDriveItemPath2.locationAsRepoRef().ShortRef(), + ParentRef: OneDriveItemPath2.locationAsRepoRef().ToBuilder().Dir().ShortRef(), + ItemInfo: details.ItemInfo{ + OneDrive: &details.OneDriveInfo{ + ItemType: details.OneDriveItem, + ParentPath: OneDriveParentFolder1, + ItemName: OneDriveItemPath2.ItemLocation() + "name", + Size: int64(42), + Owner: UserEmail1, + Created: Time1, + Modified: Time3, + }, + }, + }, + { + RepoRef: OneDriveItemPath3.locationAsRepoRef().String() + "name", + ShortRef: OneDriveItemPath3.locationAsRepoRef().ShortRef(), + ParentRef: OneDriveItemPath3.locationAsRepoRef().ToBuilder().Dir().ShortRef(), + ItemInfo: details.ItemInfo{ + OneDrive: &details.OneDriveInfo{ + ItemType: details.OneDriveItem, + ParentPath: OneDriveParentFolder2, + ItemName: OneDriveItemPath3.ItemLocation() + "name", + Size: int64(19), + Owner: UserEmail2, + Created: Time2, + Modified: Time4, + }, }, }, }, @@ -351,85 +743,241 @@ var ( SharePointParentLibrary1 = SharePointBasePath1.Loc.PopFront().String() SharePointParentLibrary2 = SharePointBasePath2.Loc.PopFront().String() - SharePointLibraryItems = []details.Entry{ - { - RepoRef: SharePointLibraryItemPath1.RR.String(), - ShortRef: SharePointLibraryItemPath1.RR.ShortRef(), - ParentRef: SharePointLibraryItemPath1.RR.ToBuilder().Dir().ShortRef(), - ItemRef: SharePointLibraryItemPath1.ItemLocation(), - LocationRef: SharePointLibraryItemPath1.Loc.String(), - ItemInfo: details.ItemInfo{ - SharePoint: &details.SharePointInfo{ - ItemType: details.SharePointLibrary, - ParentPath: SharePointLibraryFolder, - ItemName: SharePointLibraryItemPath1.ItemLocation() + "name", - Size: int64(23), - Owner: UserEmail1, - Created: Time2, - Modified: Time4, + sharePointLibraryItemsByVersion = map[int][]details.Entry{ + version.All8MigrateUserPNToID: { + { + RepoRef: SharePointLibraryItemPath1.locationAsRepoRef().String(), + ShortRef: SharePointLibraryItemPath1.locationAsRepoRef().ShortRef(), + ParentRef: SharePointLibraryItemPath1.locationAsRepoRef().ToBuilder().Dir().ShortRef(), + ItemRef: SharePointLibraryItemPath1.ItemLocation(), + LocationRef: SharePointLibraryItemPath1.Loc.String(), + ItemInfo: details.ItemInfo{ + SharePoint: &details.SharePointInfo{ + ItemType: details.SharePointLibrary, + ParentPath: SharePointLibraryFolder, + ItemName: SharePointLibraryItemPath1.ItemLocation() + "name", + Size: int64(23), + Owner: UserEmail1, + Created: Time2, + Modified: Time4, + }, + }, + }, + { + RepoRef: SharePointLibraryItemPath2.locationAsRepoRef().String(), + ShortRef: SharePointLibraryItemPath2.locationAsRepoRef().ShortRef(), + ParentRef: SharePointLibraryItemPath2.locationAsRepoRef().ToBuilder().Dir().ShortRef(), + ItemRef: SharePointLibraryItemPath2.ItemLocation(), + LocationRef: SharePointLibraryItemPath2.Loc.String(), + ItemInfo: details.ItemInfo{ + SharePoint: &details.SharePointInfo{ + ItemType: details.SharePointLibrary, + ParentPath: SharePointParentLibrary1, + ItemName: SharePointLibraryItemPath2.ItemLocation() + "name", + Size: int64(42), + Owner: UserEmail1, + Created: Time1, + Modified: Time3, + }, + }, + }, + { + RepoRef: SharePointLibraryItemPath3.locationAsRepoRef().String(), + ShortRef: SharePointLibraryItemPath3.locationAsRepoRef().ShortRef(), + ParentRef: SharePointLibraryItemPath3.locationAsRepoRef().ToBuilder().Dir().ShortRef(), + ItemRef: SharePointLibraryItemPath3.ItemLocation(), + LocationRef: SharePointLibraryItemPath3.Loc.String(), + ItemInfo: details.ItemInfo{ + SharePoint: &details.SharePointInfo{ + ItemType: details.SharePointLibrary, + ParentPath: SharePointParentLibrary2, + ItemName: SharePointLibraryItemPath3.ItemLocation() + "name", + Size: int64(19), + Owner: UserEmail2, + Created: Time2, + Modified: Time4, + }, }, }, }, - { - RepoRef: SharePointLibraryItemPath2.RR.String(), - ShortRef: SharePointLibraryItemPath2.RR.ShortRef(), - ParentRef: SharePointLibraryItemPath2.RR.ToBuilder().Dir().ShortRef(), - ItemRef: SharePointLibraryItemPath2.ItemLocation(), - LocationRef: SharePointLibraryItemPath2.Loc.String(), - ItemInfo: details.ItemInfo{ - SharePoint: &details.SharePointInfo{ - ItemType: details.SharePointLibrary, - ParentPath: SharePointParentLibrary1, - ItemName: SharePointLibraryItemPath2.ItemLocation() + "name", - Size: int64(42), - Owner: UserEmail1, - Created: Time1, - Modified: Time3, + version.OneDrive7LocationRef: { + { + RepoRef: SharePointLibraryItemPath1.locationAsRepoRef().String(), + ShortRef: SharePointLibraryItemPath1.locationAsRepoRef().ShortRef(), + ParentRef: SharePointLibraryItemPath1.locationAsRepoRef().ToBuilder().Dir().ShortRef(), + LocationRef: SharePointLibraryItemPath1.Loc.String(), + ItemInfo: details.ItemInfo{ + SharePoint: &details.SharePointInfo{ + ItemType: details.OneDriveItem, + ParentPath: SharePointLibraryFolder, + ItemName: SharePointLibraryItemPath1.ItemLocation() + "name", + Size: int64(23), + Owner: UserEmail1, + Created: Time2, + Modified: Time4, + }, + }, + }, + { + RepoRef: SharePointLibraryItemPath2.locationAsRepoRef().String(), + ShortRef: SharePointLibraryItemPath2.locationAsRepoRef().ShortRef(), + ParentRef: SharePointLibraryItemPath2.locationAsRepoRef().ToBuilder().Dir().ShortRef(), + LocationRef: SharePointLibraryItemPath2.Loc.String(), + ItemInfo: details.ItemInfo{ + SharePoint: &details.SharePointInfo{ + ItemType: details.OneDriveItem, + ParentPath: SharePointParentLibrary1, + ItemName: SharePointLibraryItemPath2.ItemLocation() + "name", + Size: int64(42), + Owner: UserEmail1, + Created: Time1, + Modified: Time3, + }, + }, + }, + { + RepoRef: SharePointLibraryItemPath3.locationAsRepoRef().String(), + ShortRef: SharePointLibraryItemPath3.locationAsRepoRef().ShortRef(), + ParentRef: SharePointLibraryItemPath3.locationAsRepoRef().ToBuilder().Dir().ShortRef(), + LocationRef: SharePointLibraryItemPath3.Loc.String(), + ItemInfo: details.ItemInfo{ + SharePoint: &details.SharePointInfo{ + ItemType: details.OneDriveItem, + ParentPath: SharePointParentLibrary2, + ItemName: SharePointLibraryItemPath3.ItemLocation() + "name", + Size: int64(19), + Owner: UserEmail2, + Created: Time2, + Modified: Time4, + }, }, }, }, - { - RepoRef: SharePointLibraryItemPath3.RR.String(), - ShortRef: SharePointLibraryItemPath3.RR.ShortRef(), - ParentRef: SharePointLibraryItemPath3.RR.ToBuilder().Dir().ShortRef(), - ItemRef: SharePointLibraryItemPath3.ItemLocation(), - LocationRef: SharePointLibraryItemPath3.Loc.String(), - ItemInfo: details.ItemInfo{ - SharePoint: &details.SharePointInfo{ - ItemType: details.SharePointLibrary, - ParentPath: SharePointParentLibrary2, - ItemName: SharePointLibraryItemPath3.ItemLocation() + "name", - Size: int64(19), - Owner: UserEmail2, - Created: Time2, - Modified: Time4, + version.OneDrive6NameInMeta: { + { + RepoRef: SharePointLibraryItemPath1.locationAsRepoRef().String(), + ShortRef: SharePointLibraryItemPath1.locationAsRepoRef().ShortRef(), + ParentRef: SharePointLibraryItemPath1.locationAsRepoRef().ToBuilder().Dir().ShortRef(), + ItemInfo: details.ItemInfo{ + SharePoint: &details.SharePointInfo{ + ItemType: details.OneDriveItem, + ParentPath: SharePointLibraryFolder, + ItemName: SharePointLibraryItemPath1.ItemLocation() + "name", + Size: int64(23), + Owner: UserEmail1, + Created: Time2, + Modified: Time4, + }, + }, + }, + { + RepoRef: SharePointLibraryItemPath2.locationAsRepoRef().String(), + ShortRef: SharePointLibraryItemPath2.locationAsRepoRef().ShortRef(), + ParentRef: SharePointLibraryItemPath2.locationAsRepoRef().ToBuilder().Dir().ShortRef(), + ItemInfo: details.ItemInfo{ + SharePoint: &details.SharePointInfo{ + ItemType: details.OneDriveItem, + ParentPath: SharePointParentLibrary1, + ItemName: SharePointLibraryItemPath2.ItemLocation() + "name", + Size: int64(42), + Owner: UserEmail1, + Created: Time1, + Modified: Time3, + }, + }, + }, + { + RepoRef: SharePointLibraryItemPath3.locationAsRepoRef().String(), + ShortRef: SharePointLibraryItemPath3.locationAsRepoRef().ShortRef(), + ParentRef: SharePointLibraryItemPath3.locationAsRepoRef().ToBuilder().Dir().ShortRef(), + ItemInfo: details.ItemInfo{ + SharePoint: &details.SharePointInfo{ + ItemType: details.OneDriveItem, + ParentPath: SharePointParentLibrary2, + ItemName: SharePointLibraryItemPath3.ItemLocation() + "name", + Size: int64(19), + Owner: UserEmail2, + Created: Time2, + Modified: Time4, + }, + }, + }, + }, + 0: { + { + RepoRef: SharePointLibraryItemPath1.locationAsRepoRef().String() + "name", + ShortRef: SharePointLibraryItemPath1.locationAsRepoRef().ShortRef(), + ParentRef: SharePointLibraryItemPath1.locationAsRepoRef().ToBuilder().Dir().ShortRef(), + ItemInfo: details.ItemInfo{ + SharePoint: &details.SharePointInfo{ + ItemType: details.OneDriveItem, + ParentPath: SharePointLibraryFolder, + ItemName: SharePointLibraryItemPath1.ItemLocation() + "name", + Size: int64(23), + Owner: UserEmail1, + Created: Time2, + Modified: Time4, + }, + }, + }, + { + RepoRef: SharePointLibraryItemPath2.locationAsRepoRef().String() + "name", + ShortRef: SharePointLibraryItemPath2.locationAsRepoRef().ShortRef(), + ParentRef: SharePointLibraryItemPath2.locationAsRepoRef().ToBuilder().Dir().ShortRef(), + ItemInfo: details.ItemInfo{ + SharePoint: &details.SharePointInfo{ + ItemType: details.OneDriveItem, + ParentPath: SharePointParentLibrary1, + ItemName: SharePointLibraryItemPath2.ItemLocation() + "name", + Size: int64(42), + Owner: UserEmail1, + Created: Time1, + Modified: Time3, + }, + }, + }, + { + RepoRef: SharePointLibraryItemPath3.locationAsRepoRef().String() + "name", + ShortRef: SharePointLibraryItemPath3.locationAsRepoRef().ShortRef(), + ParentRef: SharePointLibraryItemPath3.locationAsRepoRef().ToBuilder().Dir().ShortRef(), + ItemInfo: details.ItemInfo{ + SharePoint: &details.SharePointInfo{ + ItemType: details.OneDriveItem, + ParentPath: SharePointParentLibrary2, + ItemName: SharePointLibraryItemPath3.ItemLocation() + "name", + Size: int64(19), + Owner: UserEmail2, + Created: Time2, + Modified: Time4, + }, }, }, }, } ) -func GetDetailsSet() *details.Details { +func GetDetailsSetForVersion(t *testing.T, wantedVersion int) *details.Details { entries := []details.Entry{} - - for _, e := range ExchangeEmailItems { - entries = append(entries, e) + // TODO(ashmrtn): At some point make an exported variable somewhere that has + // all the valid service/category pairs. + dataTypes := map[path.ServiceType][]path.CategoryType{ + path.ExchangeService: { + path.EmailCategory, + path.EventsCategory, + path.ContactsCategory, + }, + path.OneDriveService: { + path.FilesCategory, + }, + path.SharePointService: { + path.LibrariesCategory, + }, } - for _, e := range ExchangeContactsItems { - entries = append(entries, e) - } - - for _, e := range ExchangeEventsItems { - entries = append(entries, e) - } - - for _, e := range OneDriveItems { - entries = append(entries, e) - } - - for _, e := range SharePointLibraryItems { - entries = append(entries, e) + for s, cats := range dataTypes { + for _, cat := range cats { + entries = append(entries, GetDeetsForVersion(t, s, cat, wantedVersion)...) + } } return &details.Details{ @@ -438,3 +986,95 @@ func GetDetailsSet() *details.Details { }, } } + +// GetItemsForVersion returns the set of items for the requested +// (service, category, version) tuple that reside at the indicated indices. If +// -1 is the only index provided then returns all items. +func GetItemsForVersion( + t *testing.T, + service path.ServiceType, + cat path.CategoryType, + wantVersion int, + indices ...int, +) []details.Entry { + deets := GetDeetsForVersion(t, service, cat, wantVersion) + + if len(indices) == 1 && indices[0] == -1 { + return deets + } + + var res []details.Entry + + for _, i := range indices { + require.Less(t, i, len(deets), "requested index out of bounds", i, len(deets)) + res = append(res, deets[i]) + } + + return res +} + +// GetDeetsForVersion returns the set of details with the highest +// version <= the requested version. +func GetDeetsForVersion( + t *testing.T, + service path.ServiceType, + cat path.CategoryType, + wantVersion int, +) []details.Entry { + var input map[int][]details.Entry + + switch service { + case path.ExchangeService: + switch cat { + case path.EmailCategory: + input = exchangeEmailItemsByVersion + + case path.EventsCategory: + input = exchangeEventsItemsByVersion + + case path.ContactsCategory: + input = exchangeContactsItemsByVersion + } + + case path.OneDriveService: + if cat == path.FilesCategory { + input = oneDriveItemsByVersion + } + + case path.SharePointService: + if cat == path.LibrariesCategory { + input = sharePointLibraryItemsByVersion + } + } + + require.NotNil( + t, + input, + "unsupported (service, category)", + service.String(), + cat.String()) + + return getDeetsForVersion(t, wantVersion, input) +} + +func getDeetsForVersion( + t *testing.T, + wantVersion int, + deetsSet map[int][]details.Entry, +) []details.Entry { + var ( + res []details.Entry + resVersion = version.NoBackup + ) + + for v, deets := range deetsSet { + if v <= wantVersion && v > resVersion { + resVersion = v + res = deets + } + } + + require.NotEmpty(t, res, "unable to find details for version", wantVersion) + + return slices.Clone(res) +} diff --git a/src/pkg/selectors/selectors_reduce_test.go b/src/pkg/selectors/selectors_reduce_test.go index c57cde409..51540ce48 100644 --- a/src/pkg/selectors/selectors_reduce_test.go +++ b/src/pkg/selectors/selectors_reduce_test.go @@ -1,6 +1,7 @@ package selectors_test import ( + "fmt" "testing" "time" @@ -9,9 +10,11 @@ import ( "github.com/alcionai/corso/src/internal/common/dttm" "github.com/alcionai/corso/src/internal/tester" + "github.com/alcionai/corso/src/internal/version" "github.com/alcionai/corso/src/pkg/backup/details" "github.com/alcionai/corso/src/pkg/backup/details/testdata" "github.com/alcionai/corso/src/pkg/fault" + "github.com/alcionai/corso/src/pkg/path" "github.com/alcionai/corso/src/pkg/selectors" ) @@ -27,25 +30,31 @@ func (suite *SelectorReduceSuite) TestReduce() { ctx, flush := tester.NewContext() defer flush() - allDetails := testdata.GetDetailsSet() table := []struct { name string - selFunc func() selectors.Reducer - expected []details.Entry + selFunc func(t *testing.T, wantVersion int) selectors.Reducer + expected func(t *testing.T, wantVersion int) []details.Entry }{ { name: "ExchangeAllMail", - selFunc: func() selectors.Reducer { + selFunc: func(t *testing.T, wantVersion int) selectors.Reducer { sel := selectors.NewExchangeRestore(selectors.Any()) sel.Include(sel.Mails(selectors.Any(), selectors.Any())) return sel }, - expected: testdata.ExchangeEmailItems, + expected: func(t *testing.T, wantVersion int) []details.Entry { + return testdata.GetItemsForVersion( + t, + path.ExchangeService, + path.EmailCategory, + wantVersion, + -1) + }, }, { name: "ExchangeMailFolderPrefixMatch", - selFunc: func() selectors.Reducer { + selFunc: func(t *testing.T, wantVersion int) selectors.Reducer { sel := selectors.NewExchangeRestore(selectors.Any()) sel.Include(sel.MailFolders( []string{testdata.ExchangeEmailInboxPath.FolderLocation()}, @@ -53,48 +62,79 @@ func (suite *SelectorReduceSuite) TestReduce() { return sel }, - expected: testdata.ExchangeEmailItems, + expected: func(t *testing.T, wantVersion int) []details.Entry { + return testdata.GetItemsForVersion( + t, + path.ExchangeService, + path.EmailCategory, + wantVersion, + -1) + }, }, { name: "ExchangeMailSubject", - selFunc: func() selectors.Reducer { + selFunc: func(t *testing.T, wantVersion int) selectors.Reducer { sel := selectors.NewExchangeRestore(selectors.Any()) sel.Filter(sel.MailSubject("foo")) return sel }, - expected: []details.Entry{testdata.ExchangeEmailItems[0]}, + expected: func(t *testing.T, wantVersion int) []details.Entry { + return testdata.GetItemsForVersion( + t, + path.ExchangeService, + path.EmailCategory, + wantVersion, + 0) + }, }, { name: "ExchangeMailSubjectExcludeItem", - selFunc: func() selectors.Reducer { + selFunc: func(t *testing.T, wantVersion int) selectors.Reducer { + deets := testdata.GetDeetsForVersion( + t, + path.ExchangeService, + path.EmailCategory, + wantVersion) + sel := selectors.NewExchangeRestore(selectors.Any()) sel.Filter(sel.MailSender("a-person")) sel.Exclude(sel.Mails( selectors.Any(), - []string{testdata.ExchangeEmailItemPath2.RR.ShortRef()}, + []string{deets[1].ShortRef}, )) return sel }, - expected: []details.Entry{testdata.ExchangeEmailItems[0]}, + expected: func(t *testing.T, wantVersion int) []details.Entry { + return testdata.GetItemsForVersion( + t, + path.ExchangeService, + path.EmailCategory, + wantVersion, + 0) + }, }, { name: "ExchangeMailSender", - selFunc: func() selectors.Reducer { + selFunc: func(t *testing.T, wantVersion int) selectors.Reducer { sel := selectors.NewExchangeRestore(selectors.Any()) sel.Filter(sel.MailSender("a-person")) return sel }, - expected: []details.Entry{ - testdata.ExchangeEmailItems[0], - testdata.ExchangeEmailItems[1], + expected: func(t *testing.T, wantVersion int) []details.Entry { + return testdata.GetItemsForVersion( + t, + path.ExchangeService, + path.EmailCategory, + wantVersion, + 0, 1) }, }, { name: "ExchangeMailReceivedTime", - selFunc: func() selectors.Reducer { + selFunc: func(t *testing.T, wantVersion int) selectors.Reducer { sel := selectors.NewExchangeRestore(selectors.Any()) sel.Filter(sel.MailReceivedBefore( dttm.Format(testdata.Time1.Add(time.Second)), @@ -102,11 +142,18 @@ func (suite *SelectorReduceSuite) TestReduce() { return sel }, - expected: []details.Entry{testdata.ExchangeEmailItems[0]}, + expected: func(t *testing.T, wantVersion int) []details.Entry { + return testdata.GetItemsForVersion( + t, + path.ExchangeService, + path.EmailCategory, + wantVersion, + 0) + }, }, { name: "ExchangeMailID", - selFunc: func() selectors.Reducer { + selFunc: func(t *testing.T, wantVersion int) selectors.Reducer { sel := selectors.NewExchangeRestore(selectors.Any()) sel.Include(sel.Mails( selectors.Any(), @@ -115,24 +162,44 @@ func (suite *SelectorReduceSuite) TestReduce() { return sel }, - expected: []details.Entry{testdata.ExchangeEmailItems[0]}, + expected: func(t *testing.T, wantVersion int) []details.Entry { + return testdata.GetItemsForVersion( + t, + path.ExchangeService, + path.EmailCategory, + wantVersion, + 0) + }, }, { name: "ExchangeMailShortRef", - selFunc: func() selectors.Reducer { + selFunc: func(t *testing.T, wantVersion int) selectors.Reducer { + deets := testdata.GetDeetsForVersion( + t, + path.ExchangeService, + path.EmailCategory, + wantVersion) + sel := selectors.NewExchangeRestore(selectors.Any()) sel.Include(sel.Mails( selectors.Any(), - []string{testdata.ExchangeEmailItemPath1.RR.ShortRef()}, + []string{deets[0].ShortRef}, )) return sel }, - expected: []details.Entry{testdata.ExchangeEmailItems[0]}, + expected: func(t *testing.T, wantVersion int) []details.Entry { + return testdata.GetItemsForVersion( + t, + path.ExchangeService, + path.EmailCategory, + wantVersion, + 0) + }, }, { name: "ExchangeAllEventsAndMailWithSubject", - selFunc: func() selectors.Reducer { + selFunc: func(t *testing.T, wantVersion int) selectors.Reducer { sel := selectors.NewExchangeRestore(selectors.Any()) sel.Include(sel.Events( selectors.Any(), @@ -142,39 +209,62 @@ func (suite *SelectorReduceSuite) TestReduce() { return sel }, - expected: []details.Entry{testdata.ExchangeEmailItems[0]}, + expected: func(t *testing.T, wantVersion int) []details.Entry { + return testdata.GetItemsForVersion( + t, + path.ExchangeService, + path.EmailCategory, + wantVersion, + 0) + }, }, { name: "ExchangeEventsAndMailWithSubject", - selFunc: func() selectors.Reducer { + selFunc: func(t *testing.T, wantVersion int) selectors.Reducer { sel := selectors.NewExchangeRestore(selectors.Any()) sel.Filter(sel.EventSubject("foo")) sel.Filter(sel.MailSubject("foo")) return sel }, - expected: []details.Entry{}, + expected: func(t *testing.T, wantVersion int) []details.Entry { + return []details.Entry{} + }, }, { name: "ExchangeAll", - selFunc: func() selectors.Reducer { + selFunc: func(t *testing.T, wantVersion int) selectors.Reducer { sel := selectors.NewExchangeRestore(selectors.Any()) sel.Include(sel.AllData()) return sel }, - expected: append( - append( + expected: func(t *testing.T, wantVersion int) []details.Entry { + return append( append( - []details.Entry{}, - testdata.ExchangeEmailItems...), - testdata.ExchangeContactsItems...), - testdata.ExchangeEventsItems..., - ), + testdata.GetItemsForVersion( + t, + path.ExchangeService, + path.EmailCategory, + wantVersion, + -1), + testdata.GetItemsForVersion( + t, + path.ExchangeService, + path.EventsCategory, + wantVersion, + -1)...), + testdata.GetItemsForVersion( + t, + path.ExchangeService, + path.ContactsCategory, + wantVersion, + -1)...) + }, }, { name: "ExchangeMailByFolder", - selFunc: func() selectors.Reducer { + selFunc: func(t *testing.T, wantVersion int) selectors.Reducer { sel := selectors.NewExchangeRestore(selectors.Any()) sel.Include(sel.MailFolders( []string{testdata.ExchangeEmailBasePath.FolderLocation()}, @@ -182,14 +272,21 @@ func (suite *SelectorReduceSuite) TestReduce() { return sel }, - expected: []details.Entry{testdata.ExchangeEmailItems[0]}, + expected: func(t *testing.T, wantVersion int) []details.Entry { + return testdata.GetItemsForVersion( + t, + path.ExchangeService, + path.EmailCategory, + wantVersion, + 0) + }, }, // TODO (keepers): all folders are treated as prefix-matches at this time. // so this test actually does nothing different. In the future, we'll // need to amend the non-prefix folder tests to expect non-prefix matches. { name: "ExchangeMailByFolderPrefix", - selFunc: func() selectors.Reducer { + selFunc: func(t *testing.T, wantVersion int) selectors.Reducer { sel := selectors.NewExchangeRestore(selectors.Any()) sel.Include(sel.MailFolders( []string{testdata.ExchangeEmailBasePath.FolderLocation()}, @@ -198,11 +295,18 @@ func (suite *SelectorReduceSuite) TestReduce() { return sel }, - expected: []details.Entry{testdata.ExchangeEmailItems[0]}, + expected: func(t *testing.T, wantVersion int) []details.Entry { + return testdata.GetItemsForVersion( + t, + path.ExchangeService, + path.EmailCategory, + wantVersion, + 0) + }, }, { name: "ExchangeMailByFolderRoot", - selFunc: func() selectors.Reducer { + selFunc: func(t *testing.T, wantVersion int) selectors.Reducer { sel := selectors.NewExchangeRestore(selectors.Any()) sel.Include(sel.MailFolders( []string{testdata.ExchangeEmailInboxPath.FolderLocation()}, @@ -210,11 +314,18 @@ func (suite *SelectorReduceSuite) TestReduce() { return sel }, - expected: testdata.ExchangeEmailItems, + expected: func(t *testing.T, wantVersion int) []details.Entry { + return testdata.GetItemsForVersion( + t, + path.ExchangeService, + path.EmailCategory, + wantVersion, + -1) + }, }, { name: "ExchangeContactByFolder", - selFunc: func() selectors.Reducer { + selFunc: func(t *testing.T, wantVersion int) selectors.Reducer { sel := selectors.NewExchangeRestore(selectors.Any()) sel.Include(sel.ContactFolders( []string{testdata.ExchangeContactsBasePath.FolderLocation()}, @@ -222,11 +333,18 @@ func (suite *SelectorReduceSuite) TestReduce() { return sel }, - expected: []details.Entry{testdata.ExchangeContactsItems[0]}, + expected: func(t *testing.T, wantVersion int) []details.Entry { + return testdata.GetItemsForVersion( + t, + path.ExchangeService, + path.ContactsCategory, + wantVersion, + 0) + }, }, { name: "ExchangeContactByFolderRoot", - selFunc: func() selectors.Reducer { + selFunc: func(t *testing.T, wantVersion int) selectors.Reducer { sel := selectors.NewExchangeRestore(selectors.Any()) sel.Include(sel.ContactFolders( []string{testdata.ExchangeContactsRootPath.FolderLocation()}, @@ -234,12 +352,19 @@ func (suite *SelectorReduceSuite) TestReduce() { return sel }, - expected: testdata.ExchangeContactsItems, + expected: func(t *testing.T, wantVersion int) []details.Entry { + return testdata.GetItemsForVersion( + t, + path.ExchangeService, + path.ContactsCategory, + wantVersion, + -1) + }, }, { name: "ExchangeEventsByFolder", - selFunc: func() selectors.Reducer { + selFunc: func(t *testing.T, wantVersion int) selectors.Reducer { sel := selectors.NewExchangeRestore(selectors.Any()) sel.Include(sel.EventCalendars( []string{testdata.ExchangeEventsBasePath.FolderLocation()}, @@ -247,16 +372,28 @@ func (suite *SelectorReduceSuite) TestReduce() { return sel }, - expected: []details.Entry{testdata.ExchangeEventsItems[0]}, + expected: func(t *testing.T, wantVersion int) []details.Entry { + return testdata.GetItemsForVersion( + t, + path.ExchangeService, + path.EventsCategory, + wantVersion, + 0) + }, }, } - for _, test := range table { - suite.Run(test.name, func() { - t := suite.T() + for v := 0; v <= version.Backup; v++ { + suite.Run(fmt.Sprintf("version%d", v), func() { + for _, test := range table { + suite.Run(test.name, func() { + t := suite.T() - output := test.selFunc().Reduce(ctx, allDetails, fault.New(true)) - assert.ElementsMatch(t, test.expected, output.Entries) + allDetails := testdata.GetDetailsSetForVersion(t, v) + output := test.selFunc(t, v).Reduce(ctx, allDetails, fault.New(true)) + assert.ElementsMatch(t, test.expected(t, v), output.Entries) + }) + } }) } }