diff --git a/app/services/http_client.rb b/app/services/http_client.rb index 3a1792e6..8331f7de 100644 --- a/app/services/http_client.rb +++ b/app/services/http_client.rb @@ -30,7 +30,6 @@ def setup_connection(base_url, timeout: 10, open_timeout: 5, retries: 3) end def get(endpoint, params = {}) - response = @connection.get(endpoint, params) - response.body if response.success? + @connection.get(endpoint, params).body end end \ No newline at end of file diff --git a/spec/services/http_client_spec.rb b/spec/services/http_client_spec.rb index bddcd050..b0480466 100644 --- a/spec/services/http_client_spec.rb +++ b/spec/services/http_client_spec.rb @@ -2,9 +2,16 @@ require_relative "../../app/services/http_client" describe HttpClient do - let(:base_url) { "https://example.com/api/" } + let(:base_url) { "https://example.com/" } + let(:endpoint) { "api/endpoint" } + let(:url) { "#{base_url}#{endpoint}" } + let(:params) { { param1: "value1", param2: "value2" } } + let(:response_body) { { "key" => "value" } } let(:retries) { 2 } + # Define the webmock stub for GET requests + let(:get_stub_request) { stub_request(:get, url).with(query: params) } + # dynamically create a class for testing let(:api_client_class) do Class.new do @@ -18,6 +25,8 @@ api_client.setup_connection(base_url, retries: retries) end + # including faraday configuration tests since business logic relies on it + # raising 4xx and 5xx errors, parsing JSON responses, and retrying requests describe "#setup_connection" do let(:connection) { api_client.instance_variable_get(:@connection) } let(:handlers) { connection.builder.handlers } @@ -44,20 +53,13 @@ end describe "#get" do - let(:endpoint) { "endpoint" } - let(:params) { { param1: "value1", param2: "value2" } } - let(:response_body) { { "key" => "value" } } - context "successful request" do it "parses and returns JSON response" do - # Stub the HTTP request using WebMock - stub_request(:get, "#{base_url}#{endpoint}") - .with(query: params) - .to_return( - status: 200, - body: response_body.to_json, # simulate a JSON response - headers: { "Content-Type": "application/json" } - ) + get_stub_request.to_return( + status: 200, + body: response_body.to_json, # simulate a JSON response + headers: { "Content-Type": "application/json" } # ensure JSON parsing + ) response = api_client.get(endpoint, params) expect(response).to eq(response_body) @@ -65,26 +67,27 @@ end context "handling errors" do - it "when a 4xx error occur, raises a Faraday::ClientError" do - stub_request(:get, "#{base_url}#{endpoint}") - .with(query: params) - .to_return(status: 404, body: 'Not Found') + it "raises a Faraday::ClientError after no retries for 4xx errors" do + get_stub_request.to_return(status: 403, body: 'Not Found') expect { api_client.get(endpoint, params) }.to raise_error(Faraday::ClientError) + + # no retries for client errors + expect(WebMock).to have_requested(:get, url) + .with(query: params) + .times(1) # initial request only end - it "when a 5xx error occurs, raises a Faraday::ServerError after retries" do - stub_request(:get, "#{base_url}#{endpoint}") - .with(query: params) - .to_return(status: 500, body: 'Internal Server Error') + it "raises a Faraday::ServerError after retries for 5xx errors" do + get_stub_request.to_return(status: 500, body: 'Internal Server Error') expect { api_client.get(endpoint, params) }.to raise_error(Faraday::ServerError) - expect(WebMock).to have_requested(:get, "#{base_url}#{endpoint}") + expect(WebMock).to have_requested(:get, url) .with(query: params) .times(1 + retries) # initial request + retries end @@ -92,15 +95,13 @@ context "when a request times out" do it "retries the request and raises Faraday::TimeoutError after retries" do - stub_request(:get, "#{base_url}#{endpoint}") - .with(query: params) - .to_timeout + get_stub_request.to_timeout expect { api_client.get(endpoint, params) }.to raise_error(Faraday::ConnectionFailed) # final error after retries - expect(WebMock).to have_requested(:get, "#{base_url}#{endpoint}") + expect(WebMock).to have_requested(:get, url) .with(query: params) .times(1 + retries) # initial request + retries end