public void CanHandle_Whatever_TrueReturned(int failedAttempts)
        {
            var rawMessage = new MemoryStream();
            var headers    = new[]
            {
                new MessageHeader(
                    DefaultMessageHeaders.FailedAttempts,
                    failedAttempts.ToString(CultureInfo.InvariantCulture))
            };

            var testPolicy = new TestErrorPolicy();

            var chain = new ErrorPolicyChain(
                new RetryErrorPolicy().MaxFailedAttempts(3),
                testPolicy)
                        .Build(_serviceProvider);

            var result = chain.CanHandle(
                ConsumerPipelineContextHelper.CreateSubstitute(
                    new InboundEnvelope(
                        rawMessage,
                        headers,
                        new TestOffset(),
                        TestConsumerEndpoint.GetDefault(),
                        TestConsumerEndpoint.GetDefault().Name)),
                new InvalidOperationException("test"));

            result.Should().BeTrue();
        }
        public async Task HandleErrorAsync_RetryWithMaxFailedAttempts_AppliedAccordingToMaxFailedAttempts(int failedAttempts)
        {
            var rawMessage = new MemoryStream();
            var headers    = new[]
            {
                new MessageHeader(
                    DefaultMessageHeaders.FailedAttempts,
                    failedAttempts.ToString(CultureInfo.InvariantCulture))
            };

            var testPolicy = new TestErrorPolicy();

            var chain = new ErrorPolicyChain(
                new[]
            {
                new RetryErrorPolicy().MaxFailedAttempts(3),
                testPolicy
            })
                        .Build(_serviceProvider);

            await chain.HandleErrorAsync(
                ConsumerPipelineContextHelper.CreateSubstitute(
                    new InboundEnvelope(
                        rawMessage,
                        headers,
                        new TestOffset(),
                        TestConsumerEndpoint.GetDefault(),
                        TestConsumerEndpoint.GetDefault().Name)),
                new InvalidOperationException("test"));

            testPolicy.Applied.Should().Be(failedAttempts > 3);
        }
        public async Task HandleErrorAsync_MultiplePoliciesWithMaxFailedAttempts_CorrectPolicyApplied(
            int failedAttempts,
            int expectedAppliedPolicy)
        {
            var rawMessage = new MemoryStream();
            var headers    = new[]
            {
                new MessageHeader(
                    DefaultMessageHeaders.FailedAttempts,
                    failedAttempts.ToString(CultureInfo.InvariantCulture))
            };

            var policies = new[]
            {
                new TestErrorPolicy().MaxFailedAttempts(2),
                new TestErrorPolicy().MaxFailedAttempts(2),
                new TestErrorPolicy().MaxFailedAttempts(2)
            };

            var chain = new ErrorPolicyChain(policies)
                        .Build(_serviceProvider);

            await chain.HandleErrorAsync(
                ConsumerPipelineContextHelper.CreateSubstitute(
                    new InboundEnvelope(
                        rawMessage,
                        headers,
                        new TestOffset(),
                        TestConsumerEndpoint.GetDefault(),
                        TestConsumerEndpoint.GetDefault().Name)),
                new InvalidOperationException("test"));

            for (var i = 0; i < policies.Length; i++)
            {
                policies[i].As <TestErrorPolicy>().Applied.Should().Be(i == expectedAppliedPolicy);
            }
        }