OneDrive get and delete folder functions (#1093)

## Description

Useful helper functions for the purge script

## Type of change

<!--- Please check the type of change your PR introduces: --->
- [x] 🌻 Feature
- [ ] 🐛 Bugfix
- [ ] 🗺️ Documentation
- [ ] 🤖 Test
- [ ] 💻 CI/Deployment
- [ ] 🐹 Trivial/Minor

## Issue(s)

* #1090 

## Test Plan

<!-- How will this be tested prior to merging.-->
- [ ] 💪 Manual
- [x]  Unit test
- [ ] 💚 E2E
This commit is contained in:
ashmrtn 2022-10-07 18:34:15 -07:00 committed by GitHub
parent a5140d20b2
commit dd7710ca5b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 215 additions and 0 deletions

View File

@ -3,6 +3,7 @@ package onedrive
import (
"context"
"fmt"
"strings"
"github.com/microsoftgraph/msgraph-sdk-go/drives/item/items"
"github.com/microsoftgraph/msgraph-sdk-go/drives/item/items/item"
@ -158,3 +159,70 @@ func newItem(name string, folder bool) models.DriveItemable {
return itemToCreate
}
// GetAllFolders returns all folders in all drives for the given user. If a
// prefix is given, returns all folders with that prefix, regardless of if they
// are a subfolder or top-level folder in the hierarchy.
func GetAllFolders(
ctx context.Context,
gs graph.Service,
userID string,
prefix string,
) ([]models.DriveItemable, error) {
drives, err := drives(ctx, gs, userID)
if err != nil {
return nil, errors.Wrap(err, "getting OneDrive folders")
}
res := []models.DriveItemable{}
for _, d := range drives {
err = collectItems(
ctx,
gs,
*d.GetId(),
func(innerCtx context.Context, driveID string, items []models.DriveItemable) error {
for _, item := range items {
// Skip the root item.
if item.GetRoot() != nil {
continue
}
// Only selecting folders right now, not packages.
if item.GetFolder() == nil {
continue
}
if !strings.HasPrefix(*item.GetName(), prefix) {
continue
}
// Add the item instead of the folder because the item has more
// functionality.
res = append(res, item)
}
return nil
},
)
if err != nil {
return nil, errors.Wrapf(err, "getting items for drive %s", *d.GetName())
}
}
return res, nil
}
func DeleteItem(
ctx context.Context,
gs graph.Service,
driveID string,
itemID string,
) error {
err := gs.Client().DrivesById(driveID).ItemsById(itemID).Delete(ctx, nil)
if err != nil {
return errors.Wrapf(err, "deleting item with ID %s", itemID)
}
return nil
}

View File

@ -0,0 +1,146 @@
package onedrive
import (
"context"
"strings"
"testing"
msgraphsdk "github.com/microsoftgraph/msgraph-sdk-go"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
"github.com/alcionai/corso/src/internal/common"
"github.com/alcionai/corso/src/internal/connector/graph"
"github.com/alcionai/corso/src/internal/tester"
"github.com/alcionai/corso/src/pkg/account"
)
// TODO(ashmrtn): Merge with similar structs in graph and exchange packages.
type testService struct {
adapter msgraphsdk.GraphRequestAdapter
client msgraphsdk.GraphServiceClient
failFast bool
credentials account.M365Config
}
func (ts *testService) Client() *msgraphsdk.GraphServiceClient {
return &ts.client
}
func (ts *testService) Adapter() *msgraphsdk.GraphRequestAdapter {
return &ts.adapter
}
func (ts *testService) ErrPolicy() bool {
return ts.failFast
}
// TODO(ashmrtn): Merge with similar functions in connector and exchange
// packages.
func loadService(t *testing.T) *testService {
a := tester.NewM365Account(t)
m365, err := a.M365Config()
require.NoError(t, err)
adapter, err := graph.CreateAdapter(
m365.TenantID,
m365.ClientID,
m365.ClientSecret,
)
require.NoError(t, err)
service := &testService{
adapter: *adapter,
client: *msgraphsdk.NewGraphServiceClient(adapter),
failFast: false,
credentials: m365,
}
return service
}
type OneDriveSuite struct {
suite.Suite
userID string
}
func TestOneDriveDriveSuite(t *testing.T) {
if err := tester.RunOnAny(
tester.CorsoCITests,
tester.CorsoOneDriveTests,
); err != nil {
t.Skip(err)
}
suite.Run(t, new(OneDriveSuite))
}
func (suite *OneDriveSuite) SetupSuite() {
suite.userID = tester.M365UserID(suite.T())
}
func (suite *OneDriveSuite) TestCreateGetDeleteFolder() {
t := suite.T()
ctx := context.Background()
folderIDs := []string{}
folderName1 := "Corso_Folder_Test_" + common.FormatNow(common.SimpleTimeTesting)
folderElements := []string{folderName1}
gs := loadService(t)
drives, err := drives(ctx, gs, suite.userID)
require.NoError(t, err)
require.NotEmpty(t, drives)
driveID := *drives[0].GetId()
folderID, err := createRestoreFolders(ctx, gs, driveID, folderElements)
require.NoError(t, err)
folderIDs = append(folderIDs, folderID)
defer func() {
assert.NoError(t, DeleteItem(ctx, gs, driveID, folderIDs[0]))
}()
folderName2 := "Corso_Folder_Test_" + common.FormatNow(common.SimpleTimeTesting)
folderElements = append(folderElements, folderName2)
folderID, err = createRestoreFolders(ctx, gs, driveID, folderElements)
require.NoError(t, err)
folderIDs = append(folderIDs, folderID)
table := []struct {
name string
prefix string
}{
{
name: "NoPrefix",
prefix: "",
},
{
name: "Prefix",
prefix: "Corso_Folder_Test",
},
}
for _, test := range table {
suite.T().Run(test.name, func(t *testing.T) {
allFolders, err := GetAllFolders(ctx, gs, suite.userID, test.prefix)
require.NoError(t, err)
foundFolderIDs := []string{}
for _, f := range allFolders {
if *f.GetName() == folderName1 || *f.GetName() == folderName2 {
foundFolderIDs = append(foundFolderIDs, *f.GetId())
}
assert.True(t, strings.HasPrefix(*f.GetName(), test.prefix), "folder prefix")
}
assert.ElementsMatch(t, folderIDs, foundFolderIDs)
})
}
}

View File

@ -19,6 +19,7 @@ const (
CorsoGraphConnectorTests = "CORSO_GRAPH_CONNECTOR_TESTS"
CorsoKopiaWrapperTests = "CORSO_KOPIA_WRAPPER_TESTS"
CorsoModelStoreTests = "CORSO_MODEL_STORE_TESTS"
CorsoOneDriveTests = "CORSO_ONE_DRIVE_TESTS"
CorsoOperationTests = "CORSO_OPERATION_TESTS"
CorsoRepositoryTests = "CORSO_REPOSITORY_TESTS"
)