Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add post functionality to parliament-ruby #79

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .ruby-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.3.1
2.4.1
54 changes: 50 additions & 4 deletions lib/parliament/request/base_request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,52 @@ def get(params: nil)
build_response(net_response)
end

# Makes an HTTP POST request and process results into a response.
#
# @example HTTP POST request
# request = Parliament::Request::BaseRequest.new(base_url: 'http://example.com/people/123', headers: {'Content': 'application/json', 'Accept': 'application/json'})

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line is too long. [171/120]

#
# # url: http://example.com/people/123
#
# response = request.post(body: {}.to_json) #=> #<Parliament::Response::BaseResponse ...>
#
# @example HTTP POST request with URI encoded form values
# request = Parliament::Request::BaseRequest.new(base_url: 'http://example.com/people/current', headers: {'Content': 'application/json', 'Accept': 'application/json'})

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line is too long. [175/120]

#
# # url: http://example.com/people/current?limit=10&page=4&lang=en-gb
#
# response = request.post({ limit: 10, page: 4, lang: 'en-gb' }, body: {}.to_json) #=> #<Parliament::Response::BaseResponse ...>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line is too long. [136/120]

#
# @raise [Parliament::ServerError] when the server responds with a 5xx status code.
# @raise [Parliament::ClientError] when the server responds with a 4xx status code.
# @raise [Parliament::NoContentResponseError] when the response body is empty.
#
# @param [Hash] params (optional) additional URI encoded form values to be added to the URI.
# @param [String] body (optional) body of the post request.
#
# @return [Parliament::Response::BaseResponse] a Parliament::Response::BaseResponse object containing all of the data returned from the URL.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line is too long. [146/120]

def post(params: nil, body: nil)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assignment Branch Condition size for post is too high. [21.91/15]
Method has too many lines. [13/10]

@query_params = @query_params.merge(params) unless params.nil?

endpoint_uri = URI.parse(query_url)
endpoint_uri.query = URI.encode_www_form(@query_params.to_a) unless @query_params.empty?

http = Net::HTTP.new(endpoint_uri.host, endpoint_uri.port)
http.use_ssl = true if endpoint_uri.scheme == 'https'

net_response = http.start do |h|
api_request = Net::HTTP::Post.new(endpoint_uri.request_uri)
add_headers(api_request)
api_request.body = body unless body.nil?

h.request api_request
end

handle_errors(net_response)

build_response(net_response)
end

private

# @attr [String] base_url the base url of our api. (expected: http://example.com - without the trailing slash).
Expand Down Expand Up @@ -133,17 +179,17 @@ def add_headers(request)
end
end

def handle_errors(response)
case response
def handle_errors(net_response)
case net_response
when Net::HTTPOK # 2xx Status
exception_class = Parliament::NoContentResponseError if response['Content-Length'] == '0'
exception_class = Parliament::NoContentResponseError if net_response['Content-Length'] == '0'
when Net::HTTPClientError # 4xx Status
exception_class = Parliament::ClientError
when Net::HTTPServerError # 5xx Status
exception_class = Parliament::ServerError
end

raise exception_class.new(query_url, response) if exception_class
raise exception_class.new(query_url, net_response) if exception_class
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/parliament/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module Parliament
VERSION = '0.8.0'.freeze
VERSION = '0.9.0'.freeze
end
94 changes: 94 additions & 0 deletions spec/parliament/request/base_request_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,98 @@
end
end
end

describe '#post' do
context 'it returns a status code of 200' do
let(:base_response) { Parliament::Request::BaseRequest.new(base_url: 'http://localhost:3030/parties/current').post }

it 'returns a Parliament::Response::BaseResponse' do
stub_request(:post, 'http://localhost:3030/parties/current').to_return(status: 200, body: '{}')

expect(base_response).to be_a(Parliament::Response::BaseResponse)
end

