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

- old
+ new

@@ -1,129 +1,131 @@ -# frozen_string_literal: true - -require_relative '../../soaspec' -require_relative 'exchange_properties' -require_relative 'exchange_extractor' -require_relative 'request_builder' -require_relative 'exchange_repeater' -require_relative 'variable_storer' - -# This represents a request / response pair -# Essentially, params in the exchange that are set are related to the request -# What is returned is related to the response -# -# It is tied to an ExchangeHandler that needs to be defined either globally before it's created or in 'default_handler_used' -class Exchange - extend Soaspec::ExchangeProperties - include Soaspec::ExchangeExtractor - include Soaspec::RequestBuilder - include Soaspec::ExchangeRepeater - include Soaspec::VariableStorer - - # Instance of ExchangeHandler for which this exchange is made - attr_accessor :exchange_handler - # @return [Integer] How many times to retry for a success - attr_accessor :retry_count - # @return [Integer] Times request was retried before being returned - attr_accessor :times_retried - # @@return [String] Name used for displaying class - attr_accessor :test_name - # Expect Factory to fail upon trying to create - attr_writer :fail_factory - # Parameters to override for default params - attr_accessor :override_parameters - - # Set retry for success variable to true so that request will be retried - # for retry_count until it's true - def retry_for_success - @retry_for_success = true - self - end - - # This is set on an individual Exchange marking it as one that should be retried - # @return [Bool] Whether to keep making request until success code reached - def retry_for_success? - @retry_for_success - end - - # Defined as general rule from ExchangeHandler - # @return [Boolean] Whether exception is an exception that must be retried - def invalid_exception? - !exchange_handler.retry_on_exceptions.find { |e| e == exchange_handler.exception.class }.nil? - end - - # Override this in subclass to tie that subclass to an ExchangeHandler - # @return [Soaspec::ExchangeHandler] Soaspec::ExchangeHandler used by this exchange - def default_handler_used; end - - # Create new Exchange according to parameters set. A response will be made if called - # explicitly with 'response' method or through other methods that use it like 'status_code' - # @param [Symbol, String] name Name shown in RSpec run - # @param [Hash] override_parameters Parameters to override for default params - def initialize(name = self.class.to_s, override_parameters = {}) - self.test_name ||= name.to_s - # As a last resort this uses the global parameter. The handler should be set straight before an exchange is made to use this - @exchange_handler ||= default_handler_used || Soaspec.api_handler - raise '@exchange_handler not set. Set either with `Soaspec.api_handler = Handler.new` or within the exchange' unless @exchange_handler - - @fail_factory = nil - @override_parameters = override_parameters - @retry_for_success = false - self.retry_count = exchange_handler.retry_exception_limit - exchange_handler.elements.each { |element| methods_for_element(element) } - end - - # @return [Hash] Hash representing what will be sent - def request_parameters - exchange_handler.request_parameters(@override_parameters) - end - - # Make request to handler with parameters defined - # Will retry until success code reached if retry_for_success? is set - # @return [Response] Response from Api handler - def make_request - Soaspec::SpecLogger.info 'Example ' + test_name - request_params = @override_parameters - (0..retry_count).each do |count| - response = exchange_handler.make_request(request_params) - return response if !retry_for_success? && !invalid_exception? - return response if (200..299).cover? exchange_handler.status_code_for(response) - - sleep exchange_handler.retry_pause_time # Time before retrying - self.times_retried = count - break response if count == retry_count - end - end - - # Name describing this class when used with `RSpec.describe` - # This will make the request and store the response - # @return [String] Name given when initializing - def to_s - test_name - end - - # @return [RestClient::Response,Savon::Response] Returns response object from Api. - # Will make the request if not made and then cache it for later on - # @example For SOAP it will be a Savon response - # response.body (body of response as Hash) - # response.header (head of response as Hash) - # @example For REST it will be a RestClient::Response - def response - require 'forwardable' - Soaspec.last_exchange = self - @response ||= make_request - @response.define_singleton_method(:exchange) { Soaspec.last_exchange } unless @response.respond_to?(:exchange) - @response.extend Forwardable - @response.delegate %i[value_from_path values_from_path] => :exchange - @response - end - - # @return [ResponseObject] Currently returning response object. This will change (in 0.3) to be itself to - # allow easy method chaining - def call - if Soaspec.log_warnings - warn 'This "call" method will be changed to return "Exchange" object in 0.3. ' \ - 'Use "response" method if you want the "response" object' - end - response - end -end +# frozen_string_literal: true + +require_relative '../../soaspec' +require_relative 'exchange_properties' +require_relative 'exchange_extractor' +require_relative 'request_builder' +require_relative 'exchange_repeater' +require_relative 'variable_storer' + +# This represents a request / response pair +# Essentially, params in the exchange that are set are related to the request +# What is returned is related to the response +# +# It is tied to an ExchangeHandler that needs to be defined either globally before it's created or in 'default_handler_used' +class Exchange + extend Soaspec::ExchangeProperties + include Soaspec::ExchangeExtractor + include Soaspec::RequestBuilder + include Soaspec::ExchangeRepeater + include Soaspec::VariableStorer + + # @return [ExchangeHandler] Instance of ExchangeHandler for which this exchange is made + attr_accessor :exchange_handler + # @return [Integer] How many times to retry for a success + attr_accessor :retry_count + # @return [Integer] Times request was retried before being returned + attr_accessor :times_retried + # @return [String] Name used for displaying class + attr_accessor :test_name + # @return [Boolean] Expect Factory to fail upon trying to create + attr_writer :fail_factory + # @return [Hash] Parameters to override for default params defined in ExchangeHandler + # These are the parameters specific to the Exchange and will override, append to + # what's defined in the ExchangeHandler + attr_accessor :override_parameters + + # Set retry for success variable to true so that request will be retried + # for retry_count until it's true + def retry_for_success + @retry_for_success = true + self + end + + # This is set on an individual Exchange marking it as one that should be retried + # @return [Bool] Whether to keep making request until success code reached + def retry_for_success? + @retry_for_success + end + + # Defined as general rule from ExchangeHandler + # @return [Boolean] Whether exception is an exception that must be retried + def invalid_exception? + !exchange_handler.retry_on_exceptions.find { |e| e == exchange_handler.exception.class }.nil? + end + + # Override this in subclass to tie that subclass to an ExchangeHandler + # @return [Soaspec::ExchangeHandler] Soaspec::ExchangeHandler used by this exchange + def default_handler_used; end + + # Create new Exchange according to parameters set. A response will be made if called + # explicitly with 'response' method or through other methods that use it like 'status_code' + # @param [Symbol, String] name Name shown in RSpec run + # @param [Hash] override_parameters Parameters to override for default params (set through ExchangeHandler or Exchange class) + # These are the parameters that would be specific for a test + def initialize(name = self.class.to_s, override_parameters = {}) + if name.is_a? Hash # Name not provided + override_parameters = name + name = nil + end + self.test_name ||= name.to_s + @override_parameters = override_parameters + # As a last resort this uses the global parameter. The handler should be set straight before an exchange is made to use this + @exchange_handler ||= default_handler_used || Soaspec.api_handler + @fail_factory = nil + @retry_for_success = false + self.retry_count = exchange_handler.retry_exception_limit + exchange_handler.elements.each { |element| methods_for_element(element) } + end + + # @return [Hash] Hash representing what will be sent + def request_parameters + exchange_handler.request_parameters(@override_parameters) + end + + # Make request to handler with parameters defined + # Will retry until success code reached if retry_for_success? is set + # @return [Response] Response from Api handler + def make_request + Soaspec::SpecLogger.info 'Example ' + test_name + request_params = @override_parameters + (0..retry_count).each do |count| + response = exchange_handler.make_request(request_params) + return response if !retry_for_success? && !invalid_exception? + return response if (200..299).cover? exchange_handler.status_code_for(response) + + sleep exchange_handler.retry_pause_time # Time before retrying + self.times_retried = count + break response if count == retry_count + end + end + + # Name describing this class when used with `RSpec.describe` + # This will make the request and store the response + # @return [String] Name given when initializing + def to_s + test_name + end + + # @return [RestClient::Response,Savon::Response] Returns response object from Api. + # Will make the request if not made and then cache it for later on + # @example For SOAP it will be a Savon response + # response.body (body of response as Hash) + # response.header (head of response as Hash) + # @example For REST it will be a RestClient::Response + def response + require 'forwardable' + Soaspec.last_exchange = self + @response ||= make_request + @response.define_singleton_method(:exchange) { Soaspec.last_exchange } unless @response.respond_to?(:exchange) + @response.extend Forwardable + @response.delegate %i[value_from_path values_from_path] => :exchange + @response + end + + # @return [ResponseObject] Currently returning response object. This will change (in 0.3) to be itself to + # allow easy method chaining + def call + response + self + end +end