public void Should_stop_when_not_reusable_content_producer_gets_used()
        {
            var contentProducer = Substitute.For <IContentProducer>();

            contentProducer.IsReusable.Returns(false);
            var content = new UserContentProducerWrapper(contentProducer);

            request = Request.Post("foo/bar").WithContent(content);

            var task = strategy.SendAsync(request, parameters, sender, Budget.Infinite, replicas, replicas.Length, token);

            content.ProduceAsync(Stream.Null, CancellationToken.None).Wait();

            CompleteForkingDelay();

            task.IsCompleted.Should().BeFalse();

            CompleteRequest(replicas.First(), ResponseVerdict.Reject);

            task.IsCompleted.Should().BeTrue();

            sender.ReceivedCalls().Should().HaveCount(1);
            delaysProvider.ReceivedCalls().Should().HaveCount(1);
            delaysPlanner.ReceivedCalls().Should().HaveCount(1);
        }
        public void Should_make_retry_request_when_reusable_content_producer_is_already_used()
        {
            var contentProducer = Substitute.For <IContentProducer>();

            contentProducer.IsReusable.Returns(true);

            var content = new UserContentProducerWrapper(contentProducer);

            request = request.WithContent(content);

            content.ProduceAsync(Stream.Null, CancellationToken.None).Wait();

            var task = strategy.SendAsync(request, parameters, sender, Budget.Infinite, replicas, replicas.Length, token);

            content.ProduceAsync(Stream.Null, CancellationToken.None).Wait();

            foreach (var replica in replicas)
            {
                CompleteRequest(replica, ResponseVerdict.Reject);
            }

            task.IsCompleted.Should().BeTrue();

            sender.ReceivedCalls().Should().HaveCount(replicas.Length);
        }
        public void WasUsed_property_should_return_true_after_first_content_producing_when_underlying_content_not_reusable()
        {
            var contentProducer = Substitute.For <IContentProducer>();
            var content         = new UserContentProducerWrapper(contentProducer);

            content.ProduceAsync(Stream.Null, CancellationToken.None).Wait();
            content.WasUsed.Should().BeTrue();
        }
        public void Length_should_return_underlying_content_length(long value)
        {
            var contentProducer = Substitute.For <IContentProducer>();

            contentProducer.Length.Returns(value);
            var content = new UserContentProducerWrapper(contentProducer);

            content.Length.Should().Be(value);
        }
        public void WasUsed_property_should_always_initially_return_false([Values] bool contentReusable)
        {
            var contentProducer = Substitute.For <IContentProducer>();
            var content         = new UserContentProducerWrapper(contentProducer);

            contentProducer.IsReusable.Returns(contentReusable);

            content.WasUsed.Should().BeFalse();
        }
        public void ProduceAsync_should_call_underlying_content_method()
        {
            var contentProducer = Substitute.For <IContentProducer>();
            var content         = new UserContentProducerWrapper(contentProducer);
            var stream          = Substitute.For <Stream>();

            content.ProduceAsync(stream, CancellationToken.None).Wait();

            contentProducer.Received(1).ProduceAsync(Arg.Is <Stream>(x => ReferenceEquals(x, stream)), Arg.Any <CancellationToken>());
        }
        public void IsReusable_should_return_underlying_is_reusable([Values] bool value)
        {
            var contentProducer = Substitute.For <IContentProducer>();

            contentProducer.IsReusable.Returns(value);
            var content = new UserContentProducerWrapper(contentProducer);

            contentProducer.IsReusable.Returns(value);

            content.IsReusable.Should().Be(value);
        }
        public void ProduceAsync_should_throw_after_first_call_when_underlying_content_not_reusable()
        {
            var contentProducer = Substitute.For <IContentProducer>();
            var content         = new UserContentProducerWrapper(contentProducer);

            Action action = () => content.ProduceAsync(Stream.Null, CancellationToken.None);

            action();

            action.Should().ThrowExactly <ContentAlreadyUsedException>().Which.ShouldBePrinted();
        }
        public void IsReusable_should_be_cached_when_initially_false()
        {
            var contentProducer = Substitute.For <IContentProducer>();

            contentProducer.IsReusable.Returns(false);
            var content = new UserContentProducerWrapper(contentProducer);

            content.ProduceAsync(Stream.Null, CancellationToken.None).Wait();

            contentProducer.IsReusable.Returns(true);

            new Action(() => content.ProduceAsync(Stream.Null, CancellationToken.None).Wait()).Should().ThrowExactly <ContentAlreadyUsedException>().Which.ShouldBePrinted();
        }
        public void Should_send_requests_when_reusable_content_producer_is_already_used()
        {
            var contentProducer = Substitute.For <IContentProducer>();

            contentProducer.IsReusable.Returns(true);

            var content = new UserContentProducerWrapper(contentProducer);

            content.ProduceAsync(Stream.Null, CancellationToken.None).Wait();

            request = Request.Post("foo/bar").WithContent(content);

            Send(Budget.Infinite);

            sender.ReceivedCalls().Should().HaveCount(3);
        }
        public void Should_not_retry_if_not_reusable_content_producer_has_already_been_used()
        {
            var contentProducer = Substitute.For <IContentProducer>();

            contentProducer.IsReusable.Returns(false);

            var content = new UserContentProducerWrapper(contentProducer);

            content.ProduceAsync(Stream.Null, CancellationToken.None).Wait();

            context.Request.Returns(request.WithContent(content));

            Execute().Should().BeSameAs(result);

            nextModuleCalls.Should().Be(1);
        }
        public void Should_fork_when_reusable_content_producer_gets_used()
        {
            var contentProducer = Substitute.For <IContentProducer>();

            contentProducer.IsReusable.Returns(true);
            var content = new UserContentProducerWrapper(contentProducer);

            request = Request.Post("foo/bar").WithContent(content);

            strategy.SendAsync(request, parameters, sender, Budget.Infinite, replicas, replicas.Length, token);

            content.ProduceAsync(Stream.Null, CancellationToken.None).Wait();

            CompleteForkingDelay();
            CompleteForkingDelay();

            sender.ReceivedCalls().Should().HaveCount(3);
        }
        public void IsReusable_should_be_cached_when_initially_true()
        {
            var contentProducer = Substitute.For <IContentProducer>();

            contentProducer.IsReusable.Returns(true);
            var content = new UserContentProducerWrapper(contentProducer);

            content.ProduceAsync(Stream.Null, CancellationToken.None).Wait();

            contentProducer.IsReusable.Returns(false);

            new Action(
                () =>
            {
                content.ProduceAsync(Stream.Null, CancellationToken.None).Wait();
                content.ProduceAsync(Stream.Null, CancellationToken.None).Wait();
                content.ProduceAsync(Stream.Null, CancellationToken.None).Wait();
            })
            .Should()
            .NotThrow();
        }