Skip to content
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
11 changes: 7 additions & 4 deletions lib/mobilize_america_client/errors.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
module MobilizeAmericaClient
class NotFoundError < StandardError
class ClientError < StandardError
end

class UnauthorizedError < StandardError
class UnauthorizedError < ClientError
end

class ServerError < StandardError
class NotFoundError < ClientError
end

class ClientError < StandardError
class RateLimitedError < ClientError
end

class ServerError < StandardError
end
end
4 changes: 4 additions & 0 deletions lib/mobilize_america_client/request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ def request(method:, path:, params: {}, body: {})
raise MobilizeAmericaClient::UnauthorizedError, "Unauthorized: #{response.body}"
when 404
raise MobilizeAmericaClient::NotFoundError, "Not Found: #{response.body}"
when 429
retry_after_header = response.headers['Retry-After']
message = "Rate Limited (Retry-After #{retry_after_header}): #{response.body}"
raise MobilizeAmericaClient::RateLimitedError, message
when 400..499
raise MobilizeAmericaClient::ClientError, "Client Error (#{response.status}): #{response.body}"
when 500..599
Expand Down
23 changes: 10 additions & 13 deletions spec/client/attendances_spec.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'spec_helper'
require 'shared_examples/response_error_handling'

RSpec.describe MobilizeAmericaClient::Client::Attendances do
let(:api_key) { 'abcde-123456' }
Expand All @@ -13,20 +14,16 @@
let(:attendances_url) { "#{base_url}/organizations/#{org_id}/attendances" }
let(:response) { {'data' => [{'id' => 1, 'event' => {'id' => 1111}}, {'id' => 2, 'event' => {'id' => 2222}}]} }

context 'unauthenticated request' do
let(:api_key) { nil }

it 'should raise if response status is 401' do
stub_request(:get, attendances_url).with(headers: {'Content-Type' => 'application/json'}).to_return(status: 401, body: {error: 'unauthorized'}.to_json)

expect { subject.organization_attendances(organization_id: org_id) }.to raise_error MobilizeAmericaClient::UnauthorizedError
it_behaves_like 'response error handling' do
let(:call_client_method) do
-> { subject.organization_attendances(organization_id: org_id) }
end
let(:set_up_stub_request) do
-> do
stub_request(:get, attendances_url).with(headers: request_headers)
.to_return(status: response_status, body: response_body, headers: response_headers)
end
end
end

it 'should raise if response status is 404' do
stub_request(:get, attendances_url).with(headers: request_headers).to_return(status: 404, body: { error: 'not found'}.to_json)

expect { subject.organization_attendances(organization_id: org_id) }.to raise_error MobilizeAmericaClient::NotFoundError
end

it 'should call the endpoint and return JSON' do
Expand Down
13 changes: 13 additions & 0 deletions spec/client/enums_spec.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'spec_helper'
require 'shared_examples/response_error_handling'

RSpec.describe MobilizeAmericaClient::Client::Enums do
let(:standard_headers) { {'Content-Type' => 'application/json'} }
Expand All @@ -11,6 +12,18 @@
let(:enums_url) { "#{base_url}/enums" }
let(:response) { {'hello' => 'world'} }

it_behaves_like 'response error handling' do
let(:call_client_method) do
-> { subject.enums }
end
let(:set_up_stub_request) do
-> do
stub_request(:get, enums_url).with(headers: standard_headers)
.to_return(status: response_status, body: response_body, headers: response_headers)
end
end
end

it 'should call the endpoint and return JSON' do
stub_request(:get, enums_url).with(headers: standard_headers).to_return(body: response.to_json, headers: { 'Content-Type' => 'application/json' })
expect(subject.enums).to eq response
Expand Down
39 changes: 11 additions & 28 deletions spec/client/events_spec.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'spec_helper'
require 'shared_examples/response_error_handling'

RSpec.describe MobilizeAmericaClient::Client::Events do
let(:standard_headers) { {'Content-Type' => 'application/json'} }
Expand All @@ -12,34 +13,16 @@
let(:events_url) { "#{base_url}/organizations/#{org_id}/events" }
let(:response) { {'data' => [{'id' => 1, 'description' => 'event 1'}, {'id' => 2, 'description' => 'event 2'}]} }

it 'should raise if response status is 404' do
stub_request(:get, events_url).with(headers: standard_headers).to_return(status: 404, body: {error: 'not found'}.to_json, headers: standard_headers)

expect { subject.organization_events(organization_id: org_id) }.to raise_error MobilizeAmericaClient::NotFoundError
end

it 'should raise ServerError if response status is 500' do
stub_request(:get, events_url).with(headers: standard_headers).to_return(status: 500, body: {error: 'internal server error'}.to_json, headers: standard_headers)

expect { subject.organization_events(organization_id: org_id) }.to raise_error(MobilizeAmericaClient::ServerError, /Server Error \(500\)/)
end

