lib/soaspec/exchange_handlers/rest_handler.rb in soaspec-0.1.18 vs lib/soaspec/exchange_handlers/rest_handler.rb in soaspec-0.2.0

- old
+ new

@@ -1,38 +1,42 @@ require_relative 'exchange_handler' -require_relative 'rest_accessors' +require_relative 'rest_parameters' +require_relative 'rest_parameters_defaults' +require_relative 'rest_exchanger_factory' require_relative '../core_ext/hash' require_relative '../not_found_errors' require_relative 'handler_accessors' require_relative '../interpreter' require 'json' require 'jsonpath' require 'nori' require 'erb' +require 'hashie/extensions/indifferent_access' module Soaspec # Wraps around Savon client defining default values dependent on the soap request class RestHandler < ExchangeHandler - extend Soaspec::RestAccessors - include Soaspec::RestAccessorsDefaults + extend Soaspec::RestParameters + include Soaspec::RestParametersDefaults + extend Soaspec::RestExchangeFactory # User used in making API calls attr_accessor :api_username # Setup object to handle communicating with a particular SOAP WSDL # @param [Hash] options Options defining REST request. base_url, default_hash def initialize(name = self.class.to_s, options = {}) raise "Base URL not set! Please set in class with 'base_url' method" unless base_url_value - @default_hash = {} if name.is_a?(Hash) && options == {} # If name is not set, use first parameter as the options hash options = name name = self.class.to_s end super set_remove_keys(options, %i[api_username default_hash template_name]) @init_options = options + init_merge_options # Call this to verify any issues with options on creating object end # Used in together with Exchange request that passes such override parameters # @param [Hash] override_parameters Params to characterize REST request # @option override_parameters [Hash] :params Extra parameters (E.g. headers) @@ -41,10 +45,11 @@ # @option override_parameters [Symbol] :method REST method (:get, :post, :patch, etc) # Following are for the body of the request # @option override_parameters [Hash] :body Hash to be converted to JSON in request body # @option override_parameters [String] :payload String to be passed directly in request body # @option override_parameters [String] :template_name Path to file to be read via ERB and passed in request body + # @return [RestClient::Response] Response from making request def make_request(override_parameters) @merged_options ||= init_merge_options test_values = override_parameters test_values[:params] ||= {} test_values[:method] ||= :post @@ -80,11 +85,14 @@ end # Perform ERB on each header value # @return [Hash] Hash from 'rest_client_headers' passed through ERB def parse_headers - Hash[rest_client_headers.map { |k, header| [k, ERB.new(header).result(binding)] }] + Hash[rest_client_headers.map do |header_name, header_value| + raise ArgumentError, "Header '#{header_name}' is null. Headers are #{rest_client_headers}" if header_value.nil? + [header_name, ERB.new(header_value).result(binding)] + end] end # Convert snakecase to PascalCase def convert_to_pascal_case(key) return key if /[[:upper:]]/ =~ key[0] # If first character already capital, don't do conversion @@ -93,10 +101,11 @@ # Initialize value of merged options # @return [Hash] Hash of merged options def init_merge_options options = rest_resource_options + options.merge! basic_auth_params if respond_to? :basic_auth_params options[:headers] ||= {} options[:headers].merge! parse_headers if Soaspec.auto_oauth && respond_to?(:access_token) options[:headers][:authorization] ||= ERB.new('Bearer <%= access_token %>').result(binding) end @@ -248,13 +257,14 @@ private # Work out data to send based upon payload, template_name, or body # @return [String] Payload to send in REST request def post_data(test_values) - data = if test_values[:body] + data = if @request_option == :hash && test_values[:body] test_values[:payload] = JSON.generate(hash_used_in_request(test_values[:body])).to_s elsif @request_option == :template + test_values = test_values[:body].dup if test_values[:body] Soaspec::TemplateReader.new.render_body(template_name, binding) else test_values[:payload] end # Soaspec::SpecLogger.info "Request Empty for '#{@request_option}'" if data.strip.empty? @@ -266,41 +276,9 @@ request = @default_hash.merge(override_hash) if pascal_keys? request.map { |k, v| [convert_to_pascal_case(k.to_s), v] }.to_h else request - end - end - - # Convenience methods for once off usage of a REST request - class << self - - methods = %w[post patch put get delete] - - methods.each do |rest_method| - # Make REST Exchange within this Handler context - # @param [Hash, String] params Exchange parameters. If String is used it will be for suburl - # @return [Exchange] Instance of Exchange class. Assertions are made by default on the response body - define_method(rest_method) do |params = {}| - unless params.is_a? Hash - params = case rest_method - when 'get', 'delete' - { suburl: params.to_s } - when 'post', 'put', 'patch' - { payload: params.to_s } - else - params - end - end - params[:name] ||= rest_method - exchange_params = { name: params[:name] } - if params[:template_name] - exchange_params[:template_name] = params[:template_name] - params.delete :template_name - end - new(exchange_params) - Exchange.new(params[:name], method: rest_method.to_sym, **params) - end end end end end