lib/soaspec/exchange_handlers/rest_handler.rb in soaspec-0.2.21 vs lib/soaspec/exchange_handlers/rest_handler.rb in soaspec-0.2.22
- old
+ new
@@ -161,10 +161,28 @@
raise 'JSON does not support attributes' if attribute
JsonPath.on(response.body, path)
end
+ # Calculate all JSON path values based on rules. ',', pascal_case
+ # @param [RestClient::Response] response Response from API
+ # @param [Object] path Xpath, JSONPath or other path identifying how to find element
+ # @param [String] attribute Generic attribute to find. Will override path
+ # @param [Boolean] not_empty Whether to fail if result is empty
+ # @return [Array] Paths to check as first and matching values (List of values matching JSON Path) as second
+ def calculated_json_path_matches(path, response, attribute, not_empty: false)
+ path = add_pascal_path(path)
+ paths_to_check = path.split(',')
+ paths_to_check = paths_to_check.map { |path_to_check| prefix_json_path(path_to_check) }
+ matching_values = paths_to_check.collect do |path_to_check|
+ json_path_values_for(response, path_to_check, attribute: attribute)
+ end.reject(&:empty?)
+ raise NoElementAtPath, "No value at JSONPath '#{paths_to_check}' in '#{response.body}'" if matching_values.empty? && not_empty
+
+ matching_values.first
+ end
+
# Based on a exchange, return the value at the provided xpath
# If the path does not begin with a '/', a '//' is added to it
# @param [RestClient::Response] response Response from API
# @param [Object] path Xpath, JSONPath or other path identifying how to find element
# @param [String] attribute Generic attribute to find. Will override path
@@ -177,35 +195,28 @@
raise NoElementAtPath, "No value at Xpath '#{prefix_xpath(path, attribute)}' in '#{response.body}'" unless result
return result.inner_text if attribute.nil?
return result.attributes[attribute].inner_text
when :json
- path = add_pascal_path(path)
- paths_to_check = path.split(',')
- paths_to_check = paths_to_check.map { |path_to_check| prefix_json_path(path_to_check) }
- matching_values = paths_to_check.collect do |path_to_check|
- json_path_values_for(response, path_to_check, attribute: attribute)
- end.reject(&:empty?)
- raise NoElementAtPath, "No value at JSONPath '#{paths_to_check}' in '#{response.body}'" if matching_values.empty?
-
- matching_values.first.first
- when :hash
- response.dig(path.split('.')) # Use path as Hash dig expression separating params via '.' TODO: Unit test
- else
+ matching_values = calculated_json_path_matches(path, response, attribute, not_empty: true)
+ matching_values.first
+ else # Assume this is a String
raise NoElementAtPath, 'Response is empty' if response.to_s.empty?
- response.to_s[/path/] # Perform regular expression using path if not XML nor JSON TODO: Unit test
+ response.to_s[/#{path}/] # Perform regular expression using path if not XML nor JSON
end
end
# @return [Enumerable] List of values returned from path
def values_from_path(response, path, attribute: nil)
path = path.to_s
case Interpreter.response_type_for(response)
when :xml
xpath_elements_for(response: response, xpath: path, attribute: attribute).map(&:inner_text)
when :json
- json_path_values_for(response, path, attribute: attribute)
+ result = calculated_json_path_matches(path, response, attribute)
+ result || []
+ # json_path_values_for(response, path, attribute: attribute)
else
raise "Unable to interpret type of #{response.body}"
end
end