Keepers 52455356e5
add locationRef to details (#2427)
## Description

Adds a new reference to the details ent: location-
ref.  The location holds the human-readable
version of the item's location in whatever m365
service sourced the item.  Hookup is incomplete,
following PRs will fill out functionality.

Also adds a LocationPather interface to data_
collections to pass this data back and forth
between producers and consumers.

Should be safe to merge into main.

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

- [x] 🕐 Yes, but in a later PR

## Type of change

- [x] 🌻 Feature
- [x] 🐛 Bugfix

## Issue(s)

* #2423

## Test Plan

- [x]  Unit test
2023-02-13 20:19:04 +00:00

525 lines
13 KiB
Go

package testdata
import (
"context"
"errors"
"time"
"github.com/alcionai/corso/src/cli/utils"
"github.com/alcionai/corso/src/internal/common"
"github.com/alcionai/corso/src/internal/model"
"github.com/alcionai/corso/src/pkg/backup"
"github.com/alcionai/corso/src/pkg/backup/details"
"github.com/alcionai/corso/src/pkg/fault"
"github.com/alcionai/corso/src/pkg/selectors"
"github.com/alcionai/corso/src/pkg/selectors/testdata"
"github.com/alcionai/corso/src/pkg/store"
)
type ExchangeOptionsTest struct {
Name string
Opts utils.ExchangeOpts
BackupGetter *MockBackupGetter
Expected []details.DetailsEntry
}
var (
// BadExchangeOptionsFormats contains ExchangeOpts with flags that should
// 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.
BadExchangeOptionsFormats = []ExchangeOptionsTest{
{
Name: "BadEmailReceiveAfter",
Opts: utils.ExchangeOpts{
EmailReceivedAfter: "foo",
Populated: utils.PopulatedFlags{
utils.EmailReceivedAfterFN: struct{}{},
},
},
},
{
Name: "EmptyEmailReceiveAfter",
Opts: utils.ExchangeOpts{
EmailReceivedAfter: "",
Populated: utils.PopulatedFlags{
utils.EmailReceivedAfterFN: struct{}{},
},
},
},
{
Name: "BadEmailReceiveBefore",
Opts: utils.ExchangeOpts{
EmailReceivedBefore: "foo",
Populated: utils.PopulatedFlags{
utils.EmailReceivedBeforeFN: struct{}{},
},
},
},
{
Name: "EmptyEmailReceiveBefore",
Opts: utils.ExchangeOpts{
EmailReceivedBefore: "",
Populated: utils.PopulatedFlags{
utils.EmailReceivedBeforeFN: struct{}{},
},
},
},
{
Name: "BadEventRecurs",
Opts: utils.ExchangeOpts{
EventRecurs: "foo",
Populated: utils.PopulatedFlags{
utils.EventRecursFN: struct{}{},
},
},
},
{
Name: "EmptyEventRecurs",
Opts: utils.ExchangeOpts{
EventRecurs: "",
Populated: utils.PopulatedFlags{
utils.EventRecursFN: struct{}{},
},
},
},
{
Name: "BadEventStartsAfter",
Opts: utils.ExchangeOpts{
EventStartsAfter: "foo",
Populated: utils.PopulatedFlags{
utils.EventStartsAfterFN: struct{}{},
},
},
},
{
Name: "EmptyEventStartsAfter",
Opts: utils.ExchangeOpts{
EventStartsAfter: "",
Populated: utils.PopulatedFlags{
utils.EventStartsAfterFN: struct{}{},
},
},
},
{
Name: "BadEventStartsBefore",
Opts: utils.ExchangeOpts{
EventStartsBefore: "foo",
Populated: utils.PopulatedFlags{
utils.EventStartsBeforeFN: struct{}{},
},
},
},
{
Name: "EmptyEventStartsBefore",
Opts: utils.ExchangeOpts{
EventStartsBefore: "",
Populated: utils.PopulatedFlags{
utils.EventStartsBeforeFN: struct{}{},
},
},
},
}
// ExchangeOptionDetailLookups contains flag inputs and expected results for
// some choice input patterns. This set is not exhaustive. All inputs and
// outputs are according to the data laid out in selectors/testdata. Mocks are
// configured to return the full dataset listed in selectors/testdata.
ExchangeOptionDetailLookups = []ExchangeOptionsTest{
{
Name: "Emails",
Expected: testdata.ExchangeEmailItems,
Opts: utils.ExchangeOpts{
Email: selectors.Any(),
},
},
{
Name: "EmailsFolderPrefixMatch",
Expected: testdata.ExchangeEmailItems,
Opts: utils.ExchangeOpts{
EmailFolder: []string{testdata.ExchangeEmailInboxPath.Folder(false)},
},
},
{
Name: "EmailsFolderPrefixMatchTrailingSlash",
Expected: testdata.ExchangeEmailItems,
Opts: utils.ExchangeOpts{
EmailFolder: []string{testdata.ExchangeEmailInboxPath.Folder(false) + "/"},
},
},
{
Name: "EmailsFolderWithSlashPrefixMatch",
Expected: []details.DetailsEntry{
testdata.ExchangeEmailItems[1],
testdata.ExchangeEmailItems[2],
},
Opts: utils.ExchangeOpts{
EmailFolder: []string{testdata.ExchangeEmailBasePath2.Folder(false)},
},
},
{
Name: "EmailsFolderWithSlashPrefixMatchTrailingSlash",
Expected: []details.DetailsEntry{
testdata.ExchangeEmailItems[1],
testdata.ExchangeEmailItems[2],
},
Opts: utils.ExchangeOpts{
EmailFolder: []string{testdata.ExchangeEmailBasePath2.Folder(false) + "/"},
},
},
{
Name: "EmailsBySubject",
Expected: []details.DetailsEntry{
testdata.ExchangeEmailItems[0],
testdata.ExchangeEmailItems[1],
},
Opts: utils.ExchangeOpts{
EmailSender: "a-person",
},
},
{
Name: "AllExchange",
Expected: append(
append(
append(
[]details.DetailsEntry{},
testdata.ExchangeEmailItems...,
),
testdata.ExchangeContactsItems...,
),
testdata.ExchangeEventsItems...,
),
},
{
Name: "MailReceivedTime",
Expected: []details.DetailsEntry{testdata.ExchangeEmailItems[0]},
Opts: utils.ExchangeOpts{
EmailReceivedBefore: common.FormatTime(testdata.Time1.Add(time.Second)),
},
},
{
Name: "MailID",
Expected: []details.DetailsEntry{testdata.ExchangeEmailItems[0]},
Opts: utils.ExchangeOpts{
Email: []string{testdata.ExchangeEmailItemPath1.Item()},
},
},
{
Name: "MailShortRef",
Expected: []details.DetailsEntry{testdata.ExchangeEmailItems[0]},
Opts: utils.ExchangeOpts{
Email: []string{testdata.ExchangeEmailItemPath1.ShortRef()},
},
},
{
Name: "MultipleMailShortRef",
Expected: []details.DetailsEntry{
testdata.ExchangeEmailItems[0],
testdata.ExchangeEmailItems[1],
},
Opts: utils.ExchangeOpts{
Email: []string{
testdata.ExchangeEmailItemPath1.ShortRef(),
testdata.ExchangeEmailItemPath2.ShortRef(),
},
},
},
{
Name: "AllEventsAndMailWithSubject",
Expected: []details.DetailsEntry{testdata.ExchangeEmailItems[0]},
Opts: utils.ExchangeOpts{
EmailSubject: "foo",
Event: selectors.Any(),
},
},
{
Name: "EventsAndMailWithSubject",
Expected: []details.DetailsEntry{},
Opts: utils.ExchangeOpts{
EmailSubject: "foo",
EventSubject: "foo",
},
},
{
Name: "EventsAndMailByShortRef",
Expected: []details.DetailsEntry{
testdata.ExchangeEmailItems[0],
testdata.ExchangeEventsItems[0],
},
Opts: utils.ExchangeOpts{
Email: []string{testdata.ExchangeEmailItemPath1.ShortRef()},
Event: []string{testdata.ExchangeEventsItemPath1.ShortRef()},
},
},
}
)
type OneDriveOptionsTest struct {
Name string
Opts utils.OneDriveOpts
BackupGetter *MockBackupGetter
Expected []details.DetailsEntry
}
var (
// BadOneDriveOptionsFormats contains OneDriveOpts with flags that should
// 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.
BadOneDriveOptionsFormats = []OneDriveOptionsTest{
{
Name: "BadFileCreatedAfter",
Opts: 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{}{},
},
},
},
{
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: "BadFileModifiedAfter",
Opts: utils.OneDriveOpts{
FileModifiedAfter: "foo",
Populated: utils.PopulatedFlags{
utils.FileModifiedAfterFN: struct{}{},
},
},
},
{
Name: "EmptyFileModifiedAfter",
Opts: utils.OneDriveOpts{
FileModifiedAfter: "",
Populated: utils.PopulatedFlags{
utils.FileModifiedAfterFN: struct{}{},
},
},
},
{
Name: "BadFileModifiedBefore",
Opts: utils.OneDriveOpts{
FileModifiedBefore: "foo",
Populated: utils.PopulatedFlags{
utils.FileModifiedBeforeFN: struct{}{},
},
},
},
{
Name: "EmptyFileModifiedBefore",
Opts: utils.OneDriveOpts{
FileModifiedBefore: "",
Populated: utils.PopulatedFlags{
utils.FileModifiedBeforeFN: struct{}{},
},
},
},
}
// OneDriveOptionDetailLookups contains flag inputs and expected results for
// some choice input patterns. This set is not exhaustive. All inputs and
// outputs are according to the data laid out in selectors/testdata. Mocks are
// configured to return the full dataset listed in selectors/testdata.
OneDriveOptionDetailLookups = []OneDriveOptionsTest{
{
Name: "AllFiles",
Expected: testdata.OneDriveItems,
Opts: utils.OneDriveOpts{
Paths: selectors.Any(),
},
},
{
Name: "FolderPrefixMatch",
Expected: testdata.OneDriveItems,
Opts: utils.OneDriveOpts{
Paths: []string{testdata.OneDriveFolderFolder},
},
},
{
Name: "FolderPrefixMatchTrailingSlash",
Expected: testdata.OneDriveItems,
Opts: utils.OneDriveOpts{
Paths: []string{testdata.OneDriveFolderFolder + "/"},
},
},
{
Name: "FolderPrefixMatchTrailingSlash",
Expected: testdata.OneDriveItems,
Opts: utils.OneDriveOpts{
Paths: []string{testdata.OneDriveFolderFolder + "/"},
},
},
{
Name: "ShortRef",
Expected: []details.DetailsEntry{
testdata.OneDriveItems[0],
testdata.OneDriveItems[1],
},
Opts: utils.OneDriveOpts{
Names: []string{
testdata.OneDriveItems[0].ShortRef,
testdata.OneDriveItems[1].ShortRef,
},
},
},
{
Name: "CreatedBefore",
Expected: []details.DetailsEntry{testdata.OneDriveItems[1]},
Opts: utils.OneDriveOpts{
FileCreatedBefore: common.FormatTime(testdata.Time1.Add(time.Second)),
},
},
}
)
type SharePointOptionsTest struct {
Name string
Opts utils.SharePointOpts
BackupGetter *MockBackupGetter
Expected []details.DetailsEntry
}
var (
// BadSharePointOptionsFormats contains SharePointOpts with flags that should
// 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{}{},
// },
// },
// },
}
// SharePointOptionDetailLookups contains flag inputs and expected results for
// some choice input patterns. This set is not exhaustive. All inputs and
// outputs are according to the data laid out in selectors/testdata. Mocks are
// configured to return the full dataset listed in selectors/testdata.
SharePointOptionDetailLookups = []SharePointOptionsTest{
{
Name: "AllLibraryItems",
Expected: testdata.SharePointLibraryItems,
Opts: utils.SharePointOpts{
LibraryPaths: selectors.Any(),
},
},
{
Name: "FolderPrefixMatch",
Expected: testdata.SharePointLibraryItems,
Opts: utils.SharePointOpts{
LibraryPaths: []string{testdata.SharePointLibraryFolder},
},
},
{
Name: "FolderPrefixMatchTrailingSlash",
Expected: testdata.SharePointLibraryItems,
Opts: utils.SharePointOpts{
LibraryPaths: []string{testdata.SharePointLibraryFolder + "/"},
},
},
{
Name: "FolderPrefixMatchTrailingSlash",
Expected: testdata.SharePointLibraryItems,
Opts: utils.SharePointOpts{
LibraryPaths: []string{testdata.SharePointLibraryFolder + "/"},
},
},
{
Name: "ShortRef",
Expected: []details.DetailsEntry{
testdata.SharePointLibraryItems[0],
testdata.SharePointLibraryItems[1],
},
Opts: utils.SharePointOpts{
LibraryItems: []string{
testdata.SharePointLibraryItems[0].ShortRef,
testdata.SharePointLibraryItems[1].ShortRef,
},
},
},
// {
// Name: "CreatedBefore",
// Expected: []details.DetailsEntry{testdata.SharePointLibraryItems[1]},
// Opts: utils.SharePointOpts{
// FileCreatedBefore: common.FormatTime(testdata.Time1.Add(time.Second)),
// },
// },
}
)
// MockBackupGetter implements the repo.BackupGetter interface and returns
// (selectors/testdata.GetDetailsSet(), nil, nil) when BackupDetails is called
// on the nil instance. If an instance is given or Backups is called returns an
// error.
type MockBackupGetter struct{}
func (MockBackupGetter) Backup(
context.Context,
model.StableID,
) (*backup.Backup, error) {
return nil, errors.New("unexpected call to mock")
}
func (MockBackupGetter) Backups(
context.Context,
[]model.StableID,
) ([]*backup.Backup, *fault.Errors) {
return nil, fault.New(false).Fail(errors.New("unexpected call to mock"))
}
func (MockBackupGetter) BackupsByTag(
context.Context,
...store.FilterOption,
) ([]*backup.Backup, error) {
return nil, errors.New("unexpected call to mock")
}
func (bg *MockBackupGetter) BackupDetails(
ctx context.Context,
backupID string,
) (*details.Details, *backup.Backup, *fault.Errors) {
if bg == nil {
return testdata.GetDetailsSet(), nil, fault.New(true)
}
return nil, nil, fault.New(false).Fail(errors.New("unexpected call to mock"))
}