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
|
||||
- Fix uploading large attachments for emails and calendar
|
||||
- Fixed high memory use in OneDrive backup related to logging
|
||||
- Return a ServiceNotEnabled error when a tenant has no active SharePoint license.
|
||||
|
||||
### Changed
|
||||
- Switched to Go 1.20
|
||||
|
||||
@ -10,7 +10,6 @@ import (
|
||||
"github.com/alcionai/corso/src/internal/common/prefixmatcher"
|
||||
"github.com/alcionai/corso/src/internal/data"
|
||||
"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/graph"
|
||||
"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/path"
|
||||
"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
|
||||
}
|
||||
|
||||
type getInfoer interface {
|
||||
GetInfo(context.Context, string) (*api.UserInfo, error)
|
||||
}
|
||||
|
||||
func checkServiceEnabled(
|
||||
ctx context.Context,
|
||||
gi discovery.GetInfoer,
|
||||
gi getInfoer,
|
||||
service path.ServiceType,
|
||||
resource string,
|
||||
) (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
|
||||
|
||||
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"
|
||||
errorAccessDenied errorCode = "ErrorAccessDenied"
|
||||
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"
|
||||
MailboxNotEnabledForRESTAPI errorCode = "MailboxNotEnabledForRESTAPI"
|
||||
malwareDetected errorCode = "malwareDetected"
|
||||
@ -40,21 +50,10 @@ const (
|
||||
RequestResourceNotFound errorCode = "Request_ResourceNotFound"
|
||||
// Returned when we try to get the inbox of a user that doesn't exist.
|
||||
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"
|
||||
syncFolderNotFound errorCode = "ErrorSyncFolderNotFound"
|
||||
syncStateInvalid errorCode = "SyncStateInvalid"
|
||||
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
|
||||
|
||||
@ -8,18 +8,18 @@ import (
|
||||
|
||||
"github.com/alcionai/corso/src/internal/common/idname"
|
||||
"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/pkg/account"
|
||||
"github.com/alcionai/corso/src/pkg/fault"
|
||||
"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.
|
||||
type ServiceAccess struct {
|
||||
Exchange bool
|
||||
// TODO: onedrive, sharepoint
|
||||
// ---------------------------------------------------------------------------
|
||||
// interfaces & structs
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
if err != nil {
|
||||
// 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)
|
||||
}
|
||||
|
||||
us, err := discovery.Users(ctx, ac.Users(), errs)
|
||||
us, err := ac.Users().GetAll(ctx, errs)
|
||||
if err != nil {
|
||||
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)
|
||||
}
|
||||
|
||||
us, err := discovery.Users(ctx, ac.Users(), errs)
|
||||
us, err := ac.Users().GetAll(ctx, errs)
|
||||
if err != nil {
|
||||
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")
|
||||
}
|
||||
|
||||
userInfo, err := discovery.GetUserInfo(ctx, acct, pu.ID, errs)
|
||||
userInfo, err := ac.Users().GetInfo(ctx, pu.ID)
|
||||
if err != nil {
|
||||
return nil, clues.Wrap(err, "getting user details")
|
||||
}
|
||||
@ -220,7 +220,7 @@ func GetUserInfo(
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/alcionai/clues"
|
||||
"github.com/google/uuid"
|
||||
"github.com/microsoftgraph/msgraph-sdk-go/models"
|
||||
"github.com/microsoftgraph/msgraph-sdk-go/models/odataerrors"
|
||||
"github.com/stretchr/testify/assert"
|
||||
@ -12,11 +13,13 @@ import (
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
"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/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 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() {
|
||||
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() {
|
||||
t := suite.T()
|
||||
|
||||
@ -183,13 +164,13 @@ func (m mockDGDD) GetDefaultDrive(context.Context, string) (models.Driveable, er
|
||||
func (suite *m365UnitSuite) TestCheckUserHasDrives() {
|
||||
table := []struct {
|
||||
name string
|
||||
mock func(context.Context) discovery.GetDefaultDriver
|
||||
mock func(context.Context) getDefaultDriver
|
||||
expect assert.BoolAssertionFunc
|
||||
expectErr func(*testing.T, error)
|
||||
}{
|
||||
{
|
||||
name: "ok",
|
||||
mock: func(ctx context.Context) discovery.GetDefaultDriver {
|
||||
mock: func(ctx context.Context) getDefaultDriver {
|
||||
return mockDGDD{models.NewDrive(), nil}
|
||||
},
|
||||
expect: assert.True,
|
||||
@ -199,7 +180,7 @@ func (suite *m365UnitSuite) TestCheckUserHasDrives() {
|
||||
},
|
||||
{
|
||||
name: "mysite not found",
|
||||
mock: func(ctx context.Context) discovery.GetDefaultDriver {
|
||||
mock: func(ctx context.Context) getDefaultDriver {
|
||||
odErr := odataerrors.NewODataError()
|
||||
merr := odataerrors.NewMainError()
|
||||
merr.SetCode(ptr.To("code"))
|
||||
@ -215,7 +196,7 @@ func (suite *m365UnitSuite) TestCheckUserHasDrives() {
|
||||
},
|
||||
{
|
||||
name: "mysite URL not found",
|
||||
mock: func(ctx context.Context) discovery.GetDefaultDriver {
|
||||
mock: func(ctx context.Context) getDefaultDriver {
|
||||
odErr := odataerrors.NewODataError()
|
||||
merr := odataerrors.NewMainError()
|
||||
merr.SetCode(ptr.To("code"))
|
||||
@ -231,7 +212,7 @@ func (suite *m365UnitSuite) TestCheckUserHasDrives() {
|
||||
},
|
||||
{
|
||||
name: "no sharepoint license",
|
||||
mock: func(ctx context.Context) discovery.GetDefaultDriver {
|
||||
mock: func(ctx context.Context) getDefaultDriver {
|
||||
odErr := odataerrors.NewODataError()
|
||||
merr := odataerrors.NewMainError()
|
||||
merr.SetCode(ptr.To("code"))
|
||||
@ -247,7 +228,7 @@ func (suite *m365UnitSuite) TestCheckUserHasDrives() {
|
||||
},
|
||||
{
|
||||
name: "user not found",
|
||||
mock: func(ctx context.Context) discovery.GetDefaultDriver {
|
||||
mock: func(ctx context.Context) getDefaultDriver {
|
||||
odErr := odataerrors.NewODataError()
|
||||
merr := odataerrors.NewMainError()
|
||||
merr.SetCode(ptr.To(string(graph.RequestResourceNotFound)))
|
||||
@ -263,7 +244,7 @@ func (suite *m365UnitSuite) TestCheckUserHasDrives() {
|
||||
},
|
||||
{
|
||||
name: "arbitrary error",
|
||||
mock: func(ctx context.Context) discovery.GetDefaultDriver {
|
||||
mock: func(ctx context.Context) getDefaultDriver {
|
||||
odErr := odataerrors.NewODataError()
|
||||
merr := odataerrors.NewMainError()
|
||||
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