/// <summary> /// Build the GetMatches request body. /// </summary> /// <param name="hasState">A Boolean value that specifies whether the State field is present.</param> /// <param name="state">A STAT structure that specifies the state of a specific address book container. </param> /// <param name="hasTarget">A Boolean value that specifies whether the Target field is present.</param> /// <param name="target">A PropertyValue_r structure that specifies the property value being sought.</param> /// <param name="hasExplicitTable">A Boolean value that specifies whether the ExplicitTableCount and ExplicitTable fields are present.</param> /// <param name="explicitableCount">An unsigned integer that specifies the number of structures present in the ExplicitTable field.</param> /// <param name="explicitTable">An array of unsigned integer that constitute an Explicit Table.</param> /// <param name="hasColumns">A Boolean value that specifies whether the Columns field is present.</param> /// <param name="columns">A LargePropTagArray structure that specifies the columns that the client is requesting.</param> /// <returns>Return an instance of SeekEntriesRequestBody class.</returns> private SeekEntriesRequestBody BuildSeekEntriesRequestBody(bool hasState, STAT state, bool hasTarget, PropertyValue_r target, bool hasExplicitTable, uint explicitableCount, uint[] explicitTable, bool hasColumns, LargePropertyTagArray columns) { SeekEntriesRequestBody requestBody = new SeekEntriesRequestBody(); // Reserved. The client MUST set this field to 0x00000000 and the server MUST ignore this field. requestBody.Reserved = 0x00000000; requestBody.HasState = hasState; if (hasState) { requestBody.State = state; } requestBody.HasTarget = hasTarget; if (hasTarget) { requestBody.Target = target; } requestBody.HasExplicitTable = hasExplicitTable; if (hasExplicitTable) { requestBody.ExplicitableCount = explicitableCount; requestBody.ExplicitTable = explicitTable; } requestBody.HasColumns = hasColumns; if (hasColumns) { requestBody.Columns = columns; } requestBody.AuxiliaryBufferSize = 0; requestBody.AuxiliaryBuffer = new byte[] { }; return requestBody; }
public void MSOXCMAPIHTTP_S02_TC13_SeekEntriesRequestType() { this.CheckMapiHttpIsSupported(); #region Call Bind request type to established a session context with the address book server. this.Bind(); #endregion #region Call QueryRows request type with propTags set to null. STAT stat = new STAT(); stat.InitiateStat(); LargePropertyTagArray columns = new LargePropertyTagArray(); QueryRowsRequestBody queryRowsRequestBody = this.BuildQueryRowsRequestBody(true, stat, 0, null, ConstValues.QueryRowsRequestedRowNumber, false, columns); QueryRowsResponseBody queryRowsResponseBody = this.Adapter.QueryRows(queryRowsRequestBody); Site.Assert.AreEqual<uint>((uint)0, queryRowsResponseBody.ErrorCode, "QueryRows operation should succeed and 0 is expected to be returned. The return value is {0}.", queryRowsResponseBody.ErrorCode); uint[] outMids = new uint[queryRowsResponseBody.RowCount.Value]; for (int i = 0; i < queryRowsResponseBody.RowCount; i++) { outMids[i] = BitConverter.ToUInt32(queryRowsResponseBody.RowData[i].ValueArray[0].Value, 0); } stat = queryRowsResponseBody.State.Value; #endregion #region Call UpdateStat request type to update the STAT block that represents the position in a table to reflect positioning changes requested by the client. stat.Delta = 1; byte[] auxIn = new byte[] { }; UpdateStatRequestBody updateStatRequestBody = this.BuildUpdateStatRequestBody(true, stat, true); UpdateStatResponseBody updateStatResponseBody = this.Adapter.UpdateStat(updateStatRequestBody); Site.Assert.AreEqual<uint>(0, updateStatResponseBody.ErrorCode, "UpdateStat should succeed and 0 is expected to be returned. The returned value is {0}.", updateStatResponseBody.ErrorCode); #endregion #region Call SeekEntries request type which contains fields State, Trage and Columns. PropertyTag pidTagDisplayNameTag = new PropertyTag((ushort)PropertyID.PidTagDisplayName, (ushort)PropertyTypeValues.PtypString); string displayName = Common.GetConfigurationPropertyValue("GeneralUserName", this.Site) + "\0"; PropertyValue_r target = new PropertyValue_r() { PropTag = pidTagDisplayNameTag, Reserved = 0, Value = System.Text.Encoding.Unicode.GetBytes(displayName) }; columns = new LargePropertyTagArray() { PropertyTagCount = 1, PropertyTags = new PropertyTag[1] { target.PropTag } }; SeekEntriesRequestBody seekEntriesRequestBody = this.BuildSeekEntriesRequestBody(true, updateStatResponseBody.State.Value, true, target, true, (uint)outMids.Length, outMids, true, columns); SeekEntriesResponseBody seekEntriesResponseBody = this.Adapter.SeekEntries(seekEntriesRequestBody); Site.Assert.AreEqual<uint>(0, seekEntriesResponseBody.ErrorCode, "SeekEntries should succeed and 0 is expected to be returned. The returned value is {0}.", seekEntriesResponseBody.ErrorCode); #endregion #region Call QueryRows request type using a new list of minimal entry ids as input parameter according to the parameters of SeekEntries request type response. uint[] newTable = new uint[outMids.Length - (int)seekEntriesResponseBody.State.Value.NumPos]; Array.Copy(outMids, (int)seekEntriesResponseBody.State.Value.NumPos, newTable, 0, newTable.Length); queryRowsRequestBody = this.BuildQueryRowsRequestBody(true, stat, (uint)newTable.Length, newTable, ConstValues.QueryRowsRequestedRowNumber, true, columns); queryRowsRequestBody.Flags = (uint)RetrievePropertyFlags.fEphID; queryRowsResponseBody = this.Adapter.QueryRows(queryRowsRequestBody); Site.Assert.AreEqual<uint>((uint)0, queryRowsResponseBody.StatusCode, "QueryRows operation should succeed and 0 is expected to be returned. The return value is {0}.", queryRowsResponseBody.StatusCode); if (seekEntriesResponseBody.HasColumnsAndRows == false) { seekEntriesResponseBody = this.Adapter.SeekEntries(seekEntriesRequestBody); Site.Assert.AreEqual<uint>(0, seekEntriesResponseBody.ErrorCode, "SeekEntries should succeed and 0 is expected to be returned. The returned value is {0}.", seekEntriesResponseBody.ErrorCode); } // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R1013"); // If the RowData is not Null, then client retrieves information about rows in an Explicit Table by the SeekEntries request type. // So R1013 will be verified. this.Site.CaptureRequirementIfIsTrue( seekEntriesResponseBody.ErrorCode == 0x00000000 && seekEntriesResponseBody.RowData != null, 1013, @"[In SeekEntries Request Type] Optionally, the SeekEntries request type can also be used to retrieve information about rows in an Explicit Table."); bool isTheValueGreaterThanOrEqualTo = false; for (int i = 0; i < seekEntriesResponseBody.RowData.Length; i++) { // Check whether the returned property value is greater than or equal to the input property PidTagDisplayName. string dispalyNameReturnedFromServer = System.Text.Encoding.UTF8.GetString(seekEntriesResponseBody.RowData[i].ValueArray[0].Value); // Value Condition greater than zero indicates the returned property value follows the input PidTagDisplayName property value. int result = dispalyNameReturnedFromServer.CompareTo(displayName); if (result < 0) { this.Site.Log.Add(LogEntryKind.Debug, "The display name returned from server is {0}, the expected display name is {1}", dispalyNameReturnedFromServer.Replace("\0", string.Empty), displayName.Replace("\0", string.Empty)); isTheValueGreaterThanOrEqualTo = false; break; } else { isTheValueGreaterThanOrEqualTo = true; } } // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R1012"); this.Site.CaptureRequirementIfIsTrue( isTheValueGreaterThanOrEqualTo, 1012, @"[In SeekEntries Request Type] The SeekEntries request type is used by the client to search for and set the logical position in a specific table to the first entry greater than or equal to a specified value."); bool isLargePropertyTagArrayEqual = AdapterHelper.AreTwoLargePropertyTagArrayEqual(seekEntriesRequestBody.Columns, seekEntriesResponseBody.Columns.Value); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R1047"); this.Site.CaptureRequirementIfIsTrue( isLargePropertyTagArrayEqual, 1047, @"[In SeekEntries Request Type Success Response Body] Columns (optional) (variable): A LargePropTagArray structure (section 2.2.1.3) that specifies the columns used for the rows returned."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R1053"); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R1053 this.Site.CaptureRequirementIfIsInstanceOfType( seekEntriesResponseBody.RowData, typeof(AddressBookPropertyRow[]), 1053, @"[In SeekEntries Request Type Success Response Body] RowData (optional) (variable): An array of AddressBookPropertyRow structures (section 2.2.1.2), each of which specifies the row data for the entries queried."); #endregion #region Call SeekEntries request type without State field. seekEntriesRequestBody = this.BuildSeekEntriesRequestBody(false, stat, true, target, false, 0, null, true, columns); seekEntriesResponseBody = this.Adapter.SeekEntries(seekEntriesRequestBody); Site.Assert.AreEqual<uint>(0, seekEntriesResponseBody.StatusCode, "SeekEntries should succeed and 0 is expected to be returned. The returned value is {0}.", seekEntriesResponseBody.StatusCode); #endregion #region Call the Unbind request type to destroy the session context. this.Unbind(); #endregion }