Sanitize recurrenceTimezone prior to restoring calendar event (#3064)

<!-- PR description-->
* Do not specify recurrenceTimeZone if it's not set in the item being
restored. "" is not a valid value
---

#### Does this PR need a docs update or release note?

- [x]  No

#### Type of change

<!--- Please check the type of change your PR introduces: --->

- [x] 🐛 Bugfix


#### Issue(s)
* COR-53

#### Test Plan

<!-- How will this be tested prior to merging.-->
- [x] 💚 E2E
This commit is contained in:
Abhishek Pandey 2023-04-10 13:17:53 -07:00 committed by GitHub
parent 89ac00e64e
commit 2300727b09
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 206 additions and 52 deletions

View File

@ -115,7 +115,7 @@ func handleExchangeCalendarEventFactory(cmd *cobra.Command, args []string) error
func(id, now, subject, body string) []byte { func(id, now, subject, body string) []byte {
return mockconnector.GetMockEventWith( return mockconnector.GetMockEventWith(
User, subject, body, body, User, subject, body, body,
now, now, false) now, now, mockconnector.NoRecurrence, mockconnector.NoAttendees, false)
}, },
control.Options{}, control.Options{},
errs) errs)

View File

@ -100,12 +100,12 @@ func (suite *ExchangeRestoreSuite) TestRestoreEvent() {
defer flush() defer flush()
var ( var (
t = suite.T() t = suite.T()
userID = tester.M365UserID(t) userID = tester.M365UserID(t)
name = "TestRestoreEvent: " + common.FormatSimpleDateTime(time.Now()) subject = "TestRestoreEvent: " + common.FormatSimpleDateTime(time.Now())
) )
calendar, err := suite.ac.Events().CreateCalendar(ctx, userID, name) calendar, err := suite.ac.Events().CreateCalendar(ctx, userID, subject)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
calendarID := ptr.Val(calendar.GetId()) calendarID := ptr.Val(calendar.GetId())
@ -116,15 +116,39 @@ func (suite *ExchangeRestoreSuite) TestRestoreEvent() {
assert.NoError(t, err, clues.ToCore(err)) assert.NoError(t, err, clues.ToCore(err))
}() }()
info, err := RestoreExchangeEvent(ctx, tests := []struct {
mockconnector.GetMockEventWithAttendeesBytes(name), name string
suite.gs, bytes []byte
control.Copy, }{
calendarID, {
userID, name: "Test Event With Attendees",
fault.New(true)) bytes: mockconnector.GetMockEventWithAttendeesBytes(subject),
assert.NoError(t, err, clues.ToCore(err)) },
assert.NotNil(t, info, "event item info") {
name: "Test recurrenceTimeZone: Empty",
bytes: mockconnector.GetMockEventWithRecurrenceBytes(subject, `""`),
},
}
for _, test := range tests {
suite.Run(test.name, func() {
t := suite.T()
ctx, flush := tester.NewContext()
defer flush()
info, err := RestoreExchangeEvent(
ctx,
test.bytes,
suite.gs,
control.Copy,
calendarID,
userID,
fault.New(true))
assert.NoError(t, err, clues.ToCore(err))
assert.NotNil(t, info, "event item info")
})
}
} }
type containerDeleter interface { type containerDeleter interface {

View File

@ -19,7 +19,9 @@ import (
// 6. subject // 6. subject
// 7. hasAttachments // 7. hasAttachments
// 8. attachments // 8. attachments
// // 9. recurrence
// 10. attendees
//nolint:lll //nolint:lll
const ( const (
eventTmpl = `{ eventTmpl = `{
@ -33,7 +35,6 @@ const (
"createdDateTime":"2022-03-28T03:42:03Z", "createdDateTime":"2022-03-28T03:42:03Z",
"lastModifiedDateTime":"2022-05-26T19:25:58Z", "lastModifiedDateTime":"2022-05-26T19:25:58Z",
"allowNewTimeProposals":true, "allowNewTimeProposals":true,
"attendees":[],
"body":{ "body":{
"content":"<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"></head><body>` + "content":"<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"></head><body>` +
`<p>%s</p></body></html>", `<p>%s</p></body></html>",
@ -92,7 +93,9 @@ const (
"type":"singleInstance", "type":"singleInstance",
"hasAttachments":%v, "hasAttachments":%v,
%s %s
"webLink":"https://outlook.office365.com/owa/?itemid=AAMkAGZmNjNlYjI3LWJlZWYtNGI4Mi04YjMyLTIxYThkNGQ4NmY1MwBGAAAAAADCNgjhM9QmQYWNcI7hCpPrBwDSEBNbUIB9RL6ePDeF3FIYAAAAAAENAADSEBNbUIB9RL6ePDeF3FIYAAAAAG76AAA%%3D&exvsurl=1&path=/calendar/item" "webLink":"https://outlook.office365.com/owa/?itemid=AAMkAGZmNjNlYjI3LWJlZWYtNGI4Mi04YjMyLTIxYThkNGQ4NmY1MwBGAAAAAADCNgjhM9QmQYWNcI7hCpPrBwDSEBNbUIB9RL6ePDeF3FIYAAAAAAENAADSEBNbUIB9RL6ePDeF3FIYAAAAAG76AAA%%3D&exvsurl=1&path=/calendar/item",
"recurrence":%s,
"attendees":%s
}` }`
defaultEventBody = "This meeting is to review the latest Tailspin Toys project proposal.<br>\\r\\nBut why not eat some sushi while were at it? :)" defaultEventBody = "This meeting is to review the latest Tailspin Toys project proposal.<br>\\r\\nBut why not eat some sushi while were at it? :)"
@ -147,6 +150,48 @@ const (
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\"}]," "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\"}],"
NoRecurrence = `null`
recurrenceTmpl = `{
"pattern": {
"type": "absoluteYearly",
"interval": 1,
"month": 1,
"dayOfMonth": 1,
"firstDayOfWeek": "sunday",
"index": "first"
},
"range": {
"type": "noEnd",
"startDate": "%s",
"endDate": "0001-01-01",
"numberOfOccurrences": 0,
"recurrenceTimeZone": %s
}
}`
NoAttendees = `[]`
attendeesTmpl = `[{
"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"
}
}]`
) )
// generatePhoneNumber creates a random phone number // generatePhoneNumber creates a random phone number
@ -182,7 +227,7 @@ func GetMockEventWithSubjectBytes(subject string) []byte {
return GetMockEventWith( return GetMockEventWith(
defaultEventOrganizer, subject, defaultEventOrganizer, subject,
defaultEventBody, defaultEventBodyPreview, defaultEventBody, defaultEventBodyPreview,
atTime, endTime, false, atTime, endTime, NoRecurrence, NoAttendees, false,
) )
} }
@ -194,19 +239,49 @@ func GetMockEventWithAttachment(subject string) []byte {
return GetMockEventWith( return GetMockEventWith(
defaultEventOrganizer, subject, defaultEventOrganizer, subject,
defaultEventBody, defaultEventBodyPreview, defaultEventBody, defaultEventBodyPreview,
atTime, atTime, true, atTime, atTime, NoRecurrence, NoAttendees, true,
)
}
func GetMockEventWithRecurrenceBytes(subject, recurrenceTimeZone 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)
timeSlice := strings.Split(atTime, "T")
recurrence := string(fmt.Sprintf(
recurrenceTmpl,
timeSlice[0],
recurrenceTimeZone,
))
return GetMockEventWith(
defaultEventOrganizer, subject,
defaultEventBody, defaultEventBodyPreview,
atTime, atTime, recurrence, attendeesTmpl, true,
)
}
func GetMockEventWithAttendeesBytes(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, NoRecurrence, attendeesTmpl, true,
) )
} }
// GetMockEventWith returns bytes for an Eventable item. // 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. // 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 // The timezone (Z) will be automatically stripped. A non-utc timezone may
// produce unexpected results. // produce unexpected results.
// Body must contain a well-formatted string, consumable in a json payload. IE: no unescaped newlines. // Body must contain a well-formatted string, consumable in a json payload. IE: no unescaped newlines.
func GetMockEventWith( func GetMockEventWith(
organizer, subject, body, bodyPreview, organizer, subject, body, bodyPreview,
startDateTime, endDateTime string, startDateTime, endDateTime, recurrence, attendees string,
hasAttachments bool, hasAttachments bool,
) []byte { ) []byte {
var attachments string var attachments string
@ -235,34 +310,7 @@ func GetMockEventWith(
subject, subject,
hasAttachments, hasAttachments,
attachments, attachments,
recurrence,
attendees,
)) ))
} }
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\":\"<html>\\n<head>\\n<meta http-equiv=\\\"Content-Type\\\" content=\\\"text/html; charset=utf-8\\\">\\n</head>\\n<body>\\n<div class=\\\"elementToProof\\\" style=\\\"font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0); background-color:rgb(255,255,255)\\\">\\nDiscuss matters concerning stock options and early release of quarterly earnings.</div>\\n<br> " +
"\\n<div style=\\\"width:100%; height:20px\\\"><span style=\\\"white-space:nowrap; color:#5F5F5F; opacity:.36\\\">________________________________________________________________________________</span>\\n</div>\\n<div class=\\\"me-email-text\\\" lang=\\\"en-GB\\\" style=\\\"color:#252424; font-family:'Segoe UI','Helvetica Neue',Helvetica,Arial,sans-serif\\\"> " +
"\\n<div style=\\\"margin-top:24px; margin-bottom:20px\\\"><span style=\\\"font-size:24px; color:#252424\\\">Microsoft Teams meeting</span>\\n</div>\\n<div style=\\\"margin-bottom:20px\\\">\\n<div style=\\\"margin-top:0px; margin-bottom:0px; font-weight:bold\\\"><span style=\\\"font-size:14px; color:#252424\\\">Join on your computer or mobile app</span>" +
"\\n</div>\\n<a href=\\\"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\\\" class=\\\"me-email-headline\\\" style=\\\"font-size:14px; font-family:'Segoe UI Semibold','Segoe UI','Helvetica Neue',Helvetica,Arial,sans-serif; text-decoration:underline; color:#6264a7\\\">Click\\n here to join the meeting</a> </div>" +
"\\n<div style=\\\"margin-bottom:20px; margin-top:20px\\\">\\n<div style=\\\"margin-bottom:4px\\\"><span style=\\\"font-size:14px; color:#252424\\\">Meeting ID:\\n<span style=\\\"font-size:16px; color:#252424\\\">292 784 521 247</span> </span><br>\\n<span style=\\\"font-size:14px; color:#252424\\\">Passcode: </span><span style=\\\"font-size:16px; color:#252424\\\">SzBkfK\\n</span>" +
"\\n<div style=\\\"font-size:14px\\\"><a href=\\\"https://www.microsoft.com/en-us/microsoft-teams/download-app\\\" class=\\\"me-email-link\\\" style=\\\"font-size:14px; text-decoration:underline; color:#6264a7; font-family:'Segoe UI','Helvetica Neue',Helvetica,Arial,sans-serif\\\">Download\\n Teams</a> | <a href=\\\"https://www.microsoft.com/microsoft-teams/join-a-meeting\\\" class=\\\"me-email-link\\\" style=\\\"font-size:14px; text-decoration:underline; color:#6264a7; font-family:'Segoe UI','Helvetica Neue',Helvetica,Arial,sans-serif\\\">" +
"\\nJoin on the web</a></div>\\n</div>\\n</div>\\n<div style=\\\"margin-bottom:24px; margin-top:20px\\\"><a href=\\\"https://aka.ms/JoinTeamsMeeting\\\" class=\\\"me-email-link\\\" style=\\\"font-size:14px; text-decoration:underline; color:#6264a7; font-family:'Segoe UI','Helvetica Neue',Helvetica,Arial,sans-serif\\\">Learn more</a>" +
"\\n | <a href=\\\"https://teams.microsoft.com/meetingOptions/?organizerId=a4a472f8-ccb0-43ec-bf52-3697a91b926c&amp;tenantId=4d603060-18d6-4764-b9be-4cb794d32b69&amp;threadId=19_meeting_YWNhMzAxZjItMzE2My00ZGQzLTkzMDUtNjQ3NTY0NjNjMTZi@thread.v2&amp;messageId=0&amp;language=en-GB\\\" class=\\\"me-email-link\\\" style=\\\"font-size:14px; text-decoration:underline; color:#6264a7; font-family:'Segoe UI','Helvetica Neue',Helvetica,Arial,sans-serif\\\">" +
"\\nMeeting options</a> </div>\\n</div>\\n<div style=\\\"font-size:14px; margin-bottom:4px; font-family:'Segoe UI','Helvetica Neue',Helvetica,Arial,sans-serif\\\">\\n</div>\\n<div style=\\\"font-size:12px\\\"></div>\\n<div></div>\\n<div style=\\\"width:100%; height:20px\\\"><span style=\\\"white-space:nowrap; color:#5F5F5F; opacity:.36\\\">________________________________________________________________________________</span>" +
"\\n</div>\\n</body>\\n</html>\\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)
}

