diff --git a/src/cmd/factory/exchange.go b/src/cmd/factory/exchange.go index 9d1ec81a2..7fe46f027 100644 --- a/src/cmd/factory/exchange.go +++ b/src/cmd/factory/exchange.go @@ -1,16 +1,11 @@ package main import ( - "time" - - "github.com/google/uuid" "github.com/spf13/cobra" . "github.com/alcionai/corso/src/cli/print" "github.com/alcionai/corso/src/cli/utils" - "github.com/alcionai/corso/src/internal/common" "github.com/alcionai/corso/src/internal/connector/mockconnector" - "github.com/alcionai/corso/src/pkg/control" "github.com/alcionai/corso/src/pkg/path" "github.com/alcionai/corso/src/pkg/selectors" ) @@ -57,69 +52,65 @@ func handleExchangeEmailFactory(cmd *cobra.Command, args []string) error { return Only(ctx, err) } - items := make([]item, 0, count) - - for i := 0; i < count; i++ { - var ( - now = common.Now() - nowLegacy = common.FormatLegacyTime(time.Now()) - id = uuid.NewString() - subject = "automated " + now[:16] + " - " + id[:8] - body = "automated mail generation for " + user + " at " + now + " - " + id - ) - - items = append(items, item{ - name: id, - // TODO: allow flags that specify a different "from" user, rather than duplicating - data: mockconnector.GetMockMessageWith( + deets, err := generateAndRestoreItems( + ctx, + gc, + service, + category, + selectors.NewExchangeRestore().Selector, + tenantID, user, destination, + count, + func(id, now, subject, body string) []byte { + return mockconnector.GetMockMessageWith( user, user, user, subject, body, - nowLegacy, nowLegacy, nowLegacy, nowLegacy), - }) - } - - collections := []collection{{ - pathElements: []string{destination}, - category: category, - items: items, - }} - - // TODO: fit the desination to the containers - dest := control.DefaultRestoreDestination(common.SimpleTimeTesting) - dest.ContainerName = destination - - dataColls, err := buildCollections( - service, - tenantID, user, - dest, - collections, + now, now, now, now) + }, ) if err != nil { return Only(ctx, err) } - Infof(ctx, "Generating %d emails in %s\n", count, destination) - - sel := selectors.NewExchangeRestore().Selector - - deets, err := gc.RestoreDataCollections(ctx, sel, dest, dataColls) - if err != nil { - return Only(ctx, err) - } - deets.PrintEntries(ctx) return nil } func handleExchangeCalendarEventFactory(cmd *cobra.Command, args []string) error { - Err(cmd.Context(), ErrNotYetImplemeted) + var ( + ctx = cmd.Context() + service = path.ExchangeService + category = path.EventsCategory + ) if utils.HasNoFlagsAndShownHelp(cmd) { return nil } - // generate mocked events + gc, tenantID, err := getGCAndVerifyUser(ctx, user) + if err != nil { + return Only(ctx, err) + } + + deets, err := generateAndRestoreItems( + ctx, + gc, + service, + category, + selectors.NewExchangeRestore().Selector, + tenantID, user, destination, + count, + func(id, now, subject, body string) []byte { + return mockconnector.GetMockEventWith( + user, subject, body, body, + now, now) + }, + ) + if err != nil { + return Only(ctx, err) + } + + deets.PrintEntries(ctx) return nil } diff --git a/src/cmd/factory/factory.go b/src/cmd/factory/factory.go index bc9d1f360..f87041445 100644 --- a/src/cmd/factory/factory.go +++ b/src/cmd/factory/factory.go @@ -3,7 +3,9 @@ package main import ( "context" "os" + "time" + "github.com/google/uuid" "github.com/pkg/errors" "github.com/spf13/cobra" @@ -13,10 +15,12 @@ import ( "github.com/alcionai/corso/src/internal/connector/mockconnector" "github.com/alcionai/corso/src/internal/data" "github.com/alcionai/corso/src/pkg/account" + "github.com/alcionai/corso/src/pkg/backup/details" "github.com/alcionai/corso/src/pkg/control" "github.com/alcionai/corso/src/pkg/credentials" "github.com/alcionai/corso/src/pkg/logger" "github.com/alcionai/corso/src/pkg/path" + "github.com/alcionai/corso/src/pkg/selectors" ) var factoryCmd = &cobra.Command{ @@ -93,6 +97,64 @@ func handleOneDriveFactory(cmd *cobra.Command, args []string) error { return cmd.Help() } +// ------------------------------------------------------------------------------------------ +// Restoration +// ------------------------------------------------------------------------------------------ + +type dataBuilderFunc func(id, now, subject, body string) []byte + +func generateAndRestoreItems( + ctx context.Context, + gc *connector.GraphConnector, + service path.ServiceType, + cat path.CategoryType, + sel selectors.Selector, + tenantID, userID, destFldr string, + howMany int, + dbf dataBuilderFunc, +) (*details.Details, error) { + items := make([]item, 0, howMany) + + for i := 0; i < howMany; i++ { + var ( + now = common.Now() + nowLegacy = common.FormatLegacyTime(time.Now()) + id = uuid.NewString() + subject = "automated " + now[:16] + " - " + id[:8] + body = "automated " + cat.String() + " generation for " + userID + " at " + now + " - " + id + ) + + items = append(items, item{ + name: id, + data: dbf(id, nowLegacy, subject, body), + }) + } + + collections := []collection{{ + pathElements: []string{destFldr}, + category: cat, + items: items, + }} + + // TODO: fit the desination to the containers + dest := control.DefaultRestoreDestination(common.SimpleTimeTesting) + dest.ContainerName = destFldr + + dataColls, err := buildCollections( + service, + tenantID, userID, + dest, + collections, + ) + if err != nil { + return nil, err + } + + Infof(ctx, "Generating %d %s items in %s\n", howMany, cat, destination) + + return gc.RestoreDataCollections(ctx, sel, dest, dataColls) +} + // ------------------------------------------------------------------------------------------ // Common Helpers // ------------------------------------------------------------------------------------------ diff --git a/src/internal/connector/exchange/event_test.go b/src/internal/connector/exchange/event_test.go index 910f23487..3feb723a1 100644 --- a/src/internal/connector/exchange/event_test.go +++ b/src/internal/connector/exchange/event_test.go @@ -5,6 +5,7 @@ import ( "time" "github.com/microsoftgraph/msgraph-sdk-go/models" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" @@ -26,8 +27,8 @@ func TestEventSuite(t *testing.T) { // can be properly retrieved from a models.Eventable object func (suite *EventSuite) TestEventInfo() { initial := time.Now() - now := common.FormatTime(initial) + suite.T().Logf("Initial: %v\nFormatted: %v\n", initial, now) tests := []struct { @@ -37,56 +38,67 @@ func (suite *EventSuite) TestEventInfo() { { name: "Empty event", evtAndRP: func() (models.Eventable, *details.ExchangeInfo) { - i := &details.ExchangeInfo{ItemType: details.ExchangeEvent} - return models.NewEvent(), i + return models.NewEvent(), &details.ExchangeInfo{ + ItemType: details.ExchangeEvent, + } }, }, { name: "Start time only", evtAndRP: func() (models.Eventable, *details.ExchangeInfo) { - event := models.NewEvent() - dateTime := models.NewDateTimeTimeZone() + var ( + event = models.NewEvent() + dateTime = models.NewDateTimeTimeZone() + full, err = common.ParseTime(now) + ) + + require.NoError(suite.T(), err) + dateTime.SetDateTime(&now) event.SetStart(dateTime) - full, err := common.ParseTime(now) - require.NoError(suite.T(), err) - i := &details.ExchangeInfo{ + + return event, &details.ExchangeInfo{ ItemType: details.ExchangeEvent, Received: full, } - return event, i }, }, { name: "Subject Only", evtAndRP: func() (models.Eventable, *details.ExchangeInfo) { - subject := "Hello Corso" - event := models.NewEvent() + var ( + subject = "Hello Corso" + event = models.NewEvent() + ) + event.SetSubject(&subject) - i := &details.ExchangeInfo{ + + return event, &details.ExchangeInfo{ ItemType: details.ExchangeEvent, Subject: subject, } - return event, i }, }, { name: "Using mockable", evtAndRP: func() (models.Eventable, *details.ExchangeInfo) { - bytes := mockconnector.GetMockEventBytes("Test Mock") - event, err := support.CreateEventFromBytes(bytes) + var ( + organizer = "foobar3@8qzvrj.onmicrosoft.com" + subject = " Test Mock Review + Lunch" + bytes = mockconnector.GetDefaultMockEventBytes("Test Mock") + future = time.Now().UTC().AddDate(0, 0, 1) + eventTime = time.Date(future.Year(), future.Month(), future.Day(), future.Hour(), 0, 0, 0, time.UTC) + event, err = support.CreateEventFromBytes(bytes) + ) + require.NoError(suite.T(), err) - subject := " Test Mock Review + Lunch" - organizer := "foobar3@8qzvrj.onmicrosoft.com" - future := time.Now().AddDate(0, 0, 1) - eventTime := time.Date(2022, future.Month(), future.Day(), 6, 0, 0, 0, time.UTC) - i := &details.ExchangeInfo{ + + return event, &details.ExchangeInfo{ ItemType: details.ExchangeEvent, Subject: subject, Organizer: organizer, EventStart: eventTime, } - return event, i }, }, } @@ -94,17 +106,20 @@ func (suite *EventSuite) TestEventInfo() { suite.T().Run(test.name, func(t *testing.T) { event, expected := test.evtAndRP() result := EventInfo(event) - suite.Equal(expected.Subject, result.Subject) - suite.Equal(expected.Sender, result.Sender) + + assert.Equal(t, expected.Subject, result.Subject, "subject") + assert.Equal(t, expected.Sender, result.Sender, "sender") + expYear, expMonth, _ := expected.EventStart.Date() // Day not used at certain times of the day expHr, expMin, expSec := expected.EventStart.Clock() recvYear, recvMonth, _ := result.EventStart.Date() recvHr, recvMin, recvSec := result.EventStart.Clock() - suite.Equal(expYear, recvYear) - suite.Equal(expMonth, recvMonth) - suite.Equal(expHr, recvHr) - suite.Equal(expMin, recvMin) - suite.Equal(expSec, recvSec) + + assert.Equal(t, expYear, recvYear, "year") + assert.Equal(t, expMonth, recvMonth, "month") + assert.Equal(t, expHr, recvHr, "hour") + assert.Equal(t, expMin, recvMin, "minute") + assert.Equal(t, expSec, recvSec, "second") }) } } diff --git a/src/internal/connector/exchange/exchange_service_test.go b/src/internal/connector/exchange/exchange_service_test.go index 5a899916e..d78785ff3 100644 --- a/src/internal/connector/exchange/exchange_service_test.go +++ b/src/internal/connector/exchange/exchange_service_test.go @@ -465,7 +465,7 @@ func (suite *ExchangeServiceSuite) TestRestoreExchangeObject() { }, { name: "Test Events", - bytes: mockconnector.GetMockEventBytes("Restored Event Object"), + bytes: mockconnector.GetDefaultMockEventBytes("Restored Event Object"), category: path.EventsCategory, cleanupFunc: DeleteCalendar, destination: func(ctx context.Context) string { diff --git a/src/internal/connector/mockconnector/mock_data_collection_test.go b/src/internal/connector/mockconnector/mock_data_collection_test.go index 7b82b9b48..af0f5a5b7 100644 --- a/src/internal/connector/mockconnector/mock_data_collection_test.go +++ b/src/internal/connector/mockconnector/mock_data_collection_test.go @@ -145,7 +145,7 @@ func (suite *MockExchangeDataSuite) TestMockByteHydration() { }, { name: "Event No Attendees Bytes", transformation: func(t *testing.T) error { - bytes := mockconnector.GetMockEventBytes(subject) + bytes := mockconnector.GetDefaultMockEventBytes(subject) _, err := support.CreateEventFromBytes(bytes) return err }, diff --git a/src/internal/connector/mockconnector/mock_data_event.go b/src/internal/connector/mockconnector/mock_data_event.go new file mode 100644 index 000000000..1b7ed33ea --- /dev/null +++ b/src/internal/connector/mockconnector/mock_data_event.go @@ -0,0 +1,194 @@ +package mockconnector + +import ( + "fmt" + "math/rand" + "strconv" + "strings" + "time" + + "github.com/alcionai/corso/src/internal/common" +) + +// Order of fields to fill in: +// 1. body +// 2. body preview +// 3. endDate (rfc3339nano) +// 4. organizer email +// 5. start date (rfc3339nano) +// 6. subject +//nolint:lll +const ( + eventTmpl = `{ + "id":"AAMkAGZmNjNlYjI3LWJlZWYtNGI4Mi04YjMyLTIxYThkNGQ4NmY1MwBGAAAAAADCNgjhM9QmQYWNcI7hCpPrBwDSEBNbUIB9RL6ePDeF3FIYAAAAAAENAADSEBNbUIB9RL6ePDeF3FIYAAAAAG76AAA=", + "calendar@odata.navigationLink":"https://graph.microsoft.com/v1.0/users('foobar@8qzvrj.onmicrosoft.com')/calendars('AAMkAGZmNjNlYjI3LWJlZWYtNGI4Mi04YjMyLTIxYThkNGQ4NmY1MwAuAAAAAADCNgjhM9QmQYWNcI7hCpPrAQDSEBNbUIB9RL6ePDeF3FIYAAAAAAENAAA=')", + "calendar@odata.associationLink":"https://graph.microsoft.com/v1.0/users('foobar@8qzvrj.onmicrosoft.com')/calendars('AAMkAGZmNjNlYjI3LWJlZWYtNGI4Mi04YjMyLTIxYThkNGQ4NmY1MwAuAAAAAADCNgjhM9QmQYWNcI7hCpPrAQDSEBNbUIB9RL6ePDeF3FIYAAAAAAENAAA=')/$ref", + "@odata.etag":"W/\"0hATW1CAfUS+njw3hdxSGAAAJIxNug==\"", + "@odata.context":"https://graph.microsoft.com/v1.0/$metadata#users('foobar%%408qzvrj.onmicrosoft.com')/events/$entity", + "categories":[], + "changeKey":"0hATW1CAfUS+njw3hdxSGAAAJIxNug==", + "createdDateTime":"2022-03-28T03:42:03Z", + "lastModifiedDateTime":"2022-05-26T19:25:58Z", + "allowNewTimeProposals":true, + "attendees":[], + "body":{ + "content":"\\r\\n\\r\\n\\r\\n\\r\\n\\r\\n` + + `

%s

\\r\\n\\r\\n\\r\\n", + "contentType":"html" + }, + "bodyPreview":"%s", + "end":{ + "dateTime":"%s", + "timeZone":"UTC" + }, + "hasAttachments":false, + "hideAttendees":false, + "iCalUId":"040000008200E00074C5B7101A82E0080000000035723BC75542D801000000000000000010000000E1E7C8F785242E4894DA13AEFB947B85", + "importance":"normal", + "isAllDay":false, + "isCancelled":false, + "isDraft":false, + "isOnlineMeeting":false, + "isOrganizer":false, + "isReminderOn":true, + "location":{ + "displayName":"Umi Sake House (2230 1st Ave, Seattle, WA 98121 US)", + "locationType":"default", + "uniqueId":"Umi Sake House (2230 1st Ave, Seattle, WA 98121 US)", + "uniqueIdType":"private" + }, + "locations":[ + { + "displayName":"Umi Sake House (2230 1st Ave, Seattle, WA 98121 US)", + "locationType":"default", + "uniqueId":"", + "uniqueIdType":"unknown" + } + ], + "onlineMeetingProvider":"unknown", + "organizer":{ + "emailAddress":{ + "address":"%s", + "name":"Anu Pierson" + } + }, + "originalEndTimeZone":"UTC", + "originalStartTimeZone":"UTC", + "reminderMinutesBeforeStart":15, + "responseRequested":true, + "responseStatus":{ + "response":"notResponded", + "time":"0001-01-01T00:00:00Z" + }, + "sensitivity":"normal", + "showAs":"tentative", + "start":{ + "dateTime":"%s", + "timeZone":"UTC" + }, + "subject":"%s", + "type":"singleInstance", + "webLink":"https://outlook.office365.com/owa/?itemid=AAMkAGZmNjNlYjI3LWJlZWYtNGI4Mi04YjMyLTIxYThkNGQ4NmY1MwBGAAAAAADCNgjhM9QmQYWNcI7hCpPrBwDSEBNbUIB9RL6ePDeF3FIYAAAAAAENAADSEBNbUIB9RL6ePDeF3FIYAAAAAG76AAA%%3D&exvsurl=1&path=/calendar/item" +}` + + defaultEventBody = "This meeting is to review the latest Tailspin Toys project proposal.
\\r\\nBut why not eat some sushi while we’re at it? :)" + defaultEventBodyPreview = "This meeting is to review the latest Tailspin Toys project proposal.\\r\\nBut why not eat some sushi while we’re at it? :)" + defaultEventOrganizer = "foobar@8qzvrj.onmicrosoft.com" +) + +// generatePhoneNumber creates a random phone number +// @return string representation in format (xxx)xxx-xxxx +func generatePhoneNumber() string { + numbers := make([]string, 0) + + for i := 0; i < 10; i++ { + temp := rand.Intn(10) + value := strconv.Itoa(temp) + numbers = append(numbers, value) + } + + area := strings.Join(numbers[:3], "") + prefix := strings.Join(numbers[3:6], "") + suffix := strings.Join(numbers[6:], "") + phoneNo := "(" + area + ")" + prefix + "-" + suffix + + return phoneNo +} + +// GetMockEventBytes returns test byte array representative of full Eventable item. +func GetDefaultMockEventBytes(subject string) []byte { + return GetMockEventWithSubjectBytes(" " + subject + " Review + Lunch") +} + +func GetMockEventWithSubjectBytes(subject string) []byte { + tomorrow := time.Now().UTC().AddDate(0, 0, 1) + at := time.Date(tomorrow.Year(), tomorrow.Month(), tomorrow.Day(), tomorrow.Hour(), 0, 0, 0, time.UTC) + atTime := common.FormatTime(at) + + return GetMockEventWith( + defaultEventOrganizer, subject, + defaultEventBody, defaultEventBodyPreview, + atTime, atTime, + ) +} + +// GetMockEventWith returns bytes for an Eventable item. +// The event has no attendees. +// start and end times should be in the format 2006-01-02T15:04:05.0000000Z. +// The timezone (Z) will be automatically stripped. A non-utc timezone may +// produce unexpected results. +// Body must contain a well-formatted string, consumable in a json payload. IE: no unescaped newlines. +func GetMockEventWith( + organizer, subject, body, bodyPreview, + startDateTime, endDateTime string, +) []byte { + startDateTime = strings.TrimSuffix(startDateTime, "Z") + endDateTime = strings.TrimSuffix(endDateTime, "Z") + + if len(startDateTime) == len("2022-10-19T20:00:00") { + startDateTime += ".0000000" + } + + if len(endDateTime) == len("2022-10-19T20:00:00") { + endDateTime += ".0000000" + } + + return []byte(fmt.Sprintf( + eventTmpl, + body, + bodyPreview, + endDateTime, + organizer, + startDateTime, + subject, + )) +} + +func GetMockEventWithAttendeesBytes(subject string) []byte { + newTime := time.Now().AddDate(0, 0, 1) + conversion := common.FormatTime(newTime) + timeSlice := strings.Split(conversion, "T") + + //nolint:lll + event := "{\"id\":\"AAMkAGZmNjNlYjI3LWJlZWYtNGI4Mi04YjMyLTIxYThkNGQ4NmY1MwBGAAAAAADCNgjhM9QmQYWNcI7hCpPrBwDSEBNbUIB9RL6ePDeF3FIYAAAAAAENAADSEBNbUIB9RL6ePDeF3FIYAABU_FdvAAA=\",\"@odata.etag\":\"W/\\\"0hATW1CAfUS+njw3hdxSGAAAVK7j9A==\\\"\"," + + "\"calendar@odata.associationLink\":\"https://graph.microsoft.com/v1.0/users('a4a472f8-ccb0-43ec-bf52-3697a91b926c')/calendars('AAMkAGZmNjNlYjI3LWJlZWYtNGI4Mi04YjMyLTIxYThkNGQ4NmY1MwAuAAAAAADCNgjhM9QmQYWNcI7hCpPrAQDSEBNbUIB9RL6ePDeF3FIYAAAAAAENAAA=')/$ref\"," + + "\"calendar@odata.navigationLink\":\"https://graph.microsoft.com/v1.0/users('a4a472f8-ccb0-43ec-bf52-3697a91b926c')/calendars('AAMkAGZmNjNlYjI3LWJlZWYtNGI4Mi04YjMyLTIxYThkNGQ4NmY1MwAuAAAAAADCNgjhM9QmQYWNcI7hCpPrAQDSEBNbUIB9RL6ePDeF3FIYAAAAAAENAAA=')\"," + + "\"@odata.context\":\"https://graph.microsoft.com/v1.0/$metadata#users('a4a472f8-ccb0-43ec-bf52-3697a91b926c')/events/$entity\",\"categories\":[],\"changeKey\":\"0hATW1CAfUS+njw3hdxSGAAAVK7j9A==\",\"createdDateTime\":\"2022-08-06T12:47:56Z\",\"lastModifiedDateTime\":\"2022-08-06T12:49:59Z\",\"allowNewTimeProposals\":true," + + "\"attendees\":[{\"emailAddress\":{\"address\":\"george.martinez@8qzvrj.onmicrosoft.com\",\"name\":\"George Martinez\"},\"type\":\"required\",\"status\":{\"response\":\"none\",\"time\":\"0001-01-01T00:00:00Z\"}},{\"emailAddress\":{\"address\":\"LeeG@8qzvrj.onmicrosoft.com\",\"name\":\"Lee Gu\"},\"type\":\"required\",\"status\":{\"response\":\"none\",\"time\":\"0001-01-01T00:00:00Z\"}}]," + + "\"body\":{\"content\":\"\\n\\n\\n\\n\\n
\\nDiscuss matters concerning stock options and early release of quarterly earnings.
\\n
" + + "\\n
________________________________________________________________________________\\n
\\n
" + + "\\n
Microsoft Teams meeting\\n
\\n
\\n
Join on your computer or mobile app" + + "\\n
\\nClick\\n here to join the meeting
" + + "\\n
\\n
Meeting ID:\\n292 784 521 247
\\nPasscode: SzBkfK\\n" + + "\\n
Download\\n Teams | " + + "\\nJoin on the web
\\n
\\n
\\n
Learn more" + + "\\n | " + + "\\nMeeting options
\\n
\\n
\\n
\\n
\\n
\\n
________________________________________________________________________________" + + "\\n
\\n\\n\\n\",\"contentType\":\"html\"},\"bodyPreview\":\"Discuss matters concerning stock options and early release of quarterly earnings.\\n\\n\", " + + "\"end\":{\"dateTime\":\"" + timeSlice[0] + "T16:00:00.0000000\",\"timeZone\":\"UTC\"},\"hasAttachments\":false,\"hideAttendees\":false,\"iCalUId\":\"040000008200E00074C5B7101A82E0080000000010A45EC092A9D801000000000000000010000000999C7C6281C2B24A91D5502392B8EF38\",\"importance\":\"normal\",\"isAllDay\":false,\"isCancelled\":false,\"isDraft\":false,\"isOnlineMeeting\":true,\"isOrganizer\":true,\"isReminderOn\":true," + + "\"location\":{\"address\":{},\"coordinates\":{},\"displayName\":\"\",\"locationType\":\"default\",\"uniqueIdType\":\"unknown\"},\"locations\":[],\"onlineMeeting\":{\"joinUrl\":\"https://teams.microsoft.com/l/meetup-join/19%3ameeting_YWNhMzAxZjItMzE2My00ZGQzLTkzMDUtNjQ3NTY0NjNjMTZi%40thread.v2/0?context=%7b%22Tid%22%3a%224d603060-18d6-4764-b9be-4cb794d32b69%22%2c%22Oid%22%3a%22a4a472f8-ccb0-43ec-bf52-3697a91b926c%22%7d\"},\"onlineMeetingProvider\":\"teamsForBusiness\"," + + "\"organizer\":{\"emailAddress\":{\"address\":\"LidiaH@8qzvrj.onmicrosoft.com\",\"name\":\"Lidia Holloway\"}},\"originalEndTimeZone\":\"Eastern Standard Time\",\"originalStartTimeZone\":\"Eastern Standard Time\",\"reminderMinutesBeforeStart\":15,\"responseRequested\":true,\"responseStatus\":{\"response\":\"organizer\",\"time\":\"0001-01-01T00:00:00Z\"},\"sensitivity\":\"normal\",\"showAs\":\"busy\"," + + "\"start\":{\"dateTime\":\"" + timeSlice[0] + "T15:30:00.0000000\",\"timeZone\":\"UTC\"},\"subject\":\"Board " + subject + " Meeting\",\"transactionId\":\"28b36295-6cd3-952f-d8f5-deb313444a51\",\"type\":\"singleInstance\",\"webLink\":\"https://outlook.office365.com/owa/?itemid=AAMkAGZmNjNlYjI3LWJlZWYtNGI4Mi04YjMyLTIxYThkNGQ4NmY1MwBGAAAAAADCNgjhM9QmQYWNcI7hCpPrBwDSEBNbUIB9RL6ePDeF3FIYAAAAAAENAADSEBNbUIB9RL6ePDeF3FIYAABU%2BFdvAAA%3D&exvsurl=1&path=/calendar/item\"}" + + return []byte(event) +} diff --git a/src/internal/connector/mockconnector/mock_data_message.go b/src/internal/connector/mockconnector/mock_data_message.go index 4d302f31a..5dc3fe6c2 100644 --- a/src/internal/connector/mockconnector/mock_data_message.go +++ b/src/internal/connector/mockconnector/mock_data_message.go @@ -3,10 +3,6 @@ package mockconnector import ( "encoding/base64" "fmt" - "math/rand" - "strconv" - "strings" - "time" "github.com/alcionai/corso/src/internal/common" ) @@ -89,28 +85,6 @@ const ( ], "webLink":"https://outlook.office365.com/owa/?ItemID=AAMkAGZmNjNlYjI3LWJlZWYtNGI4Mi04YjMyLTIxYThkNGQ4NmY1MwBGAAAAAADCNgjhM9QmQYWNcI7hCpPrBwDSEBNbUIB9RL6ePDeF3FIYAAAAAAEMAADSEBNbUIB9RL6ePDeF3FIYAAB3XwIkAAA%%3D&exvsurl=1&viewmodel=ReadMessageItem" }` - - // Order of fields to fill in: - // 1. start/end date - // 2. subject - eventTmpl = "{\"id\":\"AAMkAGZmNjNlYjI3LWJlZWYtNGI4Mi04YjMyLTIxYThkNGQ4NmY1MwBGAAAAAADCNgjhM9QmQYWNcI7hCpPrBwDSEBNbUIB9RL6ePDeF3FIYAAAAAAENAADSEBNbUIB9RL6ePDeF3FIYAAAAAG76AAA=\",\"calendar@odata.navigationLink\":" + - "\"https://graph.microsoft.com/v1.0/users('foobar@8qzvrj.onmicrosoft.com')/calendars('AAMkAGZmNjNlYjI3LWJlZWYtNGI4Mi04YjMyLTIxYThkNGQ4NmY1MwAuAAAAAADCNgjhM9QmQYWNcI7hCpPrAQDSEBNbUIB9RL6ePDeF3FIYAAAAAAENAAA=')\"," + - "\"calendar@odata.associationLink\":\"https://graph.microsoft.com/v1.0/users('foobar@8qzvrj.onmicrosoft.com')/calendars('AAMkAGZmNjNlYjI3LWJlZWYtNGI4Mi04YjMyLTIxYThkNGQ4NmY1MwAuAAAAAADCNgjhM9QmQYWNcI7hCpPrAQDSEBNbUIB9RL6ePDeF3FIYAAAAAAENAAA=')/$ref\"," + - "\"@odata.etag\":\"W/\\\"0hATW1CAfUS+njw3hdxSGAAAJIxNug==\\\"\",\"@odata.context\":\"https://graph.microsoft.com/v1.0/$metadata#users('foobar%%408qzvrj.onmicrosoft.com')/events/$entity\",\"categories\":[],\"changeKey\":\"0hATW1CAfUS+njw3hdxSGAAAJIxNug==\"," + - "\"createdDateTime\":\"2022-03-28T03:42:03Z\",\"lastModifiedDateTime\":\"2022-05-26T19:25:58Z\",\"allowNewTimeProposals\":true,\"attendees\"" + - ":[],\"body\":{\"content\":\"\\r\\n\\r\\n\\r\\n\\r\\n\\r\\n" + - "

This meeting is to review the latest Tailspin Toys project proposal.
\\r\\nBut why not eat some sushi while we’re at it? :)

\\r\\n\\r\\n\\r\\n\"" + - ",\"contentType\":\"html\"},\"bodyPreview\":\"This meeting is to review the latest Tailspin Toys project proposal.\\r\\nBut why not eat some sushi while we’re at it? :)\"," + - "\"end\":{\"dateTime\":\"%[1]sT07:00:00.0000000\",\"timeZone\":\"UTC\"},\"hasAttachments\":false,\"hideAttendees\":false,\"iCalUId\":" + - "\"040000008200E00074C5B7101A82E0080000000035723BC75542D801000000000000000010000000E1E7C8F785242E4894DA13AEFB947B85\",\"importance\":\"normal\",\"isAllDay\":false,\"isCancelled\":false," + - "\"isDraft\":false,\"isOnlineMeeting\":false,\"isOrganizer\":false,\"isReminderOn\":true," + - "\"location\":{\"displayName\":\"Umi Sake House (2230 1st Ave, Seattle, WA 98121 US)\",\"locationType\":\"default\",\"uniqueId\":\"Umi Sake House (2230 1st Ave, Seattle, WA 98121 US)\"," + - "\"uniqueIdType\":\"private\"},\"locations\":[{\"displayName\":\"Umi Sake House (2230 1st Ave, Seattle, WA 98121 US)\",\"locationType\":\"default\",\"uniqueId\":\"\",\"uniqueIdType\":\"unknown\"}],\"onlineMeetingProvider\":\"unknown\",\"organizer\"" + - ":{\"emailAddress\":{\"address\":\"foobar3@8qzvrj.onmicrosoft.com\",\"name\":\"Anu Pierson\"}},\"originalEndTimeZone\":\"UTC\",\"originalStartTimeZone\":\"UTC\"," + - "\"reminderMinutesBeforeStart\":15,\"responseRequested\":true,\"responseStatus\":{\"response\":\"notResponded\",\"time\":\"0001-01-01T00:00:00Z\"},\"sensitivity\":\"normal\",\"showAs\":\"tentative\"," + - "\"start\":{\"dateTime\":\"%[1]sT06:00:00.0000000\",\"timeZone\":\"UTC\"}," + - "\"subject\":\"%s\"," + - "\"type\":\"singleInstance\",\"webLink\":\"https://outlook.office365.com/owa/?itemid=AAMkAGZmNjNlYjI3LWJlZWYtNGI4Mi04YjMyLTIxYThkNGQ4NmY1MwBGAAAAAADCNgjhM9QmQYWNcI7hCpPrBwDSEBNbUIB9RL6ePDeF3FIYAAAAAAENAADSEBNbUIB9RL6ePDeF3FIYAAAAAG76AAA%%3D&exvsurl=1&path=/calendar/item\"}" ) // GetMockMessageBytes returns bytes for a Messageable item. @@ -162,7 +136,7 @@ func GetMockMessageWithBodyBytes(subject, body string) []byte { return []byte(message) } -// GetMockMessageBytes returns bytes for a Messageable item. +// GetMockMessageWith returns bytes for a Messageable item. // Contents verified as working with sample data from kiota-serialization-json-go v0.5.5 // created, modified, sent, and received should be in the format 2006-01-02T15:04:05Z // Body must contain a well-formatted string, consumable in a json payload. IE: no unescaped newlines. @@ -341,73 +315,3 @@ func GetMockContactBytes(middleName string) []byte { return []byte(contact) } - -// generatePhoneNumber creates a random phone number -// @return string representation in format (xxx)xxx-xxxx -func generatePhoneNumber() string { - numbers := make([]string, 0) - - for i := 0; i < 10; i++ { - temp := rand.Intn(10) - value := strconv.Itoa(temp) - numbers = append(numbers, value) - } - - area := strings.Join(numbers[:3], "") - prefix := strings.Join(numbers[3:6], "") - suffix := strings.Join(numbers[6:], "") - phoneNo := "(" + area + ")" + prefix + "-" + suffix - - return phoneNo -} - -// GetMockEventBytes returns test byte array representative of full Eventable item. -func GetMockEventBytes(subject string) []byte { - newTime := time.Now().AddDate(0, 0, 1) - conversion := common.FormatTime(newTime) - timeSlice := strings.Split(conversion, "T") - fullSubject := " " + subject + " Review + Lunch" - - formatted := fmt.Sprintf(eventTmpl, timeSlice[0], fullSubject) - - return []byte(formatted) -} - -func GetMockEventWithSubjectBytes(subject string) []byte { - newTime := time.Now().AddDate(0, 0, 1) - conversion := common.FormatTime(newTime) - timeSlice := strings.Split(conversion, "T") - - formatted := fmt.Sprintf(eventTmpl, timeSlice[0], subject) - - return []byte(formatted) -} - -func GetMockEventWithAttendeesBytes(subject string) []byte { - newTime := time.Now().AddDate(0, 0, 1) - conversion := common.FormatTime(newTime) - timeSlice := strings.Split(conversion, "T") - - //nolint:lll - event := "{\"id\":\"AAMkAGZmNjNlYjI3LWJlZWYtNGI4Mi04YjMyLTIxYThkNGQ4NmY1MwBGAAAAAADCNgjhM9QmQYWNcI7hCpPrBwDSEBNbUIB9RL6ePDeF3FIYAAAAAAENAADSEBNbUIB9RL6ePDeF3FIYAABU_FdvAAA=\",\"@odata.etag\":\"W/\\\"0hATW1CAfUS+njw3hdxSGAAAVK7j9A==\\\"\"," + - "\"calendar@odata.associationLink\":\"https://graph.microsoft.com/v1.0/users('a4a472f8-ccb0-43ec-bf52-3697a91b926c')/calendars('AAMkAGZmNjNlYjI3LWJlZWYtNGI4Mi04YjMyLTIxYThkNGQ4NmY1MwAuAAAAAADCNgjhM9QmQYWNcI7hCpPrAQDSEBNbUIB9RL6ePDeF3FIYAAAAAAENAAA=')/$ref\"," + - "\"calendar@odata.navigationLink\":\"https://graph.microsoft.com/v1.0/users('a4a472f8-ccb0-43ec-bf52-3697a91b926c')/calendars('AAMkAGZmNjNlYjI3LWJlZWYtNGI4Mi04YjMyLTIxYThkNGQ4NmY1MwAuAAAAAADCNgjhM9QmQYWNcI7hCpPrAQDSEBNbUIB9RL6ePDeF3FIYAAAAAAENAAA=')\"," + - "\"@odata.context\":\"https://graph.microsoft.com/v1.0/$metadata#users('a4a472f8-ccb0-43ec-bf52-3697a91b926c')/events/$entity\",\"categories\":[],\"changeKey\":\"0hATW1CAfUS+njw3hdxSGAAAVK7j9A==\",\"createdDateTime\":\"2022-08-06T12:47:56Z\",\"lastModifiedDateTime\":\"2022-08-06T12:49:59Z\",\"allowNewTimeProposals\":true," + - "\"attendees\":[{\"emailAddress\":{\"address\":\"george.martinez@8qzvrj.onmicrosoft.com\",\"name\":\"George Martinez\"},\"type\":\"required\",\"status\":{\"response\":\"none\",\"time\":\"0001-01-01T00:00:00Z\"}},{\"emailAddress\":{\"address\":\"LeeG@8qzvrj.onmicrosoft.com\",\"name\":\"Lee Gu\"},\"type\":\"required\",\"status\":{\"response\":\"none\",\"time\":\"0001-01-01T00:00:00Z\"}}]," + - "\"body\":{\"content\":\"\\n\\n\\n\\n\\n
\\nDiscuss matters concerning stock options and early release of quarterly earnings.
\\n
" + - "\\n
________________________________________________________________________________\\n
\\n
" + - "\\n
Microsoft Teams meeting\\n
\\n
\\n
Join on your computer or mobile app" + - "\\n
\\nClick\\n here to join the meeting
" + - "\\n
\\n
Meeting ID:\\n292 784 521 247
\\nPasscode: SzBkfK\\n" + - "\\n
Download\\n Teams | " + - "\\nJoin on the web
\\n
\\n
\\n
Learn more" + - "\\n | " + - "\\nMeeting options
\\n
\\n
\\n
\\n
\\n
\\n
________________________________________________________________________________" + - "\\n
\\n\\n\\n\",\"contentType\":\"html\"},\"bodyPreview\":\"Discuss matters concerning stock options and early release of quarterly earnings.\\n\\n\", " + - "\"end\":{\"dateTime\":\"" + timeSlice[0] + "T16:00:00.0000000\",\"timeZone\":\"UTC\"},\"hasAttachments\":false,\"hideAttendees\":false,\"iCalUId\":\"040000008200E00074C5B7101A82E0080000000010A45EC092A9D801000000000000000010000000999C7C6281C2B24A91D5502392B8EF38\",\"importance\":\"normal\",\"isAllDay\":false,\"isCancelled\":false,\"isDraft\":false,\"isOnlineMeeting\":true,\"isOrganizer\":true,\"isReminderOn\":true," + - "\"location\":{\"address\":{},\"coordinates\":{},\"displayName\":\"\",\"locationType\":\"default\",\"uniqueIdType\":\"unknown\"},\"locations\":[],\"onlineMeeting\":{\"joinUrl\":\"https://teams.microsoft.com/l/meetup-join/19%3ameeting_YWNhMzAxZjItMzE2My00ZGQzLTkzMDUtNjQ3NTY0NjNjMTZi%40thread.v2/0?context=%7b%22Tid%22%3a%224d603060-18d6-4764-b9be-4cb794d32b69%22%2c%22Oid%22%3a%22a4a472f8-ccb0-43ec-bf52-3697a91b926c%22%7d\"},\"onlineMeetingProvider\":\"teamsForBusiness\"," + - "\"organizer\":{\"emailAddress\":{\"address\":\"LidiaH@8qzvrj.onmicrosoft.com\",\"name\":\"Lidia Holloway\"}},\"originalEndTimeZone\":\"Eastern Standard Time\",\"originalStartTimeZone\":\"Eastern Standard Time\",\"reminderMinutesBeforeStart\":15,\"responseRequested\":true,\"responseStatus\":{\"response\":\"organizer\",\"time\":\"0001-01-01T00:00:00Z\"},\"sensitivity\":\"normal\",\"showAs\":\"busy\"," + - "\"start\":{\"dateTime\":\"" + timeSlice[0] + "T15:30:00.0000000\",\"timeZone\":\"UTC\"},\"subject\":\"Board " + subject + " Meeting\",\"transactionId\":\"28b36295-6cd3-952f-d8f5-deb313444a51\",\"type\":\"singleInstance\",\"webLink\":\"https://outlook.office365.com/owa/?itemid=AAMkAGZmNjNlYjI3LWJlZWYtNGI4Mi04YjMyLTIxYThkNGQ4NmY1MwBGAAAAAADCNgjhM9QmQYWNcI7hCpPrBwDSEBNbUIB9RL6ePDeF3FIYAAAAAAENAADSEBNbUIB9RL6ePDeF3FIYAABU%2BFdvAAA%3D&exvsurl=1&path=/calendar/item\"}" - - return []byte(event) -} diff --git a/src/internal/connector/support/m365Support_test.go b/src/internal/connector/support/m365Support_test.go index 3e1fc1818..a73fb2d91 100644 --- a/src/internal/connector/support/m365Support_test.go +++ b/src/internal/connector/support/m365Support_test.go @@ -106,7 +106,7 @@ func (suite *DataSupportSuite) TestCreateEventFromBytes() { }, { name: "Valid Event", - byteArray: mockconnector.GetMockEventBytes("Event Test"), + byteArray: mockconnector.GetDefaultMockEventBytes("Event Test"), checkError: assert.NoError, isNil: assert.NotNil, },