Switch to using path categories in graph connector (#734)

Will help make later PRs easier as the category will already be known.

## Description

<!-- Insert PR description-->

## Type of change

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

## Issue(s)
<!-- Can reference multiple issues. Use one of the following "magic words" - "closes, fixes" to auto-close the Github issue. -->
on path to:
* #456 

## Test Plan

<!-- How will this be tested prior to merging.-->

- [ ] 💪 Manual
- [x]  Unit test
- [ ] 💚 E2E
This commit is contained in:
ashmrtn 2022-09-02 13:12:22 -07:00 committed by GitHub
parent b1cd472483
commit 12f61dd71c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 52 additions and 48 deletions

View File

@ -12,6 +12,7 @@ import (
"github.com/alcionai/corso/internal/common"
"github.com/alcionai/corso/internal/connector/graph"
"github.com/alcionai/corso/internal/connector/mockconnector"
"github.com/alcionai/corso/internal/path"
"github.com/alcionai/corso/internal/tester"
"github.com/alcionai/corso/pkg/account"
"github.com/alcionai/corso/pkg/control"
@ -457,37 +458,37 @@ func (suite *ExchangeServiceSuite) TestRestoreEvent() {
func (suite *ExchangeServiceSuite) TestGetRestoreContainer() {
tests := []struct {
name string
option string
option path.CategoryType
checkError assert.ErrorAssertionFunc
cleanupFunc func(graph.Service, string, string) error
}{
{
name: "Establish User Restore Folder",
option: "users",
option: path.CategoryType(-1),
checkError: assert.Error,
cleanupFunc: nil,
},
{
name: "Establish Event Restore Location",
option: "events",
option: path.EventsCategory,
checkError: assert.NoError,
cleanupFunc: DeleteCalendar,
},
{
name: "Establish Restore Folder for Unknown",
option: "unknown",
option: path.UnknownCategory,
checkError: assert.Error,
cleanupFunc: nil,
},
{
name: "Establish Restore folder for Mail",
option: "mail",
option: path.EmailCategory,
checkError: assert.NoError,
cleanupFunc: DeleteMailFolder,
},
{
name: "Establish Restore folder for Contacts",
option: "contacts",
option: path.ContactsCategory,
checkError: assert.NoError,
cleanupFunc: DeleteContactFolder,
},

View File

@ -13,6 +13,8 @@ import (
msmessage "github.com/microsoftgraph/msgraph-sdk-go/users/item/messages"
msitem "github.com/microsoftgraph/msgraph-sdk-go/users/item/messages/item"
"github.com/pkg/errors"
"github.com/alcionai/corso/internal/path"
)
//-----------------------------------------------------------------------
@ -99,19 +101,13 @@ const (
contacts
)
const (
mailCategory = "mail"
contactsCategory = "contacts"
eventsCategory = "events"
)
func categoryToOptionIdentifier(category string) optionIdentifier {
func categoryToOptionIdentifier(category path.CategoryType) optionIdentifier {
switch category {
case mailCategory:
case path.EmailCategory:
return messages
case contactsCategory:
case path.ContactsCategory:
return contacts
case eventsCategory:
case path.EventsCategory:
return events
default:
return unknown

View File

@ -14,6 +14,7 @@ import (
"github.com/alcionai/corso/internal/common"
"github.com/alcionai/corso/internal/connector/graph"
"github.com/alcionai/corso/internal/connector/support"
"github.com/alcionai/corso/internal/path"
"github.com/alcionai/corso/pkg/account"
"github.com/alcionai/corso/pkg/control"
"github.com/alcionai/corso/pkg/logger"
@ -302,7 +303,8 @@ func SetupExchangeCollectionVars(scope selectors.ExchangeScope) (
// that defines the application the folder is created in.
func GetRestoreContainer(
service graph.Service,
user, category string,
user string,
category path.CategoryType,
) (string, error) {
name := fmt.Sprintf("Corso_Restore_%s", common.FormatNow(common.SimpleDateTimeFormat))
option := categoryToOptionIdentifier(category)
@ -346,7 +348,7 @@ func GetRestoreContainer(
func RestoreExchangeObject(
ctx context.Context,
bits []byte,
category string,
category path.CategoryType,
policy control.CollisionPolicy,
service graph.Service,
destination, user string,
@ -354,7 +356,7 @@ func RestoreExchangeObject(
var setting optionIdentifier
switch category {
case mailCategory, contactsCategory:
case path.EmailCategory, path.ContactsCategory:
setting = categoryToOptionIdentifier(category)
default:
return fmt.Errorf("type: %s not supported for exchange restore", category)

View File

@ -9,6 +9,7 @@ import (
"github.com/alcionai/corso/internal/connector/graph"
"github.com/alcionai/corso/internal/connector/support"
"github.com/alcionai/corso/internal/path"
"github.com/alcionai/corso/pkg/selectors"
)
@ -50,7 +51,7 @@ func IterateSelectAllDescendablesForCollections(
var (
isCategorySet bool
collectionType optionIdentifier
category string
category path.CategoryType
)
return func(pageItem any) bool {
@ -58,12 +59,12 @@ func IterateSelectAllDescendablesForCollections(
if !isCategorySet {
if qp.Scope.IncludesCategory(selectors.ExchangeMail) {
collectionType = messages
category = mailCategory
category = path.EmailCategory
}
if qp.Scope.IncludesCategory(selectors.ExchangeContact) {
collectionType = contacts
category = contactsCategory
category = path.ContactsCategory
}
isCategorySet = true
@ -85,7 +86,7 @@ func IterateSelectAllDescendablesForCollections(
edc := NewCollection(
qp.User,
[]string{qp.Credentials.TenantID, qp.User, category, directory},
[]string{qp.Credentials.TenantID, qp.User, category.String(), directory},
collectionType,
service,
statusUpdater,
@ -167,7 +168,7 @@ func IterateSelectAllEventsForCollections(
edc := NewCollection(
qp.User,
[]string{qp.Credentials.TenantID, qp.User, eventsCategory, directory},
[]string{qp.Credentials.TenantID, qp.User, path.EventsCategory.String(), directory},
events,
service,
statusUpdater,
@ -276,7 +277,7 @@ func IterateFilterFolderDirectoriesForCollections(
temp := NewCollection(
qp.User,
[]string{qp.Credentials.TenantID, qp.User, mailCategory, directory},
[]string{qp.Credentials.TenantID, qp.User, path.EmailCategory.String(), directory},
messages,
service,
statusUpdater,

View File

@ -18,6 +18,7 @@ import (
"github.com/alcionai/corso/internal/connector/graph"
"github.com/alcionai/corso/internal/connector/support"
"github.com/alcionai/corso/internal/data"
"github.com/alcionai/corso/internal/path"
"github.com/alcionai/corso/pkg/account"
"github.com/alcionai/corso/pkg/control"
"github.com/alcionai/corso/pkg/selectors"
@ -260,8 +261,9 @@ func (gc *GraphConnector) RestoreExchangeDataCollection(
directory = strings.Join(dc.FullPath(), "")
user = dc.FullPath()[1]
items = dc.Items()
category = dc.FullPath()[2]
exit bool
// TODO(ashmrtn): Update this when we have path struct support in collections.
category = path.ToCategoryType(dc.FullPath()[2])
exit bool
)
if _, ok := pathCounter[directory]; !ok {

View File

@ -17,6 +17,7 @@ import (
"github.com/alcionai/corso/internal/connector/mockconnector"
"github.com/alcionai/corso/internal/connector/support"
"github.com/alcionai/corso/internal/data"
"github.com/alcionai/corso/internal/path"
"github.com/alcionai/corso/internal/tester"
"github.com/alcionai/corso/pkg/selectors"
)
@ -245,13 +246,13 @@ func (suite *GraphConnectorIntegrationSuite) TestEventsSerializationRegression()
// The result should be all successful items restored within the same folder.
func (suite *GraphConnectorIntegrationSuite) TestRestoreMessages() {
t := suite.T()
category := "mail"
category := path.EmailCategory
connector := loadConnector(t)
collection := make([]data.Collection, 0)
for i := 0; i < 3; i++ {
mdc := mockconnector.NewMockExchangeCollection(
[]string{"tenant", suite.user, category, "Inbox"},
[]string{"tenant", suite.user, category.String(), "Inbox"},
1)
collection = append(collection, mdc)
}

View File

@ -566,7 +566,7 @@ func (suite *ModelStoreRegressionSuite) TestMultipleConfigs() {
deets.Entries = append(
deets.Entries,
details.DetailsEntry{
RepoRef: fmt.Sprintf("exchange/user1/mail/inbox/mail%v", i),
RepoRef: fmt.Sprintf("exchange/user1/email/inbox/mail%v", i),
ItemInfo: details.ItemInfo{
Exchange: &details.ExchangeInfo{
Sender: "John Doe",

View File

@ -27,7 +27,7 @@ import (
const (
testTenant = "a-tenant"
testUser = "user1"
testEmailDir = "mail"
testEmailDir = "email"
testInboxDir = "inbox"
testArchiveDir = "archive"
testFileName = "file1"

View File

@ -33,7 +33,7 @@ const (
EventsCategory // events
)
func toCategoryType(category string) CategoryType {
func ToCategoryType(category string) CategoryType {
switch category {
case EmailCategory.String():
return EmailCategory
@ -59,7 +59,7 @@ func validateServiceAndCategory(s, c string) (ServiceType, CategoryType, error)
// Validity of service checked on first-level lookup to serviceCategories.
service := toServiceType(s)
category := toCategoryType(c)
category := ToCategoryType(c)
if category == UnknownCategory {
return UnknownService, UnknownCategory, errors.Errorf("unknown category string %q", c)
}

View File

@ -777,7 +777,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeScope_MatchesPath() {
)
var (
path = []string{"tid", usr, "mail", fld, mail}
path = []string{"tid", usr, "email", fld, mail}
es = NewExchangeRestore()
)
@ -843,7 +843,7 @@ func (suite *ExchangeSelectorSuite) TestIdPath() {
},
{
ExchangeMail,
[]string{"tid", "uid", "mail", "mFld", "mid"},
[]string{"tid", "uid", "email", "mFld", "mid"},
map[exchangeCategory]string{
ExchangeUser: "uid",
ExchangeMailFolder: "mFld",
@ -883,7 +883,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeRestore_Reduce() {
const (
contact = "tid/uid/contacts/cfld/cid"
event = "tid/uid/events/ecld/eid"
mail = "tid/uid/mail/mfld/mid"
mail = "tid/uid/email/mfld/mid"
)
arr := func(s ...string) []string {
@ -1090,7 +1090,7 @@ func (suite *ExchangeSelectorSuite) TestPasses() {
mail = setScopesToDefault(es.Mails(Any(), Any(), []string{mid}))
otherMail = setScopesToDefault(es.Mails(Any(), Any(), []string{"smarf"}))
noMail = setScopesToDefault(es.Mails(Any(), Any(), None()))
path = []string{"tid", "user", "mail", "folder", mid}
path = []string{"tid", "user", "email", "folder", mid}
)
table := []struct {
@ -1175,7 +1175,7 @@ func (suite *ExchangeSelectorSuite) TestIsAny() {
es = NewExchangeRestore()
anyUser = setScopesToDefault(es.Users(Any()))
noUser = setScopesToDefault(es.Users(None()))
specificMail = setScopesToDefault(es.Mails(Any(), Any(), []string{"mail"}))
specificMail = setScopesToDefault(es.Mails(Any(), Any(), []string{"email"}))
anyMail = setScopesToDefault(es.Mails(Any(), Any(), Any()))
)

View File

@ -3,6 +3,7 @@ package selectors
import (
"strings"
"github.com/alcionai/corso/internal/path"
"github.com/alcionai/corso/pkg/backup/details"
"github.com/alcionai/corso/pkg/filters"
)
@ -240,16 +241,16 @@ func reduce[T scopeT, C categoryT](
// for each entry, compare that entry against the scopes of the same data type
for _, ent := range deets.Entries {
// todo: use Path pkg for this
path := strings.Split(ent.RepoRef, "/")
repoPath := strings.Split(ent.RepoRef, "/")
dc, ok := dataCategories[pathTypeIn(path)]
dc, ok := dataCategories[pathTypeIn(repoPath)]
if !ok {
continue
}
passed := passes(
dc,
dc.pathValues(path),
dc.pathValues(repoPath),
ent,
excls[dc],
filts[dc],
@ -283,19 +284,19 @@ const (
// package. It should get handled in paths, since that's where service- and
// data-type-specific assertions are owned.
// Ideally, we'd use something like path.DataType() instead of this func.
func pathTypeIn(path []string) pathType {
func pathTypeIn(p []string) pathType {
// not all paths will be len=3. Most should be longer.
// This just protects us from panicing below.
if len(path) < 3 {
if len(p) < 3 {
return unknownPathType
}
switch path[2] {
case "mail":
switch p[2] {
case path.EmailCategory.String():
return exchangeMailPath
case "contacts":
case path.ContactsCategory.String():
return exchangeContactPath
case "events":
case path.EventsCategory.String():
return exchangeEventPath
}

View File

@ -243,7 +243,7 @@ func (suite *SelectorScopesSuite) TestReduce() {
func (suite *SelectorScopesSuite) TestPathTypeIn() {
t := suite.T()
assert.Equal(t, unknownPathType, pathTypeIn([]string{}), "empty")
assert.Equal(t, exchangeMailPath, pathTypeIn([]string{"", "", "mail"}), "mail")
assert.Equal(t, exchangeMailPath, pathTypeIn([]string{"", "", "email"}), "email")
assert.Equal(t, exchangeContactPath, pathTypeIn([]string{"", "", "contacts"}), "contact")
assert.Equal(t, exchangeEventPath, pathTypeIn([]string{"", "", "events"}), "event")
assert.Equal(t, unknownPathType, pathTypeIn([]string{"", "", "fnords"}), "bogus")