add sharepoint details command (#1618)
## Description Adds the `backup details sharepoint` command to the CLI. E2E support is already functional. Additional filters will be added as needs are identified. ## Type of change - [x] 🌻 Feature ## Issue(s) * #1614 ## Test Plan - [x] ⚡ Unit test
This commit is contained in:
parent
f1ea464ad6
commit
2778cd567e
@ -453,8 +453,7 @@ func detailsExchangeCmd(cmd *cobra.Command, args []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// runDetailsExchangeCmd actually performs the lookup in backup details. Assumes
|
||||
// len(backupID) > 0.
|
||||
// runDetailsExchangeCmd actually performs the lookup in backup details.
|
||||
func runDetailsExchangeCmd(
|
||||
ctx context.Context,
|
||||
r repository.BackupGetter,
|
||||
|
||||
@ -90,7 +90,7 @@ func addOneDriveCommands(parent *cobra.Command) *cobra.Command {
|
||||
c, fs = utils.AddCommand(parent, oneDriveListCmd())
|
||||
|
||||
fs.StringVar(&backupID,
|
||||
"backup", "",
|
||||
utils.BackupFN, "",
|
||||
"ID of the backup to retrieve.")
|
||||
|
||||
case detailsCommand:
|
||||
@ -344,8 +344,7 @@ func detailsOneDriveCmd(cmd *cobra.Command, args []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// runDetailsOneDriveCmd actually performs the lookup in backup details. Assumes
|
||||
// len(backupID) > 0.
|
||||
// runDetailsOneDriveCmd actually performs the lookup in backup details.
|
||||
func runDetailsOneDriveCmd(
|
||||
ctx context.Context,
|
||||
r repository.BackupGetter,
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
package backup
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
@ -12,6 +14,7 @@ import (
|
||||
"github.com/alcionai/corso/src/internal/kopia"
|
||||
"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/path"
|
||||
"github.com/alcionai/corso/src/pkg/repository"
|
||||
"github.com/alcionai/corso/src/pkg/selectors"
|
||||
@ -23,7 +26,9 @@ import (
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
var (
|
||||
site []string
|
||||
site []string
|
||||
libraryPaths []string
|
||||
libraryItems []string
|
||||
|
||||
sharepointData []string
|
||||
)
|
||||
@ -33,10 +38,10 @@ const (
|
||||
)
|
||||
|
||||
const (
|
||||
sharePointServiceCommand = "sharepoint"
|
||||
sharePointServiceCommandCreateUseSuffix = "--site <siteId> | '" + utils.Wildcard + "'"
|
||||
sharePointServiceCommandDeleteUseSuffix = "--backup <backupId>"
|
||||
// sharePointServiceCommandDetailsUseSuffix = "--backup <backupId>"
|
||||
sharePointServiceCommand = "sharepoint"
|
||||
sharePointServiceCommandCreateUseSuffix = "--site <siteId> | '" + utils.Wildcard + "'"
|
||||
sharePointServiceCommandDeleteUseSuffix = "--backup <backupId>"
|
||||
sharePointServiceCommandDetailsUseSuffix = "--backup <backupId>"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -54,9 +59,9 @@ corso backup create sharepoint --site '*'`
|
||||
sharePointServiceCommandDeleteExamples = `# Delete SharePoint backup with ID 1234abcd-12ab-cd34-56de-1234abcd
|
||||
corso backup delete sharepoint --backup 1234abcd-12ab-cd34-56de-1234abcd`
|
||||
|
||||
// sharePointServiceCommandDetailsExamples = `# Explore <site>'s files from backup 1234abcd-12ab-cd34-56de-1234abcd
|
||||
//
|
||||
// corso backup details sharepoint --backup 1234abcd-12ab-cd34-56de-1234abcd --site <site_id>`
|
||||
sharePointServiceCommandDetailsExamples = `# Explore <site>'s files from backup 1234abcd-12ab-cd34-56de-1234abcd
|
||||
|
||||
corso backup details sharepoint --backup 1234abcd-12ab-cd34-56de-1234abcd --site <site_id>`
|
||||
)
|
||||
|
||||
// called by backup.go to map parent subcommands to provider-specific handling.
|
||||
@ -80,18 +85,45 @@ func addSharePointCommands(parent *cobra.Command) *cobra.Command {
|
||||
fs.StringSliceVar(
|
||||
&sharepointData,
|
||||
utils.DataFN, nil,
|
||||
"Select one or more types of data to backup: "+dataLibraries)
|
||||
"Select one or more types of data to backup: "+dataLibraries+".")
|
||||
options.AddOperationFlags(c)
|
||||
|
||||
case listCommand:
|
||||
c, fs = utils.AddCommand(parent, sharePointListCmd(), utils.HideCommand())
|
||||
|
||||
fs.StringVar(&backupID,
|
||||
"backup", "",
|
||||
utils.BackupFN, "",
|
||||
"ID of the backup to retrieve.")
|
||||
|
||||
// case detailsCommand:
|
||||
// c, fs = utils.AddCommand(parent, sharePointDetailsCmd())
|
||||
case detailsCommand:
|
||||
c, fs = utils.AddCommand(parent, sharePointDetailsCmd())
|
||||
|
||||
c.Use = c.Use + " " + sharePointServiceCommandDetailsUseSuffix
|
||||
c.Example = sharePointServiceCommandDetailsExamples
|
||||
|
||||
fs.StringVar(&backupID,
|
||||
utils.BackupFN, "",
|
||||
"ID of the backup to retrieve.")
|
||||
cobra.CheckErr(c.MarkFlagRequired(utils.BackupFN))
|
||||
|
||||
// sharepoint hierarchy flags
|
||||
|
||||
fs.StringSliceVar(
|
||||
&libraryPaths,
|
||||
utils.LibraryFN, nil,
|
||||
"Select backup details by Library name.")
|
||||
|
||||
fs.StringSliceVar(
|
||||
&libraryItems,
|
||||
utils.LibraryItemFN, nil,
|
||||
"Select backup details by library item name or ID.")
|
||||
|
||||
// info flags
|
||||
|
||||
// fs.StringVar(
|
||||
// &fileCreatedAfter,
|
||||
// utils.FileCreatedAfterFN, "",
|
||||
// "Select backup details for items created after this datetime.")
|
||||
|
||||
case deleteCommand:
|
||||
c, fs = utils.AddCommand(parent, sharePointDeleteCmd(), utils.HideCommand())
|
||||
@ -282,3 +314,93 @@ func deleteSharePointCmd(cmd *cobra.Command, args []string) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// backup details
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
// `corso backup details onedrive [<flag>...]`
|
||||
func sharePointDetailsCmd() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: sharePointServiceCommand,
|
||||
Short: "Shows the details of a M365 SharePoint service backup",
|
||||
RunE: detailsSharePointCmd,
|
||||
Args: cobra.NoArgs,
|
||||
Example: sharePointServiceCommandDetailsExamples,
|
||||
}
|
||||
}
|
||||
|
||||
// lists the history of backup operations
|
||||
func detailsSharePointCmd(cmd *cobra.Command, args []string) error {
|
||||
ctx := cmd.Context()
|
||||
|
||||
if utils.HasNoFlagsAndShownHelp(cmd) {
|
||||
return nil
|
||||
}
|
||||
|
||||
s, acct, err := config.GetStorageAndAccount(ctx, true, nil)
|
||||
if err != nil {
|
||||
return Only(ctx, err)
|
||||
}
|
||||
|
||||
r, err := repository.Connect(ctx, acct, s, options.Control())
|
||||
if err != nil {
|
||||
return Only(ctx, errors.Wrapf(err, "Failed to connect to the %s repository", s.Provider))
|
||||
}
|
||||
|
||||
defer utils.CloseRepo(ctx, r)
|
||||
|
||||
opts := utils.SharePointOpts{
|
||||
Sites: site,
|
||||
LibraryPaths: libraryPaths,
|
||||
LibraryItems: libraryItems,
|
||||
|
||||
Populated: utils.GetPopulatedFlags(cmd),
|
||||
}
|
||||
|
||||
ds, err := runDetailsSharePointCmd(ctx, r, backupID, opts)
|
||||
if err != nil {
|
||||
return Only(ctx, err)
|
||||
}
|
||||
|
||||
if len(ds.Entries) == 0 {
|
||||
Info(ctx, selectors.ErrorNoMatchingItems)
|
||||
return nil
|
||||
}
|
||||
|
||||
ds.PrintEntries(ctx)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// runDetailsSharePointCmd actually performs the lookup in backup details.
|
||||
func runDetailsSharePointCmd(
|
||||
ctx context.Context,
|
||||
r repository.BackupGetter,
|
||||
backupID string,
|
||||
opts utils.SharePointOpts,
|
||||
) (*details.Details, error) {
|
||||
if err := utils.ValidateSharePointRestoreFlags(backupID, opts); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
d, _, err := r.BackupDetails(ctx, backupID)
|
||||
if err != nil {
|
||||
if errors.Is(err, kopia.ErrNotFound) {
|
||||
return nil, errors.Errorf("no backup exists with the id %s", backupID)
|
||||
}
|
||||
|
||||
return nil, errors.Wrap(err, "Failed to get backup details in the repository")
|
||||
}
|
||||
|
||||
sel := selectors.NewSharePointRestore()
|
||||
utils.IncludeSharePointRestoreDataSelectors(sel, opts)
|
||||
utils.FilterSharePointRestoreInfoSelectors(sel, opts)
|
||||
|
||||
// if no selector flags were specified, get all data in the service.
|
||||
if len(sel.Scopes()) == 0 {
|
||||
sel.Include(sel.Sites(selectors.Any()))
|
||||
}
|
||||
|
||||
return sel.Reduce(ctx, d), nil
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
"github.com/alcionai/corso/src/cli/utils/testdata"
|
||||
"github.com/alcionai/corso/src/internal/tester"
|
||||
)
|
||||
|
||||
@ -37,10 +38,10 @@ func (suite *SharePointSuite) TestAddSharePointCommands() {
|
||||
"list sharepoint", listCommand, expectUse,
|
||||
sharePointListCmd().Short, listSharePointCmd,
|
||||
},
|
||||
// {
|
||||
// "details sharepoint", detailsCommand, expectUse + " " + sharePointServiceCommandDetailsUseSuffix,
|
||||
// sharePointDetailsCmd().Short, detailsSharePointCmd,
|
||||
// },
|
||||
{
|
||||
"details sharepoint", detailsCommand, expectUse + " " + sharePointServiceCommandDetailsUseSuffix,
|
||||
sharePointDetailsCmd().Short, detailsSharePointCmd,
|
||||
},
|
||||
{
|
||||
"delete sharepoint", deleteCommand, expectUse + " " + sharePointServiceCommandDeleteUseSuffix,
|
||||
sharePointDeleteCmd().Short, deleteSharePointCmd,
|
||||
@ -87,40 +88,40 @@ func (suite *SharePointSuite) TestValidateSharePointBackupCreateFlags() {
|
||||
}
|
||||
}
|
||||
|
||||
// func (suite *SharePointSuite) TestSharePointBackupDetailsSelectors() {
|
||||
// ctx, flush := tester.NewContext()
|
||||
// defer flush()
|
||||
func (suite *SharePointSuite) TestSharePointBackupDetailsSelectors() {
|
||||
ctx, flush := tester.NewContext()
|
||||
defer flush()
|
||||
|
||||
// for _, test := range testdata.SharePointOptionDetailLookups {
|
||||
// suite.T().Run(test.Name, func(t *testing.T) {
|
||||
// output, err := runDetailsSharePointCmd(
|
||||
// ctx,
|
||||
// test.BackupGetter,
|
||||
// "backup-ID",
|
||||
// test.Opts,
|
||||
// )
|
||||
// assert.NoError(t, err)
|
||||
for _, test := range testdata.SharePointOptionDetailLookups {
|
||||
suite.T().Run(test.Name, func(t *testing.T) {
|
||||
output, err := runDetailsSharePointCmd(
|
||||
ctx,
|
||||
test.BackupGetter,
|
||||
"backup-ID",
|
||||
test.Opts,
|
||||
)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// assert.ElementsMatch(t, test.Expected, output.Entries)
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
assert.ElementsMatch(t, test.Expected, output.Entries)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// func (suite *SharePointSuite) TestSharePointBackupDetailsSelectorsBadFormats() {
|
||||
// ctx, flush := tester.NewContext()
|
||||
// defer flush()
|
||||
func (suite *SharePointSuite) TestSharePointBackupDetailsSelectorsBadFormats() {
|
||||
ctx, flush := tester.NewContext()
|
||||
defer flush()
|
||||
|
||||
// for _, test := range testdata.BadSharePointOptionsFormats {
|
||||
// suite.T().Run(test.Name, func(t *testing.T) {
|
||||
// output, err := runDetailsSharePointCmd(
|
||||
// ctx,
|
||||
// test.BackupGetter,
|
||||
// "backup-ID",
|
||||
// test.Opts,
|
||||
// )
|
||||
for _, test := range testdata.BadSharePointOptionsFormats {
|
||||
suite.T().Run(test.Name, func(t *testing.T) {
|
||||
output, err := runDetailsSharePointCmd(
|
||||
ctx,
|
||||
test.BackupGetter,
|
||||
"backup-ID",
|
||||
test.Opts,
|
||||
)
|
||||
|
||||
// assert.Error(t, err)
|
||||
// assert.Empty(t, output)
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
assert.Error(t, err)
|
||||
assert.Empty(t, output)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,12 +4,21 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
"github.com/alcionai/corso/src/cli/utils"
|
||||
"github.com/alcionai/corso/src/pkg/selectors"
|
||||
)
|
||||
|
||||
func (suite *ExchangeUtilsSuite) TestIncludeOneDriveRestoreDataSelectors() {
|
||||
type OneDriveUtilsSuite struct {
|
||||
suite.Suite
|
||||
}
|
||||
|
||||
func TestOneDriveUtilsSuite(t *testing.T) {
|
||||
suite.Run(t, new(OneDriveUtilsSuite))
|
||||
}
|
||||
|
||||
func (suite *OneDriveUtilsSuite) TestIncludeOneDriveRestoreDataSelectors() {
|
||||
var (
|
||||
empty = []string{}
|
||||
single = []string{"single"}
|
||||
|
||||
97
src/cli/utils/sharepoint.go
Normal file
97
src/cli/utils/sharepoint.go
Normal file
@ -0,0 +1,97 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/alcionai/corso/src/pkg/selectors"
|
||||
)
|
||||
|
||||
const (
|
||||
LibraryItemFN = "library-item"
|
||||
LibraryFN = "library"
|
||||
)
|
||||
|
||||
type SharePointOpts struct {
|
||||
Sites []string
|
||||
LibraryItems []string
|
||||
LibraryPaths []string
|
||||
|
||||
Populated PopulatedFlags
|
||||
}
|
||||
|
||||
// ValidateSharePointRestoreFlags checks common flags for correctness and interdependencies
|
||||
func ValidateSharePointRestoreFlags(backupID string, opts SharePointOpts) error {
|
||||
if len(backupID) == 0 {
|
||||
return errors.New("a backup ID is required")
|
||||
}
|
||||
|
||||
// if _, ok := opts.Populated[FileCreatedAfterFN]; ok && !IsValidTimeFormat(opts.FileCreatedAfter) {
|
||||
// return errors.New("invalid time format for created-after")
|
||||
// }
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddSharePointFilter adds the scope of the provided values to the selector's
|
||||
// filter set
|
||||
func AddSharePointFilter(
|
||||
sel *selectors.SharePointRestore,
|
||||
v string,
|
||||
f func(string) []selectors.SharePointScope,
|
||||
) {
|
||||
if len(v) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
sel.Filter(f(v))
|
||||
}
|
||||
|
||||
// IncludeSharePointRestoreDataSelectors builds the common data-selector
|
||||
// inclusions for SharePoint commands.
|
||||
func IncludeSharePointRestoreDataSelectors(
|
||||
sel *selectors.SharePointRestore,
|
||||
opts SharePointOpts,
|
||||
) {
|
||||
lp, ln := len(opts.LibraryPaths), len(opts.LibraryItems)
|
||||
|
||||
// only use the inclusion if either a path or item name
|
||||
// is specified
|
||||
if lp+ln == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
if len(opts.Sites) == 0 {
|
||||
opts.Sites = selectors.Any()
|
||||
}
|
||||
|
||||
// either scope the request to a set of sites
|
||||
if lp+ln == 0 {
|
||||
sel.Include(sel.Sites(opts.Sites))
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
opts.LibraryPaths = trimFolderSlash(opts.LibraryPaths)
|
||||
|
||||
if ln == 0 {
|
||||
opts.LibraryItems = selectors.Any()
|
||||
}
|
||||
|
||||
containsFolders, prefixFolders := splitFoldersIntoContainsAndPrefix(opts.LibraryPaths)
|
||||
|
||||
if len(containsFolders) > 0 {
|
||||
sel.Include(sel.LibraryItems(opts.Sites, containsFolders, opts.LibraryItems))
|
||||
}
|
||||
|
||||
if len(prefixFolders) > 0 {
|
||||
sel.Include(sel.LibraryItems(opts.Sites, prefixFolders, opts.LibraryItems, selectors.PrefixMatch()))
|
||||
}
|
||||
}
|
||||
|
||||
// FilterSharePointRestoreInfoSelectors builds the common info-selector filters.
|
||||
func FilterSharePointRestoreInfoSelectors(
|
||||
sel *selectors.SharePointRestore,
|
||||
opts SharePointOpts,
|
||||
) {
|
||||
// AddSharePointFilter(sel, opts.FileCreatedAfter, sel.CreatedAfter)
|
||||
}
|
||||
99
src/cli/utils/sharepoint_test.go
Normal file
99
src/cli/utils/sharepoint_test.go
Normal file
@ -0,0 +1,99 @@
|
||||
package utils_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
"github.com/alcionai/corso/src/cli/utils"
|
||||
"github.com/alcionai/corso/src/pkg/selectors"
|
||||
)
|
||||
|
||||
type SharePointUtilsSuite struct {
|
||||
suite.Suite
|
||||
}
|
||||
|
||||
func TestSharePointUtilsSuite(t *testing.T) {
|
||||
suite.Run(t, new(SharePointUtilsSuite))
|
||||
}
|
||||
|
||||
func (suite *ExchangeUtilsSuite) TestIncludeSharePointRestoreDataSelectors() {
|
||||
var (
|
||||
empty = []string{}
|
||||
single = []string{"single"}
|
||||
multi = []string{"more", "than", "one"}
|
||||
containsOnly = []string{"contains"}
|
||||
prefixOnly = []string{"/prefix"}
|
||||
containsAndPrefix = []string{"contains", "/prefix"}
|
||||
)
|
||||
|
||||
table := []struct {
|
||||
name string
|
||||
opts utils.SharePointOpts
|
||||
expectIncludeLen int
|
||||
}{
|
||||
{
|
||||
name: "no inputs",
|
||||
opts: utils.SharePointOpts{
|
||||
Sites: empty,
|
||||
LibraryPaths: empty,
|
||||
LibraryItems: empty,
|
||||
},
|
||||
expectIncludeLen: 0,
|
||||
},
|
||||
{
|
||||
name: "single inputs",
|
||||
opts: utils.SharePointOpts{
|
||||
Sites: single,
|
||||
LibraryPaths: single,
|
||||
LibraryItems: single,
|
||||
},
|
||||
expectIncludeLen: 1,
|
||||
},
|
||||
{
|
||||
name: "multi inputs",
|
||||
opts: utils.SharePointOpts{
|
||||
Sites: multi,
|
||||
LibraryPaths: multi,
|
||||
LibraryItems: multi,
|
||||
},
|
||||
expectIncludeLen: 1,
|
||||
},
|
||||
{
|
||||
name: "library contains",
|
||||
opts: utils.SharePointOpts{
|
||||
Sites: empty,
|
||||
LibraryPaths: containsOnly,
|
||||
LibraryItems: empty,
|
||||
},
|
||||
expectIncludeLen: 1,
|
||||
},
|
||||
{
|
||||
name: "library prefixes",
|
||||
opts: utils.SharePointOpts{
|
||||
Sites: empty,
|
||||
LibraryPaths: prefixOnly,
|
||||
LibraryItems: empty,
|
||||
},
|
||||
expectIncludeLen: 1,
|
||||
},
|
||||
{
|
||||
name: "library prefixes and contains",
|
||||
opts: utils.SharePointOpts{
|
||||
Sites: empty,
|
||||
LibraryPaths: containsAndPrefix,
|
||||
LibraryItems: empty,
|
||||
},
|
||||
expectIncludeLen: 2,
|
||||
},
|
||||
}
|
||||
for _, test := range table {
|
||||
suite.T().Run(test.name, func(t *testing.T) {
|
||||
sel := selectors.NewSharePointRestore()
|
||||
// no return, mutates sel as a side effect
|
||||
utils.IncludeSharePointRestoreDataSelectors(sel, test.opts)
|
||||
assert.Len(t, sel.Includes, test.expectIncludeLen)
|
||||
})
|
||||
}
|
||||
}
|
||||
88
src/cli/utils/testdata/opts.go
vendored
88
src/cli/utils/testdata/opts.go
vendored
@ -395,6 +395,94 @@ var (
|
||||
}
|
||||
)
|
||||
|
||||
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
|
||||
|
||||
@ -352,12 +352,14 @@ func (i ExchangeInfo) Values() []string {
|
||||
|
||||
// SharePointInfo describes a sharepoint item
|
||||
type SharePointInfo struct {
|
||||
ItemType ItemType `json:"itemType,omitempty"`
|
||||
ItemName string `json:"itemName,omitempty"`
|
||||
Created time.Time `json:"created,omitempty"`
|
||||
Modified time.Time `josn:"modified,omitempty"`
|
||||
WebURL string `json:"webUrl,omitempty"`
|
||||
Size int64 `json:"size,omitempty"`
|
||||
Created time.Time `json:"created,omitempty"`
|
||||
ItemName string `json:"itemName,omitempty"`
|
||||
ItemType ItemType `json:"itemType,omitempty"`
|
||||
Modified time.Time `josn:"modified,omitempty"`
|
||||
Owner string `json:"owner,omitempty"`
|
||||
ParentPath string `json:"parentPath"`
|
||||
Size int64 `json:"size,omitempty"`
|
||||
WebURL string `json:"webUrl,omitempty"`
|
||||
}
|
||||
|
||||
// Headers returns the human-readable names of properties in a SharePointInfo
|
||||
@ -374,13 +376,13 @@ func (i SharePointInfo) Values() []string {
|
||||
|
||||
// OneDriveInfo describes a oneDrive item
|
||||
type OneDriveInfo struct {
|
||||
ItemType ItemType `json:"itemType,omitempty"`
|
||||
ParentPath string `json:"parentPath"`
|
||||
ItemName string `json:"itemName"`
|
||||
Size int64 `json:"size,omitempty"`
|
||||
Owner string `json:"owner,omitempty"`
|
||||
Created time.Time `json:"created,omitempty"`
|
||||
ItemName string `json:"itemName"`
|
||||
ItemType ItemType `json:"itemType,omitempty"`
|
||||
Modified time.Time `json:"modified,omitempty"`
|
||||
Owner string `json:"owner,omitempty"`
|
||||
ParentPath string `json:"parentPath"`
|
||||
Size int64 `json:"size,omitempty"`
|
||||
}
|
||||
|
||||
// Headers returns the human-readable names of properties in a OneDriveInfo
|
||||
|
||||
68
src/pkg/selectors/testdata/details.go
vendored
68
src/pkg/selectors/testdata/details.go
vendored
@ -228,6 +228,70 @@ var (
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
SharePointRootPath = mustParsePath("tenant-id/sharepoint/site-id/libraries/drives/foo/root:", false)
|
||||
SharePointLibraryPath = mustAppendPath(SharePointRootPath, "library", false)
|
||||
SharePointBasePath1 = mustAppendPath(SharePointLibraryPath, "a", false)
|
||||
SharePointBasePath2 = mustAppendPath(SharePointLibraryPath, "b", false)
|
||||
|
||||
SharePointLibraryItemPath1 = mustAppendPath(SharePointLibraryPath, ItemName1, true)
|
||||
SharePointLibraryItemPath2 = mustAppendPath(SharePointBasePath1, ItemName2, true)
|
||||
SharePointLibraryItemPath3 = mustAppendPath(SharePointBasePath2, ItemName3, true)
|
||||
|
||||
SharePointLibraryFolder = stdpath.Join(SharePointLibraryPath.Folders()[3:]...)
|
||||
SharePointParentLibrary1 = stdpath.Join(SharePointBasePath1.Folders()[3:]...)
|
||||
SharePointParentLibrary2 = stdpath.Join(SharePointBasePath2.Folders()[3:]...)
|
||||
|
||||
SharePointLibraryItems = []details.DetailsEntry{
|
||||
{
|
||||
RepoRef: SharePointLibraryItemPath1.String(),
|
||||
ShortRef: SharePointLibraryItemPath1.ShortRef(),
|
||||
ParentRef: SharePointLibraryItemPath1.ToBuilder().Dir().ShortRef(),
|
||||
ItemInfo: details.ItemInfo{
|
||||
SharePoint: &details.SharePointInfo{
|
||||
ItemType: details.SharePointItem,
|
||||
ParentPath: SharePointLibraryFolder,
|
||||
ItemName: SharePointLibraryItemPath1.Item() + "name",
|
||||
Size: int64(23),
|
||||
Owner: UserEmail1,
|
||||
Created: Time2,
|
||||
Modified: Time4,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
RepoRef: SharePointLibraryItemPath2.String(),
|
||||
ShortRef: SharePointLibraryItemPath2.ShortRef(),
|
||||
ParentRef: SharePointLibraryItemPath2.ToBuilder().Dir().ShortRef(),
|
||||
ItemInfo: details.ItemInfo{
|
||||
SharePoint: &details.SharePointInfo{
|
||||
ItemType: details.SharePointItem,
|
||||
ParentPath: SharePointParentLibrary1,
|
||||
ItemName: SharePointLibraryItemPath2.Item() + "name",
|
||||
Size: int64(42),
|
||||
Owner: UserEmail1,
|
||||
Created: Time1,
|
||||
Modified: Time3,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
RepoRef: SharePointLibraryItemPath3.String(),
|
||||
ShortRef: SharePointLibraryItemPath3.ShortRef(),
|
||||
ParentRef: SharePointLibraryItemPath3.ToBuilder().Dir().ShortRef(),
|
||||
ItemInfo: details.ItemInfo{
|
||||
SharePoint: &details.SharePointInfo{
|
||||
ItemType: details.SharePointItem,
|
||||
ParentPath: SharePointParentLibrary2,
|
||||
ItemName: SharePointLibraryItemPath3.Item() + "name",
|
||||
Size: int64(19),
|
||||
Owner: UserEmail2,
|
||||
Created: Time2,
|
||||
Modified: Time4,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
func GetDetailsSet() *details.Details {
|
||||
@ -249,6 +313,10 @@ func GetDetailsSet() *details.Details {
|
||||
entries = append(entries, e)
|
||||
}
|
||||
|
||||
for _, e := range SharePointLibraryItems {
|
||||
entries = append(entries, e)
|
||||
}
|
||||
|
||||
return &details.Details{
|
||||
DetailsModel: details.DetailsModel{
|
||||
Entries: entries,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user