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