Action Data buffer format for ActionType: OP_BOUNCE
Inheritance: IActionData
        public void MSOXORULE_S01_TC06_AddMoveCopyAndBounceDeferredrules()
        {
            this.CheckMAPIHTTPTransportSupported();

            #region TestUser1 prepares value for ruleProperties variable.
            RuleProperties ruleProperties = AdapterHelper.GenerateRuleProperties(this.Site, Constants.RuleNameBounce);
            #endregion

            #region TestUser1 adds Bounce rule.
            BounceActionData bounceActionData = new BounceActionData
            {
                Bounce = BounceCode.CanNotDisplay
            };

            RuleData ruleBounce = AdapterHelper.GenerateValidRuleData(ActionType.OP_BOUNCE, TestRuleDataType.ForAdd, 0, RuleState.ST_ENABLED, bounceActionData, ruleProperties, null);
            RopModifyRulesResponse ropModifyRulesResponse = this.OxoruleAdapter.RopModifyRules(this.InboxFolderHandle, ModifyRuleFlag.Modify_ReplaceAll, new RuleData[] { ruleBounce });
            Site.Assert.AreEqual<uint>(0, ropModifyRulesResponse.ReturnValue, "Adding Bounce rule should succeed.");
            #endregion

            #region TestUser1 adds Deferred Action rule.
            ruleProperties.Name = Common.GenerateResourceName(this.Site, Constants.RuleNameDeferredAction);
            DeferredActionData deferredActionData = new DeferredActionData
            {
                Data = Common.GetBytesFromBinaryHexString(Constants.DeferredActionBufferData)
            };
            RuleData deferredActionRuleData = AdapterHelper.GenerateValidRuleData(ActionType.OP_DEFER_ACTION, TestRuleDataType.ForAdd, 1, RuleState.ST_ENABLED, deferredActionData, ruleProperties, null);

            RopModifyRulesResponse modifyRulesResponse = this.OxoruleAdapter.RopModifyRules(this.InboxFolderHandle, ModifyRuleFlag.Modify_OnExisting, new RuleData[] { deferredActionRuleData });
            Site.Assert.AreEqual<uint>(0, modifyRulesResponse.ReturnValue, "Adding deferred action rule to public folder should succeed.");
            #endregion

            if (Common.IsRequirementEnabled(294, this.Site))
            {
                #region TestUser1 creates a folder in server store.
                RopCreateFolderResponse createFolderResponse;
                string user1FolderName = Common.GenerateResourceName(this.Site, "User1Folder");
                uint folderHandle = this.OxoruleAdapter.RopCreateFolder(this.InboxFolderHandle, user1FolderName, "TestForOP_COPY", out createFolderResponse);
                ulong folderId = createFolderResponse.FolderId;
                Site.Assert.AreEqual<uint>(0, createFolderResponse.ReturnValue, "Creating folder operation should succeed.");
                #endregion

                #region TestUser1 prepares rules' data.
                MoveCopyActionData moveCopyActionData = new MoveCopyActionData();

                // Get the created folder entry ID.
                byte[] folderEId = this.OxoruleAdapter.GetFolderEntryId(StoreObjectType.Mailbox, folderHandle, folderId);

                // Get the store object's entry ID.
                byte[] storeEId = this.GetStoreObjectEntryID(StoreObjectType.Mailbox, this.Server, this.User1ESSDN);
                moveCopyActionData.FolderEID = folderEId;
                moveCopyActionData.StoreEID = storeEId;
                moveCopyActionData.FolderEIDSize = (ushort)folderEId.Length;
                moveCopyActionData.StoreEIDSize = (ushort)storeEId.Length;
                #endregion

                #region TestUSer1 generates test RuleData.
                ruleProperties.Name = Common.GenerateResourceName(this.Site, Constants.RuleNameCopy);
                RuleData ruleForCopy = AdapterHelper.GenerateValidRuleData(ActionType.OP_COPY, TestRuleDataType.ForAdd, 2, RuleState.ST_ENABLED, moveCopyActionData, ruleProperties, null);

                // Add rule for move with rule Provider Data.
                ruleProperties.ProviderData = Constants.PidTagRuleProviderData;
                ruleProperties.Name = Common.GenerateResourceName(this.Site, Constants.RuleNameMoveOne);
                RuleData ruleForMove = AdapterHelper.GenerateValidRuleData(ActionType.OP_MOVE, TestRuleDataType.ForAdd, 3, RuleState.ST_ENABLED, moveCopyActionData, ruleProperties, null);
                #endregion

                #region TestUser1 adds OP_MOVE and OP_COPY rules to the Inbox folder.
                modifyRulesResponse = this.OxoruleAdapter.RopModifyRules(this.InboxFolderHandle, ModifyRuleFlag.Modify_OnExisting, new RuleData[] { ruleForMove, ruleForCopy });

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

                // Verify MS-OXORULE requirement: MS-OXORULE_R680.
                // If the return value of the RopModifyRules response is 0x00, it means operation is successfully.
                Site.CaptureRequirementIfAreEqual<uint>(
                    0x00000000,
                    modifyRulesResponse.ReturnValue,
                    680,
                    @"[In RopModifyRules ROP Response Buffer] ReturnValue: To indicate success, the server returns 0x00000000.");

                // Wait for the mail to be received and the rule to take effect.
                Thread.Sleep(this.WaitForTheRuleToTakeEffect);
                #endregion

                RopDeleteFolderResponse deleteFolder = this.OxoruleAdapter.RopDeleteFolder(this.InboxFolderHandle, folderId);
                Site.Assert.AreEqual<uint>(0, deleteFolder.ReturnValue, "Deleting folder should succeed.");
            }

            #region TestUser1 gets rows from the rule table.
            RopGetRulesTableResponse ropGetRulesTableResponse;
            uint ruleTableHandle = this.OxoruleAdapter.RopGetRulesTable(this.InboxFolderHandle, TableFlags.Normal, out ropGetRulesTableResponse);
            Site.Assert.AreEqual<uint>(0, ropGetRulesTableResponse.ReturnValue, "RopGetRulesTable operation should succeed.");

            PropertyTag[] propertyListTag = new PropertyTag[4];

            // PidTagRuleActions property.
            propertyListTag[0].PropertyId = (ushort)PropertyId.PidTagRuleActions;
            propertyListTag[0].PropertyType = (ushort)PropertyType.PtypRuleAction;
            propertyListTag[1].PropertyId = (ushort)PropertyId.PidTagRuleName;
            propertyListTag[1].PropertyType = (ushort)PropertyType.PtypString;
            propertyListTag[2].PropertyId = (ushort)PropertyId.PidTagRuleProvider;
            propertyListTag[2].PropertyType = (ushort)PropertyType.PtypString;
            propertyListTag[3].PropertyId = (ushort)PropertyId.PidTagRuleProviderData;
            propertyListTag[3].PropertyType = (ushort)PropertyType.PtypBinary;

            // Set the query target to standardardRules.
            this.OxoruleAdapter.TargetOfRop = TargetOfRop.ForStandardRules;

            RopQueryRowsResponse getAllActionsResponse = this.OxoruleAdapter.QueryPropertiesInTable(ruleTableHandle, propertyListTag);
            Site.Assert.AreEqual<uint>(0, getAllActionsResponse.ReturnValue, "Getting rule properties should succeed.");

            // When R294 is enabled, there should be 4 rules exist on Inbox folder, otherwise only 2 rules exist.
            // If the rule table is got successfully and the rule count is correct, it means that the server is returning a table with the rule added by the test suite.
            if (Common.IsRequirementEnabled(294, this.Site))
            {
                Site.Assert.AreEqual(4, getAllActionsResponse.RowCount, @"There should be 4 rules returned, actual returned row count is {0}.", getAllActionsResponse.RowCount);
            }
            else
            {
                Site.Assert.AreEqual(2, getAllActionsResponse.RowCount, @"There should be 2 rules returned, actual returned row count is {0}.", getAllActionsResponse.RowCount);
            }

            this.VerifyRuleTable();

            // Clear the status of the adapter.
            this.OxoruleAdapter.TargetOfRop = TargetOfRop.OtherTarget;
            #endregion
        }
        public void MSOXORULE_S02_TC01_ServerExecuteRule_Action_OP_BOUNCE()
        {
            this.CheckMAPIHTTPTransportSupported();

            #region Prepare value for ruleProperties variable.
            RuleProperties ruleProperties = AdapterHelper.GenerateRuleProperties(this.Site, Constants.RuleNameBounce);
            #endregion

            #region  TestUser1 adds a Bounce rule with Bounce of action data set to CanNotDisplay.
            BounceActionData bounceActionData = new BounceActionData
            {
                Bounce = BounceCode.CanNotDisplay
            };

            RuleData ruleBounce = AdapterHelper.GenerateValidRuleData(ActionType.OP_BOUNCE, TestRuleDataType.ForAdd, 1, RuleState.ST_ENABLED, bounceActionData, ruleProperties, null);
            RopModifyRulesResponse ropModifyRulesResponse = this.OxoruleAdapter.RopModifyRules(this.InboxFolderHandle, ModifyRuleFlag.Modify_ReplaceAll, new RuleData[] { ruleBounce });
            Site.Assert.AreEqual<uint>(0, ropModifyRulesResponse.ReturnValue, "Adding Bounce rule should succeed.");
            #endregion

            #region TestUser2 delivers a message to TestUser1 to trigger these rules.

            Thread.Sleep(this.WaitForTheRuleToTakeEffect);

            // Let TestUser2 logon to the server.
            this.LogonMailbox(TestUser.TestUser2);
            string mailSubject = Common.GenerateResourceName(this.Site, ruleProperties.ConditionSubjectName + "Title", 1);
            this.DeliverMessageToTriggerRule(this.User1Name, this.User1ESSDN, mailSubject, null);
            Thread.Sleep(this.WaitForTheRuleToTakeEffect);
            #endregion

            #region TestUser1 verifies there is no new message in the Inbox folder.
            // Let TestUser1 logon to the server.
            this.LogonMailbox(TestUser.TestUser1);

            // Set PidTagSubject and PidTagMessageFlags visible.
            PropertyTag[] propertyTag = new PropertyTag[2];
            propertyTag[0].PropertyId = (ushort)PropertyId.PidTagSubject;
            propertyTag[0].PropertyType = (ushort)PropertyType.PtypString;
            propertyTag[1].PropertyId = (ushort)PropertyId.PidTagMessageFlags;
            propertyTag[1].PropertyType = (ushort)PropertyType.PtypInteger32;

            // Get mail message content.
            uint contentsTableHandle = 0;
            bool doesUnexpectedMessageExist = this.CheckUnexpectedMessageExist(this.InboxFolderHandle, ref contentsTableHandle, propertyTag, mailSubject);

            #region Capture Code
            if (Common.IsRequirementEnabled(5472, this.Site))
            {
                // Add the debug information.
                Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXORULE_R5472");

                // Verify MS-OXORULE requirement: MS-OXORULE_R5472.
                // TestUser2 has sent a message to TestUser1. If the message doesn't appear in the user's mailbox, this requirement can be verified.
                Site.CaptureRequirementIfIsFalse(
                    doesUnexpectedMessageExist,
                    5472,
                    @"[In Appendix A: Product Behavior] [""OP_BOUNCE""]Implementation does not support the original message appears in the user's mailbox. (Exchange 2010 and above follow this behavior.)");
            }
            // Add the debug information.
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXORULE_R342");

            // If the message doesn't appear in the user's mailbox, this requirement can be verified.
            Site.CaptureRequirementIfIsFalse(
                doesUnexpectedMessageExist,
                342,
                @"[In OP_BOUNCE ActionData Structure] The meaning of the BounceCode value 0x0000001F: The message was rejected because it cannot be displayed to the user.");
            #endregion
            #endregion

            #region TestUser2 verifies there is a reply message in the Inbox folder.
            // Let TestUser2 logon to the server.
            this.LogonMailbox(TestUser.TestUser2);

            PropertyTag[] propertyTagList = new PropertyTag[2];
            propertyTagList[0].PropertyId = (ushort)PropertyId.PidTagSubject;
            propertyTagList[0].PropertyType = (ushort)PropertyType.PtypString;
            propertyTagList[1].PropertyId = (ushort)PropertyId.PidTagMessageFlags;
            propertyTagList[1].PropertyType = (ushort)PropertyType.PtypInteger32;

            int expectedMessageIndex = 0;
            uint contentTableHandle = 0;
            RopQueryRowsResponse getMailMessageContent2 = this.GetExpectedMessage(this.InboxFolderHandle, ref contentTableHandle, propertyTagList, ref expectedMessageIndex, mailSubject);
            string mailSubjectForCanNotDisplay = AdapterHelper.PropertyValueConvertToString(getMailMessageContent2.RowData.PropertyRows[expectedMessageIndex].PropertyValues[0].Value);
            bool isReceivedReplyMessageForCanNotDisplay = mailSubjectForCanNotDisplay.Contains(mailSubject);
            Site.Assert.IsTrue(isReceivedReplyMessageForCanNotDisplay, "The server should send a reply message to the sender for the Can_Not_Display Bounce rule.");

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

            // Verify MS-OXORULE requirement: MS-OXORULE_R260.
            // TestUser2 has send a message to TestUser1, if the message cannot be found in TestUser1's mailbox and TestUser2 received the replied message,
            // it means the server has executed the BOUNCE rule.
            bool isVerifyR260 = (!doesUnexpectedMessageExist) && isReceivedReplyMessageForCanNotDisplay;

            Site.CaptureRequirementIfIsTrue(
                isVerifyR260,
                260,
                @"[In ActionBlock Structure] The meaning of action type OP_BOUNCE: Rejects the message back to the sender.");
            #endregion

            #region TestUser1 adds a Bounce rule with Bounce of action data set to TooLarge.
            // Let TestUser1 log on to the server.
            this.LogonMailbox(TestUser.TestUser1);
            bounceActionData = new BounceActionData
            {
                Bounce = BounceCode.TooLarge
            };

            ruleBounce = AdapterHelper.GenerateValidRuleData(ActionType.OP_BOUNCE, TestRuleDataType.ForAdd, 1, RuleState.ST_ENABLED, bounceActionData, ruleProperties, null);
            ropModifyRulesResponse = this.OxoruleAdapter.RopModifyRules(this.InboxFolderHandle, ModifyRuleFlag.Modify_ReplaceAll, new RuleData[] { ruleBounce });
            Site.Assert.AreEqual<uint>(0, ropModifyRulesResponse.ReturnValue, "Adding Bounce rule should succeed.");
            #endregion

            #region TestUser2 delivers a message to TestUser1 to trigger these rules.

            Thread.Sleep(this.WaitForTheRuleToTakeEffect);

            // Let TestUser2 logon to the server.
            this.LogonMailbox(TestUser.TestUser2);
            mailSubject = Common.GenerateResourceName(this.Site, ruleProperties.ConditionSubjectName + "Title", 2);
            this.DeliverMessageToTriggerRule(this.User1Name, this.User1ESSDN, mailSubject, null);
            Thread.Sleep(this.WaitForTheRuleToTakeEffect);
            #endregion

            #region TestUser1 verifies the server rejects the too large messages.
            // Let TestUser1 logon to the server.
            this.LogonMailbox(TestUser.TestUser1);
            doesUnexpectedMessageExist = this.CheckUnexpectedMessageExist(this.InboxFolderHandle, ref contentsTableHandle, propertyTag, mailSubject);

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

            // TestUser2 has sent a message to TestUser1. If the message doesn't appear in the user's mailbox, this requirement can be verified.
            Site.CaptureRequirementIfIsFalse(
                doesUnexpectedMessageExist,
                341,
                @"[In OP_BOUNCE ActionData Structure] The meaning of the BounceCode value 0x0000000D: The message was rejected because it was too large.");
            #endregion

            #region TestUser2 verifies there is a reply message in the Inbox folder.
            // Let TestUser2 logon to the server.
            this.LogonMailbox(TestUser.TestUser2);
            expectedMessageIndex = 0;
            contentTableHandle = 0;
            RopQueryRowsResponse getMailMessageContentForTooLarge = this.GetExpectedMessage(this.InboxFolderHandle, ref contentTableHandle, propertyTagList, ref expectedMessageIndex, mailSubject);
            string mailSubjectForTooLarge = AdapterHelper.PropertyValueConvertToString(getMailMessageContentForTooLarge.RowData.PropertyRows[expectedMessageIndex].PropertyValues[0].Value);
            Site.Assert.AreEqual<uint>(0, getMailMessageContentForTooLarge.ReturnValue, "Getting the message should succeed, the actual returned value is {0}!", getMailMessageContentForTooLarge.ReturnValue);
            bool isReceivedReplyMessageForTooLarge = mailSubjectForTooLarge.Contains(mailSubject);
            Site.Assert.IsTrue(isReceivedReplyMessageForTooLarge, "The server should send a reply message to the sender for the Too_Large Bounce rule.");

            // Let TestUser1 logon to the server.
            this.LogonMailbox(TestUser.TestUser1);
            #endregion

            // The Denied Bounce rule cannot be verified on Exchange 2007.
            if (Common.IsRequirementEnabled(343, this.Site))
            {
                #region TestUser1 adds a Bounce rule with Bounce of action data set to Denied.
                bounceActionData = new BounceActionData
                {
                    Bounce = BounceCode.Denied
                };

                ruleBounce = AdapterHelper.GenerateValidRuleData(ActionType.OP_BOUNCE, TestRuleDataType.ForAdd, 1, RuleState.ST_ENABLED, bounceActionData, ruleProperties, null);
                ropModifyRulesResponse = this.OxoruleAdapter.RopModifyRules(this.InboxFolderHandle, ModifyRuleFlag.Modify_ReplaceAll, new RuleData[] { ruleBounce });
                Site.Assert.AreEqual<uint>(0, ropModifyRulesResponse.ReturnValue, "Adding Bounce rule should succeed.");
                #endregion

                #region TestUser2 delivers a message to TestUser1 to trigger these rules.

                Thread.Sleep(this.WaitForTheRuleToTakeEffect);

                // Let TestUser2 logon to the server.
                this.LogonMailbox(TestUser.TestUser2);
                mailSubject = Common.GenerateResourceName(this.Site, ruleProperties.ConditionSubjectName + "Title", 3);
                this.DeliverMessageToTriggerRule(this.User1Name, this.User1ESSDN, mailSubject, null);
                Thread.Sleep(this.WaitForTheRuleToTakeEffect);
                #endregion

                #region TestUser1 gets the messages in its Inbox folder
                // Let TestUser1 logon to the server.
                this.LogonMailbox(TestUser.TestUser1);
                doesUnexpectedMessageExist = this.CheckUnexpectedMessageExist(this.InboxFolderHandle, ref contentsTableHandle, propertyTag, mailSubject);

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

                // TestUser2 has sent a message to TestUser1. If the message doesn't appear in the user's mailbox, this requirement can be verified.
                Site.CaptureRequirementIfIsFalse(
                    doesUnexpectedMessageExist,
                    343,
                    @"[In OP_BOUNCE ActionData Structure] The meaning of the BounceCode value 0x00000026: The message delivery was denied for other reasons.");
                #endregion

                #region TestUser2 verifies there is a reply message in the Inbox folder.
                // Let TestUser2 logon to the server.
                this.LogonMailbox(TestUser.TestUser2);
                expectedMessageIndex = 0;
                contentTableHandle = 0;
                RopQueryRowsResponse getMailMessageContentForDenied = this.GetExpectedMessage(this.InboxFolderHandle, ref contentTableHandle, propertyTagList, ref expectedMessageIndex, mailSubject);
                string mailSubjectForDenied = AdapterHelper.PropertyValueConvertToString(getMailMessageContentForDenied.RowData.PropertyRows[expectedMessageIndex].PropertyValues[0].Value);
                Site.Assert.AreEqual<uint>(0, getMailMessageContentForDenied.ReturnValue, "Getting the message should succeed, the actual returned value is {0}!", getMailMessageContentForDenied.ReturnValue);
                bool isReceivedReplyMessageForDenied = mailSubjectForDenied.Contains(mailSubject);
                Site.Assert.IsTrue(isReceivedReplyMessageForDenied, "The server should send a reply message to the sender for the Denied Bounce rule.");
                if (Common.IsRequirementEnabled(5462, this.Site))
                {
                    // Add the debug information.
                    Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXORULE_R5462");

                    // Verify MS-OXORULE requirement: MS-OXORULE_R5462.
                    bool isVerifyR546 = isReceivedReplyMessageForCanNotDisplay && isReceivedReplyMessageForTooLarge && isReceivedReplyMessageForDenied;
                    Site.CaptureRequirementIfIsTrue(
                        isVerifyR546,
                        5462,
                        @"[In Appendix A: Product Behavior] [""OP_BOUNCE""]Implementation does send a reply message to the sender detailing why the sender's message couldn't be delivered to the user's mailbox. (Exchange 2010 and above follow this behavior.)");
                }
                #endregion
            }
            else
            {
                if (Common.IsRequirementEnabled(5462, this.Site))
                {
                    // Add the debug information.
                    Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXORULE_R5462");

                    // Verify MS-OXORULE requirement: MS-OXORULE_R5462.
                    bool isVerifyR546 = isReceivedReplyMessageForCanNotDisplay && isReceivedReplyMessageForTooLarge;
                    Site.CaptureRequirementIfIsTrue(
                        isVerifyR546,
                        5462,
                        @"[In Appendix A: Product Behavior] [""OP_BOUNCE""]Implementation does send a reply message to the sender detailing why the sender's message couldn't be delivered to the user's mailbox. (Exchange 2010 and above follow this behavior.)");
                }
            }
        }