public void MSOXWSMTGS_S03_TC01_CopySingleCalendar()
        {
            #region Define a calendar item to copy
            CalendarItemType calendarItem = new CalendarItemType();
            calendarItem.UID = Guid.NewGuid().ToString();
            calendarItem.Subject = this.Subject;
            #endregion

            #region Create the calendar item with CalendarItemCreateOrDeleteOperationType set to SendToNone
            ItemInfoResponseMessageType item = this.CreateSingleCalendarItem(Role.Organizer, calendarItem, CalendarItemCreateOrDeleteOperationType.SendToNone);
            Site.Assert.IsNotNull(item, "Create a calendar item should be successful.");
            ItemIdType calendarId = item.Items.Items[0].ItemId;
            #endregion

            #region Copy the calendar item to Drafts folder
            DistinguishedFolderIdType folderId = new DistinguishedFolderIdType();
            folderId.Id = DistinguishedFolderIdNameType.drafts;
            TargetFolderIdType targetFolderId = new TargetFolderIdType();
            targetFolderId.Item = folderId;

            ItemInfoResponseMessageType copiedItem = this.CopySingleCalendarItem(Role.Organizer, calendarId, targetFolderId);

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R602");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R602
            this.Site.CaptureRequirementIfIsNotNull(
                copiedItem,
                602,
                @"[In Messages] CopyItemSoapIn: For each item being copied that is not a recurring calendar item, the ItemIds element MUST contain an ItemId child element ([MS-OXWSCORE] section 2.2.4.11).");
            #endregion

            #region Call GetItem operation to verify whether the calendar item is really copied
            CalendarItemType calendar = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.drafts, "IPM.Appointment", calendarItem.UID) as CalendarItemType;
            Site.Assert.IsNotNull(calendar, "The calendar item should be in organizer's drafts folder.");

            CalendarItemType calendarInCalendar = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.calendar, "IPM.Appointment", calendarItem.UID) as CalendarItemType;
            Site.Assert.IsNotNull(calendarInCalendar, "The calendar item should also be in organizer's calendar folder.");
            #endregion

            #region Clean up organizer's drafts and calendar folders
            this.CleanupFoldersByRole(Role.Organizer, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.calendar, DistinguishedFolderIdNameType.drafts });
            #endregion
        }
        public void MSOXWSMTGS_S04_TC01_MoveSingleCalendar()
        {
            #region Define a calendar item to move
            CalendarItemType calendarItem = new CalendarItemType();
            calendarItem.UID = Guid.NewGuid().ToString();
            calendarItem.Subject = this.Subject;
            #endregion

            #region Create the calendar item
            ItemInfoResponseMessageType item = this.CreateSingleCalendarItem(Role.Organizer, calendarItem, CalendarItemCreateOrDeleteOperationType.SendToNone);
            ItemIdType calendarId = item.Items.Items[0].ItemId;
            #endregion

            #region Move the created calendar item to Inbox folder
            DistinguishedFolderIdType folderId = new DistinguishedFolderIdType();
            folderId.Id = DistinguishedFolderIdNameType.inbox;
            TargetFolderIdType targetFolderId = new TargetFolderIdType();
            targetFolderId.Item = folderId;

            ItemInfoResponseMessageType movedItem = this.MoveSingleCalendarItem(Role.Organizer, calendarId, targetFolderId);

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R640");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R640
            this.Site.CaptureRequirementIfIsNotNull(
                movedItem,
                640,
                @"[In Messages] MoveItemSoapIn: For each item being moved that is not a recurring calendar item, the ItemIds element MUST contain an ItemId child element ([MS-OXWSCORE] section 2.2.4.11).");
            #endregion

            #region Verify the calendar item is moved to Inbox folder
            CalendarItemType calendar = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.inbox, "IPM.Appointment", calendarItem.UID) as CalendarItemType;
            Site.Assert.IsNotNull(calendar, "The calendar item should be moved to Inbox folder.");

            CalendarItemType calendarInCalendar = this.SearchDeletedSingleItem(Role.Organizer, DistinguishedFolderIdNameType.calendar, "IPM.Appointment", calendarItem.UID) as CalendarItemType;
            Site.Assert.IsNull(calendarInCalendar, "The calendar item should not be in the Calendar folder.");
            #endregion

            #region Clean up organizer's inbox folder.
            this.CleanupFoldersByRole(Role.Organizer, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.inbox });
            #endregion
        }
        public void MSOXWSCORE_S05_TC20_CreateMeetingItemWithInvalidItemClass()
        {
            #region Step 1: Create the Meeting item with ItemClass set to IPM.DistList.
            CreateItemType createItemRequest = new CreateItemType();
            createItemRequest.Items = new NonEmptyArrayOfAllItemsType();
            CalendarItemType item = new CalendarItemType();
            createItemRequest.Items.Items = new ItemType[] { item };
            createItemRequest.Items.Items[0].Subject = Common.GenerateResourceName(this.Site, TestSuiteHelper.SubjectForCreateItem, 1);
            createItemRequest.Items.Items[0].ItemClass = "IPM.DistList";
            DistinguishedFolderIdType folderIdForCreateItems = new DistinguishedFolderIdType();
            folderIdForCreateItems.Id = DistinguishedFolderIdNameType.calendar;
            createItemRequest.SavedItemFolderId = new TargetFolderIdType();
            createItemRequest.SavedItemFolderId.Item = folderIdForCreateItems;
            createItemRequest.SendMeetingInvitations = CalendarItemCreateOrDeleteOperationType.SendToAllAndSaveCopy;
            createItemRequest.SendMeetingInvitationsSpecified = true;

            CreateItemResponseType createItemResponse = this.COREAdapter.CreateItem(createItemRequest);
            Site.Assert.AreEqual<ResponseCodeType>(
                ResponseCodeType.ErrorObjectTypeChanged,
                createItemResponse.ResponseMessages.Items[0].ResponseCode,
                "ErrorObjectTypeChanged should be returned if create a Meeting item with ItemClass IPM.DistList.");
            #endregion

            #region Step 2: Create the Meeting item with ItemClass set to IPM.Post.
            createItemRequest.Items.Items[0].Subject = Common.GenerateResourceName(this.Site, TestSuiteHelper.SubjectForCreateItem, 2);
            createItemRequest.Items.Items[0].ItemClass = "IPM.Post";
            createItemResponse = this.COREAdapter.CreateItem(createItemRequest);
            Site.Assert.AreEqual<ResponseCodeType>(
                ResponseCodeType.ErrorObjectTypeChanged,
                createItemResponse.ResponseMessages.Items[0].ResponseCode,
                "ErrorObjectTypeChanged should be returned if create a Meeting item with ItemClass IPM.Post.");
            #endregion

            #region Step 3: Create the Meeting item with ItemClass set to IPM.Task.
            createItemRequest.Items.Items[0].Subject = Common.GenerateResourceName(this.Site, TestSuiteHelper.SubjectForCreateItem, 3);
            createItemRequest.Items.Items[0].ItemClass = "IPM.Task";
            createItemResponse = this.COREAdapter.CreateItem(createItemRequest);
            Site.Assert.AreEqual<ResponseCodeType>(
                ResponseCodeType.ErrorObjectTypeChanged,
                createItemResponse.ResponseMessages.Items[0].ResponseCode,
                "ErrorObjectTypeChanged should be returned if create a Meeting item with ItemClass IPM.Task.");
            #endregion

            #region Step 4: Create the Meeting item with ItemClass set to IPM.Contact.
            createItemRequest.Items.Items[0].Subject = Common.GenerateResourceName(this.Site, TestSuiteHelper.SubjectForCreateItem, 4);
            createItemRequest.Items.Items[0].ItemClass = "IPM.Contact";
            createItemResponse = this.COREAdapter.CreateItem(createItemRequest);
            Site.Assert.AreEqual<ResponseCodeType>(
                ResponseCodeType.ErrorObjectTypeChanged,
                createItemResponse.ResponseMessages.Items[0].ResponseCode,
                "ErrorObjectTypeChanged should be returned if create a Meeting item with ItemClass IPM.Contact.");
            #endregion

            #region Step 5: Create the Meeting item with ItemClass set to random string.
            createItemRequest.Items.Items[0].Subject = Common.GenerateResourceName(this.Site, TestSuiteHelper.SubjectForCreateItem, 5);
            createItemRequest.Items.Items[0].ItemClass = Common.GenerateResourceName(this.Site, "ItemClass");
            createItemResponse = this.COREAdapter.CreateItem(createItemRequest);
            Site.Assert.AreEqual<ResponseCodeType>(
                ResponseCodeType.ErrorObjectTypeChanged,
                createItemResponse.ResponseMessages.Items[0].ResponseCode,
                "ErrorObjectTypeChanged should be returned if create a Meeting item with ItemClass is set to a random string.");
            #endregion

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSCORE_R2023");

            // Verify MS-OXWSCORE requirement: MS-OXWSCORE_R2023
            this.Site.CaptureRequirement(
                2023,
                @"[In t:ItemType Complex Type] If invalid values are set for these items in the CreateItem request, an ErrorObjectTypeChanged ([MS-OXWSCDATA] section 2.2.5.24) response code will be returned in the CreateItem response.");
        }
        public void MSOXWSCORE_S05_TC03_MoveMeetingItemSuccessfully()
        {
            #region Step 1: Create the calendar item.
            CalendarItemType item = new CalendarItemType();
            ItemIdType[] createdItemIds = this.CreateItemWithMinimumElements(item);
            #endregion

            #region Step 2: Move the calendar item.
            // Clear ExistItemIds for MoveItem.
            this.InitializeCollection();

            // Call MoveItem operation.
            MoveItemResponseType moveItemResponse = this.CallMoveItemOperation(DistinguishedFolderIdNameType.inbox, createdItemIds);

            // Check the operation response.
            Common.CheckOperationSuccess(moveItemResponse, 1, this.Site);

            ItemIdType[] movedItemIds = Common.GetItemIdsFromInfoResponse(moveItemResponse);

            // One moved calendar item should be returned.
            Site.Assert.AreEqual<int>(
                1,
                 movedItemIds.GetLength(0),
                 "One moved calendar item should be returned! Expected Item Count: {0}, Actual Item Count: {1}",
                 1,
                 movedItemIds.GetLength(0));
            #endregion 

            #region Step 3: Get the created calendar item failed.
            // Call the GetItem operation.
            GetItemResponseType getItemResponse = this.CallGetItemOperation(createdItemIds);

            Site.Assert.AreEqual<int>(
                 1,
                 getItemResponse.ResponseMessages.Items.GetLength(0),
                 "Expected Item Count: {0}, Actual Item Count: {1}",
                 1,
                 getItemResponse.ResponseMessages.Items.GetLength(0));

            Site.Assert.AreEqual<ResponseClassType>(
                ResponseClassType.Error,
                getItemResponse.ResponseMessages.Items[0].ResponseClass,
                string.Format(
                    "Get calendar item operation should be failed with error! Actual response code: {0}",
                    getItemResponse.ResponseMessages.Items[0].ResponseCode));
            #endregion 

            #region Step 4: Get the moved calendar item.
            // Call the GetItem operation.
            getItemResponse = this.CallGetItemOperation(movedItemIds);

            // Check the operation response.
            Common.CheckOperationSuccess(getItemResponse, 1, this.Site);

            ItemIdType[] getItemIds = Common.GetItemIdsFromInfoResponse(getItemResponse);

            // One calendar item should be returned.
            Site.Assert.AreEqual<int>(
                1,
                 getItemIds.GetLength(0),
                 "One calendar item should be returned! Expected Item Count: {0}, Actual Item Count: {1}",
                 1,
                 getItemIds.GetLength(0));

            #endregion 
        }
        public void MSOXWSCORE_S05_TC19_VerifyItemWithReminderIsSet()
        {
            #region Step 1: Create the items.
            // Define two calendar items, the first one has the reminder set and the second one hasn't the reminder set.
            CalendarItemType[] calendar = new CalendarItemType[2]
            {
                new CalendarItemType
                {
                    ReminderIsSetSpecified = true,
                    ReminderIsSet = true,
                    Subject = Common.GenerateResourceName(
                        this.Site,
                        "ReminderIsSet")
                },
                new CalendarItemType
                {
                    ReminderIsSetSpecified = true,
                    ReminderIsSet = false,
                    Subject = Common.GenerateResourceName(
                        this.Site,
                        "ReminderIsNotSet")
                }
            };

            // Call the CreateItem operation.
            CreateItemResponseType createItemResponse = this.CallCreateItemOperation(DistinguishedFolderIdNameType.calendar, calendar);

            ItemIdType[] createdItemIds = Common.GetItemIdsFromInfoResponse(createItemResponse);

            // Two created items should be returned.
            Site.Assert.AreEqual<int>(
                 2,
                 createdItemIds.GetLength(0),
                 "Two created items should be returned! Expected Item Count: {0}, Actual Item Count: {1}",
                 2,
                 createdItemIds.GetLength(0));

            #endregion

            #region Step 2: Get the items.
            // Call the GetItem operation.
            GetItemResponseType getItemResponse = this.CallGetItemOperation(createdItemIds);

            // Check the operation response.
            Common.CheckOperationSuccess(getItemResponse, 2, this.Site);

            ItemIdType[] getItemIds = Common.GetItemIdsFromInfoResponse(getItemResponse);

            // Two items should be returned.
            Site.Assert.AreEqual<int>(
                 2,
                 getItemIds.GetLength(0),
                 "Two items should be returned! Expected Item Count: {0}, Actual Item Count: {1}",
                 2,
                 getItemIds.GetLength(0));

            // The ReminderIsSet of the second item should not be set to true.
            ItemInfoResponseMessageType itemInfoResponseMessage = getItemResponse.ResponseMessages.Items[0] as ItemInfoResponseMessageType;
            ArrayOfRealItemsType arrayOfRealItemsType = itemInfoResponseMessage.Items;

            Site.Assert.IsTrue(this.IsSchemaValidated, "The schema should be validated.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSCORE_R1616");

            // Verify MS-OXWSCORE requirement: MS-OXWSCORE_R1616
            // The schema is validated and the ReminderIsSet element is true, so this requirement can be captured.
            this.Site.CaptureRequirementIfIsTrue(
                arrayOfRealItemsType.Items[0].ReminderIsSet,
                1616,
                @"[In t:ItemType Complex Type] [ReminderIsSet is] True, indicates a reminder has been set for an item.");

            // The ReminderIsSet of the second item should not be set to false.
            itemInfoResponseMessage = getItemResponse.ResponseMessages.Items[1] as ItemInfoResponseMessageType;
            arrayOfRealItemsType = itemInfoResponseMessage.Items;

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSCORE_R1617");

            // Verify MS-OXWSCORE requirement: MS-OXWSCORE_R1617
            // The schema is validated and the ReminderIsSet element is false, so this requirement can be captured.
            this.Site.CaptureRequirementIfIsFalse(
                arrayOfRealItemsType.Items[0].ReminderIsSet,
                1617,
                @"[In t:ItemType Complex Type] otherwise [ReminderIsSet is] false, indicates [a reminder has not been set for an item].");
            #endregion
        }
        public void MSOXWSCORE_S05_TC05_MarkAllMeetingItemsAsReadSuccessfully()
        {
            Site.Assume.IsTrue(Common.IsRequirementEnabled(1290, this.Site), "Exchange 2007 and Exchange 2010 do not support the MarkAllItemsAsRead operation.");

            CalendarItemType[] items = new CalendarItemType[] { new CalendarItemType(), new CalendarItemType() };
            this.TestSteps_VerifyMarkAllItemsAsRead(items);
        }
        public void MSOXWSMTGS_S04_TC02_MoveMeeting()
        {
            #region Define the target folder to move
            // Define the Inbox folder as the target folder for moving meeting item.
            DistinguishedFolderIdType inboxFolder = new DistinguishedFolderIdType();
            inboxFolder.Id = DistinguishedFolderIdNameType.inbox;
            TargetFolderIdType meetingTargetFolder = new TargetFolderIdType();
            meetingTargetFolder.Item = inboxFolder;

            // Define the Calendar folder as the target folder for moving meeting request message, meeting response message and meeting cancellation message.
            DistinguishedFolderIdType calendarFolder = new DistinguishedFolderIdType();
            calendarFolder.Id = DistinguishedFolderIdNameType.calendar;
            TargetFolderIdType msgTargetFolder = new TargetFolderIdType();
            msgTargetFolder.Item = calendarFolder;
            #endregion

            #region Organizer creates a meeting with CalendarItemCreateOrDeleteOperationType value set to SendOnlyToAll
            #region Define a meeting to be moved
            CalendarItemType meetingItem = new CalendarItemType();
            meetingItem.Subject = this.Subject;
            meetingItem.UID = Guid.NewGuid().ToString();
            meetingItem.RequiredAttendees = new AttendeeType[] { GetAttendeeOrResource(this.AttendeeEmailAddress) };
            meetingItem.OptionalAttendees = new AttendeeType[] { GetAttendeeOrResource(this.OrganizerEmailAddress) };
            meetingItem.Resources = new AttendeeType[] { GetAttendeeOrResource(this.RoomEmailAddress) };
            #endregion

            ItemInfoResponseMessageType item = this.CreateSingleCalendarItem(Role.Organizer, meetingItem, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll);
            ItemIdType meetingId = item.Items.Items[0].ItemId;
            #endregion

            #region Organizer moves the meeting item to Inbox folder
            ItemInfoResponseMessageType movedItem = this.MoveSingleCalendarItem(Role.Organizer, meetingId, meetingTargetFolder);

            Site.Assert.AreEqual<ResponseClassType>(
                ResponseClassType.Success,
                movedItem.ResponseClass,
                "Server should return success for moving the meeting item.");

            ItemIdType movedMeetingItemId = movedItem.Items.Items[0].ItemId;
            #endregion

            #region Organizer calls FindItem to verify the meeting item is moved to Inbox folder
            CalendarItemType calendar = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.inbox, "IPM.Appointment", meetingItem.UID) as CalendarItemType;
            Site.Assert.IsNotNull(calendar, "The meeting item should be moved into organizer's Inbox folder.");
            #endregion

            #region Attendee finds the meeting request message in his Inbox folder
            MeetingRequestMessageType request = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.inbox, "IPM.Schedule.Meeting.Request", meetingItem.UID) as MeetingRequestMessageType;
            Site.Assert.IsNotNull(request, "The meeting request message should exist in attendee's inbox folder.");
            #endregion

            #region Attendee moves the meeting request message to the Calendar folder
            movedItem = this.MoveSingleCalendarItem(Role.Attendee, request.ItemId, msgTargetFolder);

            Site.Assert.AreEqual<ResponseClassType>(
                ResponseClassType.Success,
                movedItem.ResponseClass,
                @"Server should return success for moving meeting request message.");
            #endregion

            #region Attendee calls FindItem to verify the meeting request message is moved to Calendar folder
            request = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.calendar, "IPM.Schedule.Meeting.Request", meetingItem.UID) as MeetingRequestMessageType;
            Site.Assert.IsNotNull(request, "The meeting request message should exist in attendee's calendar folder.");
            #endregion

            #region Attendee calls CreateItem to accept the meeting request with CalendarItemCreateOrDeleteOperationType value set to SendOnlyToAll
            AcceptItemType acceptItem = new AcceptItemType();
            acceptItem.ReferenceItemId = request.ItemId;

            item = this.CreateSingleCalendarItem(Role.Attendee, acceptItem, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll);
            #endregion

            #region Organizer finds the meeting response message in its Inbox folder
            MeetingResponseMessageType response = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.inbox, "IPM.Schedule.Meeting.Resp", meetingItem.UID) as MeetingResponseMessageType;
            Site.Assert.IsNotNull(response, "The meeting response message should exist in organizer's inbox folder.");
            #endregion

            #region Organizer moves the meeting response message to his Calendar folder
            movedItem = this.MoveSingleCalendarItem(Role.Organizer, response.ItemId, msgTargetFolder);

            Site.Assert.AreEqual<ResponseClassType>(
                ResponseClassType.Success,
                movedItem.ResponseClass,
                "EWS should return success for moving the meeting response message.");
            #endregion

            #region Organizer calls FindItem to verify the meeting response message is moved to Calendar folder
            response = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.calendar, "IPM.Schedule.Meeting.Resp", meetingItem.UID) as MeetingResponseMessageType;
            Site.Assert.IsNotNull(response, "The meeting response message should be in organizer's calendar folder.");
            #endregion

            #region Organizer calls DeleteItem to delete the meeting with CalendarItemCreateOrDeleteOperationType value set to SendOnlyToAll
            ResponseMessageType deletedItem = this.DeleteSingleCalendarItem(Role.Organizer, movedMeetingItemId, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll);
            Site.Assert.IsNotNull(deletedItem, "Delete the meeting should be successful.");
            #endregion

            #region Attendee finds the meeting cancellation message in his Inbox folder
            MeetingCancellationMessageType canceledMeeting = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.inbox, "IPM.Schedule.Meeting.Canceled", meetingItem.UID) as MeetingCancellationMessageType;
            Site.Assert.IsNotNull(canceledMeeting, "The meeting cancellation message should be in attendee's inbox folder.");
            #endregion

            #region Attendee moves the meeting cancellation message to his Calendar folder
            movedItem = this.MoveSingleCalendarItem(Role.Attendee, canceledMeeting.ItemId, msgTargetFolder);

            Site.Assert.AreEqual<ResponseClassType>(
                ResponseClassType.Success,
                movedItem.ResponseClass,
                "EWS should return success for moving the meeting cancellation message.");
            #endregion

            #region Attendee calls FindItem to verify the meeting cancellation message is moved to Calendar folder
            canceledMeeting = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.calendar, "IPM.Schedule.Meeting.Canceled", meetingItem.UID) as MeetingCancellationMessageType;
            Site.Assert.IsNotNull(canceledMeeting, "The meeting cancellation message should be in attendee's calendar folder.");
            #endregion

            #region Attendee removes the meeting item
            RemoveItemType removeItem = new RemoveItemType();
            removeItem.ReferenceItemId = canceledMeeting.ItemId;
            item = this.CreateSingleCalendarItem(Role.Attendee, removeItem, CalendarItemCreateOrDeleteOperationType.SendToNone);
            Site.Assert.IsNotNull(item, "The meeting item should be removed.");
            #endregion

            #region Clean up organizer's calendar and deleteditems folders, and attendee's sentitems and deleteditems folders
            this.CleanupFoldersByRole(Role.Organizer, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.calendar, DistinguishedFolderIdNameType.deleteditems });
            this.CleanupFoldersByRole(Role.Attendee, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.sentitems, DistinguishedFolderIdNameType.deleteditems });
            #endregion
        }
        /// <summary>
        /// Create and get a recurring calendar item.
        /// </summary>
        /// <param name="start">The start time of a recurring calendar item</param>
        /// <param name="numberOfOccurrences">The number of occurrences of a recurring calendar item</param>
        /// <returns>The created recurring calendar item</returns>
        private CalendarItemType CreateAndGetRecurringCalendarItem(DateTime start, int numberOfOccurrences)
        {
            #region Step 1: Create a recurring calendar item.
            CalendarItemType[] items = new CalendarItemType[] { new CalendarItemType() };
            items[0].Subject = Common.GenerateResourceName(
                this.Site,
                TestSuiteHelper.SubjectForCreateItem);
            items[0].Recurrence = new RecurrenceType();

            DailyRecurrencePatternType pattern = new DailyRecurrencePatternType();
            pattern.Interval = 1;

            NumberedRecurrenceRangeType range = new NumberedRecurrenceRangeType();
            range.NumberOfOccurrences = numberOfOccurrences;
            range.StartDate = start;

            items[0].Recurrence.Item = pattern;
            items[0].Recurrence.Item1 = range;

            CreateItemResponseType createItemResponse = this.CallCreateItemOperation(DistinguishedFolderIdNameType.calendar, items);

            // Check the operation response.
            Common.CheckOperationSuccess(createItemResponse, 1, this.Site);

            ItemIdType[] createdCalendarItemIds = Common.GetItemIdsFromInfoResponse(createItemResponse);

            // One created calendar item should be returned.
            Site.Assert.AreEqual<int>(
                1,
                 createdCalendarItemIds.GetLength(0),
                 "One created calendar item should be returned! Expected Item Count: {0}, Actual Item Count: {1}",
                 1,
                 createdCalendarItemIds.GetLength(0));
            #endregion 

            #region Step 2: Get the recurring calendar item by ItemIdType.
            // Call the GetItem operation.
            GetItemResponseType getItemResponse = this.CallGetItemOperation(createdCalendarItemIds);

            // Check the operation response.
            Common.CheckOperationSuccess(getItemResponse, 1, this.Site);

            CalendarItemType[] getCalendarItems = Common.GetItemsFromInfoResponse<CalendarItemType>(getItemResponse);

            // One calendar item should be returned.
            Site.Assert.AreEqual<int>(
                1,
                 getCalendarItems.GetLength(0),
                 "One calendar item should be returned! Expected Item Count: {0}, Actual Item Count: {1}",
                 1,
                 getCalendarItems.GetLength(0));

            Site.Assert.IsNotNull(
                 getCalendarItems[0].FirstOccurrence,
                 "FirstOccurrence element in calendar item should not be null!");

            return getCalendarItems[0];
            #endregion 
        }
        public void MSOXWSMTGS_S03_TC03_CopyRecurringCalendar()
        {
            #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 calendarItem = new CalendarItemType();
            calendarItem.UID = Guid.NewGuid().ToString();
            calendarItem.Subject = this.Subject;
            calendarItem.Start = startTime;
            calendarItem.StartSpecified = true;
            calendarItem.End = startTime.AddHours(this.TimeInterval);
            calendarItem.EndSpecified = true;
            calendarItem.Recurrence = new RecurrenceType();
            calendarItem.Recurrence.Item = pattern;
            calendarItem.Recurrence.Item1 = range;
            #endregion

            #region Create the recurring calendar item and extract the Id of an occurrence item
            ItemInfoResponseMessageType item = this.CreateSingleCalendarItem(Role.Organizer, calendarItem, CalendarItemCreateOrDeleteOperationType.SendToNone);

            OccurrenceItemIdType occurrenceItemId = new OccurrenceItemIdType();
            occurrenceItemId.ChangeKey = item.Items.Items[0].ItemId.ChangeKey;
            occurrenceItemId.RecurringMasterId = item.Items.Items[0].ItemId.Id;
            occurrenceItemId.InstanceIndex = this.InstanceIndex;
            #endregion

            #region Get the targeted occurrence item
            ItemInfoResponseMessageType getItem = this.GetSingleCalendarItem(Role.Organizer, occurrenceItemId);
            Site.Assert.IsNotNull(getItem, @"Get the occurrence should be successful.");

            RecurringMasterItemIdType recurringMasterItemId = new RecurringMasterItemIdType();
            recurringMasterItemId.ChangeKey = getItem.Items.Items[0].ItemId.ChangeKey;
            recurringMasterItemId.OccurrenceId = getItem.Items.Items[0].ItemId.Id;
            #endregion

            #region Copy the recurring calendar item to Drafts folder through Id of recurring master getItem
            DistinguishedFolderIdType folderId = new DistinguishedFolderIdType();
            folderId.Id = DistinguishedFolderIdNameType.drafts;
            TargetFolderIdType targetFolderId = new TargetFolderIdType();
            targetFolderId.Item = folderId;

            ItemInfoResponseMessageType copiedItem = this.CopySingleCalendarItem(Role.Organizer, recurringMasterItemId, targetFolderId);
            Site.Assert.IsNotNull(copiedItem, @"Copy recurring calendar item through RecurringMasterItemId should be successful.");
            ItemIdType calendarIdByCopied = copiedItem.Items.Items[0].ItemId;
            #endregion

            #region Call GetItem operation to verify whether the recurring calendar item is really copied
            getItem = this.GetSingleCalendarItem(Role.Organizer, calendarIdByCopied);

            if (Common.IsRequirementEnabled(806, this.Site))
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R806");

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R806
                this.Site.CaptureRequirementIfIsNotNull(
                    getItem,
                    806,
                    @"[In Appendix C: Product Behavior] CopyItemSoapIn: For each item being copied that is a recurring calendar item, implementation does contain a RecurringMasterItemId child element ([MS-OXWSCORE] section 2.2.4.11). (Exchange 2007 and above follow this behavior.)");
            }
            #endregion

            #region Clean up organizer's drafts and calendar folders.
            this.CleanupFoldersByRole(Role.Organizer, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.calendar, DistinguishedFolderIdNameType.drafts });
            #endregion
        }
        public void MSOXWSCORE_S05_TC12_GetMeetingItemWithConvertHtmlCodePageToUTF8()
        {
            Site.Assume.IsTrue(Common.IsRequirementEnabled(21498, this.Site), "Exchange 2007 and Exchange 2010 do not include the ConvertHtmlCodePageToUTF8 element.");

            CalendarItemType item = new CalendarItemType();
            this.TestSteps_VerifyGetItemWithItemResponseShapeType_ConvertHtmlCodePageToUTF8Boolean(item);
        }
        public void MSOXWSCORE_S05_TC13_GetMeetingItemWithAddBlankTargetToLinks()
        {
            Site.Assume.IsTrue(Common.IsRequirementEnabled(2149908, this.Site), "Exchange 2007 and Exchange 2010 do not use the AddBlankTargetToLinks element.");

            CalendarItemType item = new CalendarItemType();
            this.TestSteps_VerifyGetItemWithItemResponseShapeType_AddBlankTargetToLinksBoolean(item);
        }
 public void MSOXWSCORE_S05_TC09_OperateMultipleMeetingItemsSuccessfully()
 {
     CalendarItemType[] items = new CalendarItemType[] { new CalendarItemType(), new CalendarItemType() };
     this.TestSteps_VerifyOperateMultipleItems(items);
 }
 public void MSOXWSCORE_S05_TC11_GetMeetingItemWithIncludeMimeContent()
 {
     CalendarItemType item = new CalendarItemType();
     this.TestSteps_VerifyGetItemWithItemResponseShapeType_IncludeMimeContentBoolean(item);
 }
        public void MSOXWSCORE_S05_TC08_VerifyExtendPropertyType()
        {
            CalendarItemType item = new CalendarItemType();
            this.TestSteps_VerifyDistinguishedPropertySetIdConflictsWithPropertySetId(DistinguishedFolderIdNameType.calendar, item);

            this.TestSteps_VerifyDistinguishedPropertySetIdConflictsWithPropertyTag(DistinguishedFolderIdNameType.calendar, item);

            this.TestSteps_VerifyDistinguishedPropertySetIdWithPropertyTypeOrPropertyName(DistinguishedFolderIdNameType.calendar, item);

            this.TestSteps_VerifyPropertySetIdConflictsWithDistinguishedPropertySetId(DistinguishedFolderIdNameType.calendar, item);

            this.TestSteps_VerifyPropertySetIdConflictsWithPropertyTag(DistinguishedFolderIdNameType.calendar, item);

            this.TestSteps_VerifyPropertySetIdWithPropertyTypeOrPropertyName(DistinguishedFolderIdNameType.calendar, item);

            this.TestSteps_VerifyPropertyTagRepresentation(DistinguishedFolderIdNameType.calendar, item);

            this.TestSteps_VerifyPropertyTagConflictsWithDistinguishedPropertySetId(DistinguishedFolderIdNameType.calendar, item);

            this.TestSteps_VerifyPropertyTagConflictsWithPropertyName(DistinguishedFolderIdNameType.calendar, item);

            this.TestSteps_VerifyPropertyTagConflictsWithPropertyId(DistinguishedFolderIdNameType.calendar, item);

            this.TestSteps_VerifyPropertyNameWithDistinguishedPropertySetIdOrPropertySetId(DistinguishedFolderIdNameType.calendar, item);

            this.TestSteps_VerifyPropertyIdWithDistinguishedPropertySetIdOrPropertySetId(DistinguishedFolderIdNameType.calendar, item);
        }
        public void MSOXWSCORE_S05_TC07_CreateMeetingItemFailed()
        {
            #region Step 1: Create the calendar item with invalid item class.
            CalendarItemType[] items = new CalendarItemType[]
            { 
                new CalendarItemType()
                { 
                    Subject = Common.GenerateResourceName(
                        this.Site,
                        TestSuiteHelper.SubjectForCreateItem),

                    // Set an invalid ItemClass to calendar item.
                    ItemClass = TestSuiteHelper.InvalidItemClass
                }
            };

            CreateItemResponseType createItemResponse = this.CallCreateItemOperation(DistinguishedFolderIdNameType.calendar, items);
            #endregion 

            // Get ResponseCode from CreateItem operation response.
            ResponseCodeType responseCode = createItemResponse.ResponseMessages.Items[0].ResponseCode;

            // Verify MS-OXWSCDATA_R619.
            this.VerifyErrorObjectTypeChanged(responseCode);
        }
 public void MSOXWSCORE_S05_TC06_UpdateMeetingItemFailed()
 {
     CalendarItemType item = new CalendarItemType();
     this.TestSteps_VerifyUpdateItemFailedResponse(item);
 }
        public void MSOXWSCORE_S05_TC21_ResponseObjectsProposeNewTime()
        {
            Site.Assume.IsTrue(Common.IsRequirementEnabled(2302, this.Site), "Exchange 2007, Exchange 2010, and the initial release of Exchange 2013 do not support the ProposeNewTime element. ");

            #region Organizer sends meeting to attendee.
            CalendarItemType item = new CalendarItemType();
            item.RequiredAttendees = new AttendeeType[1];
            EmailAddressType attendeeEmail = new EmailAddressType();
            attendeeEmail.EmailAddress = Common.GetConfigurationPropertyValue("User2Name", this.Site) + "@" + Common.GetConfigurationPropertyValue("Domain", this.Site);
            AttendeeType attendee = new AttendeeType();
            attendee.Mailbox = attendeeEmail;
            item.RequiredAttendees[0] = attendee;

            CreateItemType createItemRequest = new CreateItemType();
            createItemRequest.Items = new NonEmptyArrayOfAllItemsType();
            createItemRequest.Items.Items = new ItemType[] { item };
            createItemRequest.Items.Items[0].Subject = Common.GenerateResourceName(this.Site, TestSuiteHelper.SubjectForCreateItem);
            createItemRequest.SendMeetingInvitations = CalendarItemCreateOrDeleteOperationType.SendOnlyToAll;
            createItemRequest.SendMeetingInvitationsSpecified = true;

            CreateItemResponseType createItemResponse = this.COREAdapter.CreateItem(createItemRequest);

            // Check the operation response.
            Common.CheckOperationSuccess(createItemResponse, 1, this.Site);

            ItemIdType[] createdItemIds = Common.GetItemIdsFromInfoResponse(createItemResponse);

            // One created item should be returned.
            Site.Assert.AreEqual<int>(
                1,
                 createdItemIds.GetLength(0),
                 "One created item should be returned! Expected Item Count: {0}, Actual Item Count: {1}",
                 1,
                 createdItemIds.GetLength(0));
            #endregion

            #region Attendee gets the meeting request
            ItemIdType[] findItemIds = this.FindItemsInFolder(DistinguishedFolderIdNameType.inbox, createItemRequest.Items.Items[0].Subject, "User2");
            Site.Assert.AreEqual<int>(1, findItemIds.Length, "Attendee should receive the meeting request");

            GetItemResponseType getItemResponse = this.CallGetItemOperation(findItemIds);

            // Check the operation response.
            Common.CheckOperationSuccess(getItemResponse, 1, this.Site);

            // Check whether the child elements of ResponseObjects have been returned successfully.
            ItemInfoResponseMessageType getItems = getItemResponse.ResponseMessages.Items[0] as ItemInfoResponseMessageType;
            ResponseObjectType[] responseObjects = getItems.Items.Items[0].ResponseObjects;
            foreach (ResponseObjectType responseObject in responseObjects)
            {
                if (responseObject.GetType() == typeof(ProposeNewTimeType))
                {
                    // Add the debug information
                    this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSCORE_R2302");

                    // Verify MS-OXWSCORE requirement: MS-OXWSCORE_R2302
                    // Element ProposeNewTime is returned from server, this requirement can be captured directly.
                    this.Site.CaptureRequirement(
                        2302,
                        @"[In Appendix C: Product Behavior] Implementation does support the ProposeNewTime element which specifies the response object that is used to propose a new time. (<82> Section 2.2.4.33:  This element [ProposeNewTime] was introduced in Exchange 2013 SP1.)");

                    // Add the debug information
                    this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSCORE_R2135");

                    // Verify MS-OXWSCORE requirement: MS-OXWSCORE_R2135
                    // Element ProposeNewTime is returned from server and pass schema validation, this requirement can be captured directly.
                    this.Site.CaptureRequirement(
                        2135,
                        @"[In t:NonEmptyArrayOfResponseObjectsType Complex Type] The type of ProposeNewTime is t:ProposeNewTimeType ([MS-OXWSCDATA] section 2.2.4.38).");
                    break;
                }
            }

            this.CleanItemsSentOut(new string[] { createItemRequest.Items.Items[0].Subject });
            this.ExistItemIds.Remove(getItems.Items.Items[0].ItemId);
            #endregion
        }
        public void MSOXWSCORE_S05_TC14_GetMeetingItemWithBlockExternalImages()
        {
            Site.Assume.IsTrue(Common.IsRequirementEnabled(2149905, this.Site), "Exchange 2007 and Exchange 2010 do not use the BlockExternalImages element.");

            CalendarItemType item = new CalendarItemType();
            this.TestSteps_VerifyGetItemWithItemResponseShapeType_BlockExternalImagesBoolean(item);
        }
        public void MSOXWSCORE_S05_TC22_VerifyCompareOriginalStartTime()
        {
            #region Step 1: Create and get a recurring calendar item.
            DateTime start = DateTime.Now;
            int numberOfOccurrences = 5;
            CalendarItemType calendar = this.CreateAndGetRecurringCalendarItem(start, numberOfOccurrences);

            #endregion

            #region Step 2: Get the first occurrence of the recurring calendar item by OccurrenceItemIdType.
            // The calendar item to get.
            OccurrenceItemIdType[] occurrenceItemId = new OccurrenceItemIdType[1];
            occurrenceItemId[0] = new OccurrenceItemIdType();
            occurrenceItemId[0].RecurringMasterId = calendar.ItemId.Id;
            occurrenceItemId[0].ChangeKey = calendar.FirstOccurrence.ItemId.ChangeKey;
            occurrenceItemId[0].InstanceIndex = 1;

            // Call the GetItem operation.
            GetItemResponseType getItemResponse = this.CallGetItemOperation(occurrenceItemId);

            // Check the operation response.
            Common.CheckOperationSuccess(getItemResponse, 1, this.Site);

            CalendarItemType[] getCalendarOccurences = Common.GetItemsFromInfoResponse<CalendarItemType>(getItemResponse);

            // One calendar item should be returned.
            Site.Assert.AreEqual<int>(
                1,
                 getCalendarOccurences.GetLength(0),
                 "One calendar item should be returned! Expected Item Count: {0}, Actual Item Count: {1}",
                 1,
                 getCalendarOccurences.GetLength(0));

            ItemIdType[] itemIds = Common.GetItemIdsFromInfoResponse(getItemResponse);
            ItemIdId itemIdId = this.ITEMIDAdapter.ParseItemId(itemIds[0]);
            #endregion

            #region Step 3: Update the start date of the calendar item.

            ItemChangeType itemChange = new ItemChangeType();
            itemChange.Item = itemIds[0];

            CalendarItemType calendarChange = new CalendarItemType();
            calendarChange.Start = calendar.Start.AddMinutes(20);
            calendarChange.StartSpecified = true;

            itemChange.Updates = new ItemChangeDescriptionType[1];
            SetItemFieldType setItemField = new SetItemFieldType();
            setItemField.Item = new PathToUnindexedFieldType()
            {
                FieldURI = UnindexedFieldURIType.calendarStart
            };

            setItemField.Item1 = calendarChange;
            itemChange.Updates[0] = setItemField;

            UpdateItemResponseType updatedItem = this.CallUpdateItemOperation(DistinguishedFolderIdNameType.calendar, true, new ItemChangeType[] { itemChange });

            #endregion

            SutVersion currentSutVersion = (SutVersion)Enum.Parse(typeof(SutVersion), Common.GetConfigurationPropertyValue("SutVersion", this.Site));
            if (currentSutVersion.Equals(SutVersion.ExchangeServer2016))
            {
                #region Step 4: Get the recurring calendar item by RecurringMasterItemIdRangesType with set CompareOriginalStartTime to true.

                // The calendar item to get.
                RecurringMasterItemIdRangesType[] recurringMasterItemIdRanges = new RecurringMasterItemIdRangesType[1];
                recurringMasterItemIdRanges[0] = new RecurringMasterItemIdRangesType();

                // Use the first occurrence item id and change key to form the recurringMasterItemId
                recurringMasterItemIdRanges[0].Id = calendar.ItemId.Id;
                recurringMasterItemIdRanges[0].ChangeKey = calendar.ItemId.ChangeKey;
                recurringMasterItemIdRanges[0].Ranges = new OccurrencesRangeType[1];
                recurringMasterItemIdRanges[0].Ranges[0] = new OccurrencesRangeType();
                recurringMasterItemIdRanges[0].Ranges[0].Start = calendar.Start.AddMinutes(10);
                recurringMasterItemIdRanges[0].Ranges[0].StartSpecified = true;
                recurringMasterItemIdRanges[0].Ranges[0].End = start.AddDays(5);
                recurringMasterItemIdRanges[0].Ranges[0].EndSpecified = true;
                recurringMasterItemIdRanges[0].Ranges[0].Count = 5;
                recurringMasterItemIdRanges[0].Ranges[0].CountSpecified = true;
                recurringMasterItemIdRanges[0].Ranges[0].CompareOriginalStartTime = true;
                recurringMasterItemIdRanges[0].Ranges[0].CompareOriginalStartTimeSpecified = true;

                // Call the GetItem operation.
                GetItemResponseType getItemResponse1 = this.CallGetItemOperation(recurringMasterItemIdRanges);

                // Check the operation response.
                Common.CheckOperationSuccess(getItemResponse1, 1, this.Site);

                CalendarItemType[] getCalendarRecurring = Common.GetItemsFromInfoResponse<CalendarItemType>(getItemResponse1);

                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSCORE_R1697");

                // Verify MS-OXWSCORE requirement: MS-OXWSCORE_R1697
                this.Site.CaptureRequirementIfAreEqual(
                    5,
                    getCalendarRecurring.Length,
                    1697,
                    @"[In t:OccurrencesRangeType Complex Type] [CompareOriginalStartTime is] True, indicates comparing the specified ranges to an original start time.");

                #endregion

                #region Step 5: Get the recurrence master calendar item by RecurringMasterItemIdRangesType with set CompareOriginalStartTime to false.

                // The calendar item to get.
                recurringMasterItemIdRanges[0].Ranges[0].CompareOriginalStartTime = false;
                recurringMasterItemIdRanges[0].Ranges[0].CompareOriginalStartTimeSpecified = true;

                // Call the GetItem operation.
                getItemResponse1 = this.CallGetItemOperation(recurringMasterItemIdRanges);

                // Check the operation response.
                Common.CheckOperationSuccess(getItemResponse1, 1, this.Site);

                getCalendarRecurring = Common.GetItemsFromInfoResponse<CalendarItemType>(getItemResponse1);

                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSCORE_R1698");

                // Verify MS-OXWSCORE requirement: MS-OXWSCORE_R1698
                this.Site.CaptureRequirementIfAreEqual(
                    6,
                    getCalendarRecurring.Length,
                    1698,
                    @"[In t:OccurrencesRangeType Complex Type] otherwise [CompareOriginalStartTime is] false, indicates comparing the specified ranges to a pair of start and end values.");
                #endregion
            }

            // Clear ExistItemIds for DeleteItem.
            this.ExistItemIds.Clear();
            this.ExistItemIds.Add(calendar.ItemId);
        }
        public void MSOXWSMTGS_S03_TC02_CopySingleMeetingItem()
        {
            #region Organizer creates a single meeting getItem with CalendarItemCreateOrDeleteOperationType value set to SendOnlyToAll
            CalendarItemType meetingItem = new CalendarItemType();
            meetingItem.Subject = this.Subject;
            meetingItem.UID = Guid.NewGuid().ToString();
            meetingItem.RequiredAttendees = new AttendeeType[] { GetAttendeeOrResource(this.AttendeeEmailAddress) };
            meetingItem.OptionalAttendees = new AttendeeType[] { GetAttendeeOrResource(this.OrganizerEmailAddress) };
            meetingItem.Resources = new AttendeeType[] { GetAttendeeOrResource(this.RoomEmailAddress) };

            ItemInfoResponseMessageType item = this.CreateSingleCalendarItem(Role.Organizer, meetingItem, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll);
            Site.Assert.IsNotNull(item, "Create single meeting item should be successful.");
            #endregion

            #region Organizer copies the created single meeting item to Drafts folder
            CalendarItemType calendar = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.calendar, "IPM.Appointment", meetingItem.UID) as CalendarItemType;
            Site.Assert.IsNotNull(calendar, "The created calendar should exist in organizer's calendar folder.");
            ItemIdType itemId = calendar.ItemId;

            DistinguishedFolderIdType folderId = new DistinguishedFolderIdType();
            folderId.Id = DistinguishedFolderIdNameType.drafts;
            TargetFolderIdType targetFolderId = new TargetFolderIdType();
            targetFolderId.Item = folderId;

            ItemInfoResponseMessageType copiedItem = this.CopySingleCalendarItem(Role.Organizer, itemId, targetFolderId);
            Site.Assert.IsNotNull(copiedItem, @"Copy the single meeting item should be successful.");
            #endregion

            #region Organizer calls GetItem operation to verify whether the meeting item is really copied
            calendar = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.drafts, "IPM.Appointment", meetingItem.UID) as CalendarItemType;
            Site.Assert.IsNotNull(calendar, "The copied calendar should exist in organizer's Drafts folder.");
            #endregion

            #region Attendee gets the meeting request message in the Inbox folder
            MeetingRequestMessageType request = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.inbox, meetingItem.Subject, meetingItem.UID, UnindexedFieldURIType.itemSubject) as MeetingRequestMessageType;
            Site.Assert.IsNotNull(request, "The meeting request message should exist in attendee's inbox folder.");
            #endregion

            #region Attendee copies the meeting request message to the Drafts folder
            copiedItem = this.CopySingleCalendarItem(Role.Attendee, request.ItemId, targetFolderId);
            Site.Assert.IsNotNull(copiedItem, @"Copy the single meeting request message should be successful.");
            #endregion

            #region Attendee calls CreateItem to accept the meeting request with CalendarItemCreateOrDeleteOperationType value set to SendOnlyToAll
            AcceptItemType acceptItem = new AcceptItemType();
            acceptItem.ReferenceItemId = request.ItemId;

            Site.Assert.IsNotNull(
                this.CreateSingleCalendarItem(Role.Attendee, acceptItem, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll),
                "Attendee creates items for meeting request should succeed.");
            #endregion

            #region Organizer finds the meeting response message in his Inbox folder and copies it to the Drafts folder
            MeetingResponseMessageType response = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.inbox, "IPM.Schedule.Meeting.Resp", meetingItem.UID) as MeetingResponseMessageType;
            Site.Assert.IsNotNull(response, "The response message from Attendee should be in organizer's Inbox folder.");

            copiedItem = this.CopySingleCalendarItem(Role.Organizer, response.ItemId, targetFolderId);
            Site.Assert.IsNotNull(copiedItem, @"Copy the single meeting response message should be successful.");
            #endregion

            #region Organizer deletes the meeting item with CalendarItemCreateOrDeleteOperationType value set to SendOnlyToAll
            ResponseMessageType deletedItem = this.DeleteSingleCalendarItem(Role.Organizer, itemId, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll);
            Site.Assert.IsNotNull(deletedItem, @"Delete the single meeting item should be successful.");
            #endregion

            #region Attendee finds the meeting cancellation message in the Inbox folder and copies it to the Drafts folder
            int upperBound = int.Parse(Common.GetConfigurationPropertyValue("RetryCount", this.Site));
            int waitTime = int.Parse(Common.GetConfigurationPropertyValue("WaitTime", this.Site));
            int count = 1;

            MeetingCancellationMessageType canceledItem = null;

            while (canceledItem == null && count++ <= upperBound)
            {
                canceledItem = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.inbox, "IPM.Schedule.Meeting.Canceled", meetingItem.UID) as MeetingCancellationMessageType;
                System.Threading.Thread.Sleep(waitTime);
            }

            Site.Assert.IsNotNull(canceledItem, "The cancellation meeting message should be in attendee's Inbox folder.");

            ItemIdType canceledItemId = canceledItem.ItemId;
            copiedItem = this.CopySingleCalendarItem(Role.Attendee, canceledItemId, targetFolderId);
            Site.Assert.IsNotNull(copiedItem, "Attendee should copy the meeting cancellation message to the Drafts folder.");
            #endregion

            #region Clean up inbox, drafts and deleteditems folders of both organizer and attendee. Attendee's sentitems and calendar should also be cleaned up.
            this.CleanupFoldersByRole(Role.Organizer, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.inbox, DistinguishedFolderIdNameType.drafts, DistinguishedFolderIdNameType.deleteditems });
            this.CleanupFoldersByRole(Role.Attendee, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.inbox, DistinguishedFolderIdNameType.calendar, DistinguishedFolderIdNameType.sentitems, DistinguishedFolderIdNameType.drafts, DistinguishedFolderIdNameType.deleteditems });
            #endregion
        }
        /// <summary>
        /// Create an item in the specified folder.
        /// </summary>
        /// <param name="parentFolderType">Type of the parent folder.</param>
        /// <param name="parentFolderId">ID of the parent folder.</param>
        /// <param name="itemSubject">Subject of the item which should be created.</param>
        /// <returns>ID of the created item.</returns>
        protected ItemIdType CreateItem(DistinguishedFolderIdNameType parentFolderType, string parentFolderId, string itemSubject)
        {
            // Create a request for the CreateItem operation and initialize the ItemType instance.
            CreateItemType createItemRequest = new CreateItemType();
            ItemType item = null;

            // Get different values for item based on different parent folder type.
            switch (parentFolderType)
            {
                case DistinguishedFolderIdNameType.contacts:
                    ContactItemType contact = new ContactItemType();
                    contact.Subject = itemSubject;
                    contact.FileAs = itemSubject;
                    item = contact;
                    break;
                case DistinguishedFolderIdNameType.calendar:
                    // Set the sendMeetingInvitations property.
                    CalendarItemCreateOrDeleteOperationType sendMeetingInvitations = CalendarItemCreateOrDeleteOperationType.SendToNone;
                    createItemRequest.SendMeetingInvitations = (CalendarItemCreateOrDeleteOperationType)sendMeetingInvitations;
                    createItemRequest.SendMeetingInvitationsSpecified = true;
                    CalendarItemType calendar = new CalendarItemType();
                    calendar.Subject = itemSubject;
                    item = calendar;
                    break;
                case DistinguishedFolderIdNameType.inbox:
                    MessageType message = new MessageType();
                    message.Subject = itemSubject;
                    item = message;
                    break;
                case DistinguishedFolderIdNameType.tasks:
                    TaskType taskItem = new TaskType();
                    taskItem.Subject = itemSubject;
                    item = taskItem;
                    break;
                default:
                    Site.Assert.Fail("The parent folder type '{0}' is invalid and the valid folder types are: contacts, calendar, inbox and tasks.", parentFolderType.ToString());
                    break;
            }

            // Set the MessageDisposition property.
            MessageDispositionType messageDisposition = MessageDispositionType.SaveOnly;
            createItemRequest.MessageDisposition = (MessageDispositionType)messageDisposition;
            createItemRequest.MessageDispositionSpecified = true;

            // Specify the folder in which new items are saved.
            createItemRequest.SavedItemFolderId = new TargetFolderIdType();
            FolderIdType folderId = new FolderIdType();
            folderId.Id = parentFolderId;
            createItemRequest.SavedItemFolderId.Item = folderId;

            // Specify the collection of items to be created.
            createItemRequest.Items = new NonEmptyArrayOfAllItemsType();
            createItemRequest.Items.Items = new ItemType[] { item };

            // Initialize the ID of the created item.
            ItemIdType createdItemId = null;

            // Invoke the create item operation and get the response.
            CreateItemResponseType createItemResponse = this.COREAdapter.CreateItem(createItemRequest);

            if (createItemResponse != null && createItemResponse.ResponseMessages.Items[0].ResponseClass == ResponseClassType.Success)
            {
                ItemInfoResponseMessageType info = createItemResponse.ResponseMessages.Items[0] as ItemInfoResponseMessageType;
                Site.Assert.IsNotNull(info, "The items in CreateItem response should not be null.");

                // Get the ID of the created item.
                createdItemId = info.Items.Items[0].ItemId;
            }

            return createdItemId;
        }
        public void MSOXWSMTGS_S04_TC04_MoveItemErrorCalendarCannotMoveOrCopyOccurrence()
        {
            #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 calendarItem = new CalendarItemType();
            calendarItem.UID = Guid.NewGuid().ToString();
            calendarItem.Subject = this.Subject;
            calendarItem.Start = startTime;
            calendarItem.StartSpecified = true;
            calendarItem.End = startTime.AddHours(this.TimeInterval);
            calendarItem.EndSpecified = true;
            calendarItem.Recurrence = new RecurrenceType();
            calendarItem.Recurrence.Item = pattern;
            calendarItem.Recurrence.Item1 = range;
            #endregion

            #region Create the recurring calendar item and extract the Id of an occurrence item
            ItemInfoResponseMessageType item = this.CreateSingleCalendarItem(Role.Organizer, calendarItem, CalendarItemCreateOrDeleteOperationType.SendToNone);

            OccurrenceItemIdType occurrenceItemId = new OccurrenceItemIdType();
            occurrenceItemId.ChangeKey = item.Items.Items[0].ItemId.ChangeKey;
            occurrenceItemId.RecurringMasterId = item.Items.Items[0].ItemId.Id;
            occurrenceItemId.InstanceIndex = this.InstanceIndex;
            #endregion

            #region Copy one occurrence of the recurring calendar item
            DistinguishedFolderIdType folderId = new DistinguishedFolderIdType();
            folderId.Id = DistinguishedFolderIdNameType.drafts;
            TargetFolderIdType targetFolderId = new TargetFolderIdType();
            targetFolderId.Item = folderId;

            MoveItemType moveItemRequest = new MoveItemType();
            moveItemRequest.ItemIds = new BaseItemIdType[] { occurrenceItemId };
            moveItemRequest.ToFolderId = targetFolderId;
            MoveItemResponseType response = this.MTGSAdapter.MoveItem(moveItemRequest);

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R1228");

            // Verify MS-OXWSMSG requirement: MS-OXWSMTGS_R1228
            Site.CaptureRequirementIfAreEqual<ResponseClassType>(
                ResponseClassType.Error,
                response.ResponseMessages.Items[0].ResponseClass,
                1228,
                @"[In Messages] If the request is unsuccessful, the MoveItem operation returns a MoveItemResponse element with the ResponseClass attribute of the MoveItemResponseMessage element set to ""Error"". ");

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R1231");

            // Verify MS-OXWSMSG requirement: MS-OXWSMTGS_R1231
            Site.CaptureRequirementIfAreEqual<ResponseCodeType>(
                ResponseCodeType.ErrorCalendarCannotMoveOrCopyOccurrence,
                response.ResponseMessages.Items[0].ResponseCode,
                1231,
                @"[In Messages] ErrorCalendarCannotMoveOrCopyOccurrence: Specifies that an attempt was made to move or copy an occurrence of a recurring calendar item.");
            #endregion

            #region Clean up organizer's calendar folders.
            this.CleanupFoldersByRole(Role.Organizer, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.calendar });
            #endregion
        }
 public void MSOXWSCORE_S05_TC15_GetMeetingItemWithDefaultShapeNamesTypeEnum()
 {
     CalendarItemType item = new CalendarItemType();
     this.TestSteps_VerifyGetItemWithItemResponseShapeType_DefaultShapeNamesTypeEnum(item);
 }
 public void MSOXWSCORE_S05_TC04_UpdateMeetingItemSuccessfully()
 {
     CalendarItemType item = new CalendarItemType();
     this.TestSteps_VerifyUpdateItemSuccessfulResponse(item);
 }
        public void MSOXWSMTGS_S04_TC03_MoveRecurringCalendar()
        {
            #region Define a recurring calendar item to move
            DateTime startTime = DateTime.Now;

            DailyRecurrencePatternType pattern = new DailyRecurrencePatternType();
            pattern.Interval = this.PatternInterval;

            NumberedRecurrenceRangeType range = new NumberedRecurrenceRangeType();
            range.NumberOfOccurrences = this.NumberOfOccurrences;
            range.StartDate = startTime;

            CalendarItemType calendarItem = new CalendarItemType();
            calendarItem.UID = Guid.NewGuid().ToString();
            calendarItem.Subject = this.Subject;
            calendarItem.Start = startTime;
            calendarItem.StartSpecified = true;
            calendarItem.End = startTime.AddHours(this.TimeInterval);
            calendarItem.EndSpecified = true;
            calendarItem.Recurrence = new RecurrenceType();
            calendarItem.Recurrence.Item = pattern;
            calendarItem.Recurrence.Item1 = range;
            #endregion

            #region Create the recurring calendar item and extract the Id of an occurrence item
            ItemInfoResponseMessageType item = this.CreateSingleCalendarItem(Role.Organizer, calendarItem, CalendarItemCreateOrDeleteOperationType.SendToNone);
            OccurrenceItemIdType occurrenceItemId = new OccurrenceItemIdType();
            occurrenceItemId.ChangeKey = item.Items.Items[0].ItemId.ChangeKey;
            occurrenceItemId.RecurringMasterId = item.Items.Items[0].ItemId.Id;
            occurrenceItemId.InstanceIndex = this.InstanceIndex;
            #endregion

            #region Get the Id of the occurrence item
            ItemInfoResponseMessageType getItem = this.GetSingleCalendarItem(Role.Organizer, occurrenceItemId);
            Site.Assert.IsNotNull(getItem, "Organizer should get the occurrence item successfully.");

            RecurringMasterItemIdType recurringMasterItemId = new RecurringMasterItemIdType();
            recurringMasterItemId.ChangeKey = getItem.Items.Items[0].ItemId.ChangeKey;
            recurringMasterItemId.OccurrenceId = getItem.Items.Items[0].ItemId.Id;
            #endregion

            #region Move the recurring calendar item to Inbox folder
            DistinguishedFolderIdType folderId = new DistinguishedFolderIdType();
            folderId.Id = DistinguishedFolderIdNameType.inbox;
            TargetFolderIdType targetFolderId = new TargetFolderIdType();
            targetFolderId.Item = folderId;

            ItemInfoResponseMessageType movedItem = this.MoveSingleCalendarItem(Role.Organizer, recurringMasterItemId, targetFolderId);
            Site.Assert.IsNotNull(movedItem, @"Server should return success for moving the recurring calendar item.");
            #endregion

            #region Call FindItem to verify the recurring calendar item is moved to Inbox folder
            CalendarItemType calendar = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.inbox, "IPM.Appointment", calendarItem.UID) as CalendarItemType;
            Site.Assert.IsNotNull(calendar, "The recurring calendar should be in organizer's inbox folder.");

            if (Common.IsRequirementEnabled(808, this.Site))
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R808");

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R808
                this.Site.CaptureRequirementIfAreEqual<CalendarItemTypeType>(
                    CalendarItemTypeType.RecurringMaster,
                    calendar.CalendarItemType1,
                    808,
                    @"[In Appendix C: Product Behavior] MoveItemSoapIn: For each item being moved that is a recurring calendar item, implementation does contain a RecurringMasterItemId child element ([MS-OXWSCORE] section 2.2.4.11). (Exchange 2007 and above follow this behavior.)");
            }
            #endregion

            #region Clean up organizer's inbox folder.
            this.CleanupFoldersByRole(Role.Organizer, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.inbox });
            #endregion
        }
 public void MSOXWSCORE_S05_TC01_CreateGetDeleteMeetingItemSuccessfully()
 {
     CalendarItemType item = new CalendarItemType();
     this.TestSteps_VerifyCreateGetDeleteItem(item);
 }
 public void MSOXWSCORE_S05_TC16_GetMeetingItemWithBodyTypeResponseTypeEnum()
 {
     CalendarItemType item = new CalendarItemType();
     this.TestSteps_VerifyGetItemWithItemResponseShapeType_BodyTypeResponseTypeEnum(item);
 }
        public void MSOXWSCORE_S05_TC02_CopyMeetingItemSuccessfully()
        {
            #region Step 1: Create the calendar item.
            CalendarItemType item = new CalendarItemType();
            ItemIdType[] createdItemIds = this.CreateItemWithMinimumElements(item);
            ItemIdId itemIdId = this.ITEMIDAdapter.ParseItemId(createdItemIds[0]);

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSITEMID_R66");

            // Verify MS-OXWSITEMID requirement: MS-OXWSITEMID_R66
            Site.CaptureRequirementIfAreEqual<IdProcessingInstructionType>(
                IdProcessingInstructionType.Normal,
                (IdProcessingInstructionType)itemIdId.IdProcessingInstruction,
                "MS-OXWSITEMID",
                66,
                @"[In Id Storage Type (byte)] The Id processing uses the value of the following enumeration.
                        /// <summary>
                        /// Indicates any special processing to perform on an Id when deserializing it.
                        /// </summary>
                        internal enum IdProcessingInstruction : byte
                        {
                            /// <summary>
                            /// No special processing.  The Id represents a PR_ENTRY_ID
                            /// </summary>
                            Normal = 0,

                    [        /// <summary>
                            /// The Id represents an OccurenceStoreObjectId and therefore
                           /// must be deserialized as a StoreObjectId.
                            /// </summary>
                            Recurrence = 1,

                            /// <summary>
                            /// The Id represents a series.
                            /// </summary>
                            Series = 2,]
                        }");
            #endregion

            #region Step 2: Copy the calendar item.
            // Call CopyItem operation.
            CopyItemResponseType copyItemResponse = this.CallCopyItemOperation(DistinguishedFolderIdNameType.drafts, createdItemIds);

            // Check the operation response.
            Common.CheckOperationSuccess(copyItemResponse, 1, this.Site);

            ItemIdType[] copiedItemIds = Common.GetItemIdsFromInfoResponse(copyItemResponse);

            // One copied calendar item should be returned.
            Site.Assert.AreEqual<int>(
                1,
                 copiedItemIds.GetLength(0),
                 "One copied calendar item should be returned! Expected Item Count: {0}, Actual Item Count: {1}",
                 1,
                 copiedItemIds.GetLength(0));
            #endregion 

            #region Step 3: Get the first created calendar item success.
            // Call the GetItem operation.
            GetItemResponseType getItemResponse = this.CallGetItemOperation(createdItemIds);

            // Check the operation response.
            Common.CheckOperationSuccess(getItemResponse, 1, this.Site);

            ItemIdType[] getItemIds = Common.GetItemIdsFromInfoResponse(getItemResponse);

            // One calendar item should be returned.
            Site.Assert.AreEqual<int>(
                1,
                 getItemIds.GetLength(0),
                 "One calendar item should be returned! Expected Item Count: {0}, Actual Item Count: {1}",
                 1,
                 getItemIds.GetLength(0));

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSCORE_R2019");

            // Verify MS-OXWSCORE requirement: MS-OXWSCORE_R2019
            this.Site.CaptureRequirementIfAreEqual<string>(
                "IPM.Appointment",
                ((ItemInfoResponseMessageType)getItemResponse.ResponseMessages.Items[0]).Items.Items[0].ItemClass,
                2019,
                @"[In t:ItemType Complex Type] This value is ""IPM.Appointment"" for calendar item.");
            #endregion 

            #region Step 4: Get the second copied calendar item success.
            // Call the GetItem operation.
            getItemResponse = this.CallGetItemOperation(copiedItemIds);

            // Check the operation response.
            Common.CheckOperationSuccess(getItemResponse, 1, this.Site);

            getItemIds = Common.GetItemIdsFromInfoResponse(getItemResponse);

            // One calendar item should be returned.
            Site.Assert.AreEqual<int>(
                1,
                 getItemIds.GetLength(0),
                 "One calendar item should be returned! Expected Item Count: {0}, Actual Item Count: {1}",
                 1,
                 getItemIds.GetLength(0));
            #endregion 
        }
        public void MSOXWSSYNC_S02_TC08_SyncFolderItems_CalendarItemType()
        {
            #region Step 1. Client invokes SyncFolderItems operation get initial syncState of calendar folder.
            DistinguishedFolderIdNameType calendarFolder = DistinguishedFolderIdNameType.calendar;
            SyncFolderItemsType request = this.CreateSyncFolderItemsRequestWithoutOptionalElements(calendarFolder, DefaultShapeNamesType.IdOnly);
            SyncFolderItemsResponseType response = this.SYNCAdapter.SyncFolderItems(request);
            SyncFolderItemsResponseMessageType responseMessage = TestSuiteHelper.EnsureResponse<SyncFolderItemsResponseMessageType>(response);
            #endregion

            #region Step 2. Client invokes CreateItem create a CalendarItemType item and get its ID.
            CalendarItemType calendarItem = new CalendarItemType();
            BaseItemIdType[] itemIds = this.CreateItem(calendarFolder, calendarItem);
            #endregion

            #region Step 3. Client invokes SyncFolderItems operation with previous SyncState to sync the operation result in Step 2 and verify related requirements.
            SyncFolderItemsType requestWithNormalItems = this.CreateSyncFolderItemsRequestWithoutOptionalElements(calendarFolder, DefaultShapeNamesType.AllProperties);

            // Include SyncState element and set its value to the one that got from the first synchronization
            requestWithNormalItems.SyncState = responseMessage.SyncState;
            if (Common.IsRequirementEnabled(37811008, this.Site))
            {
                // Set the value of SyncScope to "NormalItems"
                requestWithNormalItems.SyncScopeSpecified = true;
                requestWithNormalItems.SyncScope = SyncFolderItemsScopeType.NormalItems;
            }

            // Set the value of AdditionalProperties element
            requestWithNormalItems.ItemShape.AdditionalProperties = new BasePathToElementType[] 
            { 
                new PathToUnindexedFieldType() 
                { 
                    FieldURI = UnindexedFieldURIType.itemSubject
                } 
            };

            SyncFolderItemsResponseType responseWithNormalItems = this.SYNCAdapter.SyncFolderItems(requestWithNormalItems);
            SyncFolderItemsResponseMessageType responseMessageWithNormalItems = TestSuiteHelper.EnsureResponse<SyncFolderItemsResponseMessageType>(responseWithNormalItems);
            if (Common.IsRequirementEnabled(37811008, this.Site))
            {
                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "MS-OXWSSYNC_R37811008");

                // Verify MS-OXWSSYNC requirement: MS-OXWSSYNC_R37811008
                Site.CaptureRequirementIfAreEqual<ResponseCodeType>(
                    ResponseCodeType.NoError,
                    responseMessage.ResponseCode,
                    37811008,
                    @"[In Appendix C: Product Behavior] Implementation does support the SyncScope element. (Exchange 2010 and above follow this behavior.)");
            }

            // Assert the changes in response is not null
            Site.Assert.IsNotNull(responseMessage.Changes, "There is one item created on server, so the changes between server and client should not be null");
            SyncFolderItemsChangesType changesWithNormalItems = responseMessageWithNormalItems.Changes;

            // Assert both the Items and ItemsElementName are not null
            Site.Assert.IsNotNull(changesWithNormalItems.ItemsElementName, "There should be changes information returned in SyncFolderItems response since there is one item created on server.");
            Site.Assert.IsNotNull(changesWithNormalItems.Items, "There should be item information returned in SyncFolderItems response since there is one item created on server.");

            Site.Assert.AreEqual<int>(1, changesWithNormalItems.Items.Length, "Just one CalendarItemType item was created in previous step, so the count of Items array in responseMessage.Changes should be 1.");

            // If the type of item in SyncFolderItems response is CalendarItemType, then requirement MS-OXWSSYNC_R158 can be captured.
            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSSYNC_R158");

            // Verify MS-OXWSSYNC requirement: MS-OXWSSYNC_R158
            Site.CaptureRequirementIfIsInstanceOfType(
                (changesWithNormalItems.Items[0] as SyncFolderItemsCreateOrUpdateType).Item,
                typeof(CalendarItemType),
                158,
                @"[In t:SyncFolderItemsCreateOrUpdateType Complex Type]  The type of CalendarItem is t:CalendarItemType ([MS-OXWSMTGS] section 2.2.4.9).");

            // If the value of SyncScope is set to 'NormalItems', there should be only items in the folder returned and the value of IsAssociated property of the items in the folder should be false
            Site.Assert.IsFalse(
                (changesWithNormalItems.Items[0] as SyncFolderItemsCreateOrUpdateType).Item.IsAssociated,
                "The folder associated items should not be returned if the value of SyncScope is set to 'NormalItems'.");
            if (Common.IsRequirementEnabled(37811008, this.Site))
            {
                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "MS-OXWSSYNC_R347");

                // If there is only a CalendarType item in Changes and the IsAssociated property is false, it indicates if the SyncScope is set to "NormalItems", only the item in the folder is returned.
                // Verify MS-OXWSSYNC requirement: MS-OXWSSYNC_R347
                Site.CaptureRequirementIfIsInstanceOfType(
                    (changesWithNormalItems.Items[0] as SyncFolderItemsCreateOrUpdateType).Item,
                    typeof(CalendarItemType),
                    347,
                    @"[In t:SyncFolderItemsScopeType Simple Type] [The value NormalItems] specifies that only items in the folder are returned.");
            }

            // If the AdditionalProperties element is included in SyncFolderItems request and the FieldURI is point to item subject, 
            // the additional property subject should be returned in response, then requirement MS-OXWSSYNC_R37814 and MS-OXWSSYNC_R37815 can be captured.
            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSSYNC_R37814");

            // Verify MS-OXWSSYNC requirement: MS-OXWSSYNC_R37814
            Site.CaptureRequirementIfIsNotNull(
                (changesWithNormalItems.Items[0] as SyncFolderItemsCreateOrUpdateType).Item.Subject,
                37814,
                @"[In m:SyncFolderItemsType Complex Type] [ItemShape element AdditionalProperties] Specifies a set of requested additional properties to return in a response.");

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSSYNC_R37815");

            // Verify MS-OXWSSYNC requirement: MS-OXWSSYNC_R37815
            Site.CaptureRequirementIfIsNotNull(
                (changesWithNormalItems.Items[0] as SyncFolderItemsCreateOrUpdateType).Item.Subject,
                37815,
                @"[In m:SyncFolderItemsType Complex Type] [ItemShape element AdditionalProperties, element t:Path] Specifies a property to be returned in a response.");

            // Assert both the length of responseMessage.Changes.ItemsElementName and responseMessage.Changes.Items are 1.
            Site.Assert.AreEqual<int>(1, changesWithNormalItems.ItemsElementName.Length, "Just one CalendarItemType item was created in previous step, so the count of ItemsElementName array in responseMessage.Changes should be 1.");

            bool isCalendarItemCreated = changesWithNormalItems.ItemsElementName[0] == ItemsChoiceType1.Create &&
                        (changesWithNormalItems.Items[0] as SyncFolderItemsCreateOrUpdateType).Item.GetType() == typeof(CalendarItemType);

            // Add the debug information
            Site.Log.Add(
                LogEntryKind.Debug,
                "Verify MS-OXWSSYNC_R1591. Expected value: ItemsElementName: {0}, item type: {1}; actual value: ItemsElementName: {2}, item type: {3}",
                ItemsChoiceType1.Create,
                typeof(CalendarItemType),
                changesWithNormalItems.ItemsElementName[0],
                (changesWithNormalItems.Items[0] as SyncFolderItemsCreateOrUpdateType).Item.GetType());

            // If the ItemsElementName of Changes is Create and the type of Item is CalendarItemType, it indicates a calendar item 
            // has been created on server and synced on client, then requirement MS-OXWSSYNC_R1591 can be captured.
            // Verify MS-OXWSSYNC requirement: MS-OXWSSYNC_R1591
            Site.CaptureRequirementIfIsTrue(
                isCalendarItemCreated,
                1591,
                @"[In t:SyncFolderItemsCreateOrUpdateType Complex Type][The element CalendarItem] specifies a calendar item to create in the client message store.");
            #endregion

            #region Step 4. Client invokes UpdateItem operation update the created item which created in Step 2.
            // Generate a new item subject
            string newItemSubject = Common.GenerateResourceName(this.Site, calendarFolder + "NewItemSubject");
            this.UpdateItemSubject(itemIds, newItemSubject);
            #endregion

            #region Step 5. Client invokes SyncFolderItems operation with previous SyncState to sync the operation result in Step 4 and verify related requirements.
            responseMessage = this.GetResponseMessage(calendarFolder, responseMessageWithNormalItems, DefaultShapeNamesType.AllProperties);
            if (Common.IsRequirementEnabled(37811008, this.Site))
            {
                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "MS-OXWSSYNC_R37811008");

                // Verify MS-OXWSSYNC requirement: MS-OXWSSYNC_R37811008
                Site.CaptureRequirementIfAreEqual<ResponseCodeType>(
                    ResponseCodeType.NoError,
                    responseMessage.ResponseCode,
                    37811008,
                    @"[In Appendix C: Product Behavior] Implementation does support the SyncScope element. (Exchange 2010 and above follow this behavior.)");
            }

            // Assert the changes in response is not null
            Site.Assert.IsNotNull(responseMessage.Changes, "There is one item updated on server, so the changes between server and client should not be null");
            SyncFolderItemsChangesType changes = responseMessage.Changes;

            // Assert both the Items and ItemsElementName are not null
            Site.Assert.IsNotNull(changes.ItemsElementName, "There should be changes information returned in SyncFolderItems response since there is one item updated on server.");
            Site.Assert.IsNotNull(changes.Items, "There should be item information returned in SyncFolderItems response since there is one item updated on server.");

            Site.Assert.AreEqual<int>(1, changes.Items.Length, "Just one CalendarItemType item was updated in previous step, so the count of Items array in responseMessage.Changes should be 1.");
            Site.Assert.AreEqual<int>(1, changes.ItemsElementName.Length, "Just one CalendarItemType item was updated in previous step, so the count of ItemsElementName array in responseMessage.Changes should be 1.");

            bool isCalendarItemUpdated = changes.ItemsElementName[0] == ItemsChoiceType1.Update
                && (changes.Items[0] as SyncFolderItemsCreateOrUpdateType).Item.GetType() == typeof(CalendarItemType);

            // Add the debug information
            Site.Log.Add(
                LogEntryKind.Debug,
                "Verify MS-OXWSSYNC_R1592. Expected value: ItemsElementName: {0}, item type: {1}; actual value: ItemsElementName: {2}, item type: {3}",
                ItemsChoiceType1.Update,
                typeof(CalendarItemType),
                changes.ItemsElementName[0],
                (changes.Items[0] as SyncFolderItemsCreateOrUpdateType).Item.GetType());

            // If the ItemsElementName of Changes is Update and the type of Item is CalendarItemType, it indicates a calendar item 
            // has been updated on server and synced on client, then requirement MS-OXWSSYNC_R1592 can be captured.
            // Verify MS-OXWSSYNC requirement: MS-OXWSSYNC_R1592
            Site.CaptureRequirementIfIsTrue(
                isCalendarItemUpdated,
                1592,
                @"[In t:SyncFolderItemsCreateOrUpdateType Complex Type][The element CalendarItem] specifies a calendar item to update in the client message store.");
            #endregion

            #region Step 6. Client invokes DeleteItem operation to delete the CalendarItemType item which updated in Step 4.
            this.DeleteItem(itemIds);
            #endregion

            #region Step 7. Client invokes SyncFolderItems operation with previous SyncState to sync the operation result in Step 6.
            responseMessage = this.GetResponseMessage(calendarFolder, responseMessage, DefaultShapeNamesType.AllProperties);

            // Assert the changes in response is not null
            Site.Assert.IsNotNull(responseMessage.Changes, "There is one item deleted on server, so the changes between server and client should not be null");
            changes = responseMessage.Changes;

            // Assert both the Items and ItemsElementName are not null
            Site.Assert.IsNotNull(changes.ItemsElementName, "There should be changes information returned in SyncFolderItems response since there is one item deleted on server.");
            Site.Assert.IsNotNull(changes.Items, "There should be item information returned in SyncFolderItems response since there is one item deleted on server.");

            Site.Assert.AreEqual<int>(1, changes.ItemsElementName.Length, "Just one CalendarItemType item was deleted in previous step, so the count of ItemsElementName array in responseMessage.Changes should be 1.");
            Site.Assert.IsTrue(
                changes.ItemsElementName[0] == ItemsChoiceType1.Delete,
                string.Format("The responseMessage.Changes.ItemsElementName should be 'Delete', the actual value is '{0}'", changes.ItemsElementName[0]));

            Site.Assert.AreEqual<int>(1, changes.Items.Length, "Just one CalendarItemType item was deleted in previous step, so the count of Items array in responseMessage.Changes should be 1.");
            Site.Assert.IsTrue(
                changes.Items[0].GetType() == typeof(SyncFolderItemsDeleteType),
                string.Format("The responseMessage.Changes.Items should be an instance of '{0}'.", typeof(SyncFolderItemsDeleteType)));
            #endregion
        }
        public void MSOXWSMTGS_S06_TC04_CalendarPermissionLevelEditor()
        {
            this.MTGSAdapter = new MS_OXWSMTGSAdapter();
            this.MTGSAdapter.Initialize(this.Site);
            this.SRCHAdapter = new MS_OXWSSRCHAdapter();
            this.SRCHAdapter.Initialize(this.Site);
            this.FOLDAdapter = new MS_OXWSFOLDAdapter();
            this.FOLDAdapter.Initialize(this.Site);

            #region Organizer creates a calendar folder in the inbox folder and grant Editor permission to attendee.

            // Switch to user organizer.
            this.FOLDAdapter.SwitchUser(this.Organizer, this.OrganizerPassword, this.Domain);

            CalendarPermissionSetType calendarPermissionSet = new CalendarPermissionSetType();
            calendarPermissionSet.CalendarPermissions = new CalendarPermissionType[1];
            calendarPermissionSet.CalendarPermissions[0] = new CalendarPermissionType();
            calendarPermissionSet.CalendarPermissions[0].CalendarPermissionLevel = CalendarPermissionLevelType.Editor;
            calendarPermissionSet.CalendarPermissions[0].UserId = new UserIdType();
            calendarPermissionSet.CalendarPermissions[0].UserId.PrimarySmtpAddress = Common.GetConfigurationPropertyValue("AttendeeName", this.Site) + "@" + Common.GetConfigurationPropertyValue("Domain", this.Site);

            CreateFolderType createFolderRequest = this.GetCreateFolderRequest(DistinguishedFolderIdNameType.inbox.ToString(), new string[] { "CustomFolderByOrganizer" }, new string[] { "IPF.Appointment" }, null);
            ((CalendarFolderType)createFolderRequest.Folders[0]).PermissionSet = calendarPermissionSet;

            // Create a new folder.
            CreateFolderResponseType createFolderResponse = this.FOLDAdapter.CreateFolder(createFolderRequest);

            // Check the response.
            Common.CheckOperationSuccess(createFolderResponse, 1, this.Site);

            // Save the new created folder's folder id.
            FolderIdType newFolderIdByOrganizer = ((FolderInfoResponseMessageType)createFolderResponse.ResponseMessages.Items[0]).Folders[0].FolderId;
            this.FolderToDelete = newFolderIdByOrganizer;
            #endregion

            #region Organizer gets the new created folder.

            // GetFolder request.
            GetFolderType getNewFolderRequest = this.GetGetFolderRequest(DefaultShapeNamesType.AllProperties, newFolderIdByOrganizer);

            // Get the new created folder.
            GetFolderResponseType getInboxFolderResponse = this.FOLDAdapter.GetFolder(getNewFolderRequest);

            // Check the response.
            Common.CheckOperationSuccess(getInboxFolderResponse, 1, this.Site);

            // Verify the folder is created successfully.
            FolderInfoResponseMessageType foldersResponseInfo = (FolderInfoResponseMessageType)getInboxFolderResponse.ResponseMessages.Items[0];
            Site.Assert.AreEqual<string>(newFolderIdByOrganizer.Id, foldersResponseInfo.Folders[0].FolderId.Id, "The calendar folder should be created successfully in inbox.");
            #endregion

            #region Organizer creates a calendar item in the created folder.
            CalendarItemType calendarItembyOrganizer = new CalendarItemType();
            calendarItembyOrganizer.UID = Guid.NewGuid().ToString();
            calendarItembyOrganizer.Subject = Common.GenerateResourceName(this.Site, "CalendarItemCreatedByOrganizer");
            NonEmptyArrayOfAllItemsType allItemArray = new NonEmptyArrayOfAllItemsType();
            allItemArray.Items = new ItemType[] { calendarItembyOrganizer };
            CreateItemType createItemRequest = new CreateItemType();
            createItemRequest.Items = allItemArray;
            createItemRequest.SendMeetingInvitationsSpecified = true;
            createItemRequest.SendMeetingInvitations = CalendarItemCreateOrDeleteOperationType.SendToNone;
            createItemRequest.SavedItemFolderId = new TargetFolderIdType();
            createItemRequest.SavedItemFolderId.Item = newFolderIdByOrganizer;
            CreateItemResponseType response = this.MTGSAdapter.CreateItem(createItemRequest);
            Site.Assert.AreEqual<ResponseClassType>(ResponseClassType.Success, response.ResponseMessages.Items[0].ResponseClass, "The calendar item should be created successfully.");
            ItemInfoResponseMessageType itemInfoResponse = response.ResponseMessages.Items[0] as ItemInfoResponseMessageType;
            Site.Assert.IsNotNull(itemInfoResponse, "The calendar item should be created successfully.");
            ItemIdType itemIdByOrganizer = itemInfoResponse.Items.Items[0].ItemId;
            #endregion

            #region Attendee creates a folder in the created folder.

            // Switch to user attendee.
            this.FOLDAdapter.SwitchUser(this.Attendee, this.AttendeePassword, this.Domain);

            createFolderRequest = this.GetCreateFolderRequest(newFolderIdByOrganizer.Id, new string[] { "CustomFolderByAttendee" }, new string[] { "IPF.Appointment" }, null);
            createFolderResponse = this.FOLDAdapter.CreateFolder(createFolderRequest);
            bool canCreateSubFolder = ResponseClassType.Success == createFolderResponse.ResponseMessages.Items[0].ResponseClass;

            #endregion

            #region Attendee creates a calendar item in the created folder.
            this.SwitchMTGSUser(Role.Attendee);
            CalendarItemType calendarItembyAttendee = new CalendarItemType();
            calendarItembyAttendee.UID = Guid.NewGuid().ToString();
            calendarItembyAttendee.Subject = Common.GenerateResourceName(this.Site, "CalendarItemCreatedByAttendee");
            createItemRequest.Items.Items[0] = calendarItembyAttendee;
            response = this.MTGSAdapter.CreateItem(createItemRequest);
            Site.Assert.AreEqual<ResponseClassType>(ResponseClassType.Success, response.ResponseMessages.Items[0].ResponseClass, "The calendar item should be created successfully.");
            itemInfoResponse = response.ResponseMessages.Items[0] as ItemInfoResponseMessageType;
            bool canCreateOwnItem = null != itemInfoResponse;
            Site.Assert.IsTrue(canCreateOwnItem, "The calendar item should be created successfully.");
            ItemIdType itemIdByAttendee = itemInfoResponse.Items.Items[0].ItemId;
            #endregion

            #region Attendee gets the calendar item created by hisself.
            itemInfoResponse = this.GetSingleCalendarItem(Role.Attendee, itemIdByAttendee);
            bool canReadOwnItem = null != itemInfoResponse;
            #endregion

            #region Attendee updates the calendar item created by hisself.
            CalendarItemType calendarUpdate = new CalendarItemType();
            calendarUpdate.Location = this.LocationUpdate;

            AdapterHelper itemChangeInfo = new AdapterHelper();
            itemChangeInfo.FieldURI = UnindexedFieldURIType.calendarLocation;
            itemChangeInfo.Item = calendarUpdate;
            itemChangeInfo.ItemId = itemIdByAttendee;

            // Update the created calendar item.
            UpdateItemResponseMessageType updatedItem = this.UpdateSingleCalendarItem(Role.Attendee, itemChangeInfo, CalendarItemUpdateOperationType.SendToNone);
            bool canUpdateOwnItem = null != updatedItem;
            #endregion

            #region Attendee deletes the calendar item created by hisself.
            ResponseMessageType responseMessage = this.DeleteSingleCalendarItem(Role.Attendee, itemIdByAttendee, CalendarItemCreateOrDeleteOperationType.SendToNone);
            bool canDeleteOwnItem = null != responseMessage && responseMessage.ResponseClass == ResponseClassType.Success;
            #endregion

            #region Attendee gets the calendar item created by organizer.
            itemInfoResponse = this.GetSingleCalendarItem(Role.Attendee, itemIdByOrganizer);
            bool canReadNotOwnItem = null != itemInfoResponse;
            #endregion

            #region Attendee updates the calendar item created by organizer.
            calendarUpdate = new CalendarItemType();
            calendarUpdate.Location = this.LocationUpdate;

            itemChangeInfo = new AdapterHelper();
            itemChangeInfo.FieldURI = UnindexedFieldURIType.calendarLocation;
            itemChangeInfo.Item = calendarUpdate;
            itemChangeInfo.ItemId = itemIdByOrganizer;

            // Update the created calendar item.
            updatedItem = this.UpdateSingleCalendarItem(Role.Attendee, itemChangeInfo, CalendarItemUpdateOperationType.SendToNone);
            bool canUpdateNotOwnItem = null != updatedItem;
            #endregion

            #region Attendee deletes the calendar item created by organizer.
            responseMessage = this.DeleteSingleCalendarItem(Role.Attendee, itemIdByOrganizer, CalendarItemCreateOrDeleteOperationType.SendToNone);
            bool canDeleteNotOwnItem = null != responseMessage && responseMessage.ResponseClass == ResponseClassType.Success;
            #endregion

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R91");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R91
            bool isVerifiedR91 = canCreateOwnItem && canReadOwnItem && canUpdateOwnItem && canDeleteOwnItem && canReadNotOwnItem
                && canUpdateNotOwnItem && canDeleteNotOwnItem && !canCreateSubFolder;

            Site.Assert.IsTrue(
                isVerifiedR91,
                "Can create own item is {0};\n" +
                "Can read own item is {1};\n" +
                "Can edit own item is {2};\n " +
                "Can delete own item is {3};\n" +
                "Can read not own item is {4};\n" +
                "Can edit not own item is {5};\n" +
                "Can delete not own item is {6};\n" +
                "Can create subfolders is {7};\n",
                canCreateOwnItem,
                canReadOwnItem,
                canUpdateOwnItem,
                canDeleteOwnItem,
                canReadNotOwnItem,
                canUpdateNotOwnItem,
                canDeleteNotOwnItem,
                canCreateSubFolder);

            this.Site.CaptureRequirementIfIsTrue(
                isVerifiedR91,
                91,
                @"[In t:CalendarPermissionLevelType Simple Type] Editor: The user can create, read, edit and delete all items in the folder.");
        }