public void MSOXCNOTIF_S02_TC02_VerifyTableRowDeleteEventAndCreateTableViewByTableFindRow()
{
this.CheckWhetherSupportMAPIHTTP();
this.NotificationInitialize();
#region Open Inbox folder and get content table of the Inbox folder
uint inboxTableHandle;
this.OpenFolder(this.InboxFolderId, out inboxTableHandle);
uint contentTableHandle;
this.GetContentsTable(inboxTableHandle, out contentTableHandle, false);
#endregion
#region Create table view by FindRow
// The properties need to be set
PropertyTag[] tags = new PropertyTag[] { PropertyTags.All[PropertyNames.PidTagInstID], PropertyTags.All[PropertyNames.PidTagImportance], PropertyTags.All[PropertyNames.PidTagInstanceNum], PropertyTags.All[PropertyNames.PidTagFolderId], PropertyTags.All[PropertyNames.PidTagLastModificationTime] };
this.SetColumns(contentTableHandle, tags);
// Set the value of restriction data
byte[] restrictionData = new byte[5];
ushort pidTagMessageClassID = PropertyTags.All[PropertyNames.PidTagLastModificationTime].PropertyId;
ushort typeOfPidTagMessageClass = PropertyTags.All[PropertyNames.PidTagLastModificationTime].PropertyType;
restrictionData[0] = (byte)Restrictions.ExistRestriction;
Array.Copy(BitConverter.GetBytes(typeOfPidTagMessageClass), 0, restrictionData, 1, sizeof(ushort));
Array.Copy(BitConverter.GetBytes(pidTagMessageClassID), 0, restrictionData, 3, sizeof(ushort));
this.FindRow(contentTableHandle, restrictionData);
#endregion
#region Trigger TableRowDeleted event and get notification
this.TriggerTableRowDeletedEvent();
IList<IDeserializable> rsp = this.CNOTIFAdapter.GetNotification(true);
Site.Assert.IsTrue(rsp.Count > 0, "The response should contain notification message.");
#endregion
#region Verify notification response for TableRowDeleted event
foreach (IDeserializable response in rsp)
{
Site.Assert.IsTrue(response.GetType() == typeof(RopNotifyResponse) || response.GetType() == typeof(RopPendingResponse), "The ROP response type should be RopNotifyResponse or RopPendingResponse.");
if (response is RopNotifyResponse)
{
RopNotifyResponse notifyResponse = (RopNotifyResponse)response;
Site.Assert.AreEqual<NotificationType>(NotificationType.TableModified, notifyResponse.NotificationData.NotificationType, "The notification type for the RopNotify response should be TableModified.");
Site.Assert.AreEqual<EventTypeOfTable>(EventTypeOfTable.TableRowDeleted, notifyResponse.NotificationData.TableEvent, "The table event type for the RopNotify response should be TableRowDeleted.");
this.VerifyTableModifyNotificationFlag(notifyResponse);
this.VerifyTableRowDeletedNotificationElements(notifyResponse);
// Add the debug information
this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R262: The value of the Folder ID and Message ID separately are {0},{1}", notifyResponse.NotificationData.TableRowFolderID, notifyResponse.NotificationData.TableRowMessageID);
// Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R262
bool isVerifiedR262 = notifyResponse.NotificationData.TableRowFolderID != null && notifyResponse.NotificationData.TableRowMessageID != null;
this.Site.CaptureRequirementIfIsTrue(
isVerifiedR262,
262,
@"[In Creating and Sending TableModified Event Notifications] [When a TableModified event occurs, the server generates a notification using one of the following three methods, listed in descending order of usefulness to the client.] For TableRowDeleted event, the server generates an informative notification that specifies the nature of the change (content or hierarchy), the value of the Folder ID structure, as specified in [MS-OXCDATA] section 2.2.1.1, the value of the Message ID structure, as specified in [MS-OXCDATA] section 2.2.1.2, and new table values.");
this.VeriyServerGenerateInformativeNotification(isVerifiedR262);
Site.Assert.IsNotNull(notifyResponse.NotificationData.TableEventType, "The TableEventType in the RopNotifyResponse should not null.");
// Add the debug information
this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R130");
// Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R130
this.Site.CaptureRequirementIfAreEqual<int>(
0x0004,
(int)notifyResponse.NotificationData.TableEventType,
130,
@"[In NotificationData Structure] [TableEventType value] 0x0004: The notification is for TableRowDeleted events.");
// Add the debug information
this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R24");
// Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R24
// The client can receive TableRowDeleted notification indicates that an existing row has been deleted from the table.
this.Site.CaptureRequirementIfAreEqual<int>(
0x0004,
(int)notifyResponse.NotificationData.TableEventType,
24,
@"[In TableModified Event Types] TableRowDeleted: An existing row has been deleted from the table.");
// Only Exchange 2010 and above require a table view, this server version restrict is the same with MS-OXCNTOIF_R245.
if (Common.IsRequirementEnabled(245, this.Site))
{
// Add the debug information
Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R249");
// If the server can return notification response, it can verify RopQueryRows create a table view. so the following requirements can be captured directly.
this.Site.CaptureRequirement(
249,
@"[In Creating and Sending TableModified Event Notifications] If a table view is required on the server, the server MUST receive a request from one of the following ROPs, each of which cause a table view to be created on the server: RopFindRow ([MS-OXCROPS] section 2.2.5.13).");
this.VerifyTableViewCreated();
}
}
}
#endregion
// Only Exchange 2010 and above will stop sending notifications if the RopResetTable ROP is received, until a new table view is created.
if (Common.IsRequirementEnabled(275, this.Site))
{
#region Reset the contents table
this.ResetTable(contentTableHandle);
#endregion
#region Trigger TableRowAdded event after ResetTable and get notification
this.TriggerTableRowAddedEvent();
rsp = this.CNOTIFAdapter.GetNotification(false);
bool isServerCreateSubscription = false;
foreach (IDeserializable response in rsp)
{
Site.Assert.IsTrue(response.GetType() == typeof(RopNotifyResponse) || response.GetType() == typeof(RopPendingResponse), "The ROP response type should be RopNotifyResponse or RopPendingResponse.");
if (response is RopNotifyResponse)
{
isServerCreateSubscription = true;
}
}
Site.Assert.IsFalse(isServerCreateSubscription, "The server can't send notify response when reset table.");
#endregion
#region Create table view by FindRow
this.SetColumns(contentTableHandle, tags);
this.FindRow(contentTableHandle, restrictionData);
#endregion
#region Trigger TableRowAdded event again and get notification
this.TriggerTableRowAddedEvent();
// Create table view by FindRow after ResetTable, and trigger table event again the server should send notification response.
rsp = this.CNOTIFAdapter.GetNotification(true);
Site.Assert.IsTrue(rsp.Count > 0, "The response should contain notification message.");
foreach (IDeserializable response in rsp)
{
Site.Assert.IsTrue(response.GetType() == typeof(RopNotifyResponse) || response.GetType() == typeof(RopPendingResponse), "The ROP response type should be RopNotifyResponse or RopPendingResponse.");
if (response is RopNotifyResponse)
{
isServerCreateSubscription = true;
}
}
#endregion
#region Verify notification response after reset Table and create table view by FindRow
// Since the server return the notification after a table view is created by RopFindRow, this requirement can be verified.
this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNTOIF_R275: The implementation does return notifications after get RopFindRow", isServerCreateSubscription ? string.Empty : "not");
// Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R275
bool isR275Satisfied = isServerCreateSubscription;
Site.CaptureRequirementIfIsTrue(
isR275Satisfied,
275,
@"[In Appendix A: Product Behavior] Implementation does stop sending notifications if the RopResetTable ROP ([MS-OXCROPS] section 2.2.5.15) is received, until a new table view is created using one of the following ROPs: RopFindRow. (Exchange 2010 and above follow this behavior.)");
#endregion
}
}