From f57b0f1f7e43310c39f3c652e1936391a1f96a87 Mon Sep 17 00:00:00 2001 From: Keepers Date: Thu, 20 Oct 2022 10:58:12 -0600 Subject: [PATCH] add contact generation to the factory script (#1202) ## Type of change - [x] :robot: Test ## Issue(s) * #902 ## Test Plan - [x] :muscle: Manual - [x] :green_heart: E2E --- src/cmd/factory/exchange.go | 38 ++++++++- src/cmd/factory/factory.go | 9 ++- .../connector/graph_connector_test.go | 3 + .../mockconnector/mock_data_contact.go | 75 ++++++++++++++++++ .../mockconnector/mock_data_message.go | 78 +++++++------------ 5 files changed, 147 insertions(+), 56 deletions(-) create mode 100644 src/internal/connector/mockconnector/mock_data_contact.go diff --git a/src/cmd/factory/exchange.go b/src/cmd/factory/exchange.go index 7fe46f027..24f4bfb15 100644 --- a/src/cmd/factory/exchange.go +++ b/src/cmd/factory/exchange.go @@ -63,7 +63,7 @@ func handleExchangeEmailFactory(cmd *cobra.Command, args []string) error { func(id, now, subject, body string) []byte { return mockconnector.GetMockMessageWith( user, user, user, - subject, body, + subject, body, body, now, now, now, now) }, ) @@ -116,13 +116,45 @@ func handleExchangeCalendarEventFactory(cmd *cobra.Command, args []string) error } func handleExchangeContactFactory(cmd *cobra.Command, args []string) error { - Err(cmd.Context(), ErrNotYetImplemeted) + var ( + ctx = cmd.Context() + service = path.ExchangeService + category = path.ContactsCategory + ) if utils.HasNoFlagsAndShownHelp(cmd) { return nil } - // generate mocked contacts + 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 { + given, mid, sur := id[:8], id[9:13], id[len(id)-12:] + + return mockconnector.GetMockContactBytesWith( + given+" "+sur, + sur+", "+given, + given, mid, sur, + "123-456-7890", + ) + }, + ) + 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 f87041445..9cd201b9e 100644 --- a/src/cmd/factory/factory.go +++ b/src/cmd/factory/factory.go @@ -3,6 +3,7 @@ package main import ( "context" "os" + "strings" "time" "github.com/google/uuid" @@ -179,7 +180,13 @@ func getGCAndVerifyUser(ctx context.Context, userID string) (*connector.GraphCon return nil, "", errors.Wrap(err, "connecting to graph api") } - if _, ok := gc.Users[user]; !ok { + normUsers := map[string]struct{}{} + + for k := range gc.Users { + normUsers[strings.ToLower(k)] = struct{}{} + } + + if _, ok := normUsers[strings.ToLower(user)]; !ok { return nil, "", errors.New("user not found within tenant") } diff --git a/src/internal/connector/graph_connector_test.go b/src/internal/connector/graph_connector_test.go index 0b1d74cc0..0b094a97a 100644 --- a/src/internal/connector/graph_connector_test.go +++ b/src/internal/connector/graph_connector_test.go @@ -475,6 +475,7 @@ func (suite *GraphConnectorIntegrationSuite) TestRestoreAndBackup() { data: mockconnector.GetMockMessageWithBodyBytes( subjectText+"-1", bodyText+" 1.", + bodyText+" 1.", ), lookupKey: subjectText + "-1", }, @@ -489,6 +490,7 @@ func (suite *GraphConnectorIntegrationSuite) TestRestoreAndBackup() { data: mockconnector.GetMockMessageWithBodyBytes( subjectText+"-2", bodyText+" 2.", + bodyText+" 2.", ), lookupKey: subjectText + "-2", }, @@ -497,6 +499,7 @@ func (suite *GraphConnectorIntegrationSuite) TestRestoreAndBackup() { data: mockconnector.GetMockMessageWithBodyBytes( subjectText+"-3", bodyText+" 3.", + bodyText+" 3.", ), lookupKey: subjectText + "-3", }, diff --git a/src/internal/connector/mockconnector/mock_data_contact.go b/src/internal/connector/mockconnector/mock_data_contact.go new file mode 100644 index 000000000..c939d1fcb --- /dev/null +++ b/src/internal/connector/mockconnector/mock_data_contact.go @@ -0,0 +1,75 @@ +package mockconnector + +import "fmt" + +const ( + // Order of fields to fill in: + // 1. displayName + // 2. fileAsName + // 3. phone + // 4. givenName + // 5. middleName + // 6. surname + //nolint:lll + contactTmpl = `{ + "id":"AAMkAGZmNjNlYjI3LWJlZWYtNGI4Mi04YjMyLTIxYThkNGQ4NmY1MwBGAAAAAADCNgjhM9QmQYWNcI7hCpPrBwDSEBNbUIB9RL6ePDeF3FIYAAAAAAEOAADSEBNbUIB9RL6ePDeF3FIYAABS7DZnAAA=", + "@odata.context":"https://graph.microsoft.com/v1.0/$metadata#users('foobar%%408qzvrj.onmicrosoft.com')/contacts/$entity", + "@odata.etag":"W/\"EQAAABYAAADSEBNbUIB9RL6ePDeF3FIYAABSx4Tr\"", + "categories":[], + "changeKey":"EQAAABYAAADSEBNbUIB9RL6ePDeF3FIYAABSx4Tr", + "createdDateTime":"2019-08-04T06:55:33Z", + "lastModifiedDateTime":"2019-08-04T06:55:33Z", + "businessAddress":{}, + "businessPhones":[], + "children":[], + "displayName":"%s", + "emailAddresses":[], + "fileAs":"%s", + "mobilePhone":"%s", + "givenName":"%s", + "homeAddress":{}, + "homePhones":[], + "imAddresses":[], + "otherAddress":{}, + "parentFolderId":"AAMkAGZmNjNlYjI3LWJlZWYtNGI4Mi04YjMyLTIxYThkNGQ4NmY1MwAuAAAAAADCNgjhM9FIYAAAAAAEOAAA=", + "personalNotes":"", + "middleName":"%s", + "surname":"%s" +}` + + defaultContactDisplayName = "Santiago Quail" + defaultContactFileAsName = "Quail, Santiago" + defaultContactGivenName = "Santiago" + defaultContactSurname = "Quail" +) + +// GetMockContactBytes returns bytes for Contactable item. +// When hydrated: contact.GetGivenName() shows differences +func GetMockContactBytes(middleName string) []byte { + phone := generatePhoneNumber() + + return GetMockContactBytesWith( + defaultContactDisplayName, + defaultContactFileAsName, + defaultContactGivenName, + middleName, + defaultContactSurname, + phone, + ) +} + +func GetMockContactBytesWith( + displayName, fileAsName, + givenName, middleName, surname, + phone string, +) []byte { + return []byte(fmt.Sprintf( + contactTmpl, + displayName, + fileAsName, + phone, + givenName, + middleName, + surname, + )) +} diff --git a/src/internal/connector/mockconnector/mock_data_message.go b/src/internal/connector/mockconnector/mock_data_message.go index 5dc3fe6c2..cff6f3664 100644 --- a/src/internal/connector/mockconnector/mock_data_message.go +++ b/src/internal/connector/mockconnector/mock_data_message.go @@ -17,6 +17,14 @@ const ( defaultMessagePreview = "Lidia,\\n\\nWe have not received any reports on the development during Q2. It is in our best interest to have a new TPS Report by next Thursday prior to the retreat. If you have any questions, please let me know so I can address them.\\n" + "\\nThanking you in adv" + defaultMessageCreatedTime = "2022-09-26T23:15:50Z" + defaultMessageModifiedTime = "2022-09-26T23:15:51Z" + defaultMessageReceivedTime = "2022-09-26T23:15:50Z" + defaultMessageSentTime = "2022-09-26T23:15:46Z" + defaultMessageSender = "foobar@8qzvrj.onmicrosoft.com" + defaultMessageTo = "LidiaH@8qzvrj.onmicrosoft.com" + defaultMessageFrom = "foobar@8qzvrj.onmicrosoft.com" + // Order of fields to fill in: // 1. created datetime // 2. modified datetime @@ -90,50 +98,27 @@ const ( // GetMockMessageBytes returns bytes for a Messageable item. // Contents verified as working with sample data from kiota-serialization-json-go v0.5.5 func GetMockMessageBytes(subject string) []byte { - userID := "foobar@8qzvrj.onmicrosoft.com" - timestamp := " " + common.FormatNow(common.SimpleDateTime) - - message := fmt.Sprintf( - messageTmpl, - "2022-09-26T23:15:50Z", // created - "2022-09-26T23:15:51Z", // modified - defaultMessageBody, - defaultMessagePreview, - userID, - "2022-09-26T23:15:50Z", - "foobar@8qzvrj.onmicrosoft.com", - "2022-09-26T23:15:46Z", - "TPS Report "+subject+timestamp, - "LidiaH@8qzvrj.onmicrosoft.com") - - return []byte(message) + return GetMockMessageWithBodyBytes( + "TPS Report "+subject+" "+common.FormatNow(common.SimpleDateTime), + defaultMessageBody, defaultMessagePreview) } // GetMockMessageBytes returns bytes for a Messageable item. // Contents verified as working with sample data from kiota-serialization-json-go v0.5.5 // Body must contain a well-formatted string, consumable in a json payload. IE: no unescaped newlines. -func GetMockMessageWithBodyBytes(subject, body string) []byte { - userID := "foobar@8qzvrj.onmicrosoft.com" - preview := body - - if len(preview) > 255 { - preview = preview[:256] - } - - message := fmt.Sprintf( - messageTmpl, - "2022-09-26T23:15:50Z", // created - "2022-09-26T23:15:51Z", // modified +func GetMockMessageWithBodyBytes(subject, body, preview string) []byte { + return GetMockMessageWith( + defaultMessageTo, + defaultMessageFrom, + defaultMessageSender, + subject, body, preview, - userID, - "2022-09-26T23:15:50Z", - "foobar@8qzvrj.onmicrosoft.com", - "2022-09-26T23:15:46Z", - subject, - "LidiaH@8qzvrj.onmicrosoft.com") - - return []byte(message) + defaultMessageCreatedTime, + defaultMessageModifiedTime, + defaultMessageSentTime, + defaultMessageReceivedTime, + ) } // GetMockMessageWith returns bytes for a Messageable item. @@ -142,10 +127,12 @@ func GetMockMessageWithBodyBytes(subject, body string) []byte { // Body must contain a well-formatted string, consumable in a json payload. IE: no unescaped newlines. func GetMockMessageWith( to, from, sender, // user PNs - subject, body, // arbitrary data + subject, body, preview, // arbitrary data created, modified, sent, received string, // legacy datetimes ) []byte { - preview := body + if len(preview) == 0 { + preview = body + } if len(preview) > 255 { preview = preview[:256] @@ -302,16 +289,3 @@ func GetMockMessageWithTwoAttachments(subject string) []byte { return []byte(message) } - -// GetMockContactBytes returns bytes for Contactable item. -// When hydrated: contact.GetGivenName() shows differences -func GetMockContactBytes(middleName string) []byte { - phone := generatePhoneNumber() - //nolint:lll - contact := "{\"id\":\"AAMkAGZmNjNlYjI3LWJlZWYtNGI4Mi04YjMyLTIxYThkNGQ4NmY1MwBGAAAAAADCNgjhM9QmQYWNcI7hCpPrBwDSEBNbUIB9RL6ePDeF3FIYAAAAAAEOAADSEBNbUIB9RL6ePDeF3FIYAABS7DZnAAA=\",\"@odata.context\":\"https://graph.microsoft.com/v1.0/$metadata#users('foobar%408qzvrj.onmicrosoft.com')/contacts/$entity\"," + - "\"@odata.etag\":\"W/\\\"EQAAABYAAADSEBNbUIB9RL6ePDeF3FIYAABSx4Tr\\\"\",\"categories\":[],\"changeKey\":\"EQAAABYAAADSEBNbUIB9RL6ePDeF3FIYAABSx4Tr\",\"createdDateTime\":\"2019-08-04T06:55:33Z\",\"lastModifiedDateTime\":\"2019-08-04T06:55:33Z\",\"businessAddress\":{},\"businessPhones\":[],\"children\":[]," + - "\"displayName\":\"Santiago Quail\",\"emailAddresses\":[],\"fileAs\":\"Quail, Santiago\",\"mobilePhone\": \"" + phone + "\"," + - "\"givenName\":\"Santiago\",\"homeAddress\":{},\"homePhones\":[],\"imAddresses\":[],\"otherAddress\":{},\"parentFolderId\":\"AAMkAGZmNjNlYjI3LWJlZWYtNGI4Mi04YjMyLTIxYThkNGQ4NmY1MwAuAAAAAADCNgjhM9FIYAAAAAAEOAAA=\",\"personalNotes\":\"\",\"middleName\":\"" + middleName + "\",\"surname\":\"Quail\"}" - - return []byte(contact) -}