soaspec 0.2.33 → 0.3.1
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 +4 -4
- data/.gitignore +15 -15
- data/.gitlab-ci.yml +62 -62
- data/.rspec +3 -3
- data/.rubocop.yml +2 -2
- data/CODE_OF_CONDUCT.md +74 -74
- data/ChangeLog +643 -632
- data/Dockerfile +7 -7
- data/Gemfile +8 -8
- data/LICENSE.txt +21 -21
- data/README.md +253 -231
- data/Rakefile +52 -52
- data/Todo.md +16 -16
- data/exe/soaspec +140 -138
- data/exe/xml_to_yaml_file +43 -43
- data/lib/soaspec.rb +118 -106
- data/lib/soaspec/baseline.rb +82 -22
- data/lib/soaspec/core_ext/hash.rb +44 -44
- data/lib/soaspec/cucumber/generic_steps.rb +94 -94
- data/lib/soaspec/demo.rb +6 -6
- data/lib/soaspec/errors.rb +24 -24
- data/lib/soaspec/exchange/exchange.rb +131 -129
- data/lib/soaspec/exchange/exchange_extractor.rb +105 -90
- data/lib/soaspec/exchange/exchange_properties.rb +28 -28
- data/lib/soaspec/exchange/exchange_repeater.rb +21 -21
- data/lib/soaspec/exchange/request_builder.rb +108 -70
- data/lib/soaspec/exchange/variable_storer.rb +24 -24
- data/lib/soaspec/exchange_handlers/exchange_handler.rb +98 -98
- data/lib/soaspec/exchange_handlers/exchange_handler_defaults.rb +61 -61
- data/lib/soaspec/exchange_handlers/handler_accessors.rb +132 -132
- data/lib/soaspec/exchange_handlers/request/rest_request.rb +77 -59
- data/lib/soaspec/exchange_handlers/request/soap_request.rb +41 -41
- data/lib/soaspec/exchange_handlers/response_extractor.rb +84 -84
- data/lib/soaspec/exchange_handlers/rest_exchanger_factory.rb +111 -111
- data/lib/soaspec/exchange_handlers/rest_handler.rb +307 -307
- data/lib/soaspec/exchange_handlers/rest_methods.rb +65 -65
- data/lib/soaspec/exchange_handlers/rest_parameters.rb +112 -112
- data/lib/soaspec/exchange_handlers/rest_parameters_defaults.rb +42 -42
- data/lib/soaspec/exchange_handlers/soap_handler.rb +241 -241
- data/lib/soaspec/exe_helpers.rb +94 -94
- data/lib/soaspec/generate_server.rb +48 -48
- data/lib/soaspec/generator/.rspec.erb +5 -5
- data/lib/soaspec/generator/.travis.yml.erb +5 -5
- data/lib/soaspec/generator/Gemfile.erb +8 -8
- data/lib/soaspec/generator/README.md.erb +29 -29
- data/lib/soaspec/generator/Rakefile.erb +20 -19
- data/lib/soaspec/generator/config/data/default.yml.erb +2 -2
- data/lib/soaspec/generator/css/bootstrap.css +6833 -6833
- data/lib/soaspec/generator/features/support/env.rb.erb +3 -3
- data/lib/soaspec/generator/generate_exchange.html.erb +47 -47
- data/lib/soaspec/generator/lib/blz_service.rb.erb +26 -26
- data/lib/soaspec/generator/lib/dynamic_class_content.rb.erb +12 -12
- data/lib/soaspec/generator/lib/new_rest_service.rb.erb +56 -56
- data/lib/soaspec/generator/lib/new_soap_service.rb.erb +29 -29
- data/lib/soaspec/generator/lib/package_service.rb.erb +2 -2
- data/lib/soaspec/generator/lib/shared_example.rb.erb +8 -8
- data/lib/soaspec/generator/spec/dynamic_soap_spec.rb.erb +12 -12
- data/lib/soaspec/generator/spec/rest_spec.rb.erb +9 -9
- data/lib/soaspec/generator/spec/soap_spec.rb.erb +51 -51
- data/lib/soaspec/generator/spec/spec_helper.rb.erb +23 -23
- data/lib/soaspec/generator/template/soap_template.xml +6 -6
- data/lib/soaspec/indifferent_hash.rb +9 -9
- data/lib/soaspec/interpreter.rb +70 -70
- data/lib/soaspec/matchers.rb +136 -140
- data/lib/soaspec/o_auth2.rb +142 -142
- data/lib/soaspec/soaspec_shared_examples.rb +26 -26
- data/lib/soaspec/spec_logger.rb +143 -143
- data/lib/soaspec/template_reader.rb +30 -30
- data/lib/soaspec/test_server/bank.wsdl +90 -90
- data/lib/soaspec/test_server/get_bank.rb +166 -166
- data/lib/soaspec/test_server/id_manager.rb +41 -41
- data/lib/soaspec/test_server/invoices.rb +29 -29
- data/lib/soaspec/test_server/namespace.xml +14 -14
- data/lib/soaspec/test_server/note.xml +5 -5
- data/lib/soaspec/test_server/puppy_service.rb +21 -21
- data/lib/soaspec/test_server/test_attribute.rb +14 -14
- data/lib/soaspec/test_server/test_namespace.rb +14 -14
- data/lib/soaspec/version.rb +6 -6
- data/lib/soaspec/virtual_server.rb +193 -190
- data/lib/soaspec/wait.rb +43 -43
- data/lib/soaspec/wsdl_generator.rb +215 -215
- data/soaspec.gemspec +58 -58
- data/test.wsdl +116 -116
- data/test.xml +10 -10
- data/test_wsdl.rb +43 -43
- metadata +3 -3
data/lib/soaspec/demo.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# Load this file for demoing Soaspec (e.g in IRB). Has common settings applicable for demoing
|
4
|
-
|
5
|
-
require_relative '../soaspec'
|
6
|
-
Soaspec::SpecLogger.output_to_terminal = true
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Load this file for demoing Soaspec (e.g in IRB). Has common settings applicable for demoing
|
4
|
+
|
5
|
+
require_relative '../soaspec'
|
6
|
+
Soaspec::SpecLogger.output_to_terminal = true
|
data/lib/soaspec/errors.rb
CHANGED
@@ -1,24 +1,24 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Soaspec
|
4
|
-
# Standard Error related to Soaspec
|
5
|
-
class Error < StandardError; end
|
6
|
-
# Error related to a response
|
7
|
-
class ResponseError < Error; end
|
8
|
-
# Error related to not having a recorded baseline yet
|
9
|
-
class BaselineError < Error; end
|
10
|
-
end
|
11
|
-
|
12
|
-
# Raised to represent when there's no element at an Xpath
|
13
|
-
class NoElementAtPath < Soaspec::Error
|
14
|
-
def initialize(msg = 'No element at path found')
|
15
|
-
super
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
# Did not find any element by provided key in the Hash
|
20
|
-
class NoElementInHash < Soaspec::Error
|
21
|
-
def initialize(msg = 'No element in Hash found')
|
22
|
-
super
|
23
|
-
end
|
24
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Soaspec
|
4
|
+
# Standard Error related to Soaspec
|
5
|
+
class Error < StandardError; end
|
6
|
+
# Error related to a response
|
7
|
+
class ResponseError < Error; end
|
8
|
+
# Error related to not having a recorded baseline yet
|
9
|
+
class BaselineError < Error; end
|
10
|
+
end
|
11
|
+
|
12
|
+
# Raised to represent when there's no element at an Xpath
|
13
|
+
class NoElementAtPath < Soaspec::Error
|
14
|
+
def initialize(msg = 'No element at path found')
|
15
|
+
super
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Did not find any element by provided key in the Hash
|
20
|
+
class NoElementInHash < Soaspec::Error
|
21
|
+
def initialize(msg = 'No element in Hash found')
|
22
|
+
super
|
23
|
+
end
|
24
|
+
end
|
@@ -1,129 +1,131 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative '../../soaspec'
|
4
|
-
require_relative 'exchange_properties'
|
5
|
-
require_relative 'exchange_extractor'
|
6
|
-
require_relative 'request_builder'
|
7
|
-
require_relative 'exchange_repeater'
|
8
|
-
require_relative 'variable_storer'
|
9
|
-
|
10
|
-
# This represents a request / response pair
|
11
|
-
# Essentially, params in the exchange that are set are related to the request
|
12
|
-
# What is returned is related to the response
|
13
|
-
#
|
14
|
-
# It is tied to an ExchangeHandler that needs to be defined either globally before it's created or in 'default_handler_used'
|
15
|
-
class Exchange
|
16
|
-
extend Soaspec::ExchangeProperties
|
17
|
-
include Soaspec::ExchangeExtractor
|
18
|
-
include Soaspec::RequestBuilder
|
19
|
-
include Soaspec::ExchangeRepeater
|
20
|
-
include Soaspec::VariableStorer
|
21
|
-
|
22
|
-
# Instance of ExchangeHandler for which this exchange is made
|
23
|
-
attr_accessor :exchange_handler
|
24
|
-
# @return [Integer] How many times to retry for a success
|
25
|
-
attr_accessor :retry_count
|
26
|
-
# @return [Integer] Times request was retried before being returned
|
27
|
-
attr_accessor :times_retried
|
28
|
-
#
|
29
|
-
attr_accessor :test_name
|
30
|
-
# Expect Factory to fail upon trying to create
|
31
|
-
attr_writer :fail_factory
|
32
|
-
# Parameters to override for default params
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
#
|
61
|
-
#
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
exchange_handler.
|
78
|
-
end
|
79
|
-
|
80
|
-
#
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
# @return [
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
# @
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../soaspec'
|
4
|
+
require_relative 'exchange_properties'
|
5
|
+
require_relative 'exchange_extractor'
|
6
|
+
require_relative 'request_builder'
|
7
|
+
require_relative 'exchange_repeater'
|
8
|
+
require_relative 'variable_storer'
|
9
|
+
|
10
|
+
# This represents a request / response pair
|
11
|
+
# Essentially, params in the exchange that are set are related to the request
|
12
|
+
# What is returned is related to the response
|
13
|
+
#
|
14
|
+
# It is tied to an ExchangeHandler that needs to be defined either globally before it's created or in 'default_handler_used'
|
15
|
+
class Exchange
|
16
|
+
extend Soaspec::ExchangeProperties
|
17
|
+
include Soaspec::ExchangeExtractor
|
18
|
+
include Soaspec::RequestBuilder
|
19
|
+
include Soaspec::ExchangeRepeater
|
20
|
+
include Soaspec::VariableStorer
|
21
|
+
|
22
|
+
# @return [ExchangeHandler] Instance of ExchangeHandler for which this exchange is made
|
23
|
+
attr_accessor :exchange_handler
|
24
|
+
# @return [Integer] How many times to retry for a success
|
25
|
+
attr_accessor :retry_count
|
26
|
+
# @return [Integer] Times request was retried before being returned
|
27
|
+
attr_accessor :times_retried
|
28
|
+
# @return [String] Name used for displaying class
|
29
|
+
attr_accessor :test_name
|
30
|
+
# @return [Boolean] Expect Factory to fail upon trying to create
|
31
|
+
attr_writer :fail_factory
|
32
|
+
# @return [Hash] Parameters to override for default params defined in ExchangeHandler
|
33
|
+
# These are the parameters specific to the Exchange and will override, append to
|
34
|
+
# what's defined in the ExchangeHandler
|
35
|
+
attr_accessor :override_parameters
|
36
|
+
|
37
|
+
# Set retry for success variable to true so that request will be retried
|
38
|
+
# for retry_count until it's true
|
39
|
+
def retry_for_success
|
40
|
+
@retry_for_success = true
|
41
|
+
self
|
42
|
+
end
|
43
|
+
|
44
|
+
# This is set on an individual Exchange marking it as one that should be retried
|
45
|
+
# @return [Bool] Whether to keep making request until success code reached
|
46
|
+
def retry_for_success?
|
47
|
+
@retry_for_success
|
48
|
+
end
|
49
|
+
|
50
|
+
# Defined as general rule from ExchangeHandler
|
51
|
+
# @return [Boolean] Whether exception is an exception that must be retried
|
52
|
+
def invalid_exception?
|
53
|
+
!exchange_handler.retry_on_exceptions.find { |e| e == exchange_handler.exception.class }.nil?
|
54
|
+
end
|
55
|
+
|
56
|
+
# Override this in subclass to tie that subclass to an ExchangeHandler
|
57
|
+
# @return [Soaspec::ExchangeHandler] Soaspec::ExchangeHandler used by this exchange
|
58
|
+
def default_handler_used; end
|
59
|
+
|
60
|
+
# Create new Exchange according to parameters set. A response will be made if called
|
61
|
+
# explicitly with 'response' method or through other methods that use it like 'status_code'
|
62
|
+
# @param [Symbol, String] name Name shown in RSpec run
|
63
|
+
# @param [Hash] override_parameters Parameters to override for default params (set through ExchangeHandler or Exchange class)
|
64
|
+
# These are the parameters that would be specific for a test
|
65
|
+
def initialize(name = self.class.to_s, override_parameters = {})
|
66
|
+
if name.is_a? Hash # Name not provided
|
67
|
+
override_parameters = name
|
68
|
+
name = nil
|
69
|
+
end
|
70
|
+
self.test_name ||= name.to_s
|
71
|
+
@override_parameters = override_parameters
|
72
|
+
# As a last resort this uses the global parameter. The handler should be set straight before an exchange is made to use this
|
73
|
+
@exchange_handler ||= default_handler_used || Soaspec.api_handler
|
74
|
+
@fail_factory = nil
|
75
|
+
@retry_for_success = false
|
76
|
+
self.retry_count = exchange_handler.retry_exception_limit
|
77
|
+
exchange_handler.elements.each { |element| methods_for_element(element) }
|
78
|
+
end
|
79
|
+
|
80
|
+
# @return [Hash] Hash representing what will be sent
|
81
|
+
def request_parameters
|
82
|
+
exchange_handler.request_parameters(@override_parameters)
|
83
|
+
end
|
84
|
+
|
85
|
+
# Make request to handler with parameters defined
|
86
|
+
# Will retry until success code reached if retry_for_success? is set
|
87
|
+
# @return [Response] Response from Api handler
|
88
|
+
def make_request
|
89
|
+
Soaspec::SpecLogger.info 'Example ' + test_name
|
90
|
+
request_params = @override_parameters
|
91
|
+
(0..retry_count).each do |count|
|
92
|
+
response = exchange_handler.make_request(request_params)
|
93
|
+
return response if !retry_for_success? && !invalid_exception?
|
94
|
+
return response if (200..299).cover? exchange_handler.status_code_for(response)
|
95
|
+
|
96
|
+
sleep exchange_handler.retry_pause_time # Time before retrying
|
97
|
+
self.times_retried = count
|
98
|
+
break response if count == retry_count
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# Name describing this class when used with `RSpec.describe`
|
103
|
+
# This will make the request and store the response
|
104
|
+
# @return [String] Name given when initializing
|
105
|
+
def to_s
|
106
|
+
test_name
|
107
|
+
end
|
108
|
+
|
109
|
+
# @return [RestClient::Response,Savon::Response] Returns response object from Api.
|
110
|
+
# Will make the request if not made and then cache it for later on
|
111
|
+
# @example For SOAP it will be a Savon response
|
112
|
+
# response.body (body of response as Hash)
|
113
|
+
# response.header (head of response as Hash)
|
114
|
+
# @example For REST it will be a RestClient::Response
|
115
|
+
def response
|
116
|
+
require 'forwardable'
|
117
|
+
Soaspec.last_exchange = self
|
118
|
+
@response ||= make_request
|
119
|
+
@response.define_singleton_method(:exchange) { Soaspec.last_exchange } unless @response.respond_to?(:exchange)
|
120
|
+
@response.extend Forwardable
|
121
|
+
@response.delegate %i[value_from_path values_from_path] => :exchange
|
122
|
+
@response
|
123
|
+
end
|
124
|
+
|
125
|
+
# @return [ResponseObject] Currently returning response object. This will change (in 0.3) to be itself to
|
126
|
+
# allow easy method chaining
|
127
|
+
def call
|
128
|
+
response
|
129
|
+
self
|
130
|
+
end
|
131
|
+
end
|
@@ -1,90 +1,105 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Soaspec
|
4
|
-
# Methods for extracting aspects of the traffic for a request / response
|
5
|
-
# in an exchange from the ExchangeHandler that it's tied to
|
6
|
-
module ExchangeExtractor
|
7
|
-
# Request of API call. Either intended request or actual request
|
8
|
-
# @return [Object] Object representing request of API
|
9
|
-
def request
|
10
|
-
exchange_handler.request(@response)
|
11
|
-
end
|
12
|
-
|
13
|
-
# Get status code from api class. This is http response code for Web Api
|
14
|
-
# @return [Integer] Status code from api class
|
15
|
-
def status_code
|
16
|
-
exchange_handler.status_code_for(response)
|
17
|
-
end
|
18
|
-
|
19
|
-
# @return [Boolean] Whether Api success code is successful
|
20
|
-
def successful_status_code?
|
21
|
-
(200..299).cover? status_code
|
22
|
-
end
|
23
|
-
|
24
|
-
# Extract value from path api class
|
25
|
-
# @example Extract unique value
|
26
|
-
# @exchange['unique_value_name']
|
27
|
-
# @example Extract value via JSON path
|
28
|
-
# @exchange['$..path.to.element']
|
29
|
-
# @example Extract value via XPath
|
30
|
-
# @exchange['//path/to/element']
|
31
|
-
# @param [Object] path Path to return element for api class E.g - for SOAP this is XPath string. For JSON, this is Hash dig Array
|
32
|
-
# @return [String] Value at path
|
33
|
-
def [](path)
|
34
|
-
exchange_handler.value_from_path(response, path.to_s)
|
35
|
-
end
|
36
|
-
|
37
|
-
alias value_from_path []
|
38
|
-
|
39
|
-
#
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
# @
|
54
|
-
#
|
55
|
-
# @
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
#
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
#
|
66
|
-
# @
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Soaspec
|
4
|
+
# Methods for extracting aspects of the traffic for a request / response
|
5
|
+
# in an exchange from the ExchangeHandler that it's tied to
|
6
|
+
module ExchangeExtractor
|
7
|
+
# Request of API call. Either intended request or actual request
|
8
|
+
# @return [Object] Object representing request of API
|
9
|
+
def request
|
10
|
+
exchange_handler.request(@response)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Get status code from api class. This is http response code for Web Api
|
14
|
+
# @return [Integer] Status code from api class
|
15
|
+
def status_code
|
16
|
+
exchange_handler.status_code_for(response)
|
17
|
+
end
|
18
|
+
|
19
|
+
# @return [Boolean] Whether Api success code is successful
|
20
|
+
def successful_status_code?
|
21
|
+
(200..299).cover? status_code
|
22
|
+
end
|
23
|
+
|
24
|
+
# Extract value from path api class
|
25
|
+
# @example Extract unique value
|
26
|
+
# @exchange['unique_value_name']
|
27
|
+
# @example Extract value via JSON path
|
28
|
+
# @exchange['$..path.to.element']
|
29
|
+
# @example Extract value via XPath
|
30
|
+
# @exchange['//path/to/element']
|
31
|
+
# @param [Object] path Path to return element for api class E.g - for SOAP this is XPath string. For JSON, this is Hash dig Array
|
32
|
+
# @return [String] Value at path
|
33
|
+
def [](path)
|
34
|
+
exchange_handler.value_from_path(response, path.to_s)
|
35
|
+
end
|
36
|
+
|
37
|
+
alias value_from_path []
|
38
|
+
|
39
|
+
# @return [Symbol] Type of response. XML, JSON, etc
|
40
|
+
def format
|
41
|
+
Interpreter.response_type_for(response)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Using same path syntax as []. Returns true of false depending on whether an element is found
|
45
|
+
# @return [Boolean] Whether an element exists at the path
|
46
|
+
def element?(path)
|
47
|
+
self[path]
|
48
|
+
true
|
49
|
+
rescue NoElementAtPath
|
50
|
+
false
|
51
|
+
end
|
52
|
+
|
53
|
+
# @example Counting items in a JSON list
|
54
|
+
# # Say there is JSON response {"notes":[{"title":"note1","note":"A note"},{"title":"note2"}]}
|
55
|
+
# titles = @exchange.values_at_path('$..title')
|
56
|
+
# expect(titles.count).to eq 2
|
57
|
+
# expect(titles.first).to eq 'note1'
|
58
|
+
# @param [String] path XPath, JSONPath to extract value
|
59
|
+
# @param [String] attribute Attribute to obtain from XML element
|
60
|
+
# @return [Array] List of values found at path
|
61
|
+
def values_from_path(path, attribute: nil)
|
62
|
+
exchange_handler.values_from_path(response, path, attribute: attribute)
|
63
|
+
end
|
64
|
+
|
65
|
+
# Return the response equivalent of the response. XML, JSON will be converted to a Hash
|
66
|
+
# @example Counting items in a JSON list
|
67
|
+
# # Say there is JSON response {"notes":[{"title":"note1","note":"A note"},{"title":"note2"}]}
|
68
|
+
# hash = @exchange.to_hash
|
69
|
+
# expect(hash['notes'].count).to eq 2
|
70
|
+
# expect(hash['notes'].first['title']).to eq 'note1'
|
71
|
+
# @return [Hash] Hash representing the response of the API
|
72
|
+
def to_hash
|
73
|
+
exchange_handler.to_hash(response)
|
74
|
+
end
|
75
|
+
|
76
|
+
# @return [String] Get multiline pretty version of response
|
77
|
+
def pretty_response_body
|
78
|
+
case format
|
79
|
+
when :json then JSON.pretty_generate to_hash
|
80
|
+
when :xml then response.body # TODO: Single line XML make multiline
|
81
|
+
else
|
82
|
+
response.body
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
|
88
|
+
# Used to define methods on an exchange based on what's defined by the ExchangeHandler's methods
|
89
|
+
# @param [String] element Element to define methods for
|
90
|
+
def methods_for_element(element)
|
91
|
+
element_name = element.to_s.split('__custom_path_').last
|
92
|
+
define_singleton_method(element_name) do
|
93
|
+
exchange_handler.__send__(element, response) # Forward the call onto handler to retrieve the element for the response
|
94
|
+
end
|
95
|
+
define_singleton_method("#{element_name}?") do
|
96
|
+
begin
|
97
|
+
__send__ element_name
|
98
|
+
true
|
99
|
+
rescue NoElementAtPath
|
100
|
+
false
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|