View File

@ -88,6 +88,14 @@ func ToEventSimplified(orig models.Eventable) models.Eventable {
orig.SetICalUId(nil) orig.SetICalUId(nil)
orig.SetId(nil) orig.SetId(nil)
// Sanitize recurrence timezone.
if orig.GetRecurrence() != nil {
recurrenceTimezone := ptr.Val(orig.GetRecurrence().GetRange().GetRecurrenceTimeZone())
if len(recurrenceTimezone) == 0 {
orig.GetRecurrence().GetRange().SetRecurrenceTimeZone(nil)
}
}
return orig return orig
} }

View File

@ -37,7 +37,7 @@ func (suite *SupportTestSuite) TestToMessage() {
assert.NotEqual(t, message.GetId(), clone.GetId()) assert.NotEqual(t, message.GetId(), clone.GetId())
} }
func (suite *SupportTestSuite) TestToEventSimplified() { func (suite *SupportTestSuite) TestToEventSimplified_attendees() {
t := suite.T() t := suite.T()
bytes := mockconnector.GetMockEventWithAttendeesBytes("M365 Event Support Test") bytes := mockconnector.GetMockEventWithAttendeesBytes("M365 Event Support Test")
event, err := CreateEventFromBytes(bytes) event, err := CreateEventFromBytes(bytes)
@ -57,6 +57,80 @@ func (suite *SupportTestSuite) TestToEventSimplified() {
} }
} }
func (suite *SupportTestSuite) TestToEventSimplified_recurrence() {
var (
t = suite.T()
subject = "M365 Event Support Test"
)
tests := []struct {
name string
event func() models.Eventable
validateOutput func(e models.Eventable) bool
}{
{
name: "Test recurrence: Unspecified",
event: func() models.Eventable {
bytes := mockconnector.GetMockEventWithSubjectBytes(subject)
e, err := CreateEventFromBytes(bytes)
require.NoError(t, err, clues.ToCore(err))
return e
},
validateOutput: func(e models.Eventable) bool {
return e.GetRecurrence() == nil
},
},
{
name: "Test recurrenceTimeZone: Unspecified",
event: func() models.Eventable {
bytes := mockconnector.GetMockEventWithRecurrenceBytes(subject, `null`)
e, err := CreateEventFromBytes(bytes)
require.NoError(t, err, clues.ToCore(err))
return e
},
validateOutput: func(e models.Eventable) bool {
return e.GetRecurrence().GetRange().GetRecurrenceTimeZone() == nil
},
},
{
name: "Test recurrenceTimeZone: Empty",
event: func() models.Eventable {
bytes := mockconnector.GetMockEventWithRecurrenceBytes(subject, `""`)
event, err := CreateEventFromBytes(bytes)
require.NoError(t, err, clues.ToCore(err))
return event
},
validateOutput: func(e models.Eventable) bool {
return e.GetRecurrence().GetRange().GetRecurrenceTimeZone() == nil
},
},
{
name: "Test recurrenceTimeZone: Valid",
event: func() models.Eventable {
bytes := mockconnector.GetMockEventWithRecurrenceBytes(subject, `"Pacific Standard Time"`)
event, err := CreateEventFromBytes(bytes)
require.NoError(t, err, clues.ToCore(err))
return event
},
validateOutput: func(e models.Eventable) bool {
return ptr.Val(e.GetRecurrence().GetRange().GetRecurrenceTimeZone()) == "Pacific Standard Time"
},
},
}
for _, test := range tests {
suite.Run(test.name, func() {
event := test.event()
newEvent := ToEventSimplified(event)
assert.True(t, test.validateOutput(newEvent), test.name)
})
}
}
type mockContenter struct { type mockContenter struct {
content *string content *string
contentType *models.BodyType contentType *models.BodyType

View File

@ -790,7 +790,7 @@ func (suite *BackupOpIntegrationSuite) TestBackup_Run_exchangeIncrementals() {
eventDBF := func(id, timeStamp, subject, body string) []byte { eventDBF := func(id, timeStamp, subject, body string) []byte {
return mockconnector.GetMockEventWith( return mockconnector.GetMockEventWith(
suite.user, subject, body, body, suite.user, subject, body, body,
now, now, false) now, now, mockconnector.NoRecurrence, mockconnector.NoAttendees, false)
} }
// test data set // test data set