lib/soaspec/exchange/exchange_extractor.rb in soaspec-0.2.33 vs lib/soaspec/exchange/exchange_extractor.rb in soaspec-0.3.1

- old
+ new

@@ -1,90 +1,105 @@ -# frozen_string_literal: true - -module Soaspec - # Methods for extracting aspects of the traffic for a request / response - # in an exchange from the ExchangeHandler that it's tied to - module ExchangeExtractor - # Request of API call. Either intended request or actual request - # @return [Object] Object representing request of API - def request - exchange_handler.request(@response) - end - - # Get status code from api class. This is http response code for Web Api - # @return [Integer] Status code from api class - def status_code - exchange_handler.status_code_for(response) - end - - # @return [Boolean] Whether Api success code is successful - def successful_status_code? - (200..299).cover? status_code - end - - # Extract value from path api class - # @example Extract unique value - # @exchange['unique_value_name'] - # @example Extract value via JSON path - # @exchange['$..path.to.element'] - # @example Extract value via XPath - # @exchange['//path/to/element'] - # @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 - # @return [String] Value at path - def [](path) - exchange_handler.value_from_path(response, path.to_s) - end - - alias value_from_path [] - - # Using same path syntax as []. Returns true of false depending on whether an element is found - # @return [Boolean] Whether an element exists at the path - def element?(path) - self[path] - true - rescue NoElementAtPath - false - end - - # @example Counting items in a JSON list - # # Say there is JSON response {"notes":[{"title":"note1","note":"A note"},{"title":"note2"}]} - # titles = @exchange.values_at_path('$..title') - # expect(titles.count).to eq 2 - # expect(titles.first).to eq 'note1' - # @param [String] path XPath, JSONPath to extract value - # @param [String] attribute Attribute to obtain from XML element - # @return [Array] List of values found at path - def values_from_path(path, attribute: nil) - exchange_handler.values_from_path(response, path, attribute: attribute) - end - - # Return the response equivalent of the response. XML, JSON will be converted to a Hash - # @example Counting items in a JSON list - # # Say there is JSON response {"notes":[{"title":"note1","note":"A note"},{"title":"note2"}]} - # hash = @exchange.to_hash - # expect(hash['notes'].count).to eq 2 - # expect(hash['notes'].first['title']).to eq 'note1' - # @return [Hash] Hash representing the response of the API - def to_hash - exchange_handler.to_hash(response) - end - - private - - # Used to define methods on an exchange based on what's defined by the ExchangeHandler's methods - # @param [String] element Element to define methods for - def methods_for_element(element) - element_name = element.to_s.split('__custom_path_').last - define_singleton_method(element_name) do - exchange_handler.__send__(element, response) # Forward the call onto handler to retrieve the element for the response - end - define_singleton_method("#{element_name}?") do - begin - __send__ element_name - true - rescue NoElementAtPath - false - end - end - end - end -end +# frozen_string_literal: true + +module Soaspec + # Methods for extracting aspects of the traffic for a request / response + # in an exchange from the ExchangeHandler that it's tied to + module ExchangeExtractor + # Request of API call. Either intended request or actual request + # @return [Object] Object representing request of API + def request + exchange_handler.request(@response) + end + + # Get status code from api class. This is http response code for Web Api + # @return [Integer] Status code from api class + def status_code + exchange_handler.status_code_for(response) + end + + # @return [Boolean] Whether Api success code is successful + def successful_status_code? + (200..299).cover? status_code + end + + # Extract value from path api class + # @example Extract unique value + # @exchange['unique_value_name'] + # @example Extract value via JSON path + # @exchange['$..path.to.element'] + # @example Extract value via XPath + # @exchange['//path/to/element'] + # @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 + # @return [String] Value at path + def [](path) + exchange_handler.value_from_path(response, path.to_s) + end + + alias value_from_path [] + + # @return [Symbol] Type of response. XML, JSON, etc + def format + Interpreter.response_type_for(response) + end + + # Using same path syntax as []. Returns true of false depending on whether an element is found + # @return [Boolean] Whether an element exists at the path + def element?(path) + self[path] + true + rescue NoElementAtPath + false + end + + # @example Counting items in a JSON list + # # Say there is JSON response {"notes":[{"title":"note1","note":"A note"},{"title":"note2"}]} + # titles = @exchange.values_at_path('$..title') + # expect(titles.count).to eq 2 + # expect(titles.first).to eq 'note1' + # @param [String] path XPath, JSONPath to extract value + # @param [String] attribute Attribute to obtain from XML element + # @return [Array] List of values found at path + def values_from_path(path, attribute: nil) + exchange_handler.values_from_path(response, path, attribute: attribute) + end + + # Return the response equivalent of the response. XML, JSON will be converted to a Hash + # @example Counting items in a JSON list + # # Say there is JSON response {"notes":[{"title":"note1","note":"A note"},{"title":"note2"}]} + # hash = @exchange.to_hash + # expect(hash['notes'].count).to eq 2 + # expect(hash['notes'].first['title']).to eq 'note1' + # @return [Hash] Hash representing the response of the API + def to_hash + exchange_handler.to_hash(response) + end + + # @return [String] Get multiline pretty version of response + def pretty_response_body + case format + when :json then JSON.pretty_generate to_hash + when :xml then response.body # TODO: Single line XML make multiline + else + response.body + end + end + + private + + # Used to define methods on an exchange based on what's defined by the ExchangeHandler's methods + # @param [String] element Element to define methods for + def methods_for_element(element) + element_name = element.to_s.split('__custom_path_').last + define_singleton_method(element_name) do + exchange_handler.__send__(element, response) # Forward the call onto handler to retrieve the element for the response + end + define_singleton_method("#{element_name}?") do + begin + __send__ element_name + true + rescue NoElementAtPath + false + end + end + end + end +end