class Soaspec::SoapHandler
Wraps around Savon client defining default values dependent on the soap request
Attributes
Savon client used to make SOAP calls
SOAP Operation to use by default
@return [Hash] List of Savon globals
Public Class Methods
Implement undefined setter with []= for FactoryBot to use without needing to define params to set @param [Object] method_name Name of method not defined @param [Object] args Arguments passed to method @param [Object] block
# File lib/soaspec/exchange_handlers/soap_handler.rb, line 227 def method_missing(method_name, *args, &block) if operations.include? method_name tmp_class = new(method_name) tmp_class.operation = method_name exchange = Exchange.new(method_name, *args) exchange.exchange_handler = tmp_class yield exchange if block_given? exchange else super end end
Setup object to handle communicating with a particular SOAP WSDL @param [String] name Name to describe handler. Used in calling 'to_s' @param [Hash] options Options defining SOAP request. WSDL, authentication,
See http://savonrb.com/version2/globals.html for list of options
Soaspec::ExchangeHandler::new
# File lib/soaspec/exchange_handlers/soap_handler.rb, line 71 def initialize(name = self.class.to_s, options = {}) if name.is_a?(Hash) && options == {} # If name is not set options = name name = self.class.to_s end super set_remove_keys(options, %i[operation default_hash template_name]) merged_options = SoapDefaults.options merged_options.merge!(logging_options) if Soaspec::SpecLogger.log_api_traffic? merged_options.merge! savon_options merged_options.merge! savon_globals merged_options.merge!(options) Soaspec::SpecLogger.info "Using Savon globals: #{merged_options}" self.client = Savon.client(merged_options) end
@return [Array] List of operations WSDL can perform
# File lib/soaspec/exchange_handlers/soap_handler.rb, line 218 def operations operation_class = new('Get operations') operation_class.operations end
Override respond_to_missing so that any method name that is an operation can be used
# File lib/soaspec/exchange_handlers/soap_handler.rb, line 242 def respond_to_missing?(method_name, *args) operations.include?(method_name) || super end
Public Instance Methods
Convert all XML nodes to lowercase @param [Nokogiri::XML::Document] xml_doc Xml document to convert
# File lib/soaspec/exchange_handlers/soap_handler.rb, line 159 def convert_to_lower_case(xml_doc) xml_doc.traverse do |node| node.name = node.name.downcase if node.is_a?(Nokogiri::XML::Element) end end
@return [Boolean] Whether the request found the desired value or not
# File lib/soaspec/exchange_handlers/soap_handler.rb, line 133 def found?(response) status_code_for(response) != 404 end
@return [Boolean] Whether response includes provided string within it
# File lib/soaspec/exchange_handlers/soap_handler.rb, line 145 def include_in_body?(response, expected) response.to_xml.to_s.include? expected end
@param [Symbol] expected @return [Boolean] Whether response body contains expected key
# File lib/soaspec/exchange_handlers/soap_handler.rb, line 151 def include_key?(response, expected) body = response.body body.extend Hashie::Extensions::DeepFind !body.deep_find_all(expected).empty? end
@return [Boolean] Whether any of the keys of the Body Hash
include value
# File lib/soaspec/exchange_handlers/soap_handler.rb, line 206 def include_value?(response, expected_value) response.body.include_value?(expected_value) end
Options to log xml request and response
# File lib/soaspec/exchange_handlers/soap_handler.rb, line 51 def logging_options { log: true, # See request and response. (Put this in traffic file) log_level: :debug, logger: Soaspec::SpecLogger.create, pretty_print_xml: true # Prints XML pretty } end
Used in together with Exchange
request that passes such override parameters @param [Hash] request_parameters
Parameters used to overwrite defaults in request
# File lib/soaspec/exchange_handlers/soap_handler.rb, line 109 def make_request(request_parameters) # Call the SOAP operation with the request XML provided request = request_parameters(request_parameters) begin client.call request.operation, request.body # request_body_params(request_parameters) rescue Savon::HTTPError => e e end end
Used in making request via hash or in template via Erb @param [Hash] request_parameters
Hash
representing elements to send in request
If the :body key is set, this will be used as the request body
# File lib/soaspec/exchange_handlers/soap_handler.rb, line 96 def request_body_params(request_parameters) test_values = request_parameters[:body] || request_parameters test_values.transform_keys_to_symbols if Soaspec.always_use_keys? if @request_option == :template test_values = IndifferentHash.new(test_values) # Allow test_values to be either Symbol or String { xml: Soaspec::TemplateReader.new.render_body(template_name, test_values) } elsif @request_option == :hash { message: @default_hash.merge(test_values), attributes: request_root_attributes } end end
@param [Hash] override_parameters Parameters for building the request @return [SoapRequest] Parameters used in making a request
# File lib/soaspec/exchange_handlers/soap_handler.rb, line 89 def request_parameters(override_parameters) SoapRequest.new(operation, request_body_params(override_parameters), @request_option) end
Attributes set at the root XML element of SOAP request
# File lib/soaspec/exchange_handlers/soap_handler.rb, line 48 def request_root_attributes; end
@param [Hash] format Format of expected result @return [Object] Generic body to be displayed in error messages
# File lib/soaspec/exchange_handlers/soap_handler.rb, line 121 def response_body(response, format: :hash) case format when :hash response.body when :raw response.xml else response.body end end
# File lib/soaspec/exchange_handlers/soap_handler.rb, line 38 def savon_globals @savon_globals = {} %i[wsdl basic_auth soap_version raise_errors namespace namespaces endpoint ssl_verify_mode].each do |global| @savon_globals.merge!(global => send(global)) if respond_to? global end @savon_globals end
Add values to here when extending this class to have default Savon options. See savonrb.com/version2/globals.html for details @return [Hash] Savon options adding to & overriding defaults
# File lib/soaspec/exchange_handlers/soap_handler.rb, line 63 def savon_options {} end
Response status code for response. '200' indicates a success @param [Savon::Response] response @return [Integer] Status code
# File lib/soaspec/exchange_handlers/soap_handler.rb, line 140 def status_code_for(response) response.http.code end
Hash
of response body
# File lib/soaspec/exchange_handlers/soap_handler.rb, line 211 def to_hash(response) response.body 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 [Savon::Response] response @param [String] path Xpath @param [String] attribute Generic attribute to find. Will override path @return [String] Value at Xpath
# File lib/soaspec/exchange_handlers/soap_handler.rb, line 190 def value_from_path(response, path, attribute: nil) results = xpath_elements_for(response: response, xpath: path, attribute: attribute) raise NoElementAtPath, "No value at Xpath '#{path}' in XML #{response.doc}" if results.empty? return results.first.inner_text if attribute.nil? results.first.attributes[attribute].inner_text end
@return [Enumerable] List of values returned from path
# File lib/soaspec/exchange_handlers/soap_handler.rb, line 199 def values_from_path(response, path, attribute: nil) xpath_elements_for(response: response, xpath: path, attribute: attribute).map(&:inner_text) end
Returns the value at the provided xpath @param [Savon::Response] response @param [String] xpath @return [Enumerable] Elements found through Xpath
# File lib/soaspec/exchange_handlers/soap_handler.rb, line 169 def xpath_elements_for(response: nil, xpath: nil, attribute: nil) raise ArgumentError('response and xpath must be passed to method') unless response && xpath xpath = "//*[@#{attribute}]" unless attribute.nil? xpath = '//' + xpath if xpath[0] != '/' temp_doc = response.doc.dup convert_to_lower_case(temp_doc) if convert_to_lower? if strip_namespaces? && !xpath.include?(':') temp_doc.remove_namespaces! temp_doc.xpath(xpath) else temp_doc.xpath(xpath, temp_doc.collect_namespaces) end end