public void MSOXWSMTGS_S01_TC09_CreateAndCancelMeeting() { #region Organizer creates a meeting #region Set the properties of the meeting to create CalendarItemType meeting = new CalendarItemType(); meeting.Subject = this.Subject; meeting.UID = Guid.NewGuid().ToString(); meeting.Start = DateTime.UtcNow.AddDays(1); meeting.StartSpecified = true; meeting.End = meeting.Start.AddHours(2); meeting.EndSpecified = true; meeting.Location = this.Location; meeting.ConferenceType = 0; meeting.ConferenceTypeSpecified = true; meeting.AllowNewTimeProposal = false; meeting.AllowNewTimeProposalSpecified = true; if (Common.IsRequirementEnabled(2301, this.Site)) { meeting.IsOnlineMeeting = false; meeting.IsOnlineMeetingSpecified = true; } meeting.LegacyFreeBusyStatus = LegacyFreeBusyType.Free; meeting.LegacyFreeBusyStatusSpecified = true; meeting.RequiredAttendees = new AttendeeType[] { GetAttendeeOrResource(this.AttendeeEmailAddress) }; meeting.OptionalAttendees = new AttendeeType[] { GetAttendeeOrResource(this.OrganizerEmailAddress) }; meeting.Resources = new AttendeeType[] { GetAttendeeOrResource(this.RoomEmailAddress) }; if (Common.IsRequirementEnabled(697, this.Site)) { meeting.EnhancedLocation = new EnhancedLocationType(); meeting.EnhancedLocation.DisplayName = Common.GenerateResourceName(this.Site, "Enhanced Location"); meeting.EnhancedLocation.Annotation = Common.GenerateResourceName(this.Site, "Enhanced Location Annotation"); meeting.EnhancedLocation.PostalAddress = new PersonaPostalAddressType(); meeting.EnhancedLocation.PostalAddress.LocationSource = LocationSourceType.PhonebookServices; meeting.EnhancedLocation.PostalAddress.LocationSourceSpecified = true; } #endregion #region Create the meeting and sends it to all attendees ItemInfoResponseMessageType item = this.CreateSingleCalendarItem(Role.Organizer, meeting, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll); Site.Assert.IsNotNull(item, "Create a meeting item should be successful."); #endregion #endregion #region Attendee gets and declines the meeting request in the Inbox folder CalendarItemType calendar = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.calendar, "IPM.Appointment", meeting.UID) as CalendarItemType; Site.Assert.IsNotNull(calendar, "The calendar item should be found in attendee's Calendar folder after organizer calls CreateItem with CalendarItemCreateOrDeleteOperationType set to SendOnlyToAll."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R16501"); // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R16501 this.Site.CaptureRequirementIfAreEqual<LegacyFreeBusyType>( LegacyFreeBusyType.Free, calendar.LegacyFreeBusyStatus, 16501, @"[In t:CalendarItemType Complex Type] The LegacyFreeBusyStatus which value is ""Free"" specifies the status as free."); #region Decline the meeting request MeetingRequestMessageType receivedRequest = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.inbox, "IPM.Schedule.Meeting.Request", meeting.UID) as MeetingRequestMessageType; Site.Assert.IsNotNull(receivedRequest, "The meeting request message should exist in attendee's inbox folder."); #region Capture Code if (Common.IsRequirementEnabled(707, this.Site)) { // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R707"); // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R707 this.Site.CaptureRequirementIfIsNotNull( receivedRequest.EnhancedLocation, 707, @"[In Appendix C: Product Behavior] Implementation does support the complex type ""EnhancedLocation"" with type ""EnhancedLocationType (section 2.2.4.10)"" which specifies enhanced location information. (Exchange 2013 and above follow this behavior.)"); } if (Common.IsRequirementEnabled(3541, this.Site)) { Site.Assert.IsTrue(receivedRequest.ConferenceTypeSpecified, "Element ConferenceType in MeetingRequestMessageType should be present."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R35500"); // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R35500 this.Site.CaptureRequirementIfAreEqual<int>( meeting.ConferenceType, receivedRequest.ConferenceType, 35500, @"[In t:MeetingRequestMessageType Complex Type] The value of ""ConferenceType"" is ""0"" (zero) describes the type of conferencing is video conference"); } if (Common.IsRequirementEnabled(2301, this.Site)) { Site.Assert.IsTrue(receivedRequest.IsOnlineMeetingSpecified, "The element IsOnlineMeeting should be present."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R767"); // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R767 this.Site.CaptureRequirementIfIsFalse( receivedRequest.IsOnlineMeeting, 767, @"[In t:MeetingRequestMessageType Complex Type] otherwise [if the meeting is not online], [IsOnlineMeeting is] false."); } // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R28501"); // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R28501 this.Site.CaptureRequirementIfAreEqual<LegacyFreeBusyType>( LegacyFreeBusyType.Free, receivedRequest.IntendedFreeBusyStatus, 28501, @"[In t:MeetingRequestMessageType Complex Type] The IntendedFreeBusyStatus which value is ""Free"" specifies the status as free."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R329"); // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R329 // The format of the value of Duration elements followed xs:duration (as specified in [XMLSCHEMA2]), because of the duration set to 2 hours when create the meeting, therefore the expected value is "PT2H". this.Site.CaptureRequirementIfAreEqual<string>( "PT2H", receivedRequest.Duration, 329, @"[In t:MeetingRequestMessageType Complex Type] Duration: Represents the duration of the meeting."); if (Common.IsRequirementEnabled(3311, this.Site)) { // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R3311"); // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R3311 this.Site.CaptureRequirementIfIsNotNull( receivedRequest.TimeZone, 3311, @"[In Appendix C: Product Behavior] Implementation does support TimeZone in MeetingRequestMessageType. (Exchange 2007, Exchange 2010 and Exchange 2013 follow this behavior.)"); } // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R335"); // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R335 this.Site.CaptureRequirementIfAreEqual<int>( 0, receivedRequest.AppointmentSequenceNumber, 335, @"[In t:MeetingRequestMessageType Complex Type] AppointmentSequenceNumber: Specifies the sequence number of a version of an appointment."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R137"); // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R137 Site.CaptureRequirementIfIsNotNull( receivedRequest, 137, @"[In t:AttendeeType Complex Type]Mailbox: Specifies a fully resolved e-mail address."); #endregion DeclineItemType declineItem = new DeclineItemType(); declineItem.ReferenceItemId = new ItemIdType(); declineItem.ReferenceItemId = receivedRequest.ItemId; item = this.CreateSingleCalendarItem(Role.Attendee, declineItem, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll); Site.Assert.IsNotNull(item, "Decline meeting request should be successful."); #endregion #endregion #region Organizer gets the meeting response message and verify ResponseTypeType set to decline MeetingResponseMessageType response = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.inbox, "IPM.Schedule.Meeting.Resp", meeting.UID) as MeetingResponseMessageType; Site.Assert.IsNotNull(response, "Organizer should receive the meeting response message after attendee declines the meeting."); #region Capture Code if (Common.IsRequirementEnabled(80011, this.Site)) { // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R80011"); // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R80011 this.Site.CaptureRequirementIfIsNotNull( response.EnhancedLocation, 80011, @"[In Appendix C: Product Behavior] Implementation does support the EnhancedLocation, which is an element of type EnhancedLocationType, as defined in section 2.2.4.10, that represents additional location information for the calendar item. (Exchange 2013 and above follow this behavior.)"); } // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R83"); // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R83 this.Site.CaptureRequirementIfAreEqual<ResponseTypeType>( ResponseTypeType.Decline, response.ResponseType, 83, @"[In t:ResponseTypeType Simple Type] Decline: Indicates that the recipient declined the meeting."); #endregion CancelCalendarItemType cancelMeetingItem = new CancelCalendarItemType(); cancelMeetingItem.ReferenceItemId = response.AssociatedCalendarItemId; #endregion #region Organizer cancels the meeting item = this.CreateSingleCalendarItem(Role.Organizer, cancelMeetingItem, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R491"); // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R491 Site.CaptureRequirementIfIsNotNull( item, 491, @"[In CreateItem Operation] It [CreateItem operation] can also be used to cancel a meeting."); #endregion #region Attendee removes the canceled meeting MeetingCancellationMessageType meetingResponse = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.inbox, "IPM.Schedule.Meeting.Canceled", meeting.UID) as MeetingCancellationMessageType; Site.Assert.IsNotNull(meetingResponse, "Attendee should receive the meeting cancellation message after organizer calls CreateItem to create MeetingCancellationMessage with CalendarItemCreateOrDeleteOperationType set to SendOnlyToAll."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R490"); // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R490 this.Site.CaptureRequirementIfAreEqual<string>( "IPM.Schedule.Meeting.Canceled", meetingResponse.ItemClass, 490, @"[In CreateItem Operation] This operation [CreateItem] can be used to create meeting cancellation messages."); if (Common.IsRequirementEnabled(697, this.Site)) { // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R80003"); // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R80003 this.Site.CaptureRequirementIfIsNotNull( meetingResponse.EnhancedLocation, 80003, @"[In t:MeetingCancellationMessageType Complex Type] EnhancedLocation: An element of type EnhancedLocationType, as defined in section 2.2.4.10, that specifies additional location information for a calendar item."); } #region Verify the child elements of MeetingResponseMessageType if (Common.IsRequirementEnabled(900, this.Site)) { // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R900"); // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R900 this.Site.CaptureRequirementIfAreEqual<DateTime>( meeting.Start.Date, meetingResponse.Start.Date, 900, @"[In Appendix C: Product Behavior] Implementation does support Start which is a dateTime element that represents the start time of the calendar item. (Exchange 2013 and above follow this behavior.)"); } if (Common.IsRequirementEnabled(901, this.Site)) { // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R901"); // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R901 this.Site.CaptureRequirementIfAreEqual<DateTime>( meeting.End.Date, meetingResponse.End.Date, 901, @"[In Appendix C: Product Behavior] Implementation does support End which is a dateTime element that represents the ending time of the calendar item. (Exchange 2013 and above follow this behavior.)"); } if (Common.IsRequirementEnabled(902, this.Site)) { // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R902"); // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R902 this.Site.CaptureRequirementIfAreEqual<string>( meeting.Location.ToLower(), meetingResponse.Location.ToLower(), 902, @"[In Appendix C: Product Behavior] Implementation does support Location which is a string element that represents the location of the calendar item. (Exchange 2013 and above follow this behavior.)"); } if (Common.IsRequirementEnabled(904, this.Site)) { CalendarItemTypeType actual; Site.Assert.IsTrue(Enum.TryParse<CalendarItemTypeType>(meetingResponse.CalendarItemType, out actual), "The current value of CalendarItemType should be able to convert into one of CalendarItemTypeType enum values."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R904"); // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R904 this.Site.CaptureRequirementIfAreEqual<CalendarItemTypeType>( CalendarItemTypeType.Single, actual, 904, @"[In Appendix C: Product Behavior] Implementation does support CalendarItemType which is a string element that represents the type of calendar item. (Exchange 2013 and above follow this behavior.)"); } #endregion RemoveItemType removeItem = removeItem = new RemoveItemType(); removeItem.ReferenceItemId = new ItemIdType(); removeItem.ReferenceItemId = meetingResponse.ItemId; #region Remove the canceled meeting item = this.CreateSingleCalendarItem(Role.Attendee, removeItem, CalendarItemCreateOrDeleteOperationType.SendToNone); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R492"); // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R492 this.Site.CaptureRequirementIfIsNotNull( item, 492, @"[In CreateItem Operation] and when a meeting is cancelled, it [CreateItem Operation] can be used to remove the meeting item and corresponding meeting cancellation message from the server."); #endregion #endregion #region Clean up organizer's inbox, sentitems and deleteditems folders, and attendee's inbox, sentitems and deleteditems folders this.CleanupFoldersByRole(Role.Organizer, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.inbox, DistinguishedFolderIdNameType.sentitems, DistinguishedFolderIdNameType.deleteditems }); this.CleanupFoldersByRole(Role.Attendee, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.inbox, DistinguishedFolderIdNameType.sentitems, DistinguishedFolderIdNameType.deleteditems }); #endregion }
public void MSOXWSMTGS_S01_TC03_CreateRecurringMeetingAndDecline() { #region Organizer creates a recurring meeting with CalendarItemCreateOrDeleteOperationType value set to SendOnlyToAll #region Define a recurring meeting int timeInterval = this.TimeInterval; DateTime startTime = DateTime.Now.AddHours(timeInterval); DailyRecurrencePatternType pattern = new DailyRecurrencePatternType(); pattern.Interval = this.PatternInterval; NumberedRecurrenceRangeType range = new NumberedRecurrenceRangeType(); range.NumberOfOccurrences = this.NumberOfOccurrences; range.StartDate = startTime; CalendarItemType meetingItem = new CalendarItemType(); meetingItem.UID = Guid.NewGuid().ToString(); meetingItem.Subject = this.Subject; meetingItem.Start = startTime; // Indicates the Start property is serialized in the SOAP message. meetingItem.StartSpecified = true; timeInterval++; meetingItem.End = startTime.AddHours(timeInterval); meetingItem.EndSpecified = true; meetingItem.Location = this.Location; meetingItem.Recurrence = new RecurrenceType(); meetingItem.Recurrence.Item = pattern; meetingItem.Recurrence.Item1 = range; meetingItem.RequiredAttendees = new AttendeeType[] { GetAttendeeOrResource(this.AttendeeEmailAddress) }; meetingItem.OptionalAttendees = new AttendeeType[] { GetAttendeeOrResource(this.OrganizerEmailAddress) }; meetingItem.Resources = new AttendeeType[] { GetAttendeeOrResource(this.RoomEmailAddress) }; if (Common.IsRequirementEnabled(715, this.Site)) { meetingItem.MeetingTimeZone = new TimeZoneType(); meetingItem.MeetingTimeZone.BaseOffset = "PT7H"; meetingItem.MeetingTimeZone.Standard = new TimeChangeType(); meetingItem.MeetingTimeZone.Standard.Offset = "PT0H"; meetingItem.MeetingTimeZone.Standard.Time = DateTime.Now; RelativeYearlyRecurrencePatternType yearlyRecurrence = new RelativeYearlyRecurrencePatternType(); yearlyRecurrence.DaysOfWeek = "Sunday"; yearlyRecurrence.DayOfWeekIndex = DayOfWeekIndexType.First; yearlyRecurrence.Month = MonthNamesType.November; meetingItem.MeetingTimeZone.Standard.Item = yearlyRecurrence; meetingItem.MeetingTimeZone.Daylight = new TimeChangeType(); meetingItem.MeetingTimeZone.Daylight.Offset = "-PT1H"; yearlyRecurrence = new RelativeYearlyRecurrencePatternType(); yearlyRecurrence.DaysOfWeek = "Sunday"; yearlyRecurrence.DayOfWeekIndex = DayOfWeekIndexType.Second; yearlyRecurrence.Month = MonthNamesType.March; meetingItem.MeetingTimeZone.Daylight.Item = yearlyRecurrence; meetingItem.MeetingTimeZone.Daylight.Time = DateTime.Now; meetingItem.MeetingTimeZone.TimeZoneName = "Time Zone"; } #endregion // Create the recurring meeting ItemInfoResponseMessageType item = this.CreateSingleCalendarItem(Role.Organizer, meetingItem, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll); Site.Assert.IsNotNull(item, "Server should return success for creating a recurring meeting."); ItemIdType meetingId = item.Items.Items[0].ItemId; #region Verify FirstOccurrence and LastOccurrence in the CalendarItemType ItemInfoResponseMessageType getItem = this.GetSingleCalendarItem(Role.Organizer, meetingId); Site.Assert.IsNotNull(getItem, "The calendar item to be deleted should exist."); if (Common.IsRequirementEnabled(715, this.Site)) { CalendarItemType calendar = (CalendarItemType)getItem.Items.Items[0]; // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R715"); // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R715 this.Site.CaptureRequirementIfIsNotNull( calendar.MeetingTimeZone, 715, @"[In Appendix C: Product Behavior] Implementation does support complex type ""MeetingTimeZone"" with type ""t:TimeZoneType (section 2.2.4.40)"" which does specify the time zone of the location where the meeting is hosted. (<28> Section 2.2.4.9: Only Exchange 2007 supports the MeetingTimeZone element.)"); if (Common.IsRequirementEnabled(654, this.Site)) { // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R654"); // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R654 this.Site.CaptureRequirementIfIsNotNull( calendar.MeetingTimeZone, 654, @"[In Appendix C: Product Behavior] Implementation does support the TimeZoneType complex type. (<17> Section 2.2.4: Only Exchange 2007 supports the TimeZoneType complex type.)"); } // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R1053"); // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R1053 this.Site.CaptureRequirementIfIsNotNull( calendar.MeetingTimeZone, 1053, @"[In t:CalendarItemType Complex Type] This element [MeetingTimeZone] is returned only if the value of the CalendarItemType element is RecurringMaster."); TimeZoneType timeZone = calendar.MeetingTimeZone; // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R407"); // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R407 this.Site.CaptureRequirementIfIsNotNull( timeZone.BaseOffset, 407, @"[In t:TimeZoneType Complex Type] BaseOffset: Specifies the hourly offset from Coordinated Universal Time (UTC) for the current time zone."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R409"); // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R409 this.Site.CaptureRequirementIfIsNotNull( timeZone.Standard, 409, @"[In t:TimeZoneType Complex Type] Standard: Specifies the date and time when the time changes from daylight saving time to standard time."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R411"); // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R411 this.Site.CaptureRequirementIfIsNotNull( timeZone.Daylight, 411, @"[In t:TimeZoneType Complex Type] Daylight: Specifies the date and time when the time changes from standard time to daylight saving time."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R585"); // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R585 this.Site.CaptureRequirementIfIsNotNull( timeZone.TimeZoneName, 585, @"[In t:TimeZoneType Complex Type] TimeZoneName: Specifies the time zone name."); TimeChangeType timeChange = timeZone.Standard; // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R399"); // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R399 this.Site.CaptureRequirementIfIsNotNull( timeChange.Offset, 399, @"[In t:TimeChangeType Complex Type] Offset: Specifies the offset from the duration specified by the BaseOffset element (section 2.2.4.24)."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R401"); // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R401 this.Site.CaptureRequirementIfIsNotNull( timeChange.Time, 401, @"[In t:TimeChangeType Complex Type] Time: Specifies the time when the time changes between standard time and daylight saving time."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R403"); // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R403 this.Site.CaptureRequirementIfIsNotNull( timeChange.TimeZoneName, 403, @"[In t:TimeChangeType Complex Type] TimeZoneName: Specifies the time zone name."); } string actualFirstOccurrenceId = ((CalendarItemType)getItem.Items.Items[0]).FirstOccurrence.ItemId.Id; string actualLastOccurrenceId = ((CalendarItemType)getItem.Items.Items[0]).LastOccurrence.ItemId.Id; // Get the first occurrence by item id OccurrenceItemIdType firstOccurrenceId = new OccurrenceItemIdType(); firstOccurrenceId.ChangeKey = meetingId.ChangeKey; firstOccurrenceId.RecurringMasterId = meetingId.Id; firstOccurrenceId.InstanceIndex = 1; getItem = this.GetSingleCalendarItem(Role.Organizer, firstOccurrenceId); Site.Assert.IsNotNull(getItem, "The first occurrence should be found."); CalendarItemType firstOccurrence = getItem.Items.Items[0] as CalendarItemType; // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R213"); // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R213 this.Site.CaptureRequirementIfAreEqual<string>( firstOccurrence.ItemId.Id, actualFirstOccurrenceId, 213, "[In t:CalendarItemType Complex Type]FirstOccurrence: Specifies the first occurrence of a recurring calendar item."); // Get the last occurrence by item id OccurrenceItemIdType lastOccurrenceId = new OccurrenceItemIdType(); lastOccurrenceId.ChangeKey = meetingId.ChangeKey; lastOccurrenceId.RecurringMasterId = meetingId.Id; lastOccurrenceId.InstanceIndex = this.NumberOfOccurrences; getItem = this.GetSingleCalendarItem(Role.Organizer, lastOccurrenceId); Site.Assert.IsNotNull(getItem, "The last occurrence should be found."); CalendarItemType lastOccurrence = getItem.Items.Items[0] as CalendarItemType; // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R215"); // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R215 this.Site.CaptureRequirementIfAreEqual<string>( lastOccurrence.ItemId.Id, actualLastOccurrenceId, 215, "[In t:CalendarItemType Complex Type]LastOccurrence: Specifies the last occurrence of a recurring calendar item."); #endregion #endregion #region Organizer deletes an occurrence of the recurring calendar item with CalendarItemCreateOrDeleteOperationType value set to SendOnlyToAll OccurrenceItemIdType occurrenceItemId = new OccurrenceItemIdType(); occurrenceItemId.ChangeKey = meetingId.ChangeKey; occurrenceItemId.RecurringMasterId = meetingId.Id; occurrenceItemId.InstanceIndex = this.InstanceIndex; getItem = this.GetSingleCalendarItem(Role.Organizer, occurrenceItemId); Site.Assert.IsNotNull(getItem, "The calendar item to be deleted should exist."); ResponseMessageType deletedItem = this.DeleteSingleCalendarItem(Role.Organizer, occurrenceItemId, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll); Site.Assert.IsNotNull(deletedItem, "The occurrence of the recurring calendar item should be deleted."); #endregion #region Attendee calls CreateItem to decline the meeting request with CalendarItemCreateOrDeleteOperationType value set to SendOnlyToAll MeetingRequestMessageType request = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.inbox, "IPM.Schedule.Meeting.Request", meetingItem.UID) as MeetingRequestMessageType; Site.Assert.IsNotNull(request, "Attendee should receive the meeting request message in the Inbox folder after organizer calls CreateItem with CalendarItemCreateOrDeleteOperationType set to SendOnlyToAll."); bool isFirstOccurrence = (firstOccurrence.Start == request.FirstOccurrence.Start) && (firstOccurrence.End == request.FirstOccurrence.End); if (Common.IsRequirementEnabled(715, this.Site) && Common.IsRequirementEnabled(706, this.Site)) { // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R706"); // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R706 this.Site.CaptureRequirementIfIsNotNull( request.MeetingTimeZone, 706, @"[In Appendix C: Product Behavior] Implementation does support the complex type ""MeetingTimeZone"" with type ""t:TimeZoneType (section 2.2.4.24)"" which does specify the time zone of the location where the meeting is hosted. (<52> Section 2.2.4.22: Only Exchange 2007 supports the MeetingTimeZone element.)"); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R1090"); // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R1090 this.Site.CaptureRequirementIfIsNotNull( request.MeetingTimeZone, 1090, @"[In t:MeetingRequestMessageType Complex Type] This element [MeetingTimeZone] is returned only if the value of the CalendarItemType element is RecurringMaster."); } // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R341, expected value of Start of first occurrence is {0} and actual value is {1}; expected value of End of first occurrence is {2} and actual value is {3}", firstOccurrence.Start, request.FirstOccurrence.Start, firstOccurrence.End, request.FirstOccurrence.End); // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R341 this.Site.CaptureRequirementIfIsTrue( isFirstOccurrence, 341, "[In t:MeetingRequestMessageType Complex Type] FirstOccurrence: Represents the first occurrence of a recurring meeting item."); bool isLastOccurrence = (lastOccurrence.Start == request.LastOccurrence.Start) && (lastOccurrence.End == request.LastOccurrence.End); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R343, expected value of Start of last occurrence is {0} and actual value is {1}; expected value of End of last occurrence is {2} and actual value is {3}", lastOccurrence.Start, request.LastOccurrence.Start, lastOccurrence.End, request.LastOccurrence.End); // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R343 this.Site.CaptureRequirementIfIsTrue( isLastOccurrence, 343, "[In t:MeetingRequestMessageType Complex Type] LastOccurrence: Represents the last occurrence of a recurring meeting item."); DeclineItemType declinedItem = new DeclineItemType(); declinedItem.ReferenceItemId = new ItemIdType(); declinedItem.ReferenceItemId.Id = request.ItemId.Id; item = this.CreateSingleCalendarItem(Role.Attendee, declinedItem, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll); Site.Assert.IsNotNull(item, "Decline meeting request should be successful."); #endregion #region Organizer calls CreateItem with MeetingCancellationMessageType to cancel the created meeting with CalendarItemCreateOrDeleteOperationType value set to SendOnlyToAll MeetingResponseMessageType response = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.inbox, "IPM.Schedule.Meeting.Resp", meetingItem.UID) as MeetingResponseMessageType; Site.Assert.IsNotNull(response, "The decline response should be in the Inbox folder."); CancelCalendarItemType cancelCalendarItem = new CancelCalendarItemType(); cancelCalendarItem.ReferenceItemId = response.AssociatedCalendarItemId; item = this.CreateSingleCalendarItem(Role.Organizer, cancelCalendarItem, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll); Site.Assert.IsNotNull(item, "Cancel the meeting through CancelCalendarItemType using CreateItem should be successful."); #endregion #region Attendee finds the meeting cancellation message from his Inbox folder MeetingCancellationMessageType canceledMeeting = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.inbox, "IPM.Schedule.Meeting.Canceled", meetingItem.UID) as MeetingCancellationMessageType; Site.Assert.IsNotNull(canceledMeeting, "The canceled meeting should be in the Inbox folder."); #endregion #region Clean up organizer's inbox, sentitems and deleteditems folders, and attendee's inbox, sentitems and deleteditems folders. this.CleanupFoldersByRole(Role.Organizer, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.inbox, DistinguishedFolderIdNameType.sentitems, DistinguishedFolderIdNameType.deleteditems }); this.CleanupFoldersByRole(Role.Attendee, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.inbox, DistinguishedFolderIdNameType.sentitems, DistinguishedFolderIdNameType.deleteditems }); #endregion }
public void MSOXWSMTGS_S02_TC03_UpdateRecurringCalendar() { #region Define a recurring calendar item DateTime startTime = DateTime.Now; DailyRecurrencePatternType pattern = new DailyRecurrencePatternType(); pattern.Interval = this.PatternInterval; NumberedRecurrenceRangeType range = new NumberedRecurrenceRangeType(); range.NumberOfOccurrences = this.NumberOfOccurrences; range.StartDate = startTime; CalendarItemType meetingItem = new CalendarItemType(); meetingItem.UID = Guid.NewGuid().ToString(); meetingItem.Subject = this.Subject; meetingItem.Start = startTime; meetingItem.StartSpecified = true; meetingItem.End = startTime.AddHours(this.TimeInterval); meetingItem.EndSpecified = true; meetingItem.Location = this.Location; meetingItem.Recurrence = new RecurrenceType(); meetingItem.Recurrence.Item = pattern; meetingItem.Recurrence.Item1 = range; meetingItem.RequiredAttendees = new AttendeeType[] { GetAttendeeOrResource(this.AttendeeEmailAddress) }; meetingItem.OptionalAttendees = new AttendeeType[] { GetAttendeeOrResource(this.OrganizerEmailAddress) }; meetingItem.Resources = new AttendeeType[] { GetAttendeeOrResource(this.RoomEmailAddress) }; #endregion #region Organizer creates a recurring calendar item with CalendarItemCreateOrDeleteOperationType value set to SendOnlyToAll ItemInfoResponseMessageType item = this.CreateSingleCalendarItem(Role.Organizer, meetingItem, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R494"); // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R494 Site.CaptureRequirementIfIsNotNull( item, 494, @"[In CreateItem Operation] This operation [CreateItem] can be used to create meetings."); #endregion #region Organizer updates the Location element of the first occurrence of the recurring calendar item CalendarItemType calendar = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.calendar, "IPM.Appointment", meetingItem.UID) as CalendarItemType; Site.Assert.IsNotNull(calendar, "The meeting should be found in the organizer's Calendar folder after organizer calls CreateItem with CalendarItemCreateOrDeleteOperationType value set to SendOnlyToAll."); OccurrenceItemIdType occurrenceId = new OccurrenceItemIdType(); occurrenceId.RecurringMasterId = calendar.ItemId.Id; occurrenceId.InstanceIndex = 1; ItemInfoResponseMessageType getItem = this.GetSingleCalendarItem(Role.Organizer, occurrenceId); Site.Assert.IsNotNull(getItem, "The updated occurrence should exist."); // Update the first occurrence of the recurring meeting CalendarItemType calendarUpdate = new CalendarItemType(); calendarUpdate.Location = this.LocationUpdate; AdapterHelper itemChangeInfo = new AdapterHelper(); itemChangeInfo.FieldURI = UnindexedFieldURIType.calendarLocation; itemChangeInfo.Item = calendarUpdate; itemChangeInfo.ItemId = getItem.Items.Items[0].ItemId; UpdateItemResponseMessageType updatedItem = this.UpdateSingleCalendarItem(Role.Organizer, itemChangeInfo, CalendarItemUpdateOperationType.SendOnlyToAll); Site.Assert.IsNotNull(updatedItem, "The UpdateItem operation should be successful."); #endregion #region Attendee verifies whether the location of the first occurrence of the recurring calendar item has been updated CalendarItemType updatedOccurrence = null; bool locationUpdateSuccess = false; int counter = 0; while (counter < this.UpperBound) { System.Threading.Thread.Sleep(this.WaitTime); calendar = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.calendar, "IPM.Appointment", meetingItem.UID) as CalendarItemType; Site.Assert.IsNotNull(calendar, "The meeting should be found in attendee's Calendar folder after organizer updates the meeting."); occurrenceId = new OccurrenceItemIdType(); occurrenceId.RecurringMasterId = calendar.ItemId.Id; occurrenceId.InstanceIndex = 1; getItem = this.GetSingleCalendarItem(Role.Attendee, occurrenceId); Site.Assert.IsNotNull(getItem, "The updated occurrence should exist."); updatedOccurrence = getItem.Items.Items[0] as CalendarItemType; locationUpdateSuccess = string.Compare(this.LocationUpdate, updatedOccurrence.Location, true) == 0; if (locationUpdateSuccess) { break; } counter++; } if (counter == this.UpperBound && !locationUpdateSuccess) { Site.Assert.Fail("Attendee should get the update information of calendar by the organizer."); } MeetingRequestMessageType updateRequest = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.inbox, "IPM.Schedule.Meeting.Request", meetingItem.UID) as MeetingRequestMessageType; Site.Assert.IsNotNull(updateRequest, "The meeting update request should be found in attendee's inbox folder after organizer updates the meeting."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R277"); // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R277 this.Site.CaptureRequirementIfIsNotNull( updateRequest.RecurrenceId, 277, "[In t:MeetingMessageType Complex Type] RecurrenceId: Identifies a specific instance of a recurring calendar item."); #endregion #region Attendee declines the meeting request with CalendarItemCreateOrDeleteOperationType value set to SendOnlyToAll DeclineItemType declineItem = new DeclineItemType(); declineItem.ReferenceItemId = new ItemIdType(); declineItem.ReferenceItemId = updatedOccurrence.ItemId; item = this.CreateSingleCalendarItem(Role.Attendee, declineItem, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll); Site.Assert.IsNotNull(item, "The response messages returned by the CreateItem operation should succeed."); #endregion #region Organizer calls FindItem to re-obtain the ItemId of the updated recurring calendar item because the changekey of ItemId is updated MeetingResponseMessageType response = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.inbox, "IPM.Schedule.Meeting.Resp", meetingItem.UID) as MeetingResponseMessageType; Site.Assert.IsNotNull(response, "The declined meeting response returned by Attendee should be in organizer's Inbox folder."); if (Common.IsRequirementEnabled(80049, this.Site)) { // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R80049"); // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R80049 this.Site.CaptureRequirementIfIsTrue( response.IsOrganizer, 80049, "[In Appendix C: Product Behavior] Implementation does support the IsOrganizer, which specifies whether the current user is the organizer of the meeting. (Exchange 2013 and above follow this behavior.)"); } if (Common.IsRequirementEnabled(909, this.Site)) { // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R909"); // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R909 Site.CaptureRequirementIfIsNotNull( response.Recurrence, 909, @"[In Appendix C: Product Behavior] Implementation does support Recurrence which is a RecurrenceType element that represents the recurrence for the calendar item. (Exchange 2013 and above follow this behavior.)"); } #endregion #region Clean up organizer's inbox, calendar and deleteditems folders, and attendee's inbox, calendar and sentitems folders. this.CleanupFoldersByRole(Role.Organizer, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.inbox, DistinguishedFolderIdNameType.calendar, DistinguishedFolderIdNameType.deleteditems }); this.CleanupFoldersByRole(Role.Attendee, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.inbox, DistinguishedFolderIdNameType.sentitems, DistinguishedFolderIdNameType.calendar }); #endregion }