public void WhenCallingNetworkStateChangeShouldPostAllMessages()
        {
            var networkStateWaitHandle = new AutoResetEventAdapter(false);
            var networkState           = new NetworkStateService(new Mock <ISystemNotifier>().Object, networkStateWaitHandle);

            this.PeriodicBackoutCheck.Setup(p => p.IsTimeElapsed("ForwardService", 100))
            .Returns(true);

            this.ForwardService = new ForwardService(this.PersistentStore, this.HttpClient.Object, networkState, this.WaitHandle, 100, 0, false, this.Logger.Object);
            this.ForwardService.PeriodicBackoutCheck = this.PeriodicBackoutCheck.Object;

            var returnResult = Result.TemporaryError;

            this.HttpClient.Setup(c => c.Post(It.IsAny <IMessage>()))
            .Returns(() => returnResult);

            var message = this.CreateMessage();

            this.ForwardService.Start();
            networkState.Start();
            Thread.Sleep(100);

            this.PersistentStore.Add(message);
            this.PersistentStore.Add(message);
            this.PersistentStore.Add(message);
            Thread.Sleep(200);

            returnResult = Result.Ok;
            networkStateWaitHandle.Set();
            Thread.Sleep(6000);

            Assert.Null(this.PersistentStore.Get());

            this.PeriodicBackoutCheck.Verify(p => p.Record("ForwardService"), Times.AtLeast(1));
        }
        public void WhenGettingTemporaryErrorShoudBackoutForFiveMinutes()
        {
            var waitHandle      = new AutoResetEventAdapter(false);
            var store           = new Mock <IRepository>();
            var messageProvider = new Mock <IMessageProvider>();

            messageProvider.SetupGet(m => m.CanSend).Returns(true);
            this.PeriodicBackoutCheck.Setup(p => p.IsTimeElapsed("ForwardService", 1000))
            .Returns(false);

            var forwardService = new ForwardService(store.Object, this.HttpClient.Object, this.NetworkStateService.Object, waitHandle, 1000, 0, false, this.Logger.Object);

            forwardService.MessageProvider      = messageProvider.Object;
            forwardService.PeriodicBackoutCheck = this.PeriodicBackoutCheck.Object;
            forwardService.Start();

            Thread.Sleep(500);
            forwardService.Stop();

            this.HttpClient.Verify(c => c.Post(It.IsAny <IMessage>()), Times.Never());
            messageProvider.Verify(m => m.CanSend, Times.AtLeast(1));
            messageProvider.Verify(m => m.GetNext(), Times.Never());
            messageProvider.Verify(m => m.Delete(It.IsAny <IMessage>()), Times.Never());
            messageProvider.Verify(m => m.Close(), Times.Never());
            this.PeriodicBackoutCheck.Verify(p => p.IsTimeElapsed("ForwardService", 1000), Times.AtLeast(1));
        }
        public void WhenMessageProviderCanSendShouldCallClose()
        {
            this.HttpClient.Setup(c => c.Post(It.IsAny <IMessage>()))
            .Returns(Result.Ok);

            var store           = new Mock <IRepository>();
            var waitHandle      = new AutoResetEventAdapter(false);
            var messageProvider = new Mock <IMessageProvider>();

            messageProvider.SetupGet(m => m.CanSend).Returns(true);
            messageProvider.Setup(s => s.GetNext()).Returns(this.CreateMessage());
            var forwardService = new ForwardService(store.Object, this.HttpClient.Object, this.NetworkStateService.Object, waitHandle, 1000, 0, false, this.Logger.Object);

            forwardService.MessageProvider           = messageProvider.Object;
            this.ForwardService.PeriodicBackoutCheck = this.PeriodicBackoutCheck.Object;

            forwardService.Start();

            Thread.Sleep(500);
            forwardService.Stop();

            messageProvider.Verify(m => m.CanSend, Times.AtLeast(1));
            messageProvider.Verify(m => m.GetNext(), Times.AtLeast(1));
            messageProvider.Verify(m => m.Delete(It.IsAny <IMessage>()), Times.AtLeast(1));
            messageProvider.Verify(m => m.Close(), Times.AtLeast(1));
        }
        public void WhenCallingNetworkStateChangeAndServiceStopedShouldNotPostAllMessages()
        {
            var networkStateWaitHandle = new AutoResetEventAdapter(false);
            var networkState           = new NetworkStateService(new Mock <ISystemNotifier>().Object, networkStateWaitHandle);

            this.ForwardService = new ForwardService(this.PersistentStore, this.HttpClient.Object, networkState, this.WaitHandle, 100, 0, false, this.Logger.Object);

            var returnResult = Result.TemporaryError;

            this.HttpClient.Setup(c => c.Post(It.IsAny <IMessage>()))
            .Returns(() => returnResult);

            var message = this.CreateMessage();

            this.ForwardService.Start();
            networkState.Start();
            Thread.Sleep(50);

            this.PersistentStore.Add(message);
            Thread.Sleep(200);

            this.ForwardService.Stop();
            returnResult = Result.Ok;
            networkStateWaitHandle.Set();
            Thread.Sleep(500);

            Assert.NotNull(this.PersistentStore.Get());
        }
        public void WhenThrowsWhileForwardingMessagesShouldNotStopThreadAndContinueSending()
        {
            this.HttpClient.Setup(c => c.Post(It.IsAny <IMessage>()))
            .Returns(Result.Ok);

            var store = new Mock <IRepository>();

            var waitHandle      = new AutoResetEventAdapter(false);
            var messageProvider = new Mock <IMessageProvider>();

            messageProvider.SetupGet(m => m.CanSend).Returns(true);
            messageProvider.Setup(s => s.GetNext()).Returns(this.CreateMessage());

            var exception = new InvalidOperationException("Error");
            var callCount = 0;

            messageProvider.Setup(s => s.Delete(It.IsAny <IMessage>()))
            .Callback(() =>
            {
                callCount++;
                if (callCount % 2 == 0)
                {
                    throw exception;
                }
            });

            var forwardService = new ForwardService(store.Object, this.HttpClient.Object, this.NetworkStateService.Object, waitHandle, 1000, 0, false, this.Logger.Object);

            forwardService.MessageProvider           = messageProvider.Object;
            this.ForwardService.PeriodicBackoutCheck = this.PeriodicBackoutCheck.Object;

            forwardService.Start();

            Thread.Sleep(3000);
            forwardService.Stop();

            messageProvider.Verify(m => m.CanSend, Times.AtLeast(1));
            messageProvider.Verify(m => m.GetNext(), Times.AtLeast(1));
            messageProvider.Verify(m => m.Delete(It.IsAny <IMessage>()), Times.AtLeast(1));
            messageProvider.Verify(m => m.Close(), Times.AtLeast(1));
            this.Logger.Verify(l => l.Err("ForwardService.ThreadStart. Error {0}", exception.ToString()), Times.AtLeast(1));
        }
        public void WhenSendingMessagesShouldSleepFor1SecondBetweenEachMessage()
        {
            this.HttpClient.Setup(c => c.Post(It.IsAny <IMessage>()))
            .Returns(Result.Ok);

            var waitHandle = new AutoResetEventAdapter(false);
            var store      = new Mock <IRepository>();

            store.Setup(s => s.Get()).Returns(this.CreateMessage());

            var forwardService = new ForwardService(store.Object, this.HttpClient.Object, this.NetworkStateService.Object, waitHandle, 100, 1000, false, this.Logger.Object);

            forwardService.PeriodicBackoutCheck = this.PeriodicBackoutCheck.Object;

            forwardService.Start();
            Thread.Sleep(3000);
            forwardService.Stop();

            store.Verify(s => s.Get(), Times.AtLeast(3));
        }
        public void WhenReceivingTemporaryErrorMessageFromServerAndSleepFor5MinutesThenTerminateSignaledShouldExit()
        {
            this.HttpClient.Setup(c => c.Post(It.IsAny <IMessage>()))
            .Returns(Result.TemporaryError);

            var waitHandle = new AutoResetEventAdapter(false);
            var store      = new Mock <IRepository>();

            store.Setup(s => s.Get()).Returns(this.CreateMessage());

            var forwardService = new ForwardService(store.Object, this.HttpClient.Object, this.NetworkStateService.Object, waitHandle, 5 * 60 * 1000, 0, false, this.Logger.Object);

            this.PeriodicBackoutCheck.Setup(p => p.IsTimeElapsed("ForwardService", 5 * 60 * 1000))
            .Returns(true);
            forwardService.PeriodicBackoutCheck = this.PeriodicBackoutCheck.Object;

            new Thread(this.StopForwardService).Start(forwardService);
            forwardService.Start();
            Thread.Sleep(1000);

            store.Verify(s => s.Get(), Times.Once());
        }
        public void WhenReceivingNotConnectedErrorShouldNotSleepAndNotDeletingMessages()
        {
            this.HttpClient.Setup(c => c.Post(It.IsAny <IMessage>()))
            .Returns(Result.NotConnected);

            var waitHandle = new AutoResetEventAdapter(false);
            var store      = new Mock <IRepository>();

            store.Setup(s => s.Get()).Returns(this.CreateMessage());

            var forwardService = new ForwardService(store.Object, this.HttpClient.Object, this.NetworkStateService.Object, waitHandle, 1000, 0, false, this.Logger.Object);

            this.PeriodicBackoutCheck.Setup(p => p.IsTimeElapsed("ForwardService", 1000))
            .Returns(true);
            forwardService.PeriodicBackoutCheck = this.PeriodicBackoutCheck.Object;

            forwardService.Start();
            Thread.Sleep(500);
            forwardService.Stop();

            store.Verify(s => s.Get(), Times.Once());
            store.Verify(s => s.Remove(), Times.Never());
        }
        public void WhenCallingNetworkStateChangeAndServiceStopedShouldNotPostAllMessages()
        {
            var networkStateWaitHandle = new AutoResetEventAdapter(false);
            var networkState = new NetworkStateService(new Mock<ISystemNotifier>().Object, networkStateWaitHandle);

            this.ForwardService = new ForwardService(this.PersistentStore, this.HttpClient.Object, networkState, this.WaitHandle, 100, 0);

            var returnResult = Result.TemporaryError;
            this.HttpClient.Setup(c => c.Post(It.IsAny<IMessage>()))
                .Returns(() => returnResult);

            var message = this.CreateMessage();

            this.ForwardService.Start();
            networkState.Start();
            Thread.Sleep(50);

            this.PersistentStore.Add(message);
            Thread.Sleep(200);

            this.ForwardService.Stop();
            returnResult = Result.Ok;
            networkStateWaitHandle.Set();
            Thread.Sleep(500);

            Assert.NotNull(this.PersistentStore.Get());
        }
        public void WhenThrowsWhileForwardingMessagesShouldNotStopThreadAndContinueSending()
        {
            this.HttpClient.Setup(c => c.Post(It.IsAny<IMessage>()))
               .Returns(Result.Ok);

            var store = new Mock<IRepository>();

            var waitHandle = new AutoResetEventAdapter(false);
            var messageProvider = new Mock<IMessageProvider>();
            messageProvider.SetupGet(m => m.CanSend).Returns(true);
            messageProvider.Setup(s => s.GetNext()).Returns(this.CreateMessage());

            var exception = new InvalidOperationException("Error");
            var callCount = 0;
            messageProvider.Setup(s => s.Delete(It.IsAny<IMessage>()))
                 .Callback(() => 
                     {
                         callCount++;
                         if (callCount % 2 == 0)
                         {
                             throw exception;
                         }
                     });

            var forwardService = new ForwardService(store.Object, this.HttpClient.Object, this.NetworkStateService.Object, waitHandle, 1000, 0, false, this.Logger.Object);
            forwardService.MessageProvider = messageProvider.Object;
            this.ForwardService.PeriodicBackoutCheck = this.PeriodicBackoutCheck.Object;

            forwardService.Start();

            Thread.Sleep(3000);
            forwardService.Stop();

            messageProvider.Verify(m => m.CanSend, Times.AtLeast(1));
            messageProvider.Verify(m => m.GetNext(), Times.AtLeast(1));
            messageProvider.Verify(m => m.Delete(It.IsAny<IMessage>()), Times.AtLeast(1));
            messageProvider.Verify(m => m.Close(), Times.AtLeast(1));
            this.Logger.Verify(l => l.Err("ForwardService.ThreadStart. Error {0}", exception.ToString()), Times.AtLeast(1));
        }
        public void WhenGettingTemporaryErrorShoudBackoutForFiveMinutes()
        {
            var waitHandle = new AutoResetEventAdapter(false);
            var store = new Mock<IRepository>();
            var messageProvider = new Mock<IMessageProvider>();
            messageProvider.SetupGet(m => m.CanSend).Returns(true);
            this.PeriodicBackoutCheck.Setup(p => p.IsTimeElapsed("ForwardService", 1000))
                .Returns(false);

            var forwardService = new ForwardService(store.Object, this.HttpClient.Object, this.NetworkStateService.Object, waitHandle, 1000, 0, false, this.Logger.Object);
            forwardService.MessageProvider = messageProvider.Object;
            forwardService.PeriodicBackoutCheck = this.PeriodicBackoutCheck.Object;
            forwardService.Start();

            Thread.Sleep(500);
            forwardService.Stop();

            this.HttpClient.Verify(c => c.Post(It.IsAny<IMessage>()), Times.Never());
            messageProvider.Verify(m => m.CanSend, Times.AtLeast(1));
            messageProvider.Verify(m => m.GetNext(), Times.Never());
            messageProvider.Verify(m => m.Delete(It.IsAny<IMessage>()), Times.Never());
            messageProvider.Verify(m => m.Close(), Times.Never());
            this.PeriodicBackoutCheck.Verify(p => p.IsTimeElapsed("ForwardService", 1000), Times.AtLeast(1));
        }
        public void WhenMessageProviderCanSendShouldCallClose()
        {
            this.HttpClient.Setup(c => c.Post(It.IsAny<IMessage>()))
               .Returns(Result.Ok);

            var store = new Mock<IRepository>();
            var waitHandle = new AutoResetEventAdapter(false);
            var messageProvider = new Mock<IMessageProvider>();
            messageProvider.SetupGet(m => m.CanSend).Returns(true);
            messageProvider.Setup(s => s.GetNext()).Returns(this.CreateMessage());
            var forwardService = new ForwardService(store.Object, this.HttpClient.Object, this.NetworkStateService.Object, waitHandle, 1000, 0, false, this.Logger.Object);
            forwardService.MessageProvider = messageProvider.Object;
            this.ForwardService.PeriodicBackoutCheck = this.PeriodicBackoutCheck.Object;

            forwardService.Start();

            Thread.Sleep(500);
            forwardService.Stop();

            messageProvider.Verify(m => m.CanSend, Times.AtLeast(1));
            messageProvider.Verify(m => m.GetNext(), Times.AtLeast(1));
            messageProvider.Verify(m => m.Delete(It.IsAny<IMessage>()), Times.AtLeast(1));
            messageProvider.Verify(m => m.Close(), Times.AtLeast(1));
        }
        public void WhenReceivingTemporaryErrorMessageFromServerAndSleepFor5MinutesThenTerminateSignaledShouldExit()
        {
            this.HttpClient.Setup(c => c.Post(It.IsAny<IMessage>()))
                .Returns(Result.TemporaryError);

            var waitHandle = new AutoResetEventAdapter(false);
            var store = new Mock<IRepository>();
            store.Setup(s => s.Get()).Returns(this.CreateMessage());

            var forwardService = new ForwardService(store.Object, this.HttpClient.Object, this.NetworkStateService.Object, waitHandle, 5 * 60 * 1000, 0, false, this.Logger.Object);
            this.PeriodicBackoutCheck.Setup(p => p.IsTimeElapsed("ForwardService", 5 * 60 * 1000))
                .Returns(true);
            forwardService.PeriodicBackoutCheck = this.PeriodicBackoutCheck.Object;

            new Thread(this.StopForwardService).Start(forwardService);
            forwardService.Start();
            Thread.Sleep(1000);

            store.Verify(s => s.Get(), Times.Once());
        }
        public void WhenReceivingNotConnectedErrorShouldNotSleepAndNotDeletingMessages()
        {
            this.HttpClient.Setup(c => c.Post(It.IsAny<IMessage>()))
                .Returns(Result.NotConnected);

            var waitHandle = new AutoResetEventAdapter(false);
            var store = new Mock<IRepository>();
            store.Setup(s => s.Get()).Returns(this.CreateMessage());

            var forwardService = new ForwardService(store.Object, this.HttpClient.Object, this.NetworkStateService.Object, waitHandle, 1000, 0, false, this.Logger.Object);
            this.PeriodicBackoutCheck.Setup(p => p.IsTimeElapsed("ForwardService", 1000))
               .Returns(true);
            forwardService.PeriodicBackoutCheck = this.PeriodicBackoutCheck.Object;

            forwardService.Start();
            Thread.Sleep(500);
            forwardService.Stop();

            store.Verify(s => s.Get(), Times.Once());
            store.Verify(s => s.Remove(), Times.Never());
        }
        public void WhenSendingMessagesShouldSleepFor1SecondBetweenEachMessage()
        {
            this.HttpClient.Setup(c => c.Post(It.IsAny<IMessage>()))
                .Returns(Result.Ok);

            var waitHandle = new AutoResetEventAdapter(false);
            var store = new Mock<IRepository>();
            store.Setup(s => s.Get()).Returns(this.CreateMessage());

            var forwardService = new ForwardService(store.Object, this.HttpClient.Object, this.NetworkStateService.Object, waitHandle, 100, 1000, false, this.Logger.Object);
            forwardService.PeriodicBackoutCheck = this.PeriodicBackoutCheck.Object;

            forwardService.Start();
            Thread.Sleep(3000);
            forwardService.Stop();

            store.Verify(s => s.Get(), Times.AtLeast(3));
        }
        public void WhenCallingNetworkStateChangeShouldPostAllMessages()
        {
            var networkStateWaitHandle = new AutoResetEventAdapter(false);
            var networkState = new NetworkStateService(new Mock<ISystemNotifier>().Object, networkStateWaitHandle);

            this.PeriodicBackoutCheck.Setup(p => p.IsTimeElapsed("ForwardService", 100))
               .Returns(true);

            this.ForwardService = new ForwardService(this.PersistentStore, this.HttpClient.Object, networkState, this.WaitHandle, 100, 0, false, this.Logger.Object);
            this.ForwardService.PeriodicBackoutCheck = this.PeriodicBackoutCheck.Object;

            var returnResult = Result.TemporaryError;
            this.HttpClient.Setup(c => c.Post(It.IsAny<IMessage>()))
                .Returns(() => returnResult);

            var message = this.CreateMessage();

            this.ForwardService.Start();
            networkState.Start();
            Thread.Sleep(100);

            this.PersistentStore.Add(message);
            this.PersistentStore.Add(message);
            this.PersistentStore.Add(message);
            Thread.Sleep(200);

            returnResult = Result.Ok;
            networkStateWaitHandle.Set();
            Thread.Sleep(6000);

            Assert.Null(this.PersistentStore.Get());

            this.PeriodicBackoutCheck.Verify(p => p.Record("ForwardService"), Times.AtLeast(1));
        }