it 'raises a Parliament::NoContentError if there is no content' do
stub_request(:post, 'http://localhost:3030/parties/lookup/mnisId/abc').to_return(status: [200, 'OK'], headers: { 'Content-Length' => 0 })

expect {
Parliament::Request::BaseRequest.new(base_url: 'http://localhost:3030/parties/lookup/mnisId/abc').post
}.to raise_error(Parliament::NoContentResponseError, '200 HTTP status code received from: http://localhost:3030/parties/lookup/mnisId/abc - OK')
end
end

context 'it returns a status code in either the 400 or 500 range' do
it 'and raises client error when status is within the 400 range' do
stub_request(:post, 'http://localhost:3030/dogs/cats').to_return(status: 404)

expect {
Parliament::Request::BaseRequest.new(base_url: 'http://localhost:3030/dogs/cats').post
}.to raise_error(Parliament::ClientError, '404 HTTP status code received from: http://localhost:3030/dogs/cats - ')
end

it 'and raises server error when status is within the 500 range' do
stub_request(:post, 'http://localhost:3030/parties/current').to_return(status: 500)

expect {
Parliament::Request::BaseRequest.new(base_url: 'http://localhost:3030/parties/current').post
}.to raise_error(Parliament::ServerError, '500 HTTP status code received from: http://localhost:3030/parties/current - ')
end
end

context 'it accepts query parameters' do
it 'sets the query parameters correctly when passed in' do
stub_request(:post, 'http://localhost:3030/people/lookup?id=3898&source=mnisId').to_return(status: 200)

Parliament::Request::BaseRequest.new(base_url: 'http://localhost:3030/people/lookup').post(params: { source: 'mnisId', id: '3898' })

expect(WebMock).to have_requested(:post, 'http://localhost:3030/people/lookup?id=3898&source=mnisId').
with(:headers => {'Accept'=>['*/*', 'application/n-triples'], 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'}).once
end

it 'merges passed in params with @query_params' do
stub_request(:post, 'http://localhost:3030/people/lookup?test=true&id=3898&source=mnisId').to_return(status: 200)

request = Parliament::Request::BaseRequest.new(base_url: 'http://localhost:3030/people/lookup')
request.instance_variable_set(:@query_params, { test: true })
request.post(params: { source: 'mnisId', id: '3898' })

expect(WebMock).to have_requested(:post, 'http://localhost:3030/people/lookup?test=true&id=3898&source=mnisId').
with(:headers => {'Accept'=>['*/*', 'application/n-triples'], 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'}).once
end
end

context 'it accepts headers' do
before :each do
stub_request(:post, 'http://localhost:3030/people').to_return(status: 200)
end

it 'sets the header correctly when passed in' do
Parliament::Request::BaseRequest.headers = { 'Access-Token'=>'Test-Token' }
Parliament::Request::BaseRequest.new(base_url: 'http://localhost:3030/people').post

expect(WebMock).to have_requested(:post, 'http://localhost:3030/people').
with(:headers => {'Accept'=>['*/*', 'application/n-triples'], 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Access-Token'=>'Test-Token', 'User-Agent'=>'Ruby'}).once
end

it 'sets the default headers only when no additional headers passed' do
Parliament::Request::BaseRequest.new(base_url: 'http://localhost:3030/people').post

expect(WebMock).to have_requested(:post, 'http://localhost:3030/people').
with(:headers => {'Accept'=>['*/*', 'application/n-triples'], 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'}).once
end
end

context 'it accepts a body' do
before :each do
stub_request(:post, 'http://localhost:3030/people').to_return(status: 200)
end

it 'sends the body as passed' do
Parliament::Request::BaseRequest.new(base_url: 'http://localhost:3030/people').post(body: { foo: 'bar', test: true, number: 1 }.to_json)

expect(WebMock).to have_requested(:post, 'http://localhost:3030/people').
with(:body => '{"foo":"bar","test":true,"number":1}').once
end
end
end
end