it 'should raise ServerError if response status is 503' do
stub_request(:get, events_url).with(headers: standard_headers).to_return(status: 503, body: 'Service Unavailable')

expect { subject.organization_events(organization_id: org_id) }.to raise_error(MobilizeAmericaClient::ServerError, /Server Error \(503\)/)
end

it 'should raise ClientError if response status is 400' do
stub_request(:get, events_url).with(headers: standard_headers).to_return(status: 400, body: {error: 'bad request'}.to_json, headers: standard_headers)

expect { subject.organization_events(organization_id: org_id) }.to raise_error(MobilizeAmericaClient::ClientError, /Client Error \(400\)/)
end

it 'should raise ClientError if response status is 422' do
stub_request(:get, events_url).with(headers: standard_headers).to_return(status: 422, body: {error: 'unprocessable entity'}.to_json, headers: standard_headers)

expect { subject.organization_events(organization_id: org_id) }.to raise_error(MobilizeAmericaClient::ClientError, /Client Error \(422\)/)
it_behaves_like 'response error handling' do
let(:call_client_method) do
-> { subject.organization_events(organization_id: org_id) }
end
let(:set_up_stub_request) do
-> do
stub_request(:get, events_url).with(headers: standard_headers)
.to_return(status: response_status, body: response_body, headers: response_headers)
end
end
end

it 'should call the endpoint and return JSON' do
Expand Down
13 changes: 13 additions & 0 deletions spec/client/organizations_spec.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'spec_helper'
require 'shared_examples/response_error_handling'

RSpec.describe MobilizeAmericaClient::Client::Organizations do
let(:standard_headers) { {'Content-Type' => 'application/json'} }
Expand All @@ -11,6 +12,18 @@
let(:organizations_url) { "#{base_url}/organizations" }
let(:response) { fixture('organizations.json').read }

it_behaves_like 'response error handling' do
let(:call_client_method) do
-> { subject.organizations }
end
let(:set_up_stub_request) do
-> do
stub_request(:get, organizations_url).with(headers: standard_headers)
.to_return(status: response_status, body: response_body, headers: response_headers)
end
end
end

it 'should call the endpoint and return JSON' do
stub_request(:get, organizations_url).with(headers: standard_headers).to_return(body: response.to_json, headers: { 'Content-Type' => 'application/json' })
expect(subject.organizations).to eq response
Expand Down
79 changes: 79 additions & 0 deletions spec/shared_examples/response_error_handling.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
RSpec.shared_examples_for 'response error handling' do
let(:response_headers) { {'Content-Type' => 'application/json'} }

before :each do
set_up_stub_request.call
end

context 'response status is 400' do
let(:response_status) { 400 }
let(:response_body) { {error: 'bad request'}.to_json }

it 'should raise ClientError' do
expect{ call_client_method.call }.to raise_error(MobilizeAmericaClient::ClientError, /Client Error \(400\)/)
end
end

context 'response status is 401' do
let(:response_status) { 401 }
let(:response_body) { {error: 'unauthorized'}.to_json }

it 'should raise UnauthorizedError' do
expect { call_client_method.call }.to raise_error MobilizeAmericaClient::UnauthorizedError
end
end

context 'response status is 404' do
let(:response_status) { 404 }
let(:response_body) { {error: 'not found'}.to_json }

it 'should raise NotFoundError' do
expect{ call_client_method.call }.to raise_error MobilizeAmericaClient::NotFoundError
end
end

context 'response status is 422' do
let(:response_status) { 422 }
let(:response_body) { {error: 'unprocessable entity'}.to_json }

it 'should raise ClientError' do
expect{ call_client_method.call }.to raise_error(MobilizeAmericaClient::ClientError, /Client Error \(422\)/)
end
end

context 'response status is 429' do
let(:response_status) { 429 }
let(:response_body) { {error: 'rate-limited'}.to_json }

it 'should raise RateLimitedError' do
expect{ call_client_method.call }.to raise_error(MobilizeAmericaClient::RateLimitedError)
end

context 'with a Retry-After header' do
let(:response_headers) { {'Content-Type' => 'application/json', 'Retry-After' => '3600'} }

it 'should raise include that info in the error' do
expect{ call_client_method.call }.to raise_error(MobilizeAmericaClient::RateLimitedError, /3600/)
end
end
end

context 'response status is 500' do
let(:response_status) { 500 }
let(:response_body) { {error: 'internal server error'}.to_json }

it 'should raise ServerError' do
expect{ call_client_method.call }.to raise_error(MobilizeAmericaClient::ServerError, /Server Error \(500\)/)
end
end

context 'response status is 503' do
let(:response_status) { 503 }
let(:response_body) { 'Service Unavailable' }
let(:response_headers) { {} }

it 'should raise ServerError' do
expect{ call_client_method.call }.to raise_error(MobilizeAmericaClient::ServerError, /Server Error \(503\)/)
end
end
end