public void TestSingle()
        {
            var apiConnection = new MainApiConnection(_apiConnectionSettings)
            {
                HttpClient = Substitute.For <IHttpClient>()
            };

            AddResponseToClient(apiConnection.HttpClient, "http://main_server/path?query",
                                CreateSimpleWebResponse("test"));

            var apiResponse = apiConnection.GetResponse("/path", "query", CancellationToken.Empty);

            Assert.AreEqual("test", apiResponse.Body);
        }
        public void TestCustomPort()
        {
            _apiConnectionSettings.MainServer.Port = 81;
            var apiConnection = new MainApiConnection(_apiConnectionSettings)
            {
                HttpClient = Substitute.For <IHttpClient>()
            };

            AddResponseToClient(apiConnection.HttpClient, "http://main_server:81/path?query",
                                CreateSimpleWebResponse("test"));

            var apiResponse = apiConnection.GetResponse("/path", "query");

            Assert.AreEqual("test", apiResponse.Body);
        }
        // ReSharper disable once InconsistentNaming
        public void Test4XXException()
        {
            // any 4XX error from the main server should throw an ApiResponseException
            var apiConnection = new MainApiConnection(_apiConnectionSettings)
            {
                HttpClient = Substitute.For <IHttpClient>()
            };

            AddResponseToClient(apiConnection.HttpClient, "http://main_server/path?query",
                                CreateErrorResponse(HttpStatusCode.NotFound));

            Assert.Throws(
                Is.TypeOf <ApiResponseException>(),
                () => apiConnection.GetResponse("/path", "query", CancellationToken.Empty)
                );
        }
        // ReSharper disable once InconsistentNaming
        public void Test5XXException()
        {
            // any 5XX error from the main server should throw an ApiConnectionException
            var apiConnection = new MainApiConnection(_apiConnectionSettings)
            {
                HttpClient = Substitute.For <IHttpClient>()
            };

            AddResponseToClient(apiConnection.HttpClient, "http://main_server/path?query",
                                CreateErrorResponse(HttpStatusCode.InternalServerError));

            var exception = (ApiConnectionException)Assert.Throws(
                Is.TypeOf <ApiConnectionException>(),
                () => apiConnection.GetResponse("/path", "query", CancellationToken.Empty)
                );

            Assert.IsTrue(exception.MainServerExceptions.Any());
            Assert.IsTrue(exception.CacheServersExceptions.Any());
        }
        public void TestApiCache500()
        {
            // test how connection will behave on 500 error
            var apiConnection = new MainApiConnection(_apiConnectionSettings)
            {
                HttpClient = Substitute.For <IHttpClient>()
            };

            // main
            AddResponseToClient(apiConnection.HttpClient, "http://main_server/path?query",
                                CreateErrorResponse(HttpStatusCode.InternalServerError));

            // cache
            AddResponseToClient(apiConnection.HttpClient, "http://cache_server_1/path?query",
                                CreateSimpleWebResponse("test"));

            var apiResponse = apiConnection.GetResponse("/path", "query", CancellationToken.Empty);

            Assert.AreEqual("test", apiResponse.Body);
        }
        // ReSharper disable once InconsistentNaming
        public void TestCache4XXException()
        {
            var apiConnection = new MainApiConnection(_apiConnectionSettings)
            {
                HttpClient = Substitute.For <IHttpClient>()
            };

            AddThrowToClient(apiConnection.HttpClient, "http://main_server/path?query",
                             new WebException("main-server"));
            AddThrowToClient(apiConnection.HttpClient, "http://cache_server_1/path?query",
                             new WebException("cache-server-1"));
            AddResponseToClient(apiConnection.HttpClient, "http://cache_server_2/path?query",
                                CreateErrorResponse(HttpStatusCode.NotFound));

            var exception = (ApiConnectionException)Assert.Throws(
                Is.TypeOf <ApiConnectionException>(),
                () => apiConnection.GetResponse("/path", "query", CancellationToken.Empty)
                );

            Assert.IsTrue(exception.MainServerExceptions.All(e => e.Message == "main-server"));
            Assert.IsTrue(exception.CacheServersExceptions.Any(e => e.Message == "cache-server-1"));
        }
        public void TestExceptions()
        {
            var apiConnection = new MainApiConnection(_apiConnectionSettings)
            {
                HttpClient = Substitute.For <IHttpClient>()
            };

            AddThrowToClient(apiConnection.HttpClient, "http://main_server/path?query",
                             new WebException("main-server"));
            AddThrowToClient(apiConnection.HttpClient, "http://cache_server_1/path?query",
                             new WebException("cache-server-1"));
            AddThrowToClient(apiConnection.HttpClient, "http://cache_server_2/path?query",
                             new WebException("cache-server-2"));

            var exception = (ApiConnectionException)Assert.Throws(
                Is.TypeOf <ApiConnectionException>(),
                () => apiConnection.GetResponse("/path", "query")
                );

            Assert.IsTrue(exception.MainServerExceptions.All(e => e.Message == "main-server"));
            Assert.IsTrue(exception.CacheServersExceptions.All(e =>
                                                               e.Message == "cache-server-1" || e.Message == "cache-server-2"));
        }
        public void TestErrorOnCache()
        {
            // Any code different than 200 on API cache should skip it
            var apiConnection = new MainApiConnection(_apiConnectionSettings)
            {
                HttpClient = Substitute.For <IHttpClient>()
            };

            // main
            AddResponseToClient(apiConnection.HttpClient, "http://main_server/path?query",
                                CreateErrorResponse(HttpStatusCode.BadGateway));

            // cache1
            AddResponseToClient(apiConnection.HttpClient, "http://cache_server_1/path?query",
                                CreateErrorResponse(HttpStatusCode.NotFound));

            // cache2
            AddResponseToClient(apiConnection.HttpClient, "http://cache_server_2/path?query",
                                CreateSimpleWebResponse("test"));

            var apiResponse = apiConnection.GetResponse("/path", "query", CancellationToken.Empty);

            Assert.AreEqual("test", apiResponse.Body);
        }