public void SendingFinishedSessionsIsAbortedImmediatelyWhenTooManyRequestsResponseIsReceived()
        {
            // given
            const int sleepTime = 4321;
            var       target    = new BeaconSendingCaptureOnState();

            var statusResponse = Substitute.For <IStatusResponse>();

            statusResponse.ResponseCode.Returns(StatusResponse.HttpTooManyRequests);
            statusResponse.IsErroneousResponse.Returns(true);
            statusResponse.GetRetryAfterInMilliseconds().Returns(sleepTime);

            mockSession3Finished.SendBeacon(Arg.Any <IHttpClientProvider>(), Arg.Any <IAdditionalQueryParameters>())
            .Returns(statusResponse);
            mockSession3Finished.IsDataSendingAllowed.Returns(true);
            mockSession4Finished.SendBeacon(Arg.Any <IHttpClientProvider>(), Arg.Any <IAdditionalQueryParameters>())
            .Returns(statusResponse);
            mockSession4Finished.IsDataSendingAllowed.Returns(true);

            BeaconSendingCaptureOffState captureState = null;

            mockContext.NextState = Arg.Do <BeaconSendingCaptureOffState>(c => captureState = c);

            // when
            target.Execute(mockContext);

            // then
            _ = mockSession3Finished.Received(1).IsDataSendingAllowed;
            mockSession3Finished.Received(1)
            .SendBeacon(Arg.Any <IHttpClientProvider>(), mockContext);
            mockSession3Finished.Received(0).UpdateServerConfiguration(Arg.Any <IServerConfiguration>());
            mockSession3Finished.Received(0).DecreaseNumRemainingSessionRequests();

            // verify no interactions with second finished session
            Assert.That(mockSession4Finished.ReceivedCalls(), Is.Empty);

            // verify no interactions with open sessions
            Assert.That(mockSession1Open.ReceivedCalls(), Is.Empty);
            Assert.That(mockSession2Open.ReceivedCalls(), Is.Empty);

            _ = mockContext.Received(1).GetAllFinishedAndConfiguredSessions();
            mockContext.Received(0).RemoveSession(Arg.Any <ISessionInternals>());

            Assert.That(captureState, Is.Not.Null);
            mockContext.Received(1).NextState = captureState;
            Assert.That(captureState.SleepTimeInMilliseconds, Is.EqualTo(sleepTime));
        }
        public void NewSessionRequestsAreAbortedWhenTooManyRequestsResponseIsReceived()
        {
            // given
            const int sleepTime = 6543;
            var       target    = new BeaconSendingCaptureOnState();

            var statusResponse = Substitute.For <IStatusResponse>();

            statusResponse.ResponseCode.Returns(StatusResponse.HttpTooManyRequests);
            statusResponse.IsErroneousResponse.Returns(true);
            statusResponse.GetRetryAfterInMilliseconds().Returns(sleepTime);

            var mockClient = Substitute.For <IHttpClient>();

            mockClient.SendNewSessionRequest(Arg.Any <IAdditionalQueryParameters>()).Returns(statusResponse);
            mockContext.GetHttpClient().Returns(mockClient);
            mockContext.GetAllNotConfiguredSessions()
            .Returns(new List <ISessionInternals> {
                mockSession5New, mockSession6New
            });

            mockSession5New.CanSendNewSessionRequest.Returns(true);
            mockSession6New.CanSendNewSessionRequest.Returns(true);

            BeaconSendingCaptureOffState capturedState = null;

            mockContext.NextState = Arg.Do <BeaconSendingCaptureOffState>(x => capturedState = x);

            // when
            target.Execute(mockContext);

            // verify for first new sessions a new session request has been made
            mockClient.Received(1).SendNewSessionRequest(mockContext);

            // verify no changes on first
            _ = mockSession5New.Received(1).CanSendNewSessionRequest;
            mockSession5New.Received(0).UpdateServerConfiguration(Arg.Any <IServerConfiguration>());
            mockSession5New.Received(0).DecreaseNumRemainingSessionRequests();

            // verify second new session is not used at all
            Assert.That(mockSession6New.ReceivedCalls(), Is.Empty);

            // ensure also transition to CaptureOffState
            Assert.That(capturedState, Is.Not.Null);
            mockContext.Received(1).NextState = capturedState;
            Assert.That(capturedState.SleepTimeInMilliseconds, Is.EqualTo(sleepTime));
        }