private async Task PutSagaAsync( long trackingCodeId, IReadOnlyDictionary <IDeliveryChannel, IReadOnlyList <ChannelOperationInstruction> > channelToOperationInstructionsMap, IReadOnlyCollection <NamedValue <string> > inheritableTags) { var channelToOperationsMonitoringInfoMap = channelToOperationInstructionsMap.ToDictionary( _ => _.Key, _ => (IReadOnlyList <ChannelOperationMonitoringInfo>)_.Value.Select(c => c.MonitoringInfo).ToList()); var processSendNotificationSagaOp = new ProcessSendNotificationSagaOp(trackingCodeId, channelToOperationsMonitoringInfoMap); var @event = new ExecuteOpRequestedEvent <long, ProcessSendNotificationSagaOp>(trackingCodeId, processSendNotificationSagaOp, DateTime.UtcNow); var tags = this.buildExecuteProcessSendNotificationSagaEventTagsProtocol.ExecuteBuildTags(trackingCodeId, @event, inheritableTags); await this.sagaStream.PutWithIdAsync(trackingCodeId, @event, tags, ExistingRecordStrategy.DoNotWriteIfFoundById); }
static ProcessSendNotificationSagaOpTest() { ConstructorArgumentValidationTestScenarios .AddScenario(() => new ConstructorArgumentValidationTestScenario <ProcessSendNotificationSagaOp> { Name = "constructor should throw ArgumentException when parameter 'channelToOperationsMonitoringInfoMap' has a value that is empty", ConstructionFunc = () => { var referenceObject = A.Dummy <ProcessSendNotificationSagaOp>(); var channelToOperationsMonitoringInfoMap = new Dictionary <IDeliveryChannel, IReadOnlyList <ChannelOperationMonitoringInfo> > { { new SlackDeliveryChannel(), new ChannelOperationMonitoringInfo[0] }, }; var result = new ProcessSendNotificationSagaOp( referenceObject.NotificationTrackingCodeId, channelToOperationsMonitoringInfoMap); return(result); }, ExpectedExceptionType = typeof(ArgumentException), ExpectedExceptionMessageContains = new[] { "perChannelOperationsMonitoringInfo", "empty enumerable" }, }) .AddScenario(() => new ConstructorArgumentValidationTestScenario <ProcessSendNotificationSagaOp> { Name = "constructor should throw ArgumentException when parameter 'channelToOperationsMonitoringInfoMap' has a value that contains a null element", ConstructionFunc = () => { var referenceObject = A.Dummy <ProcessSendNotificationSagaOp>(); var channelToOperationsMonitoringInfoMap = new Dictionary <IDeliveryChannel, IReadOnlyList <ChannelOperationMonitoringInfo> > { { new SlackDeliveryChannel(), new[] { A.Dummy <ChannelOperationMonitoringInfo>(), null } }, }; var result = new ProcessSendNotificationSagaOp( referenceObject.NotificationTrackingCodeId, channelToOperationsMonitoringInfoMap); return(result); }, ExpectedExceptionType = typeof(ArgumentException), ExpectedExceptionMessageContains = new[] { "perChannelOperationsMonitoringInfo", "null element" }, }) .AddScenario(() => new ConstructorArgumentValidationTestScenario <ProcessSendNotificationSagaOp> { Name = "constructor should throw ArgumentException when parameter 'channelToOperationsMonitoringInfoMap' has a value that contains two or more elements with the same tracking code", ConstructionFunc = () => { var referenceObject = A.Dummy <ProcessSendNotificationSagaOp>(); var channelMonitoringInfo = A.Dummy <ChannelOperationMonitoringInfo>(); var channelMonitoringInfo2 = A.Dummy <ChannelOperationMonitoringInfo>().DeepCloneWithChannelOperationTrackingCodeId(channelMonitoringInfo.ChannelOperationTrackingCodeId); var channelToOperationsMonitoringInfoMap = new Dictionary <IDeliveryChannel, IReadOnlyList <ChannelOperationMonitoringInfo> > { { new SlackDeliveryChannel(), new[] { channelMonitoringInfo, A.Dummy <ChannelOperationMonitoringInfo>(), channelMonitoringInfo2, } }, }; var result = new ProcessSendNotificationSagaOp( referenceObject.NotificationTrackingCodeId, channelToOperationsMonitoringInfoMap); return(result); }, ExpectedExceptionType = typeof(ArgumentException), ExpectedExceptionMessageContains = new[] { "channelOperationTrackingCodeIds", "two or more elements that are equal" }, }); }