public void EmailStatusUpdate_EmailIsComplained_ReplyFailed()
        {
            const EmailStatus emailStatus = EmailStatus.Complained;
            var emailData = new EmailData
            {
                ToAddress = "toaddress"
            };
            var requestMessage = new ScheduleEmailForSendingLater(DateTime.Now.AddMinutes(5), emailData, new SmsMetaData(), Guid.NewGuid(), "username");
            var data = new ScheduledEmailData
            {
                ScheduleMessageId = requestMessage.CorrelationId,
                OriginalMessageData = new OriginalEmailMessageData(requestMessage)
            };
            var emailStatusUpdate = new EmailStatusUpdate { Status = emailStatus };

            Test.Initialize();
            Test.Saga<EmailScheduler>()
                .WithExternalDependencies(a => { a.Data = data; })
                .WhenReceivesMessageFrom("address")
                .ExpectPublish<ScheduledEmailFailed>(m =>
                    m.CoordinatorId == requestMessage.CorrelationId
                    && m.EmailStatus == emailStatus
                    && m.ScheduledSmsId == data.ScheduleMessageId
                    && m.ToAddress == emailData.ToAddress
                    && m.Username == requestMessage.Username)
                .ExpectSendLocal<ScheduleStatusChanged>(s =>
                    s.Status == MessageStatus.Failed
                    && s.ScheduleId == data.ScheduleMessageId)
                .When(s => s.Handle(emailStatusUpdate))
                .AssertSagaCompletionIs(true);
        }
        public void EmailStatusUpdate_EmailIsDelivered_SetsTimeoutForFurtherInformation_TimeoutExpires_PublishSuccess()
        {
            const EmailStatus emailStatus = EmailStatus.Delivered;
            var emailData = new EmailData
            {
                ToAddress = "toaddress"
            };
            var requestMessage = new ScheduleEmailForSendingLater(DateTime.Now.AddMinutes(5), emailData, new SmsMetaData(), Guid.NewGuid(), "username");
            var data = new ScheduledEmailData
            {
                ScheduleMessageId = requestMessage.CorrelationId,
                OriginalMessageData = new OriginalEmailMessageData(requestMessage)
            };
            var emailStatusUpdate = new EmailStatusUpdate { Status = emailStatus };

            Test.Initialize();
            Test.Saga<EmailScheduler>()
                .WithExternalDependencies(a => { a.Data = data; })
                .WhenReceivesMessageFrom("address")
                    .ExpectTimeoutToBeSetIn<ScheduleEmailDeliveredTimeout>((message, timespan) => timespan.Ticks == new TimeSpan(1, 0, 0, 0).Ticks)
                .When(s => s.Handle(emailStatusUpdate))
                    .ExpectPublish<ScheduledEmailSent>(m =>
                        m.CoordinatorId == requestMessage.CorrelationId
                        && m.EmailStatus == emailStatus
                        && m.ScheduledSmsId == data.ScheduleMessageId
                        && m.ToAddress == emailData.ToAddress
                        && m.Username == requestMessage.Username)
                    .ExpectSendLocal<ScheduleStatusChanged>(s =>
                        s.Status == MessageStatus.Sent
                        && s.ScheduleId == data.ScheduleMessageId)
                .WhenSagaTimesOut()
                .AssertSagaCompletionIs(true);
        }
        public void TimeoutSendingPausedNoAction_Data()
        {
            var bus = MockRepository.GenerateStrictMock<IBus>();

            var dataId = Guid.NewGuid();
            var originalMessage = new ScheduleEmailForSendingLater { EmailData = new EmailData()};
            var data = new ScheduledEmailData { Id = dataId, OriginalMessageData = new OriginalEmailMessageData(originalMessage), SchedulingPaused = true };

            var scheduleEmail = new EmailScheduler { Bus = bus, Data = data };
            var timeoutMessage = new ScheduleEmailTimeout();
            scheduleEmail.Timeout(timeoutMessage);

            bus.VerifyAllExpectations();
        }
        public void TimeoutPromptsMessageSending_Data()
        {
            var bus = MockRepository.GenerateMock<IBus>();

            var sendOneEmailNow = new SendOneEmailNow();
            bus.Expect(b => b.Send(Arg<string>.Is.Anything, Arg<SendOneEmailNow>.Is.NotNull))
               .WhenCalled(i => sendOneEmailNow = (SendOneEmailNow)(i.Arguments[1]));

            var dataId = Guid.NewGuid();
            var originalMessage = new ScheduleEmailForSendingLater { EmailData = new EmailData
                {
                    BodyHtml = "html",
                    BodyText = "text",
                    FromAddress = "from",
                    FromDisplayName = "display",
                    ReplyToAddress = "replyto",
                    Subject = "subject",
                    ToAddress = "to"
                }};
            var data = new ScheduledEmailData { Id = dataId, OriginalMessageData = new OriginalEmailMessageData(originalMessage) };

            var scheduleEmail = new EmailScheduler { Bus = bus, Data = data };
            var timeoutMessage = new ScheduleEmailTimeout();
            scheduleEmail.Timeout(timeoutMessage);

            Assert.That(sendOneEmailNow.BodyHtml, Is.EqualTo(data.OriginalMessageData.BodyHtml));
            Assert.That(sendOneEmailNow.BodyText, Is.EqualTo(data.OriginalMessageData.BodyText));
            Assert.That(sendOneEmailNow.FromAddress, Is.EqualTo(data.OriginalMessageData.FromAddress));
            Assert.That(sendOneEmailNow.FromDisplayName, Is.EqualTo(data.OriginalMessageData.FromDisplayName));
            Assert.That(sendOneEmailNow.ReplyToAddress, Is.EqualTo(data.OriginalMessageData.ReplyToAddress));
            Assert.That(sendOneEmailNow.Subject, Is.EqualTo(data.OriginalMessageData.Subject));
            Assert.That(sendOneEmailNow.ToAddress, Is.EqualTo(data.OriginalMessageData.ToAddress));
            Assert.That(sendOneEmailNow.Username, Is.EqualTo(data.OriginalMessageData.Username));
            Assert.That(sendOneEmailNow.CorrelationId, Is.EqualTo(data.Id));

            bus.VerifyAllExpectations();
        }
        public void ScheduleEmailForSendingLaterIsPausedThenResumedAndSent()
        {
            var scheduleEmailForSendingLater = new ScheduleEmailForSendingLater
                {
                    SendMessageAtUtc = DateTime.Now.AddDays(1),
                    EmailData = new EmailData()
                };
            var sagaId = Guid.NewGuid();

            var scheduledEmailData = new ScheduledEmailData
                {
                    Id = sagaId,
                    Originator = "place",
                    OriginalMessageId = Guid.NewGuid().ToString(),
                    OriginalMessageData = new OriginalEmailMessageData(new ScheduleEmailForSendingLater { EmailData= scheduleEmailForSendingLater.EmailData })
                };

            Test.Initialize();
            Test.Saga<EmailScheduler>()
                .WithExternalDependencies(a => { a.Data = scheduledEmailData; })
                .ExpectTimeoutToBeSetAt<ScheduleEmailTimeout>((state, timeout) => timeout == scheduleEmailForSendingLater.SendMessageAtUtc && state.TimeoutCounter == 0)
                .ExpectSendLocal<EmailScheduleCreated>()
                .When(s => s.Handle(scheduleEmailForSendingLater))
                .ExpectPublish<MessageSchedulePaused>()
                .ExpectSendLocal<ScheduleStatusChanged>(s => s.Status == MessageStatus.Paused)
                .When(s => s.Handle(new PauseScheduledMessageIndefinitely(Guid.Empty)))
                .ExpectTimeoutToBeSetAt<ScheduleEmailTimeout>((state, timeout) => state.TimeoutCounter == 1)
                .ExpectPublish<MessageRescheduled>()
                .ExpectSendLocal<ScheduleStatusChanged>(s => s.Status == MessageStatus.Scheduled)
                .When(s => s.Handle(new ResumeScheduledMessageWithOffset(Guid.Empty, new TimeSpan())))
                .ExpectNotSend<SendOneEmailNow>(now => false)
                .When(s => s.Timeout(new ScheduleEmailTimeout { TimeoutCounter = 0 }))
                .ExpectSendToDestination<SendOneEmailNow>((m,d) => d.Queue == "smsactioner")
                .When(s => s.Timeout(new ScheduleEmailTimeout { TimeoutCounter = 1 }))
                .ExpectPublish<ScheduledEmailSent>()
                .ExpectSendLocal<ScheduleStatusChanged>(s => s.Status == MessageStatus.Sent)
                .When(s => s.Handle(new EmailStatusUpdate { Status = EmailStatus.Opened}))
                .AssertSagaCompletionIs(true);
        }
        public void ScheduleEmailForSendingLaterIsPaused()
        {
            var scheduleEmailForSendingLater = new ScheduleEmailForSendingLater
                {
                    SendMessageAtUtc = DateTime.Now.AddDays(1),
                    ScheduleMessageId = Guid.NewGuid(),
                    EmailData = new EmailData()
                };
            var sagaId = Guid.NewGuid();

            var scheduledEmailData = new ScheduledEmailData
                {
                    Id = sagaId,
                    Originator = "place",
                    OriginalMessageId = "one",
                    OriginalMessageData = new OriginalEmailMessageData(new ScheduleEmailForSendingLater { EmailData = scheduleEmailForSendingLater.EmailData })
                };

            Test.Initialize();
            Test.Saga<EmailScheduler>()
                .WithExternalDependencies(a => { a.Data = scheduledEmailData; })
                .ExpectTimeoutToBeSetAt<ScheduleEmailTimeout>((state, timeout) => timeout == scheduleEmailForSendingLater.SendMessageAtUtc)
                .ExpectSendLocal<EmailScheduleCreated>()
                .When(s => s.Handle(scheduleEmailForSendingLater))
                .ExpectPublish<MessageSchedulePaused>()
                .ExpectSendLocal<ScheduleStatusChanged>(s => s.Status == MessageStatus.Paused)
                .When(s => s.Handle(new PauseScheduledMessageIndefinitely(Guid.Empty)))
                .ExpectNotSend<SendOneEmailNow>(now => false)
                .WhenSagaTimesOut();
        }
        public void ScheduleEmailForSendingLaterFails()
        {
            var scheduleEmailForSendingLater = new ScheduleEmailForSendingLater
                {
                    SendMessageAtUtc = DateTime.Now.AddDays(1),
                    ScheduleMessageId = Guid.NewGuid(),
                    EmailData = new EmailData()
                };
            var sagaId = Guid.NewGuid();
            var scheduledEmailData = new ScheduledEmailData
                {
                    Id = sagaId,
                    Originator = "place",
                    OriginalMessageId = Guid.NewGuid().ToString(),
                    OriginalMessageData = new OriginalEmailMessageData(new ScheduleEmailForSendingLater { EmailData = scheduleEmailForSendingLater.EmailData })
                };

            Test.Initialize();
            Test.Saga<EmailScheduler>()
                .WithExternalDependencies(a => { a.Data = scheduledEmailData; })
                .ExpectTimeoutToBeSetAt<ScheduleEmailTimeout>((state, timeout) => timeout == scheduleEmailForSendingLater.SendMessageAtUtc)
                .When(s => s.Handle(scheduleEmailForSendingLater))
                .ExpectSendToDestination<SendOneEmailNow>((m,d) => d.Queue == "smsactioner")
                .WhenSagaTimesOut()
                .ExpectPublish<ScheduledEmailFailed>()
                .ExpectSendLocal<ScheduleStatusChanged>(s => s.Status == MessageStatus.Failed)
                .When(s => s.Handle(new EmailStatusUpdate { Status = EmailStatus.Failed }))
                .AssertSagaCompletionIs(true);
        }
        public void OriginalMessageGetsSavedToSaga_Data()
        {
            var data = new ScheduledEmailData();
            var originalMessage = new ScheduleEmailForSendingLater { SendMessageAtUtc = DateTime.Now };

            Test.Initialize();
            Test.Saga<EmailScheduler>()
                .WithExternalDependencies(a => { a.Data = data; })
                .WhenReceivesMessageFrom("address")
                .ExpectPublish<SmsScheduled>(m => m.CoordinatorId == data.Id && m.ScheduleMessageId == originalMessage.ScheduleMessageId)
                .When(s => s.Handle(originalMessage));

            Assert.That(data.OriginalMessageData, Is.EqualTo(originalMessage));
        }