protected TestCase()
        {
            Client = new MockClient();

            BaseURL  = TestBaseURL;
            User     = TestUser;
            Password = TestPassword;
        }
        public const string TestUser = null; // "<your-api-key-here>";

        #endregion Fields

        #region Constructors

        protected TestCase()
        {
            Client = new MockClient();

            BaseURL = TestBaseURL;
            User = TestUser;
            Password = TestPassword;
        }
        public void TestExecuteThrowsFromResponse()
        {
            var client = new MockClient
            {
                Exception = null,
                Response  = new Response(500, "{\"error\":{\"message\":\"Something went wrong\"}}")
            };

            Assert.ThrowsAsync <ServiceException>(
                () => client.Execute(HttpMethod.Get, "http://localhost/", null, null, null));
        }
        public void TestExecuteThrowsFromException()
        {
            var client = new MockClient
            {
                Exception = new ServiceException("Exception raised", null, null),
                Response  = null
            };

            Assert.ThrowsAsync <ServiceException>(
                () => client.Execute(HttpMethod.Get, "http://localhost/", null, null, null));
        }
        public async void TestExecuteThrowsFromResponse()
        {
            var client = new MockClient
            {
                Exception = null,
                Response = new Response(500, "{\"error\":{\"message\":\"Something went wrong\"}}")
            };

            var response = await client.Execute(HttpMethod.Get, "http://localhost/", null, null, null);
            Assert.NotNull(response);
            Assert.AreEqual(500, response.StatusCode);
            Assert.AreEqual("{\"error\":{\"message\":\"Something went wrong\"}}", response.GetBodyString());
        }
        public async void TestExecuteSuccess()
        {
            var client = new MockClient
            {
                Exception = null,
                Response = new Response(200, "{}")
            };

            var response = await client.Execute(HttpMethod.Get, "http://localhost/", null, null, null);
            Assert.NotNull(response);
            Assert.AreEqual(200, response.StatusCode);
            Assert.AreEqual("{}", response.GetBodyString());
        }
        public async Task TestExecuteSuccess()
        {
            var client = new MockClient
            {
                Exception = null,
                Response  = new Response(200, "{}")
            };

            var response = await client.Execute(HttpMethod.Get, "http://localhost/", null, null, null);

            Assert.NotNull(response);
            Assert.AreEqual(200, response.StatusCode);
            Assert.AreEqual("{}", response.GetBodyString());
        }
        public async Task TestExecuteSuccess()
        {
            var client = new MockClient
            {
                Exception = null,
                Response  = new Response(200, "{}")
            };


            IResponse response  = null;
            var       retries   = 0;
            var       successes = 0;
            var       failures  = 0;
            var       policy    = Policy.Handle <Exception>().WaitAndRetryAsync(
                6,
                attempt => TimeSpan.FromSeconds(0.1 * Math.Pow(2, attempt)),
                (exception, waitTime) => { retries++; }
                );

            try
            {
                await policy.ExecuteAsync(async() =>
                {
                    response = await client.Execute(HttpMethod.Get, "http://localhost/", null, null, null);
                    successes++;
                });
            }
            catch (Exception)
            {
                failures++;
            }

            Assert.NotNull(response);
            Assert.AreEqual(200, response.StatusCode);
            Assert.AreEqual("{}", response.GetBodyString());
            Assert.AreEqual(1, successes);
            Assert.AreEqual(0, failures);
            Assert.AreEqual(0, retries);
        }
        public async Task TestExecuteFailureWithRetriesAndExponentialBackoff()
        {
            // This test uses Polly to wrap a HTTP request/response cycle with
            // retries and exponential backoff. Polly is much more versatile,
            // and supports integration into HttpClientFactory as well.
            //
            // The main Polly repository can be found at https://github.com/App-vNext/Polly.
            // See advanced samples at https://github.com/App-vNext/Polly-Samples.
            //
            // Documentation is good. Just Google for "Polly HttpClient"

            var client = new MockClient
            {
                Exception = null,
                Response  = new Response(429, "{\"error\":{\"message\":\"Too many requests\"}}")
            };


            IResponse response  = null;
            var       retries   = 0;
            var       successes = 0;
            var       failures  = 0;
            var       policy    = Policy.Handle <Exception>().WaitAndRetryAsync(
                5,
                attempt => TimeSpan.FromSeconds(0.1 * Math.Pow(2, attempt)),
                (exception, waitTime) =>
            {
                Assert.NotNull(exception);
                Assert.IsInstanceOf <ServiceException>(exception);
                Assert.AreEqual("Too many requests", exception.Message);
                retries++;

                Console.WriteLine($"Retry {retries} with a wait time of {waitTime}");
            }
                );

            try
            {
                await policy.ExecuteAsync(async() =>
                {
                    response = await client.Execute(HttpMethod.Get, "http://localhost/", null, null, null);
                    successes++;
                });
            }
            catch (ServiceException ex)
            {
                Assert.NotNull(ex);
                Assert.IsInstanceOf <ServiceException>(ex);
                Assert.AreEqual(429, ex.StatusCode);
                Assert.AreEqual("Too many requests", ex.Message);
                failures++;
            }
            catch (Exception ex)
            {
                Assert.Fail("expected ServiceException, got {0}", ex);
            }

            Assert.Null(response);
            Assert.AreEqual(0, successes);
            Assert.AreEqual(1, failures);
            Assert.AreEqual(5, retries);
        }