diff --git a/src/internal/connector/graph_connector_test.go b/src/internal/connector/graph_connector_test.go index 9a8974ed3..925ef6faa 100644 --- a/src/internal/connector/graph_connector_test.go +++ b/src/internal/connector/graph_connector_test.go @@ -61,8 +61,10 @@ func (suite *GraphConnectorIntegrationSuite) TestGraphConnector_setTenantUsers() } func (suite *GraphConnectorIntegrationSuite) TestGraphConnector_ExchangeDataCollection() { + userID, err := tester.M365UserID() + require.NoError(suite.T(), err) sel := selectors.NewExchangeBackup() - sel.Include(sel.Users([]string{"lidiah@8qzvrj.onmicrosoft.com"})) + sel.Include(sel.Users([]string{userID})) collectionList, err := suite.connector.ExchangeDataCollection(context.Background(), sel.Selector) assert.NotNil(suite.T(), collectionList, "collection list") assert.Nil(suite.T(), err) @@ -102,13 +104,14 @@ func (suite *GraphConnectorIntegrationSuite) TestGraphConnector_restoreMessages( // TestGraphConnector_CreateAndDeleteFolder ensures msgraph application has the ability // to create and remove folders within the tenant func (suite *GraphConnectorIntegrationSuite) TestGraphConnector_CreateAndDeleteFolder() { - user := "lidiah@8qzvrj.onmicrosoft.com" + userID, err := tester.M365UserID() + require.NoError(suite.T(), err) now := time.Now() folderName := "TestFolder: " + common.FormatSimpleDateTime(now) - aFolder, err := exchange.CreateMailFolder(&suite.connector.graphService, user, folderName) + aFolder, err := exchange.CreateMailFolder(&suite.connector.graphService, userID, folderName) assert.NoError(suite.T(), err, support.ConnectorStackErrorTrace(err)) if aFolder != nil { - err = exchange.DeleteMailFolder(&suite.connector.graphService, user, *aFolder.GetId()) + err = exchange.DeleteMailFolder(&suite.connector.graphService, userID, *aFolder.GetId()) assert.NoError(suite.T(), err) } } @@ -116,9 +119,10 @@ func (suite *GraphConnectorIntegrationSuite) TestGraphConnector_CreateAndDeleteF // TestGraphConnector_GetMailFolderID verifies the ability to retrieve folder ID of folders // at the top level of the file tree func (suite *GraphConnectorIntegrationSuite) TestGraphConnector_GetMailFolderID() { - user := "lidiah@8qzvrj.onmicrosoft.com" + userID, err := tester.M365UserID() + require.NoError(suite.T(), err) folderName := "Inbox" - folderID, err := exchange.GetMailFolderID(&suite.connector.graphService, folderName, user) + folderID, err := exchange.GetMailFolderID(&suite.connector.graphService, folderName, userID) assert.NoError(suite.T(), err) assert.NotNil(suite.T(), folderID) } diff --git a/src/internal/connector/mockconnector/mock_data_collection.go b/src/internal/connector/mockconnector/mock_data_collection.go index 2c46d80bc..ac44a5383 100644 --- a/src/internal/connector/mockconnector/mock_data_collection.go +++ b/src/internal/connector/mockconnector/mock_data_collection.go @@ -9,6 +9,7 @@ import ( "github.com/alcionai/corso/internal/common" "github.com/alcionai/corso/internal/data" + "github.com/alcionai/corso/internal/tester" "github.com/alcionai/corso/pkg/backup/details" ) @@ -88,8 +89,13 @@ func (med *MockExchangeData) Info() details.ItemInfo { // Contents verified as working with sample data from kiota-serialization-json-go v0.5.5 func getMockMessageBytes(subject string) []byte { + userID, err := tester.M365UserID() + if err != nil { + userID = "lidiah@8qzvrj.onmicrosoft.com" + } + message := "{\n \"@odata.etag\": \"W/\\\"CQAAABYAAAB8wYc0thTTTYl3RpEYIUq+AAAZ0f0I\\\"\",\n \"id\": \"AAMkAGQ1NzViZTdhLTEwMTMtNGJjNi05YWI2LTg4NWRlZDA2Y2UxOABGAAAAAAAPvVwUramXT7jlSGpVU8_7BwB8wYc0thTTTYl3RpEYIUq_AAAAAAEMAAB8wYc0thTTTYl3RpEYIUq_AAAZ3wG3AAA=\",\n \"createdDateTime\": \"2022-04-08T18:08:02Z\",\n \"lastModifiedDateTime\": \"2022-05-17T13:46:55Z\",\n \"changeKey\": \"CQAAABYAAAB8wYc0thTTTYl3RpEYIUq+AAAZ0f0I\",\n \"categories\": [],\n \"receivedDateTime\": \"2022-04-08T18:08:02Z\",\n \"sentDateTime\": \"2022-04-08T18:07:53Z\",\n \"hasAttachments\": false,\n \"internetMessageId\": \"\",\n \"subject\": \"" + - subject + " " + common.FormatSimpleDateTime(time.Now()) + " Different\",\n \"bodyPreview\": \"Who is coming to next week's party? I cannot imagine it is July soon\",\n \"importance\": \"normal\",\n \"parentFolderId\": \"AQMkAGQ1NzViZTdhLTEwMTMtNGJjNi05YWI2LTg4ADVkZWQwNmNlMTgALgAAAw_9XBStqZdPuOVIalVTz7sBAHzBhzS2FNNNiXdGkRghSr4AAAIBDAAAAA==\",\n \"conversationId\": \"AAQkAGQ1NzViZTdhLTEwMTMtNGJjNi05YWI2LTg4NWRlZDA2Y2UxOAAQAI7SSzmEPaRJsY-TWIALn1g=\",\n \"conversationIndex\": \"AQHYS3N3jtJLOYQ9pEmxj9NYgAufWA==\",\n \"isDeliveryReceiptRequested\": null,\n \"isReadReceiptRequested\": false,\n \"isRead\": true,\n \"isDraft\": false,\n \"webLink\": \"https://outlook.office365.com/owa/?ItemID=AAMkAGQ1NzViZTdhLTEwMTMtNGJjNi05YWI2LTg4NWRlZDA2Y2UxOABGAAAAAAAPvVwUramXT7jlSGpVU8%2B7BwB8wYc0thTTTYl3RpEYIUq%2BAAAAAAEMAAB8wYc0thTTTYl3RpEYIUq%2BAAAZ3wG3AAA%3D&exvsurl=1&viewmodel=ReadMessageItem\",\n \"inferenceClassification\": \"focused\",\n \"body\": {\n \"contentType\": \"html\",\n \"content\": \"

I've been going through with the changing of messages. It shouldn't have the same calls, right? Call Me?

 

We want to be able to send multiple messages and we want to be able to respond and do other things that make sense for our users. In this case. Let’s consider a Mailbox

\"\n },\n \"sender\": {\n \"emailAddress\": {\n \"name\": \"Lidia Holloway\",\n \"address\": \"lidiah@8qzvrj.onmicrosoft.com\"\n }\n },\n \"from\": {\n \"emailAddress\": {\n \"name\": \"Lidia Holloway\",\n \"address\": \"lidiah@8qzvrj.onmicrosoft.com\"\n }\n },\n \"toRecipients\": [\n {\n \"emailAddress\": {\n \"name\": \"Dustin Abbot\",\n \"address\": \"dustina@8qzvrj.onmicrosoft.com\"\n }\n }\n ],\n \"ccRecipients\": [],\n \"bccRecipients\": [],\n \"replyTo\": [],\n \"flag\": {\n \"flagStatus\": \"notFlagged\"\n }\n}\n" + subject + " " + common.FormatSimpleDateTime(time.Now()) + " Different\",\n \"bodyPreview\": \"Who is coming to next week's party? I cannot imagine it is July soon\",\n \"importance\": \"normal\",\n \"parentFolderId\": \"AQMkAGQ1NzViZTdhLTEwMTMtNGJjNi05YWI2LTg4ADVkZWQwNmNlMTgALgAAAw_9XBStqZdPuOVIalVTz7sBAHzBhzS2FNNNiXdGkRghSr4AAAIBDAAAAA==\",\n \"conversationId\": \"AAQkAGQ1NzViZTdhLTEwMTMtNGJjNi05YWI2LTg4NWRlZDA2Y2UxOAAQAI7SSzmEPaRJsY-TWIALn1g=\",\n \"conversationIndex\": \"AQHYS3N3jtJLOYQ9pEmxj9NYgAufWA==\",\n \"isDeliveryReceiptRequested\": null,\n \"isReadReceiptRequested\": false,\n \"isRead\": true,\n \"isDraft\": false,\n \"webLink\": \"https://outlook.office365.com/owa/?ItemID=AAMkAGQ1NzViZTdhLTEwMTMtNGJjNi05YWI2LTg4NWRlZDA2Y2UxOABGAAAAAAAPvVwUramXT7jlSGpVU8%2B7BwB8wYc0thTTTYl3RpEYIUq%2BAAAAAAEMAAB8wYc0thTTTYl3RpEYIUq%2BAAAZ3wG3AAA%3D&exvsurl=1&viewmodel=ReadMessageItem\",\n \"inferenceClassification\": \"focused\",\n \"body\": {\n \"contentType\": \"html\",\n \"content\": \"

I've been going through with the changing of messages. It shouldn't have the same calls, right? Call Me?

 

We want to be able to send multiple messages and we want to be able to respond and do other things that make sense for our users. In this case. Let’s consider a Mailbox

\"\n },\n \"sender\": {\n \"emailAddress\": {\n \"name\": \"Lidia Holloway\",\n \"address\": \"" + userID + "\"\n }\n },\n \"from\": {\n \"emailAddress\": {\n \"name\": \"Lidia Holloway\",\n \"address\": \"lidiah@8qzvrj.onmicrosoft.com\"\n }\n },\n \"toRecipients\": [\n {\n \"emailAddress\": {\n \"name\": \"Dustin Abbot\",\n \"address\": \"dustina@8qzvrj.onmicrosoft.com\"\n }\n }\n ],\n \"ccRecipients\": [],\n \"bccRecipients\": [],\n \"replyTo\": [],\n \"flag\": {\n \"flagStatus\": \"notFlagged\"\n }\n}\n" return []byte(message) } diff --git a/src/internal/operations/backup_test.go b/src/internal/operations/backup_test.go index 48b78ea27..6cac6a641 100644 --- a/src/internal/operations/backup_test.go +++ b/src/internal/operations/backup_test.go @@ -131,7 +131,8 @@ func (suite *BackupOpIntegrationSuite) TestBackup_Run() { t := suite.T() ctx := context.Background() - m365User := "lidiah@8qzvrj.onmicrosoft.com" + m365UserID, err := tester.M365UserID() + require.NoError(suite.T(), err) acct, err := tester.NewM365Account() require.NoError(t, err) @@ -157,7 +158,7 @@ func (suite *BackupOpIntegrationSuite) TestBackup_Run() { sw := store.NewKopiaStore(ms) sel := selectors.NewExchangeBackup() - sel.Include(sel.Users([]string{m365User})) + sel.Include(sel.Users([]string{m365UserID})) bo, err := NewBackupOperation( ctx, diff --git a/src/internal/operations/restore_test.go b/src/internal/operations/restore_test.go index 401e1f687..6c6ff82ed 100644 --- a/src/internal/operations/restore_test.go +++ b/src/internal/operations/restore_test.go @@ -129,7 +129,8 @@ func (suite *RestoreOpIntegrationSuite) TestRestore_Run() { t := suite.T() ctx := context.Background() - m365User := "lidiah@8qzvrj.onmicrosoft.com" + m365UserID, err := tester.M365UserID() + require.NoError(suite.T(), err) acct, err := tester.NewM365Account() require.NoError(t, err) @@ -152,7 +153,7 @@ func (suite *RestoreOpIntegrationSuite) TestRestore_Run() { sw := store.NewKopiaStore(ms) bsel := selectors.NewExchangeBackup() - bsel.Include(bsel.Users([]string{m365User})) + bsel.Include(bsel.Users([]string{m365UserID})) bo, err := NewBackupOperation( ctx, @@ -166,7 +167,7 @@ func (suite *RestoreOpIntegrationSuite) TestRestore_Run() { require.NotEmpty(t, bo.Results.BackupID) rsel := selectors.NewExchangeRestore() - rsel.Include(rsel.Users([]string{m365User})) + rsel.Include(rsel.Users([]string{m365UserID})) ro, err := NewRestoreOperation( ctx, @@ -192,7 +193,8 @@ func (suite *RestoreOpIntegrationSuite) TestRestore_Run_ErrorNoResults() { t := suite.T() ctx := context.Background() - m365User := "lidiah@8qzvrj.onmicrosoft.com" + m365UserID, err := tester.M365UserID() + require.NoError(suite.T(), err) acct, err := tester.NewM365Account() require.NoError(t, err) @@ -215,7 +217,7 @@ func (suite *RestoreOpIntegrationSuite) TestRestore_Run_ErrorNoResults() { sw := store.NewKopiaStore(ms) bsel := selectors.NewExchangeBackup() - bsel.Include(bsel.Users([]string{m365User})) + bsel.Include(bsel.Users([]string{m365UserID})) bo, err := NewBackupOperation( ctx, diff --git a/src/internal/tester/account.go b/src/internal/tester/account.go index 33568502c..380876c86 100644 --- a/src/internal/tester/account.go +++ b/src/internal/tester/account.go @@ -16,7 +16,7 @@ var M365AcctCredEnvs = []string{ func NewM365Account() (account.Account, error) { cfg, err := readTestConfig() if err != nil { - return account.Account{}, errors.Wrap(err, "configuring m365 account from test file") + return account.Account{}, errors.Wrap(err, "configuring m365 account from test configuration") } return account.NewAccount( diff --git a/src/internal/tester/config.go b/src/internal/tester/config.go index 110afe3ce..f2104fd75 100644 --- a/src/internal/tester/config.go +++ b/src/internal/tester/config.go @@ -18,8 +18,29 @@ const ( // M365 config testCfgTenantID = "tenantid" + testCfgUserID = "m365userid" ) +// test specific env vars +const ( + EnvCorsoM365TestUserID = "CORSO_M356_TEST_USER_ID" +) + +// global to hold the test config results. +var testConfig map[string]string + +// call this instead of returning testConfig directly. +func cloneTestConfig() map[string]string { + if testConfig == nil { + return map[string]string{} + } + clone := map[string]string{} + for k, v := range testConfig { + clone[k] = v + } + return clone +} + func newTestViper() (*viper.Viper, error) { vpr := viper.New() @@ -48,6 +69,10 @@ func newTestViper() (*viper.Viper, error) { // local integration test controls. Populates values with // defaults where standard. func readTestConfig() (map[string]string, error) { + if testConfig != nil { + return cloneTestConfig(), nil + } + vpr, err := newTestViper() if err != nil { return nil, err @@ -66,8 +91,10 @@ func readTestConfig() (map[string]string, error) { fallbackTo(testEnv, testCfgEndpoint, vpr.GetString(testCfgEndpoint), "s3.amazonaws.com") fallbackTo(testEnv, testCfgPrefix, vpr.GetString(testCfgPrefix)) fallbackTo(testEnv, testCfgTenantID, os.Getenv(account.TenantID), vpr.GetString(testCfgTenantID)) + fallbackTo(testEnv, testCfgUserID, os.Getenv(EnvCorsoM365TestUserID), vpr.GetString(testCfgTenantID), "lidiah@8qzvrj.onmicrosoft.com") - return testEnv, nil + testConfig = testEnv + return cloneTestConfig(), nil } // writes the first non-zero valued string to the map at the key. diff --git a/src/internal/tester/users.go b/src/internal/tester/users.go new file mode 100644 index 000000000..23f81c022 --- /dev/null +++ b/src/internal/tester/users.go @@ -0,0 +1,18 @@ +package tester + +import ( + "github.com/pkg/errors" +) + +// M365UserID returns an userID string representing the m365UserID described +// by either the env var CORSO_M356_TEST_USER_ID, the corso_test.toml config +// file or the default value (in that order of priority). The default is a +// last-attempt fallback that will only work on alcion's testing org. +func M365UserID() (string, error) { + cfg, err := readTestConfig() + if err != nil { + return "", errors.Wrap(err, "retrieving m365 user id from test configuration") + } + + return cfg[testCfgUserID], nil +}