Skip to content
This repository has been archived by the owner on Oct 11, 2024. It is now read-only.

Commit

Permalink
add export support to teamschats service layer (#5126)
Browse files Browse the repository at this point in the history
more boilerplate adaptation
  • Loading branch information
ryanfkeepers authored Feb 15, 2024
1 parent 7ab1276 commit 8badbdd
Show file tree
Hide file tree
Showing 17 changed files with 906 additions and 256 deletions.
8 changes: 4 additions & 4 deletions src/cli/backup/teamschats.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
Expand Down Expand Up @@ -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,
}
Expand All @@ -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,
}
Expand Down Expand Up @@ -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,
}
Expand Down
1 change: 1 addition & 0 deletions src/cli/export/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ var exportCommands = []func(cmd *cobra.Command) *cobra.Command{
addSharePointCommands,
addGroupsCommands,
addExchangeCommands,
addTeamsChatsCommands,
}

var defaultAcceptedFormatTypes = []string{string(control.DefaultFormat)}
Expand Down
101 changes: 101 additions & 0 deletions src/cli/export/teamschats.go
Original file line number Diff line number Diff line change
@@ -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 = "<destination> --backup <backupId>"

//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 [<flag>...] <destination>`
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)
}
78 changes: 78 additions & 0 deletions src/cli/export/teamschats_test.go
Original file line number Diff line number Diff line change
@@ -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)
})
}
}
4 changes: 4 additions & 0 deletions src/internal/m365/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/alcionai/corso/src/internal/m365/service/groups"
"github.com/alcionai/corso/src/internal/m365/service/onedrive"
"github.com/alcionai/corso/src/internal/m365/service/sharepoint"
"github.com/alcionai/corso/src/internal/m365/service/teamschats"
"github.com/alcionai/corso/src/internal/operations/inject"
"github.com/alcionai/corso/src/pkg/path"
)
Expand All @@ -30,6 +31,9 @@ func (ctrl *Controller) NewServiceHandler(

case path.ExchangeService:
return exchange.NewExchangeHandler(ctrl.AC, ctrl.resourceHandler), nil

case path.TeamsChatsService:
return teamschats.NewTeamsChatsHandler(ctrl.AC, ctrl.resourceHandler), nil
}

return nil, clues.New("unrecognized service").
Expand Down
13 changes: 7 additions & 6 deletions src/internal/m365/service/groups/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"github.com/alcionai/clues"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"

"github.com/alcionai/corso/src/internal/data"
Expand Down Expand Up @@ -79,7 +80,7 @@ func (suite *ExportUnitSuite) TestExportRestoreCollections_messages() {
)

p, err := path.Build("t", "pr", path.GroupsService, path.ChannelMessagesCategory, false, containerName)
assert.NoError(t, err, "build path")
require.NoError(t, err, clues.ToCore(err))

dcs := []data.RestoreCollection{
data.FetchRestoreCollection{
Expand All @@ -106,7 +107,7 @@ func (suite *ExportUnitSuite) TestExportRestoreCollections_messages() {
dcs,
stats,
fault.New(true))
assert.NoError(t, err, "export collections error")
require.NoError(t, err, clues.ToCore(err))
assert.Len(t, ecs, 1, "num of collections")

assert.Equal(t, expectedPath, ecs[0].BasePath(), "base dir")
Expand All @@ -117,7 +118,7 @@ func (suite *ExportUnitSuite) TestExportRestoreCollections_messages() {

for item := range ecs[0].Items(ctx) {
b, err := io.ReadAll(item.Body)
assert.NoError(t, err, clues.ToCore(err))
require.NoError(t, err, clues.ToCore(err))

// count up size for tests
size += len(b)
Expand Down Expand Up @@ -181,7 +182,7 @@ func (suite *ExportUnitSuite) TestExportRestoreCollections_libraries() {
false,
odConsts.SitesPathDir,
siteID)
assert.NoError(t, err, "build path")
require.NoError(t, err, clues.ToCore(err))

dcs := []data.RestoreCollection{
data.FetchRestoreCollection{
Expand Down Expand Up @@ -210,7 +211,7 @@ func (suite *ExportUnitSuite) TestExportRestoreCollections_libraries() {
dcs,
stats,
fault.New(true))
assert.NoError(t, err, "export collections error")
require.NoError(t, err, clues.ToCore(err))
assert.Len(t, ecs, 1, "num of collections")

assert.Equal(t, expectedPath, ecs[0].BasePath(), "base dir")
Expand All @@ -222,7 +223,7 @@ func (suite *ExportUnitSuite) TestExportRestoreCollections_libraries() {
for item := range ecs[0].Items(ctx) {
// unwrap the body from stats reader
b, err := io.ReadAll(item.Body)
assert.NoError(t, err, clues.ToCore(err))
require.NoError(t, err, clues.ToCore(err))

size += len(b)
bitem := io.NopCloser(bytes.NewBuffer(b))
Expand Down
Loading

0 comments on commit 8badbdd

Please sign in to comment.