diff --git a/src/cli/backup/teamschats.go b/src/cli/backup/teamschats.go index e4318bdbf..210a1e027 100644 --- a/src/cli/backup/teamschats.go +++ b/src/cli/backup/teamschats.go @@ -102,7 +102,7 @@ func teamschatsCreateCmd() *cobra.Command { return &cobra.Command{ Use: teamschatsServiceCommand, Aliases: []string{teamsServiceCommand}, - Short: "Backup M365 Chats service data", + Short: "Backup M365 Chats data", RunE: createTeamsChatsCmd, Args: cobra.NoArgs, } @@ -170,7 +170,7 @@ func createTeamsChatsCmd(cmd *cobra.Command, args []string) error { func teamschatsListCmd() *cobra.Command { return &cobra.Command{ Use: teamschatsServiceCommand, - Short: "List the history of M365 TeamsChats service backups", + Short: "List the history of M365 Chats backups", RunE: listTeamsChatsCmd, Args: cobra.NoArgs, } @@ -189,7 +189,7 @@ func listTeamsChatsCmd(cmd *cobra.Command, args []string) error { func teamschatsDetailsCmd() *cobra.Command { return &cobra.Command{ Use: teamschatsServiceCommand, - Short: "Shows the details of a M365 TeamsChats service backup", + Short: "Shows the details of a M365 Chats backup", RunE: detailsTeamsChatsCmd, Args: cobra.NoArgs, } @@ -237,7 +237,7 @@ func runDetailsTeamsChatsCmd(cmd *cobra.Command) error { func teamschatsDeleteCmd() *cobra.Command { return &cobra.Command{ Use: teamschatsServiceCommand, - Short: "Delete backed-up M365 TeamsChats service data", + Short: "Delete backed-up M365 Chats data", RunE: deleteTeamsChatsCmd, Args: cobra.NoArgs, } diff --git a/src/cli/export/export.go b/src/cli/export/export.go index 1b5a40d69..e10270bb2 100644 --- a/src/cli/export/export.go +++ b/src/cli/export/export.go @@ -25,6 +25,7 @@ var exportCommands = []func(cmd *cobra.Command) *cobra.Command{ addSharePointCommands, addGroupsCommands, addExchangeCommands, + addTeamsChatsCommands, } var defaultAcceptedFormatTypes = []string{string(control.DefaultFormat)} diff --git a/src/cli/export/teamschats.go b/src/cli/export/teamschats.go new file mode 100644 index 000000000..7ca66e5d4 --- /dev/null +++ b/src/cli/export/teamschats.go @@ -0,0 +1,101 @@ +package export + +import ( + "github.com/pkg/errors" + "github.com/spf13/cobra" + + "github.com/alcionai/corso/src/cli/flags" + "github.com/alcionai/corso/src/cli/utils" + "github.com/alcionai/corso/src/pkg/control" +) + +// called by export.go to map subcommands to provider-specific handling. +func addTeamsChatsCommands(cmd *cobra.Command) *cobra.Command { + var c *cobra.Command + + switch cmd.Use { + case exportCommand: + c, _ = utils.AddCommand(cmd, teamschatsExportCmd(), utils.MarkPreviewCommand()) + + c.Use = c.Use + " " + teamschatsServiceCommandUseSuffix + + flags.AddBackupIDFlag(c, true) + flags.AddTeamsChatsDetailsAndRestoreFlags(c) + flags.AddExportConfigFlags(c) + flags.AddFailFastFlag(c) + } + + return c +} + +const ( + teamschatsServiceCommand = "chats" + teamschatsServiceCommandUseSuffix = " --backup " + + //nolint:lll + teamschatsServiceCommandExportExamples = `# Export a specific chat from the last backup (1234abcd...) to /my-exports +corso export chats my-exports --backup 1234abcd-12ab-cd34-56de-1234abcd --chat 98765abcdef + +# Export all of Bob's chats to the current directory +corso export chats . --backup 1234abcd-12ab-cd34-56de-1234abcd \ + --chat '*' + +# Export all chats that were created before 2020 to /my-exports +corso export chats my-exports --backup 1234abcd-12ab-cd34-56de-1234abcd + --chat-created-before 2020-01-01T00:00:00` +) + +// `corso export chats [...] ` +func teamschatsExportCmd() *cobra.Command { + return &cobra.Command{ + Use: teamschatsServiceCommand, + Aliases: []string{teamsServiceCommand}, + Short: "Export M365 Chats data", + RunE: exportTeamsChatsCmd, + Args: func(cmd *cobra.Command, args []string) error { + if len(args) != 1 { + return errors.New("missing export destination") + } + + return nil + }, + Example: teamschatsServiceCommandExportExamples, + } +} + +// processes an teamschats service export. +func exportTeamsChatsCmd(cmd *cobra.Command, args []string) error { + ctx := cmd.Context() + + if utils.HasNoFlagsAndShownHelp(cmd) { + return nil + } + + opts := utils.MakeTeamsChatsOpts(cmd) + + if flags.RunModeFV == flags.RunModeFlagTest { + return nil + } + + if err := utils.ValidateTeamsChatsRestoreFlags(flags.BackupIDFV, opts, false); err != nil { + return err + } + + sel := utils.IncludeTeamsChatsRestoreDataSelectors(ctx, opts) + utils.FilterTeamsChatsRestoreInfoSelectors(sel, opts) + + acceptedTeamsChatsFormatTypes := []string{ + string(control.DefaultFormat), + string(control.JSONFormat), + } + + return runExport( + ctx, + cmd, + args, + opts.ExportCfg, + sel.Selector, + flags.BackupIDFV, + "Chats", + acceptedTeamsChatsFormatTypes) +} diff --git a/src/cli/export/teamschats_test.go b/src/cli/export/teamschats_test.go new file mode 100644 index 000000000..841d026eb --- /dev/null +++ b/src/cli/export/teamschats_test.go @@ -0,0 +1,78 @@ +package export + +import ( + "testing" + + "github.com/spf13/cobra" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" + + "github.com/alcionai/corso/src/cli/flags" + flagsTD "github.com/alcionai/corso/src/cli/flags/testdata" + cliTD "github.com/alcionai/corso/src/cli/testdata" + "github.com/alcionai/corso/src/cli/utils" + "github.com/alcionai/corso/src/internal/tester" +) + +type TeamsChatsUnitSuite struct { + tester.Suite +} + +func TestTeamsChatsUnitSuite(t *testing.T) { + suite.Run(t, &TeamsChatsUnitSuite{Suite: tester.NewUnitSuite(t)}) +} + +func (suite *TeamsChatsUnitSuite) TestAddTeamsChatsCommands() { + expectUse := teamschatsServiceCommand + " " + teamschatsServiceCommandUseSuffix + + table := []struct { + name string + use string + expectUse string + expectShort string + expectRunE func(*cobra.Command, []string) error + }{ + {"export teamschats", exportCommand, expectUse, teamschatsExportCmd().Short, exportTeamsChatsCmd}, + } + for _, test := range table { + suite.Run(test.name, func() { + t := suite.T() + parent := &cobra.Command{Use: exportCommand} + + cmd := cliTD.SetUpCmdHasFlags( + t, + parent, + addTeamsChatsCommands, + []cliTD.UseCobraCommandFn{ + flags.AddAllProviderFlags, + flags.AddAllStorageFlags, + }, + flagsTD.WithFlags( + teamschatsServiceCommand, + []string{ + flagsTD.RestoreDestination, + "--" + flags.RunModeFN, flags.RunModeFlagTest, + "--" + flags.BackupFN, flagsTD.BackupInput, + "--" + flags.FormatFN, flagsTD.FormatType, + "--" + flags.ArchiveFN, + }, + flagsTD.PreparedProviderFlags(), + flagsTD.PreparedStorageFlags())) + + cliTD.CheckCmdChild( + t, + parent, + 3, + test.expectUse, + test.expectShort, + test.expectRunE) + + opts := utils.MakeTeamsChatsOpts(cmd) + + assert.Equal(t, flagsTD.BackupInput, flags.BackupIDFV) + assert.Equal(t, flagsTD.Archive, opts.ExportCfg.Archive) + assert.Equal(t, flagsTD.FormatType, opts.ExportCfg.Format) + flagsTD.AssertStorageFlags(t, cmd) + }) + } +}