api_client_builder 1.0.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.gitignore +3 -0
- data/.rubocop.yml +34 -0
- data/.travis.yml +20 -0
- data/Gemfile +6 -0
- data/Jenkinsfile +13 -0
- data/LICENSE.txt +22 -0
- data/{readme.md → README.md} +65 -50
- data/api_client_builder.gemspec +15 -13
- data/build.sh +16 -0
- data/lib/api_client_builder.rb +14 -0
- data/lib/api_client_builder/api_client.rb +96 -0
- data/lib/api_client_builder/delete_request.rb +19 -0
- data/lib/api_client_builder/get_collection_request.rb +43 -0
- data/lib/api_client_builder/get_item_request.rb +27 -0
- data/lib/api_client_builder/post_request.rb +19 -0
- data/lib/api_client_builder/put_request.rb +19 -0
- data/lib/api_client_builder/request.rb +66 -0
- data/lib/api_client_builder/response.rb +32 -0
- data/lib/api_client_builder/url_generator.rb +37 -0
- data/lib/api_client_builder/version.rb +3 -0
- data/spec/lib/api_client_builder/api_client_spec.rb +13 -4
- data/spec/lib/api_client_builder/delete_request_spec.rb +29 -0
- data/spec/lib/api_client_builder/get_collection_request_spec.rb +7 -10
- data/spec/lib/api_client_builder/get_item_request_spec.rb +4 -6
- data/spec/lib/api_client_builder/post_request_spec.rb +3 -5
- data/spec/lib/api_client_builder/put_request_spec.rb +3 -5
- data/spec/lib/api_client_builder/request_spec.rb +7 -9
- data/spec/lib/api_client_builder/response_spec.rb +1 -2
- data/spec/lib/api_client_builder/test_client/client.rb +3 -3
- data/spec/lib/api_client_builder/test_client/http_client_handler.rb +1 -2
- data/spec/lib/api_client_builder/test_client/response_handler.rb +13 -14
- data/spec/lib/api_client_builder/url_generator_spec.rb +29 -7
- data/spec/spec_helper.rb +8 -2
- metadata +51 -31
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
module APIClientBuilder
|
|
2
|
+
# The base APIClient that defines the interface for defining an API Client.
|
|
3
|
+
# Should be sub-classed and then provided an HTTPClient handler and a
|
|
4
|
+
# response handler.
|
|
5
|
+
class APIClient
|
|
6
|
+
attr_reader :url_generator, :http_client
|
|
7
|
+
|
|
8
|
+
# @param opts [Hash] options hash
|
|
9
|
+
# @option opts [Symbol] :http_client The http client handler
|
|
10
|
+
# @option opts [Symbol] :paginator The response handler
|
|
11
|
+
def initialize(**opts)
|
|
12
|
+
@url_generator = APIClientBuilder::URLGenerator.new(opts[:domain])
|
|
13
|
+
@http_client = opts[:http_client]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Used to define a GET api route on the base class. Will
|
|
17
|
+
# yield a method that takes the shape of 'get_type' that will
|
|
18
|
+
# return a CollectionResponse or ItemResponse based on plurality.
|
|
19
|
+
#
|
|
20
|
+
# @param type [Symbol] defines the route model
|
|
21
|
+
# @param plurality [Symbol] defines the routes plurality
|
|
22
|
+
# @param route [String] defines the routes endpoint
|
|
23
|
+
#
|
|
24
|
+
# @return [Request] either a GetCollection or GetItem request
|
|
25
|
+
def self.get(type, plurality, route, **_opts)
|
|
26
|
+
if plurality == :collection
|
|
27
|
+
define_method("get_#{type}") do |**params|
|
|
28
|
+
GetCollectionRequest.new(
|
|
29
|
+
type,
|
|
30
|
+
response_handler_build(http_client, @url_generator.build_route(route, **params), type)
|
|
31
|
+
)
|
|
32
|
+
end
|
|
33
|
+
elsif plurality == :singular
|
|
34
|
+
define_method("get_#{type}") do |**params|
|
|
35
|
+
GetItemRequest.new(
|
|
36
|
+
type,
|
|
37
|
+
response_handler_build(http_client, @url_generator.build_route(route, **params), type)
|
|
38
|
+
)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Used to define a POST api route on the base class. Will
|
|
44
|
+
# yield a method that takes the shape of 'post_type' that will
|
|
45
|
+
# return a PostRequest.
|
|
46
|
+
#
|
|
47
|
+
# @param type [Symbol] defines the route model
|
|
48
|
+
# @param route [String] defines the routes endpoint
|
|
49
|
+
#
|
|
50
|
+
# @return [PostRequest] the request object that handles posts
|
|
51
|
+
def self.post(type, route)
|
|
52
|
+
define_method("post_#{type}") do |body, **params|
|
|
53
|
+
PostRequest.new(
|
|
54
|
+
type,
|
|
55
|
+
response_handler_build(http_client, @url_generator.build_route(route, **params), type),
|
|
56
|
+
body
|
|
57
|
+
)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Used to define a PUT api route on the base class. Will
|
|
62
|
+
# yield a method that takes the shape of 'put_type' that will
|
|
63
|
+
# return a PutRequest.
|
|
64
|
+
#
|
|
65
|
+
# @param type [Symbol] defines the route model
|
|
66
|
+
# @param route [String] defines the routes endpoint
|
|
67
|
+
#
|
|
68
|
+
# @return [PutRequest] the request object that handles puts
|
|
69
|
+
def self.put(type, route)
|
|
70
|
+
define_method("put_#{type}") do |body, **params|
|
|
71
|
+
PutRequest.new(
|
|
72
|
+
type,
|
|
73
|
+
response_handler_build(http_client, @url_generator.build_route(route, **params), type),
|
|
74
|
+
body
|
|
75
|
+
)
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Used to define a DELETE api route on the base class. Will
|
|
80
|
+
# yield a method that takes the shape of 'delete_type' that will
|
|
81
|
+
# return a DeleteRequest.
|
|
82
|
+
#
|
|
83
|
+
# @param type [Symbol] defines the route model
|
|
84
|
+
# @param route [String] defines the routes endpoint
|
|
85
|
+
#
|
|
86
|
+
# @return [DeleteRequest] the request object that handles puts
|
|
87
|
+
def self.delete(type, route)
|
|
88
|
+
define_method("delete_#{type}") do |**params|
|
|
89
|
+
DeleteRequest.new(
|
|
90
|
+
type,
|
|
91
|
+
response_handler_build(http_client, @url_generator.build_route(route, **params), type)
|
|
92
|
+
)
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module APIClientBuilder
|
|
2
|
+
class DeleteRequest < Request
|
|
3
|
+
# Yields the response body if the response was successful. Will call
|
|
4
|
+
# the response handlers if there was not a successful response.
|
|
5
|
+
#
|
|
6
|
+
# @return [JSON] the http response body
|
|
7
|
+
def response
|
|
8
|
+
response = response_handler.delete_request
|
|
9
|
+
|
|
10
|
+
if response.success?
|
|
11
|
+
response
|
|
12
|
+
else
|
|
13
|
+
error_handlers.each do |handler|
|
|
14
|
+
handler.call(response, self)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module APIClientBuilder
|
|
2
|
+
# The multi item response object to be used as the container for
|
|
3
|
+
# collection responses from the defined API
|
|
4
|
+
class GetCollectionRequest < Request
|
|
5
|
+
include Enumerable
|
|
6
|
+
|
|
7
|
+
# Iterates over the pages and yields their items if they're successful
|
|
8
|
+
# responses. Else handles the error. Will retry the response if a retry
|
|
9
|
+
# strategy is defined concretely on the response handler.
|
|
10
|
+
#
|
|
11
|
+
# @return [JSON] the http response body
|
|
12
|
+
# rubocop:disable Metrics/AbcSize
|
|
13
|
+
def each
|
|
14
|
+
if block_given?
|
|
15
|
+
each_page do |page|
|
|
16
|
+
if page.success?
|
|
17
|
+
page.body.each do |item|
|
|
18
|
+
yield(item)
|
|
19
|
+
end
|
|
20
|
+
elsif response_handler.respond_to?(:retryable?) && response_handler.retryable?(page.status_code)
|
|
21
|
+
retried_page = attempt_retry
|
|
22
|
+
|
|
23
|
+
retried_page.body.each do |item|
|
|
24
|
+
yield(item)
|
|
25
|
+
end
|
|
26
|
+
else
|
|
27
|
+
notify_error_handlers(page)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
else
|
|
31
|
+
Enumerator.new(self, :each)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
# rubocop:enable Metrics/AbcSize
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
def each_page
|
|
39
|
+
yield(response_handler.get_first_page)
|
|
40
|
+
yield(response_handler.get_next_page) while response_handler.more_pages?
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module APIClientBuilder
|
|
2
|
+
# The single item response object to be used as the container for
|
|
3
|
+
# singular responses from the defined API
|
|
4
|
+
class GetItemRequest < Request
|
|
5
|
+
# Reads the first page from the pagination solution and yields the
|
|
6
|
+
# items if the response was successful. Else handles the error. Will
|
|
7
|
+
# retry the response if a retry strategy is defined concretely on the
|
|
8
|
+
# response handler.
|
|
9
|
+
#
|
|
10
|
+
# @return [JSON] the http response body
|
|
11
|
+
def response
|
|
12
|
+
page = response_handler.get_first_page
|
|
13
|
+
|
|
14
|
+
if page.success?
|
|
15
|
+
page.body
|
|
16
|
+
elsif response_handler.respond_to?(:retryable?) && response_handler.retryable?(page.status_code)
|
|
17
|
+
retried_page = attempt_retry
|
|
18
|
+
|
|
19
|
+
retried_page.body
|
|
20
|
+
else
|
|
21
|
+
error_handlers.each do |handler|
|
|
22
|
+
handler.call(page, self)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module APIClientBuilder
|
|
2
|
+
class PostRequest < Request
|
|
3
|
+
# Yields the response body if the response was successful. Will call
|
|
4
|
+
# the response handlers if there was not a successful response.
|
|
5
|
+
#
|
|
6
|
+
# @return [JSON] the http response body
|
|
7
|
+
def response
|
|
8
|
+
response = response_handler.post_request(@body)
|
|
9
|
+
|
|
10
|
+
if response.success?
|
|
11
|
+
response
|
|
12
|
+
else
|
|
13
|
+
error_handlers.each do |handler|
|
|
14
|
+
handler.call(response, self)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module APIClientBuilder
|
|
2
|
+
class PutRequest < Request
|
|
3
|
+
# Yields the response body if the response was successful. Will call
|
|
4
|
+
# the response handlers if there was not a successful response.
|
|
5
|
+
#
|
|
6
|
+
# @return [JSON] the http response body
|
|
7
|
+
def response
|
|
8
|
+
response = response_handler.put_request(@body)
|
|
9
|
+
|
|
10
|
+
if response.success?
|
|
11
|
+
response
|
|
12
|
+
else
|
|
13
|
+
error_handlers.each do |handler|
|
|
14
|
+
handler.call(response, self)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
module APIClientBuilder
|
|
2
|
+
class DefaultPageError < StandardError; end
|
|
3
|
+
|
|
4
|
+
class Request
|
|
5
|
+
attr_reader :type, :response_handler, :body, :error_handlers_collection
|
|
6
|
+
|
|
7
|
+
# @param type [Symbol] defines the object type to be processed
|
|
8
|
+
# @option response_handler [ResponseHandler] the response handler. Usually
|
|
9
|
+
# a pagination strategy
|
|
10
|
+
# @option body [Hash] the body of the response from the source
|
|
11
|
+
def initialize(type, response_handler, body = {})
|
|
12
|
+
@type = type
|
|
13
|
+
@response_handler = response_handler
|
|
14
|
+
@body = body
|
|
15
|
+
@error_handlers_collection = []
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Yields the collection of error handlers that have been populated
|
|
19
|
+
# via the on_error interface. If none are defined, this will provide a
|
|
20
|
+
# default error handler that will provide context about the error and
|
|
21
|
+
# also how to define a new error handler.
|
|
22
|
+
#
|
|
23
|
+
# @return [Array<Block>] the error handlers collection
|
|
24
|
+
def error_handlers
|
|
25
|
+
if error_handlers_collection.empty?
|
|
26
|
+
on_error do |page, _handler|
|
|
27
|
+
raise DefaultPageError, <<~MESSAGE
|
|
28
|
+
Default error for bad response. If you want to handle this error use #on_error
|
|
29
|
+
on the response in your api consumer. Error Code: #{page.status_code}.
|
|
30
|
+
MESSAGE
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
error_handlers_collection
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Used to define custom error handling on this response.
|
|
37
|
+
# The error handlers will be called if there is not a success
|
|
38
|
+
#
|
|
39
|
+
# @param block [Lambda] the error handling block to be stored in
|
|
40
|
+
# the error_handlers list
|
|
41
|
+
def on_error(&block)
|
|
42
|
+
@error_handlers_collection << block
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
def attempt_retry
|
|
48
|
+
page = response_handler.retry_request
|
|
49
|
+
|
|
50
|
+
if page.success?
|
|
51
|
+
response_handler.reset_retries
|
|
52
|
+
return page
|
|
53
|
+
elsif response_handler.retryable?(page.status_code)
|
|
54
|
+
attempt_retry
|
|
55
|
+
else
|
|
56
|
+
notify_error_handlers(page)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def notify_error_handlers(page)
|
|
61
|
+
error_handlers.each do |handler|
|
|
62
|
+
handler.call(page, self)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module APIClientBuilder
|
|
2
|
+
# The default page object to be used to hold the response from the API
|
|
3
|
+
# in your response handler object. Any response object that will replace this
|
|
4
|
+
# must response to #success?, and #items
|
|
5
|
+
class Response
|
|
6
|
+
attr_accessor :body, :status_code
|
|
7
|
+
|
|
8
|
+
# @param body [String/Array/Hash] the response body
|
|
9
|
+
# @param status_code [Integer] the response status code
|
|
10
|
+
# @param success_range [Array<Integer>] the success range of this response
|
|
11
|
+
def initialize(body, status_code, success_range)
|
|
12
|
+
@body = body
|
|
13
|
+
@status_code = status_code
|
|
14
|
+
@success_range = success_range
|
|
15
|
+
@failed_reason = nil
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Used to mark why the response failed
|
|
19
|
+
def mark_failed(reason)
|
|
20
|
+
@failed_reason = reason
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Defines the success conditional for a response by determining whether
|
|
24
|
+
# or not the status code of the response is within the defined success
|
|
25
|
+
# range
|
|
26
|
+
#
|
|
27
|
+
# @return [Boolean] whether or not the response is a success
|
|
28
|
+
def success?
|
|
29
|
+
@failed_reason.nil? && @success_range.include?(@status_code)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
module APIClientBuilder
|
|
2
|
+
class NoURLError < StandardError; end
|
|
3
|
+
class URLGenerator
|
|
4
|
+
# Receives a domain and parses it into a URI
|
|
5
|
+
#
|
|
6
|
+
# @param domain [String] the domain of the API
|
|
7
|
+
def initialize(domain)
|
|
8
|
+
@base_uri = URI.parse(domain)
|
|
9
|
+
@base_uri = URI.parse('https://' + domain) if @base_uri.scheme.nil?
|
|
10
|
+
@base_uri.path << '/' unless @base_uri.path.end_with?('/')
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Defines a full API route and interpolates parameters into the route
|
|
14
|
+
# provided that the parameter sent in has a key that matches the parameter
|
|
15
|
+
# that is defined by the route.
|
|
16
|
+
#
|
|
17
|
+
# @param route [String] defines the route endpoint
|
|
18
|
+
# @param params [Hash] the optional params to be interpolated into the route
|
|
19
|
+
#
|
|
20
|
+
# @raise [ArgumentError] if route defined param is not provided
|
|
21
|
+
#
|
|
22
|
+
# @return [URI] the fully built route
|
|
23
|
+
def build_route(route, **params)
|
|
24
|
+
string_params = route.split(%r{[\/=]}).select { |param| param.start_with?(':') }
|
|
25
|
+
symboled_params = string_params.map { |param| param.tr(':', '').to_sym }
|
|
26
|
+
|
|
27
|
+
new_route = route.clone
|
|
28
|
+
symboled_params.each do |param|
|
|
29
|
+
value = params[param]
|
|
30
|
+
raise ArgumentError, "Param :#{param} is required" unless value
|
|
31
|
+
new_route.gsub!(":#{param}", CGI.escape(value.to_s))
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
@base_uri.merge(new_route)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
require 'api_client_builder/api_client'
|
|
2
|
+
require_relative 'test_client/client'
|
|
4
3
|
|
|
5
4
|
module APIClientBuilder
|
|
6
5
|
describe APIClient do
|
|
7
|
-
let(:domain) {'https://www.domain.com/api/endpoints/'}
|
|
8
|
-
let(:client) {TestClient::Client.new(domain: domain)}
|
|
6
|
+
let(:domain) { 'https://www.domain.com/api/endpoints/' }
|
|
7
|
+
let(:client) { TestClient::Client.new(domain: domain) }
|
|
9
8
|
|
|
10
9
|
describe '.get' do
|
|
11
10
|
context 'plurality is :collection' do
|
|
@@ -42,5 +41,15 @@ module APIClientBuilder
|
|
|
42
41
|
expect(client.put_some_object({})).to be_a(APIClientBuilder::PutRequest)
|
|
43
42
|
end
|
|
44
43
|
end
|
|
44
|
+
|
|
45
|
+
describe '.delete' do
|
|
46
|
+
it 'defines a delete method on the client' do
|
|
47
|
+
expect(client).to respond_to(:delete_some_object)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it 'returns a DeleteRequest object' do
|
|
51
|
+
expect(client.delete_some_object({})).to be_a(APIClientBuilder::DeleteRequest)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
45
54
|
end
|
|
46
55
|
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require_relative 'test_client/client'
|
|
3
|
+
|
|
4
|
+
module APIClientBuilder
|
|
5
|
+
describe DeleteRequest do
|
|
6
|
+
describe '#response' do
|
|
7
|
+
context 'request was successful' do
|
|
8
|
+
it 'returns a response object' do
|
|
9
|
+
client = TestClient::Client.new(domain: 'https://www.domain.com/api/endpoints/')
|
|
10
|
+
|
|
11
|
+
some_object = client.delete_some_object({}).response
|
|
12
|
+
expect(some_object.body).to eq('good delete request')
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
context 'request was unsuccessful' do
|
|
17
|
+
it 'calls the error handlers' do
|
|
18
|
+
client = TestClient::Client.new(domain: 'https://www.domain.com/api/endpoints/')
|
|
19
|
+
|
|
20
|
+
bad_response = APIClientBuilder::Response.new('bad request', 400, [200])
|
|
21
|
+
allow_any_instance_of(TestClient::ResponseHandler).to receive(:delete_request).and_return(bad_response)
|
|
22
|
+
expect { client.delete_some_object({}).response }.to raise_error(
|
|
23
|
+
APIClientBuilder::DefaultPageError, /Error Code: 400/
|
|
24
|
+
)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
require 'lib/api_client_builder/test_client/client'
|
|
2
|
+
require_relative 'test_client/client'
|
|
4
3
|
|
|
5
4
|
module APIClientBuilder
|
|
6
5
|
describe GetCollectionRequest do
|
|
@@ -21,9 +20,8 @@ module APIClientBuilder
|
|
|
21
20
|
bad_response = APIClientBuilder::Response.new('bad request', 500, [200])
|
|
22
21
|
allow_any_instance_of(TestClient::ResponseHandler).to receive(:get_first_page).and_return(bad_response)
|
|
23
22
|
allow_any_instance_of(TestClient::ResponseHandler).to receive(:retry_request).and_return(bad_response)
|
|
24
|
-
expect{ client.get_some_objects.each{} }.to raise_error(
|
|
25
|
-
APIClientBuilder::DefaultPageError,
|
|
26
|
-
"Default error for bad response. If you want to handle this error use #on_error on the response in your api consumer. Error Code: 500"
|
|
23
|
+
expect { client.get_some_objects.each {} }.to raise_error(
|
|
24
|
+
APIClientBuilder::DefaultPageError, /Error Code: 500/
|
|
27
25
|
)
|
|
28
26
|
end
|
|
29
27
|
|
|
@@ -32,7 +30,7 @@ module APIClientBuilder
|
|
|
32
30
|
client = TestClient::Client.new(domain: 'https://www.domain.com/api/endpoints/')
|
|
33
31
|
|
|
34
32
|
bad_response = APIClientBuilder::Response.new('bad request', 500, [200])
|
|
35
|
-
good_response = APIClientBuilder::Response.new([1,2,3], 200, [200])
|
|
33
|
+
good_response = APIClientBuilder::Response.new([1, 2, 3], 200, [200])
|
|
36
34
|
allow_any_instance_of(TestClient::ResponseHandler).to receive(:get_first_page).and_return(bad_response)
|
|
37
35
|
allow_any_instance_of(TestClient::ResponseHandler).to receive(:more_pages?).and_return(false)
|
|
38
36
|
allow_any_instance_of(TestClient::ResponseHandler).to receive(:retry_request).and_return(good_response)
|
|
@@ -47,13 +45,12 @@ module APIClientBuilder
|
|
|
47
45
|
client = TestClient::Client.new(domain: 'https://www.domain.com/api/endpoints/')
|
|
48
46
|
|
|
49
47
|
bad_response = APIClientBuilder::Response.new('bad request', 400, [200])
|
|
50
|
-
good_response = APIClientBuilder::Response.new([1,2,3], 200, [200])
|
|
48
|
+
good_response = APIClientBuilder::Response.new([1, 2, 3], 200, [200])
|
|
51
49
|
allow_any_instance_of(TestClient::ResponseHandler).to receive(:get_first_page).and_return(bad_response)
|
|
52
50
|
allow_any_instance_of(TestClient::ResponseHandler).to receive(:more_pages?).and_return(false)
|
|
53
51
|
allow_any_instance_of(TestClient::ResponseHandler).to receive(:retry_request).and_return(good_response)
|
|
54
|
-
expect{ client.get_some_objects.each{} }.to raise_error(
|
|
55
|
-
APIClientBuilder::DefaultPageError,
|
|
56
|
-
"Default error for bad response. If you want to handle this error use #on_error on the response in your api consumer. Error Code: 400"
|
|
52
|
+
expect { client.get_some_objects.each {} }.to raise_error(
|
|
53
|
+
APIClientBuilder::DefaultPageError, /Error Code: 400/
|
|
57
54
|
)
|
|
58
55
|
end
|
|
59
56
|
end
|