remove discovery pkg (#3677)
Currently unused, and functionality is largely duplicated by the services/m365 package. --- #### Does this PR need a docs update or release note? - [x] ⛔ No #### Type of change - [ ] 🧹 Tech Debt/Cleanup #### Test Plan - [x] ⚡ Unit test - [x] 💚 E2E
This commit is contained in:
parent
8b81728488
commit
56151a82eb
@ -31,6 +31,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Handle OLE conversion errors when trying to fetch attachments
|
- Handle OLE conversion errors when trying to fetch attachments
|
||||||
- Fix uploading large attachments for emails and calendar
|
- Fix uploading large attachments for emails and calendar
|
||||||
- Fixed high memory use in OneDrive backup related to logging
|
- Fixed high memory use in OneDrive backup related to logging
|
||||||
|
- Return a ServiceNotEnabled error when a tenant has no active SharePoint license.
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- Switched to Go 1.20
|
- Switched to Go 1.20
|
||||||
|
|||||||
@ -10,7 +10,6 @@ import (
|
|||||||
"github.com/alcionai/corso/src/internal/common/prefixmatcher"
|
"github.com/alcionai/corso/src/internal/common/prefixmatcher"
|
||||||
"github.com/alcionai/corso/src/internal/data"
|
"github.com/alcionai/corso/src/internal/data"
|
||||||
"github.com/alcionai/corso/src/internal/diagnostics"
|
"github.com/alcionai/corso/src/internal/diagnostics"
|
||||||
"github.com/alcionai/corso/src/internal/m365/discovery"
|
|
||||||
"github.com/alcionai/corso/src/internal/m365/exchange"
|
"github.com/alcionai/corso/src/internal/m365/exchange"
|
||||||
"github.com/alcionai/corso/src/internal/m365/graph"
|
"github.com/alcionai/corso/src/internal/m365/graph"
|
||||||
"github.com/alcionai/corso/src/internal/m365/onedrive"
|
"github.com/alcionai/corso/src/internal/m365/onedrive"
|
||||||
@ -21,6 +20,7 @@ import (
|
|||||||
"github.com/alcionai/corso/src/pkg/logger"
|
"github.com/alcionai/corso/src/pkg/logger"
|
||||||
"github.com/alcionai/corso/src/pkg/path"
|
"github.com/alcionai/corso/src/pkg/path"
|
||||||
"github.com/alcionai/corso/src/pkg/selectors"
|
"github.com/alcionai/corso/src/pkg/selectors"
|
||||||
|
"github.com/alcionai/corso/src/pkg/services/m365/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@ -203,9 +203,13 @@ func verifyBackupInputs(sels selectors.Selector, siteIDs []string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type getInfoer interface {
|
||||||
|
GetInfo(context.Context, string) (*api.UserInfo, error)
|
||||||
|
}
|
||||||
|
|
||||||
func checkServiceEnabled(
|
func checkServiceEnabled(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
gi discovery.GetInfoer,
|
gi getInfoer,
|
||||||
service path.ServiceType,
|
service path.ServiceType,
|
||||||
resource string,
|
resource string,
|
||||||
) (bool, bool, error) {
|
) (bool, bool, error) {
|
||||||
|
|||||||
@ -1,150 +0,0 @@
|
|||||||
package discovery
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/alcionai/clues"
|
|
||||||
"github.com/microsoftgraph/msgraph-sdk-go/models"
|
|
||||||
|
|
||||||
"github.com/alcionai/corso/src/internal/m365/graph"
|
|
||||||
"github.com/alcionai/corso/src/pkg/account"
|
|
||||||
"github.com/alcionai/corso/src/pkg/fault"
|
|
||||||
"github.com/alcionai/corso/src/pkg/services/m365/api"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// interfaces
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
type getter interface {
|
|
||||||
GetByID(context.Context, string) (models.Userable, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type GetInfoer interface {
|
|
||||||
GetInfo(context.Context, string) (*api.UserInfo, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type getWithInfoer interface {
|
|
||||||
getter
|
|
||||||
GetInfoer
|
|
||||||
}
|
|
||||||
|
|
||||||
type GetDefaultDriver interface {
|
|
||||||
GetDefaultDrive(ctx context.Context, userID string) (models.Driveable, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type getAller interface {
|
|
||||||
GetAll(ctx context.Context, errs *fault.Bus) ([]models.Userable, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// helpers
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
func apiClient(ctx context.Context, acct account.Account) (api.Client, error) {
|
|
||||||
m365, err := acct.M365Config()
|
|
||||||
if err != nil {
|
|
||||||
return api.Client{}, clues.Wrap(err, "retrieving m365 account configuration").WithClues(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
client, err := api.NewClient(m365)
|
|
||||||
if err != nil {
|
|
||||||
return api.Client{}, clues.Wrap(err, "creating api client").WithClues(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
return client, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// users
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Users fetches all users in the tenant.
|
|
||||||
func Users(
|
|
||||||
ctx context.Context,
|
|
||||||
ga getAller,
|
|
||||||
errs *fault.Bus,
|
|
||||||
) ([]models.Userable, error) {
|
|
||||||
users, err := ga.GetAll(ctx, errs)
|
|
||||||
if err != nil {
|
|
||||||
return nil, clues.Wrap(err, "getting all users")
|
|
||||||
}
|
|
||||||
|
|
||||||
return users, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UserDetails fetches detailed info like - userPurpose for all users in the tenant.
|
|
||||||
func GetUserInfo(
|
|
||||||
ctx context.Context,
|
|
||||||
acct account.Account,
|
|
||||||
userID string,
|
|
||||||
errs *fault.Bus,
|
|
||||||
) (*api.UserInfo, error) {
|
|
||||||
client, err := apiClient(ctx, acct)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
aui, err := client.Users().GetInfo(ctx, userID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, clues.Stack(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return aui, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// User fetches a single user's data.
|
|
||||||
func User(
|
|
||||||
ctx context.Context,
|
|
||||||
gwi getWithInfoer,
|
|
||||||
userID string,
|
|
||||||
) (models.Userable, *api.UserInfo, error) {
|
|
||||||
u, err := gwi.GetByID(ctx, userID)
|
|
||||||
if err != nil {
|
|
||||||
if graph.IsErrUserNotFound(err) {
|
|
||||||
return nil, nil, clues.Stack(graph.ErrResourceOwnerNotFound, err).With("user_id", userID)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, nil, clues.Wrap(err, "getting user")
|
|
||||||
}
|
|
||||||
|
|
||||||
ui, err := gwi.GetInfo(ctx, userID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, clues.Wrap(err, "getting user info")
|
|
||||||
}
|
|
||||||
|
|
||||||
return u, ui, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UserInfo produces extensible user info: metadata that is relevant
|
|
||||||
// or identified in Corso, but not in m365.
|
|
||||||
func UserInfo(
|
|
||||||
ctx context.Context,
|
|
||||||
gi GetInfoer,
|
|
||||||
userID string,
|
|
||||||
) (*api.UserInfo, error) {
|
|
||||||
ui, err := gi.GetInfo(ctx, userID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, clues.Wrap(err, "getting user info")
|
|
||||||
}
|
|
||||||
|
|
||||||
return ui, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// sites
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Sites fetches all sharepoint sites in the tenant
|
|
||||||
func Sites(
|
|
||||||
ctx context.Context,
|
|
||||||
acct account.Account,
|
|
||||||
errs *fault.Bus,
|
|
||||||
) ([]models.Siteable, error) {
|
|
||||||
client, err := apiClient(ctx, acct)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return client.Sites().GetAll(ctx, errs)
|
|
||||||
}
|
|
||||||
@ -1,296 +0,0 @@
|
|||||||
package discovery_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/alcionai/clues"
|
|
||||||
"github.com/google/uuid"
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"github.com/stretchr/testify/suite"
|
|
||||||
|
|
||||||
"github.com/alcionai/corso/src/internal/m365/discovery"
|
|
||||||
"github.com/alcionai/corso/src/internal/m365/graph"
|
|
||||||
"github.com/alcionai/corso/src/internal/tester"
|
|
||||||
"github.com/alcionai/corso/src/pkg/account"
|
|
||||||
"github.com/alcionai/corso/src/pkg/credentials"
|
|
||||||
"github.com/alcionai/corso/src/pkg/fault"
|
|
||||||
"github.com/alcionai/corso/src/pkg/path"
|
|
||||||
"github.com/alcionai/corso/src/pkg/services/m365/api"
|
|
||||||
)
|
|
||||||
|
|
||||||
type DiscoveryIntgSuite struct {
|
|
||||||
tester.Suite
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDiscoveryIntgSuite(t *testing.T) {
|
|
||||||
suite.Run(t, &DiscoveryIntgSuite{
|
|
||||||
Suite: tester.NewIntegrationSuite(
|
|
||||||
t,
|
|
||||||
[][]string{tester.M365AcctCredEnvs}),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (suite *DiscoveryIntgSuite) SetupSuite() {
|
|
||||||
ctx, flush := tester.NewContext(suite.T())
|
|
||||||
defer flush()
|
|
||||||
|
|
||||||
graph.InitializeConcurrencyLimiter(ctx, true, 4)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (suite *DiscoveryIntgSuite) TestUsers() {
|
|
||||||
t := suite.T()
|
|
||||||
|
|
||||||
ctx, flush := tester.NewContext(t)
|
|
||||||
defer flush()
|
|
||||||
|
|
||||||
var (
|
|
||||||
acct = tester.NewM365Account(t)
|
|
||||||
errs = fault.New(true)
|
|
||||||
)
|
|
||||||
|
|
||||||
creds, err := acct.M365Config()
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
cli, err := api.NewClient(creds)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
users, err := discovery.Users(ctx, cli.Users(), errs)
|
|
||||||
assert.NoError(t, err, clues.ToCore(err))
|
|
||||||
|
|
||||||
ferrs := errs.Errors()
|
|
||||||
assert.Nil(t, ferrs.Failure)
|
|
||||||
assert.Empty(t, ferrs.Recovered)
|
|
||||||
assert.NotEmpty(t, users)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (suite *DiscoveryIntgSuite) TestUsers_InvalidCredentials() {
|
|
||||||
table := []struct {
|
|
||||||
name string
|
|
||||||
acct func(t *testing.T) account.Account
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "Invalid Credentials",
|
|
||||||
acct: func(t *testing.T) account.Account {
|
|
||||||
a, err := account.NewAccount(
|
|
||||||
account.ProviderM365,
|
|
||||||
account.M365Config{
|
|
||||||
M365: credentials.M365{
|
|
||||||
AzureClientID: "Test",
|
|
||||||
AzureClientSecret: "without",
|
|
||||||
},
|
|
||||||
AzureTenantID: "data",
|
|
||||||
},
|
|
||||||
)
|
|
||||||
require.NoError(t, err, clues.ToCore(err))
|
|
||||||
|
|
||||||
return a
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, test := range table {
|
|
||||||
suite.Run(test.name, func() {
|
|
||||||
t := suite.T()
|
|
||||||
|
|
||||||
ctx, flush := tester.NewContext(t)
|
|
||||||
defer flush()
|
|
||||||
|
|
||||||
acct := test.acct(t)
|
|
||||||
|
|
||||||
creds, err := acct.M365Config()
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
cli, err := api.NewClient(creds)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
users, err := discovery.Users(ctx, cli.Users(), fault.New(true))
|
|
||||||
assert.Empty(t, users, "returned some users")
|
|
||||||
assert.NotNil(t, err)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (suite *DiscoveryIntgSuite) TestSites() {
|
|
||||||
t := suite.T()
|
|
||||||
|
|
||||||
ctx, flush := tester.NewContext(t)
|
|
||||||
defer flush()
|
|
||||||
|
|
||||||
var (
|
|
||||||
acct = tester.NewM365Account(t)
|
|
||||||
errs = fault.New(true)
|
|
||||||
)
|
|
||||||
|
|
||||||
sites, err := discovery.Sites(ctx, acct, errs)
|
|
||||||
assert.NoError(t, err, clues.ToCore(err))
|
|
||||||
|
|
||||||
ferrs := errs.Errors()
|
|
||||||
assert.Nil(t, ferrs.Failure)
|
|
||||||
assert.Empty(t, ferrs.Recovered)
|
|
||||||
assert.NotEmpty(t, sites)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (suite *DiscoveryIntgSuite) TestSites_InvalidCredentials() {
|
|
||||||
table := []struct {
|
|
||||||
name string
|
|
||||||
acct func(t *testing.T) account.Account
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "Invalid Credentials",
|
|
||||||
acct: func(t *testing.T) account.Account {
|
|
||||||
a, err := account.NewAccount(
|
|
||||||
account.ProviderM365,
|
|
||||||
account.M365Config{
|
|
||||||
M365: credentials.M365{
|
|
||||||
AzureClientID: "Test",
|
|
||||||
AzureClientSecret: "without",
|
|
||||||
},
|
|
||||||
AzureTenantID: "data",
|
|
||||||
},
|
|
||||||
)
|
|
||||||
require.NoError(t, err, clues.ToCore(err))
|
|
||||||
|
|
||||||
return a
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Empty Credentials",
|
|
||||||
acct: func(t *testing.T) account.Account {
|
|
||||||
// intentionally swallowing the error here
|
|
||||||
a, _ := account.NewAccount(account.ProviderM365)
|
|
||||||
return a
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, test := range table {
|
|
||||||
suite.Run(test.name, func() {
|
|
||||||
var (
|
|
||||||
t = suite.T()
|
|
||||||
a = test.acct(t)
|
|
||||||
errs = fault.New(true)
|
|
||||||
ctx, flush = tester.NewContext(t)
|
|
||||||
)
|
|
||||||
|
|
||||||
defer flush()
|
|
||||||
|
|
||||||
sites, err := discovery.Sites(ctx, a, errs)
|
|
||||||
assert.Empty(t, sites, "returned some sites")
|
|
||||||
assert.NotNil(t, err)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (suite *DiscoveryIntgSuite) TestUserInfo() {
|
|
||||||
t := suite.T()
|
|
||||||
acct := tester.NewM365Account(t)
|
|
||||||
|
|
||||||
creds, err := acct.M365Config()
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
cli, err := api.NewClient(creds)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
uapi := cli.Users()
|
|
||||||
|
|
||||||
table := []struct {
|
|
||||||
name string
|
|
||||||
user string
|
|
||||||
expect *api.UserInfo
|
|
||||||
expectErr require.ErrorAssertionFunc
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "standard test user",
|
|
||||||
user: tester.M365UserID(t),
|
|
||||||
expect: &api.UserInfo{
|
|
||||||
ServicesEnabled: map[path.ServiceType]struct{}{
|
|
||||||
path.ExchangeService: {},
|
|
||||||
path.OneDriveService: {},
|
|
||||||
},
|
|
||||||
Mailbox: api.MailboxInfo{
|
|
||||||
Purpose: "user",
|
|
||||||
ErrGetMailBoxSetting: nil,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
expectErr: require.NoError,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "user does not exist",
|
|
||||||
user: uuid.NewString(),
|
|
||||||
expect: &api.UserInfo{
|
|
||||||
ServicesEnabled: map[path.ServiceType]struct{}{},
|
|
||||||
Mailbox: api.MailboxInfo{},
|
|
||||||
},
|
|
||||||
expectErr: require.Error,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, test := range table {
|
|
||||||
suite.Run(test.name, func() {
|
|
||||||
t := suite.T()
|
|
||||||
|
|
||||||
ctx, flush := tester.NewContext(t)
|
|
||||||
defer flush()
|
|
||||||
|
|
||||||
result, err := discovery.UserInfo(ctx, uapi, test.user)
|
|
||||||
test.expectErr(t, err, clues.ToCore(err))
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
assert.Equal(t, test.expect.ServicesEnabled, result.ServicesEnabled)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (suite *DiscoveryIntgSuite) TestUserWithoutDrive() {
|
|
||||||
t := suite.T()
|
|
||||||
acct := tester.NewM365Account(t)
|
|
||||||
userID := tester.M365UserID(t)
|
|
||||||
|
|
||||||
table := []struct {
|
|
||||||
name string
|
|
||||||
user string
|
|
||||||
expect *api.UserInfo
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "user without drive and exchange",
|
|
||||||
user: "a53c26f7-5100-4acb-a910-4d20960b2c19", // User: testevents@10rqc2.onmicrosoft.com
|
|
||||||
expect: &api.UserInfo{
|
|
||||||
ServicesEnabled: map[path.ServiceType]struct{}{},
|
|
||||||
Mailbox: api.MailboxInfo{
|
|
||||||
ErrGetMailBoxSetting: []error{api.ErrMailBoxSettingsNotFound},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "user with drive and exchange",
|
|
||||||
user: userID,
|
|
||||||
expect: &api.UserInfo{
|
|
||||||
ServicesEnabled: map[path.ServiceType]struct{}{
|
|
||||||
path.ExchangeService: {},
|
|
||||||
path.OneDriveService: {},
|
|
||||||
},
|
|
||||||
Mailbox: api.MailboxInfo{
|
|
||||||
Purpose: "user",
|
|
||||||
ErrGetMailBoxSetting: []error{},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, test := range table {
|
|
||||||
suite.Run(test.name, func() {
|
|
||||||
t := suite.T()
|
|
||||||
|
|
||||||
ctx, flush := tester.NewContext(t)
|
|
||||||
defer flush()
|
|
||||||
|
|
||||||
result, err := discovery.GetUserInfo(ctx, acct, test.user, fault.New(true))
|
|
||||||
require.NoError(t, err, clues.ToCore(err))
|
|
||||||
assert.Equal(t, test.expect.ServicesEnabled, result.ServicesEnabled)
|
|
||||||
assert.Equal(t, test.expect.Mailbox.ErrGetMailBoxSetting, result.Mailbox.ErrGetMailBoxSetting)
|
|
||||||
assert.Equal(t, test.expect.Mailbox.Purpose, result.Mailbox.Purpose)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -26,10 +26,20 @@ import (
|
|||||||
type errorCode string
|
type errorCode string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
activityLimitReached errorCode = "activityLimitReached"
|
// cannotOpenFileAttachment happen when an attachment is
|
||||||
|
// inaccessible. The error message is usually "OLE conversion
|
||||||
|
// failed for an attachment."
|
||||||
|
cannotOpenFileAttachment errorCode = "ErrorCannotOpenFileAttachment"
|
||||||
emailFolderNotFound errorCode = "ErrorSyncFolderNotFound"
|
emailFolderNotFound errorCode = "ErrorSyncFolderNotFound"
|
||||||
errorAccessDenied errorCode = "ErrorAccessDenied"
|
errorAccessDenied errorCode = "ErrorAccessDenied"
|
||||||
errorItemNotFound errorCode = "ErrorItemNotFound"
|
errorItemNotFound errorCode = "ErrorItemNotFound"
|
||||||
|
// This error occurs when an attempt is made to create a folder that has
|
||||||
|
// the same name as another folder in the same parent. Such duplicate folder
|
||||||
|
// names are not allowed by graph.
|
||||||
|
folderExists errorCode = "ErrorFolderExists"
|
||||||
|
// Some datacenters are returning this when we try to get the inbox of a user
|
||||||
|
// that doesn't exist.
|
||||||
|
invalidUser errorCode = "ErrorInvalidUser"
|
||||||
itemNotFound errorCode = "itemNotFound"
|
itemNotFound errorCode = "itemNotFound"
|
||||||
MailboxNotEnabledForRESTAPI errorCode = "MailboxNotEnabledForRESTAPI"
|
MailboxNotEnabledForRESTAPI errorCode = "MailboxNotEnabledForRESTAPI"
|
||||||
malwareDetected errorCode = "malwareDetected"
|
malwareDetected errorCode = "malwareDetected"
|
||||||
@ -40,21 +50,10 @@ const (
|
|||||||
RequestResourceNotFound errorCode = "Request_ResourceNotFound"
|
RequestResourceNotFound errorCode = "Request_ResourceNotFound"
|
||||||
// Returned when we try to get the inbox of a user that doesn't exist.
|
// Returned when we try to get the inbox of a user that doesn't exist.
|
||||||
ResourceNotFound errorCode = "ResourceNotFound"
|
ResourceNotFound errorCode = "ResourceNotFound"
|
||||||
// Some datacenters are returning this when we try to get the inbox of a user
|
|
||||||
// that doesn't exist.
|
|
||||||
invalidUser errorCode = "ErrorInvalidUser"
|
|
||||||
resyncRequired errorCode = "ResyncRequired"
|
resyncRequired errorCode = "ResyncRequired"
|
||||||
syncFolderNotFound errorCode = "ErrorSyncFolderNotFound"
|
syncFolderNotFound errorCode = "ErrorSyncFolderNotFound"
|
||||||
syncStateInvalid errorCode = "SyncStateInvalid"
|
syncStateInvalid errorCode = "SyncStateInvalid"
|
||||||
syncStateNotFound errorCode = "SyncStateNotFound"
|
syncStateNotFound errorCode = "SyncStateNotFound"
|
||||||
// This error occurs when an attempt is made to create a folder that has
|
|
||||||
// the same name as another folder in the same parent. Such duplicate folder
|
|
||||||
// names are not allowed by graph.
|
|
||||||
folderExists errorCode = "ErrorFolderExists"
|
|
||||||
// cannotOpenFileAttachment happen when an attachment is
|
|
||||||
// inaccessible. The error message is usually "OLE conversion
|
|
||||||
// failed for an attachment."
|
|
||||||
cannotOpenFileAttachment errorCode = "ErrorCannotOpenFileAttachment"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type errorMessage string
|
type errorMessage string
|
||||||
|
|||||||
@ -8,18 +8,18 @@ import (
|
|||||||
|
|
||||||
"github.com/alcionai/corso/src/internal/common/idname"
|
"github.com/alcionai/corso/src/internal/common/idname"
|
||||||
"github.com/alcionai/corso/src/internal/common/ptr"
|
"github.com/alcionai/corso/src/internal/common/ptr"
|
||||||
"github.com/alcionai/corso/src/internal/m365/discovery"
|
|
||||||
"github.com/alcionai/corso/src/internal/m365/graph"
|
"github.com/alcionai/corso/src/internal/m365/graph"
|
||||||
"github.com/alcionai/corso/src/pkg/account"
|
"github.com/alcionai/corso/src/pkg/account"
|
||||||
"github.com/alcionai/corso/src/pkg/fault"
|
"github.com/alcionai/corso/src/pkg/fault"
|
||||||
"github.com/alcionai/corso/src/pkg/services/m365/api"
|
"github.com/alcionai/corso/src/pkg/services/m365/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ServiceAccess is true if a resource owner is capable of
|
// ---------------------------------------------------------------------------
|
||||||
// accessing or utilizing the specified service.
|
// interfaces & structs
|
||||||
type ServiceAccess struct {
|
// ---------------------------------------------------------------------------
|
||||||
Exchange bool
|
|
||||||
// TODO: onedrive, sharepoint
|
type getDefaultDriver interface {
|
||||||
|
GetDefaultDrive(ctx context.Context, userID string) (models.Driveable, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@ -107,7 +107,7 @@ func UserHasDrives(ctx context.Context, acct account.Account, userID string) (bo
|
|||||||
return checkUserHasDrives(ctx, ac.Users(), userID)
|
return checkUserHasDrives(ctx, ac.Users(), userID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkUserHasDrives(ctx context.Context, dgdd discovery.GetDefaultDriver, userID string) (bool, error) {
|
func checkUserHasDrives(ctx context.Context, dgdd getDefaultDriver, userID string) (bool, error) {
|
||||||
_, err := dgdd.GetDefaultDrive(ctx, userID)
|
_, err := dgdd.GetDefaultDrive(ctx, userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// we consider this a non-error case, since it
|
// we consider this a non-error case, since it
|
||||||
@ -135,7 +135,7 @@ func usersNoInfo(ctx context.Context, acct account.Account, errs *fault.Bus) ([]
|
|||||||
return nil, clues.Stack(err).WithClues(ctx)
|
return nil, clues.Stack(err).WithClues(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
us, err := discovery.Users(ctx, ac.Users(), errs)
|
us, err := ac.Users().GetAll(ctx, errs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -167,7 +167,7 @@ func Users(ctx context.Context, acct account.Account, errs *fault.Bus) ([]*User,
|
|||||||
return nil, clues.Stack(err).WithClues(ctx)
|
return nil, clues.Stack(err).WithClues(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
us, err := discovery.Users(ctx, ac.Users(), errs)
|
us, err := ac.Users().GetAll(ctx, errs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -180,7 +180,7 @@ func Users(ctx context.Context, acct account.Account, errs *fault.Bus) ([]*User,
|
|||||||
return nil, clues.Wrap(err, "formatting user data")
|
return nil, clues.Wrap(err, "formatting user data")
|
||||||
}
|
}
|
||||||
|
|
||||||
userInfo, err := discovery.GetUserInfo(ctx, acct, pu.ID, errs)
|
userInfo, err := ac.Users().GetInfo(ctx, pu.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, clues.Wrap(err, "getting user details")
|
return nil, clues.Wrap(err, "getting user details")
|
||||||
}
|
}
|
||||||
@ -220,7 +220,7 @@ func GetUserInfo(
|
|||||||
return nil, clues.Stack(err).WithClues(ctx)
|
return nil, clues.Stack(err).WithClues(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
ui, err := discovery.UserInfo(ctx, ac.Users(), userID)
|
ui, err := ac.Users().GetInfo(ctx, userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/alcionai/clues"
|
"github.com/alcionai/clues"
|
||||||
|
"github.com/google/uuid"
|
||||||
"github.com/microsoftgraph/msgraph-sdk-go/models"
|
"github.com/microsoftgraph/msgraph-sdk-go/models"
|
||||||
"github.com/microsoftgraph/msgraph-sdk-go/models/odataerrors"
|
"github.com/microsoftgraph/msgraph-sdk-go/models/odataerrors"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
@ -12,11 +13,13 @@ import (
|
|||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
|
|
||||||
"github.com/alcionai/corso/src/internal/common/ptr"
|
"github.com/alcionai/corso/src/internal/common/ptr"
|
||||||
"github.com/alcionai/corso/src/internal/m365/discovery"
|
|
||||||
"github.com/alcionai/corso/src/internal/m365/graph"
|
"github.com/alcionai/corso/src/internal/m365/graph"
|
||||||
"github.com/alcionai/corso/src/internal/tester"
|
"github.com/alcionai/corso/src/internal/tester"
|
||||||
|
"github.com/alcionai/corso/src/pkg/account"
|
||||||
|
"github.com/alcionai/corso/src/pkg/credentials"
|
||||||
"github.com/alcionai/corso/src/pkg/fault"
|
"github.com/alcionai/corso/src/pkg/fault"
|
||||||
"github.com/alcionai/corso/src/pkg/path"
|
"github.com/alcionai/corso/src/pkg/path"
|
||||||
|
"github.com/alcionai/corso/src/pkg/services/m365/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
type M365IntegrationSuite struct {
|
type M365IntegrationSuite struct {
|
||||||
@ -31,6 +34,13 @@ func TestM365IntegrationSuite(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (suite *M365IntegrationSuite) SetupSuite() {
|
||||||
|
ctx, flush := tester.NewContext(suite.T())
|
||||||
|
defer flush()
|
||||||
|
|
||||||
|
graph.InitializeConcurrencyLimiter(ctx, true, 4)
|
||||||
|
}
|
||||||
|
|
||||||
func (suite *M365IntegrationSuite) TestUsers() {
|
func (suite *M365IntegrationSuite) TestUsers() {
|
||||||
t := suite.T()
|
t := suite.T()
|
||||||
|
|
||||||
@ -80,35 +90,6 @@ func (suite *M365IntegrationSuite) TestUsersCompat_HasNoInfo() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *M365IntegrationSuite) TestGetUserInfo() {
|
|
||||||
t := suite.T()
|
|
||||||
|
|
||||||
ctx, flush := tester.NewContext(t)
|
|
||||||
defer flush()
|
|
||||||
|
|
||||||
graph.InitializeConcurrencyLimiter(ctx, true, 4)
|
|
||||||
|
|
||||||
var (
|
|
||||||
acct = tester.NewM365Account(t)
|
|
||||||
uid = tester.M365UserID(t)
|
|
||||||
)
|
|
||||||
|
|
||||||
info, err := GetUserInfo(ctx, acct, uid)
|
|
||||||
require.NoError(t, err, clues.ToCore(err))
|
|
||||||
require.NotNil(t, info)
|
|
||||||
require.NotEmpty(t, info)
|
|
||||||
|
|
||||||
expectEnabled := map[path.ServiceType]struct{}{
|
|
||||||
path.ExchangeService: {},
|
|
||||||
path.OneDriveService: {},
|
|
||||||
}
|
|
||||||
|
|
||||||
assert.NotEmpty(t, info.ServicesEnabled)
|
|
||||||
assert.NotEmpty(t, info.Mailbox)
|
|
||||||
assert.Equal(t, expectEnabled, info.ServicesEnabled)
|
|
||||||
assert.Equal(t, "user", info.Mailbox.Purpose)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (suite *M365IntegrationSuite) TestUserHasMailbox() {
|
func (suite *M365IntegrationSuite) TestUserHasMailbox() {
|
||||||
t := suite.T()
|
t := suite.T()
|
||||||
|
|
||||||
@ -183,13 +164,13 @@ func (m mockDGDD) GetDefaultDrive(context.Context, string) (models.Driveable, er
|
|||||||
func (suite *m365UnitSuite) TestCheckUserHasDrives() {
|
func (suite *m365UnitSuite) TestCheckUserHasDrives() {
|
||||||
table := []struct {
|
table := []struct {
|
||||||
name string
|
name string
|
||||||
mock func(context.Context) discovery.GetDefaultDriver
|
mock func(context.Context) getDefaultDriver
|
||||||
expect assert.BoolAssertionFunc
|
expect assert.BoolAssertionFunc
|
||||||
expectErr func(*testing.T, error)
|
expectErr func(*testing.T, error)
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "ok",
|
name: "ok",
|
||||||
mock: func(ctx context.Context) discovery.GetDefaultDriver {
|
mock: func(ctx context.Context) getDefaultDriver {
|
||||||
return mockDGDD{models.NewDrive(), nil}
|
return mockDGDD{models.NewDrive(), nil}
|
||||||
},
|
},
|
||||||
expect: assert.True,
|
expect: assert.True,
|
||||||
@ -199,7 +180,7 @@ func (suite *m365UnitSuite) TestCheckUserHasDrives() {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "mysite not found",
|
name: "mysite not found",
|
||||||
mock: func(ctx context.Context) discovery.GetDefaultDriver {
|
mock: func(ctx context.Context) getDefaultDriver {
|
||||||
odErr := odataerrors.NewODataError()
|
odErr := odataerrors.NewODataError()
|
||||||
merr := odataerrors.NewMainError()
|
merr := odataerrors.NewMainError()
|
||||||
merr.SetCode(ptr.To("code"))
|
merr.SetCode(ptr.To("code"))
|
||||||
@ -215,7 +196,7 @@ func (suite *m365UnitSuite) TestCheckUserHasDrives() {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "mysite URL not found",
|
name: "mysite URL not found",
|
||||||
mock: func(ctx context.Context) discovery.GetDefaultDriver {
|
mock: func(ctx context.Context) getDefaultDriver {
|
||||||
odErr := odataerrors.NewODataError()
|
odErr := odataerrors.NewODataError()
|
||||||
merr := odataerrors.NewMainError()
|
merr := odataerrors.NewMainError()
|
||||||
merr.SetCode(ptr.To("code"))
|
merr.SetCode(ptr.To("code"))
|
||||||
@ -231,7 +212,7 @@ func (suite *m365UnitSuite) TestCheckUserHasDrives() {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "no sharepoint license",
|
name: "no sharepoint license",
|
||||||
mock: func(ctx context.Context) discovery.GetDefaultDriver {
|
mock: func(ctx context.Context) getDefaultDriver {
|
||||||
odErr := odataerrors.NewODataError()
|
odErr := odataerrors.NewODataError()
|
||||||
merr := odataerrors.NewMainError()
|
merr := odataerrors.NewMainError()
|
||||||
merr.SetCode(ptr.To("code"))
|
merr.SetCode(ptr.To("code"))
|
||||||
@ -247,7 +228,7 @@ func (suite *m365UnitSuite) TestCheckUserHasDrives() {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "user not found",
|
name: "user not found",
|
||||||
mock: func(ctx context.Context) discovery.GetDefaultDriver {
|
mock: func(ctx context.Context) getDefaultDriver {
|
||||||
odErr := odataerrors.NewODataError()
|
odErr := odataerrors.NewODataError()
|
||||||
merr := odataerrors.NewMainError()
|
merr := odataerrors.NewMainError()
|
||||||
merr.SetCode(ptr.To(string(graph.RequestResourceNotFound)))
|
merr.SetCode(ptr.To(string(graph.RequestResourceNotFound)))
|
||||||
@ -263,7 +244,7 @@ func (suite *m365UnitSuite) TestCheckUserHasDrives() {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "arbitrary error",
|
name: "arbitrary error",
|
||||||
mock: func(ctx context.Context) discovery.GetDefaultDriver {
|
mock: func(ctx context.Context) getDefaultDriver {
|
||||||
odErr := odataerrors.NewODataError()
|
odErr := odataerrors.NewODataError()
|
||||||
merr := odataerrors.NewMainError()
|
merr := odataerrors.NewMainError()
|
||||||
merr.SetCode(ptr.To("code"))
|
merr.SetCode(ptr.To("code"))
|
||||||
@ -363,3 +344,230 @@ func (suite *m365UnitSuite) TestGetAllSites() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DiscoveryIntgSuite struct {
|
||||||
|
tester.Suite
|
||||||
|
acct account.Account
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDiscoveryIntgSuite(t *testing.T) {
|
||||||
|
suite.Run(t, &DiscoveryIntgSuite{
|
||||||
|
Suite: tester.NewIntegrationSuite(
|
||||||
|
t,
|
||||||
|
[][]string{tester.M365AcctCredEnvs}),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (suite *DiscoveryIntgSuite) SetupSuite() {
|
||||||
|
t := suite.T()
|
||||||
|
|
||||||
|
ctx, flush := tester.NewContext(t)
|
||||||
|
defer flush()
|
||||||
|
|
||||||
|
graph.InitializeConcurrencyLimiter(ctx, true, 4)
|
||||||
|
|
||||||
|
suite.acct = tester.NewM365Account(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (suite *DiscoveryIntgSuite) TestUsers() {
|
||||||
|
t := suite.T()
|
||||||
|
|
||||||
|
ctx, flush := tester.NewContext(t)
|
||||||
|
defer flush()
|
||||||
|
|
||||||
|
errs := fault.New(true)
|
||||||
|
|
||||||
|
users, err := Users(ctx, suite.acct, errs)
|
||||||
|
assert.NoError(t, err, clues.ToCore(err))
|
||||||
|
|
||||||
|
ferrs := errs.Errors()
|
||||||
|
assert.Nil(t, ferrs.Failure)
|
||||||
|
assert.Empty(t, ferrs.Recovered)
|
||||||
|
assert.NotEmpty(t, users)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (suite *DiscoveryIntgSuite) TestUsers_InvalidCredentials() {
|
||||||
|
table := []struct {
|
||||||
|
name string
|
||||||
|
acct func(t *testing.T) account.Account
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Invalid Credentials",
|
||||||
|
acct: func(t *testing.T) account.Account {
|
||||||
|
a, err := account.NewAccount(
|
||||||
|
account.ProviderM365,
|
||||||
|
account.M365Config{
|
||||||
|
M365: credentials.M365{
|
||||||
|
AzureClientID: "Test",
|
||||||
|
AzureClientSecret: "without",
|
||||||
|
},
|
||||||
|
AzureTenantID: "data",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
require.NoError(t, err, clues.ToCore(err))
|
||||||
|
|
||||||
|
return a
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range table {
|
||||||
|
suite.Run(test.name, func() {
|
||||||
|
t := suite.T()
|
||||||
|
|
||||||
|
ctx, flush := tester.NewContext(t)
|
||||||
|
defer flush()
|
||||||
|
|
||||||
|
users, err := Users(ctx, test.acct(t), fault.New(true))
|
||||||
|
assert.Empty(t, users, "returned some users")
|
||||||
|
assert.NotNil(t, err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (suite *DiscoveryIntgSuite) TestSites_InvalidCredentials() {
|
||||||
|
table := []struct {
|
||||||
|
name string
|
||||||
|
acct func(t *testing.T) account.Account
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Invalid Credentials",
|
||||||
|
acct: func(t *testing.T) account.Account {
|
||||||
|
a, err := account.NewAccount(
|
||||||
|
account.ProviderM365,
|
||||||
|
account.M365Config{
|
||||||
|
M365: credentials.M365{
|
||||||
|
AzureClientID: "Test",
|
||||||
|
AzureClientSecret: "without",
|
||||||
|
},
|
||||||
|
AzureTenantID: "data",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
require.NoError(t, err, clues.ToCore(err))
|
||||||
|
|
||||||
|
return a
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Empty Credentials",
|
||||||
|
acct: func(t *testing.T) account.Account {
|
||||||
|
// intentionally swallowing the error here
|
||||||
|
a, _ := account.NewAccount(account.ProviderM365)
|
||||||
|
return a
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range table {
|
||||||
|
suite.Run(test.name, func() {
|
||||||
|
t := suite.T()
|
||||||
|
|
||||||
|
ctx, flush := tester.NewContext(t)
|
||||||
|
defer flush()
|
||||||
|
|
||||||
|
sites, err := Sites(ctx, test.acct(t), fault.New(true))
|
||||||
|
assert.Empty(t, sites, "returned some sites")
|
||||||
|
assert.NotNil(t, err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (suite *DiscoveryIntgSuite) TestGetUserInfo() {
|
||||||
|
table := []struct {
|
||||||
|
name string
|
||||||
|
user string
|
||||||
|
expect *api.UserInfo
|
||||||
|
expectErr require.ErrorAssertionFunc
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "standard test user",
|
||||||
|
user: tester.M365UserID(suite.T()),
|
||||||
|
expect: &api.UserInfo{
|
||||||
|
ServicesEnabled: map[path.ServiceType]struct{}{
|
||||||
|
path.ExchangeService: {},
|
||||||
|
path.OneDriveService: {},
|
||||||
|
},
|
||||||
|
Mailbox: api.MailboxInfo{
|
||||||
|
Purpose: "user",
|
||||||
|
ErrGetMailBoxSetting: nil,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expectErr: require.NoError,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "user does not exist",
|
||||||
|
user: uuid.NewString(),
|
||||||
|
expect: &api.UserInfo{
|
||||||
|
ServicesEnabled: map[path.ServiceType]struct{}{},
|
||||||
|
Mailbox: api.MailboxInfo{},
|
||||||
|
},
|
||||||
|
expectErr: require.Error,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, test := range table {
|
||||||
|
suite.Run(test.name, func() {
|
||||||
|
t := suite.T()
|
||||||
|
|
||||||
|
ctx, flush := tester.NewContext(t)
|
||||||
|
defer flush()
|
||||||
|
|
||||||
|
result, err := GetUserInfo(ctx, suite.acct, test.user)
|
||||||
|
test.expectErr(t, err, clues.ToCore(err))
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(t, test.expect.ServicesEnabled, result.ServicesEnabled)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (suite *DiscoveryIntgSuite) TestGetUserInfo_userWithoutDrive() {
|
||||||
|
userID := tester.M365UserID(suite.T())
|
||||||
|
|
||||||
|
table := []struct {
|
||||||
|
name string
|
||||||
|
user string
|
||||||
|
expect *api.UserInfo
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "user without drive and exchange",
|
||||||
|
user: "a53c26f7-5100-4acb-a910-4d20960b2c19", // User: testevents@10rqc2.onmicrosoft.com
|
||||||
|
expect: &api.UserInfo{
|
||||||
|
ServicesEnabled: map[path.ServiceType]struct{}{},
|
||||||
|
Mailbox: api.MailboxInfo{
|
||||||
|
ErrGetMailBoxSetting: []error{api.ErrMailBoxSettingsNotFound},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "user with drive and exchange",
|
||||||
|
user: userID,
|
||||||
|
expect: &api.UserInfo{
|
||||||
|
ServicesEnabled: map[path.ServiceType]struct{}{
|
||||||
|
path.ExchangeService: {},
|
||||||
|
path.OneDriveService: {},
|
||||||
|
},
|
||||||
|
Mailbox: api.MailboxInfo{
|
||||||
|
Purpose: "user",
|
||||||
|
ErrGetMailBoxSetting: []error{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, test := range table {
|
||||||
|
suite.Run(test.name, func() {
|
||||||
|
t := suite.T()
|
||||||
|
|
||||||
|
ctx, flush := tester.NewContext(t)
|
||||||
|
defer flush()
|
||||||
|
|
||||||
|
result, err := GetUserInfo(ctx, suite.acct, test.user)
|
||||||
|
require.NoError(t, err, clues.ToCore(err))
|
||||||
|
assert.Equal(t, test.expect.ServicesEnabled, result.ServicesEnabled)
|
||||||
|
assert.Equal(t, test.expect.Mailbox.ErrGetMailBoxSetting, result.Mailbox.ErrGetMailBoxSetting)
|
||||||
|
assert.Equal(t, test.expect.Mailbox.Purpose, result.Mailbox.Purpose)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user