Skip to content

Commit

Permalink
improve: Add http_timeout for RestClient
Browse files Browse the repository at this point in the history
  • Loading branch information
jylamont committed Apr 17, 2024
1 parent 5cad5d2 commit a3dd975
Show file tree
Hide file tree
Showing 20 changed files with 269 additions and 112 deletions.
2 changes: 2 additions & 0 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ Vero::App.init do |config|
config.api_key = "Your Development API key goes here"
config.secret = "Your Development API secret goes here"
end

config.http_timeout = 30 # default timeout per API request is set to 60 (seconds)
end
```

Expand Down
46 changes: 40 additions & 6 deletions lib/vero/api/base_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ module Vero
module Api
module Workers
class BaseAPI
DEFAULT_API_TIMEOUT = 60
ALLOWED_HTTP_METHODS = %i[post put].freeze

attr_accessor :domain
attr_reader :options

Expand All @@ -26,7 +29,13 @@ def perform
end

def options=(val)
@options = options_with_symbolized_keys(val)
new_options = options_with_symbolized_keys(val)

if (extra_config = new_options.delete(:_config)) && extra_config.is_a?(Hash)
@http_timeout = extra_config[:http_timeout]
end

@options = new_options
end

protected
Expand All @@ -45,6 +54,10 @@ def url
"#{@domain}/api/v2/#{api_url}"
end

def http_method
raise NotImplementedError
end

def api_url
raise NotImplementedError
end
Expand All @@ -53,14 +66,35 @@ def validate!
raise "#{self.class.name}#validate! should be overridden"
end

def request; end
def request
do_request(http_method, url, @options)
end

def do_request(method, a_url, params)
raise ArgumentError, ":method must be one of the follow: #{ALLOWED_HTTP_METHODS.join(', ')}" unless ALLOWED_HTTP_METHODS.include?(method)

rest_client_args = {
method: method,
url: a_url,
timeout: http_timeout
}

if method == :get
rest_client_args.merge!(headers: { params: params })
else
rest_client_args.merge!(payload: JSON.dump(params), headers: { content_type: :json, accept: :json })
end

def request_content_type
{ content_type: :json, accept: :json }
RestClient::Request.execute(
method: method,
url: a_url,
headers: { params: params },
timeout: http_timeout
)
end

def request_params_as_json
JSON.dump(@options)
def http_timeout
@http_timeout || DEFAULT_API_TIMEOUT
end

def options_with_symbolized_keys(val)
Expand Down
4 changes: 2 additions & 2 deletions lib/vero/api/events/track_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ def api_url
'events/track.json'
end

def request
RestClient.post(url, request_params_as_json, request_content_type)
def http_method
:post
end

def validate!
Expand Down
4 changes: 2 additions & 2 deletions lib/vero/api/users/edit_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ def api_url
'users/edit.json'
end

def request
RestClient.put(url, request_params_as_json, request_content_type)
def http_method
:put
end

def validate!
Expand Down
4 changes: 2 additions & 2 deletions lib/vero/api/users/edit_tags_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ def api_url
'users/tags/edit.json'
end

def request
RestClient.put(url, request_params_as_json, request_content_type)
def http_method
:put
end

def validate!
Expand Down
4 changes: 2 additions & 2 deletions lib/vero/api/users/reidentify_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ def api_url
'users/reidentify.json'
end

def request
RestClient.put(url, request_params_as_json, request_content_type)
def http_method
:put
end

def validate!
Expand Down
4 changes: 2 additions & 2 deletions lib/vero/api/users/resubscribe_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ def api_url
'users/resubscribe.json'
end

def request
RestClient.post(url, @options)
def http_method
:post
end

def validate!
Expand Down
4 changes: 2 additions & 2 deletions lib/vero/api/users/track_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ def api_url
'users/track.json'
end

def request
RestClient.post(url, request_params_as_json, request_content_type)
def http_method
:post
end

def validate!
Expand Down
4 changes: 2 additions & 2 deletions lib/vero/api/users/unsubscribe_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ def api_url
'users/unsubscribe.json'
end

def request
RestClient.post(url, @options)
def http_method
:post
end

def validate!
Expand Down
18 changes: 10 additions & 8 deletions lib/vero/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
module Vero
class Config
attr_writer :domain
attr_accessor :api_key, :secret, :development_mode, :async, :disabled, :logging
attr_accessor :api_key, :secret, :development_mode, :async, :disabled, :logging, :http_timeout

def self.available_attributes
%i[api_key secret development_mode async disabled logging domain]
%i[api_key secret development_mode async disabled logging domain http_timeout]
end

def initialize
Expand All @@ -22,7 +22,8 @@ def config_params
def request_params
{
auth_token: auth_token,
development_mode: development_mode
development_mode: development_mode,
_config: { http_timeout: http_timeout }
}.compact
end

Expand Down Expand Up @@ -53,12 +54,13 @@ def disable_requests!
end

def reset!
self.disabled = false
self.disabled = false
self.development_mode = false
self.async = true
self.logging = false
self.api_key = nil
self.secret = nil
self.async = true
self.logging = false
self.api_key = nil
self.secret = nil
self.http_timeout = nil
end

def update_attributes(attributes = {})
Expand Down
55 changes: 42 additions & 13 deletions spec/lib/api/events/track_api_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,15 @@
require 'spec_helper'

describe Vero::Api::Workers::Events::TrackAPI do
subject { Vero::Api::Workers::Events::TrackAPI.new('https://api.getvero.com', { auth_token: 'abcd', identity: { email: '[email protected]' }, event_name: 'test_event' }) }
let(:payload) do
{
auth_token: 'abcd',
identity: { email: '[email protected]' },
event_name: 'test_event'
}
end

subject { Vero::Api::Workers::Events::TrackAPI.new('https://api.getvero.com', payload) }

it_behaves_like 'a Vero wrapper' do
let(:end_point) { '/api/v2/events/track.json' }
Expand All @@ -16,22 +24,21 @@
subject.options = options
expect { subject.send(:validate!) }.to raise_error(ArgumentError)

options = { auth_token: 'abcd', identity: { email: '[email protected]' }, event_name: 'test_event' }
subject.options = options
subject.options = payload
expect { subject.send(:validate!) }.to_not raise_error
end

it 'should raise an error if data is not either nil or a Hash' do
options = { auth_token: 'abcd', identity: { email: '[email protected]' }, event_name: 'test_event', data: [] }
subject.options = options
payload[:data] = []
subject.options = payload
expect { subject.send(:validate!) }.to raise_error(ArgumentError)

options = { auth_token: 'abcd', identity: { email: '[email protected]' }, event_name: 'test_event', data: nil }
subject.options = options
payload[:data] = nil
subject.options = payload
expect { subject.send(:validate!) }.to_not raise_error

options = { auth_token: 'abcd', identity: { email: '[email protected]' }, event_name: 'test_event', data: {} }
subject.options = options
payload[:data] = {}
subject.options = payload
expect { subject.send(:validate!) }.to_not raise_error
end

Expand All @@ -49,18 +56,40 @@

describe :request do
it 'should send a JSON request to the Vero API' do
expect(RestClient).to receive(:post).with('https://api.getvero.com/api/v2/events/track.json', { auth_token: 'abcd', identity: { email: '[email protected]' }, event_name: 'test_event' }.to_json, { content_type: :json, accept: :json })
allow(RestClient).to receive(:post).and_return(200)
expect(RestClient::Request).to(
receive(:execute).with(
method: :post,
url: 'https://api.getvero.com/api/v2/events/track.json',
payload: { auth_token: 'abcd', identity: { email: '[email protected]' }, event_name: 'test_event' }.to_json,
headers: { content_type: :json, accept: :json },
timeout: 60
)
)
allow(RestClient::Request).to receive(:execute).and_return(200)
subject.send(:request)
end

it 'should allow configurable timeout' do
expect(RestClient::Request).to(
receive(:execute).with(
method: :post,
url: 'https://api.getvero.com/api/v2/events/track.json',
payload: { auth_token: 'abcd', identity: { email: '[email protected]' }, event_name: 'test_event' }.to_json,
headers: { content_type: :json, accept: :json },
timeout: 30
)
)
allow(RestClient::Request).to receive(:execute).and_return(200)
Vero::Api::Workers::Events::TrackAPI.new('https://api.getvero.com', payload.merge(_config: { http_timeout: 30 })).send(:request)
end
end
end

describe 'integration test' do
it 'should not raise any errors' do
obj = Vero::Api::Workers::Events::TrackAPI.new('https://api.getvero.com', { auth_token: 'abcd', identity: { email: '[email protected]' }, event_name: 'test_event' })
obj = Vero::Api::Workers::Events::TrackAPI.new('https://api.getvero.com', payload)

allow(RestClient).to receive(:post).and_return(200)
allow(RestClient::Request).to receive(:execute).and_return(200)
expect { obj.perform }.to_not raise_error
end
end
Expand Down
24 changes: 20 additions & 4 deletions spec/lib/api/users/edit_api_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,15 @@
require 'spec_helper'

describe Vero::Api::Workers::Users::EditAPI do
subject { Vero::Api::Workers::Users::EditAPI.new('https://api.getvero.com', { auth_token: 'abcd', email: '[email protected]', changes: { email: '[email protected]' } }) }
let(:payload) do
{
auth_token: 'abcd',
email: '[email protected]',
changes: { email: '[email protected]' }
}
end

subject { Vero::Api::Workers::Users::EditAPI.new('https://api.getvero.com', payload) }

it_behaves_like 'a Vero wrapper' do
let(:end_point) { '/api/v2/users/edit.json' }
Expand All @@ -19,15 +27,23 @@

describe :request do
it 'should send a request to the Vero API' do
expect(RestClient).to receive(:put).with('https://api.getvero.com/api/v2/users/edit.json', { auth_token: 'abcd', email: '[email protected]', changes: { email: '[email protected]' } }.to_json, { content_type: :json, accept: :json })
allow(RestClient).to receive(:put).and_return(200)
expect(RestClient::Request).to(
receive(:execute).with(
method: :put,
url: 'https://api.getvero.com/api/v2/users/edit.json',
payload: { auth_token: 'abcd', email: '[email protected]', changes: { email: '[email protected]' } }.to_json,
headers: { content_type: :json, accept: :json },
timeout: 60
)
)
allow(RestClient::Request).to receive(:execute).and_return(200)
subject.send(:request)
end
end

describe 'integration test' do
it 'should not raise any errors' do
allow(RestClient).to receive(:put).and_return(200)
allow(RestClient::Request).to receive(:execute).and_return(200)
expect { subject.perform }.to_not raise_error
end
end
Expand Down
Loading

0 comments on commit a3dd975

Please sign in to comment.