Class: Exchange

Inherits:
Object
  • Object
show all
Extended by:
ExchangeAccessors
Defined in:
lib/soaspec/exchange.rb

Overview

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from ExchangeAccessors

default_handler, expect_positive_status

Constructor Details

#initialize(name = self.class.to_s, override_parameters = {}) ⇒ Exchange

Returns a new instance of Exchange.

Parameters:

  • name (Symbol, String) (defaults to: self.class.to_s)

    Name shown in RSpec run

  • override_parameters (Hash) (defaults to: {})

    Parameters to override for default params



80
81
82
83
84
85
86
87
88
89
90
# File 'lib/soaspec/exchange.rb', line 80

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 = 3
  @exchange_handler.elements.each { |element| methods_for_element(element) }
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_name, *args, &block) ⇒ Object

Implement undefined setter with []= for FactoryBot to use without needing to define params to set

Parameters:

  • method_name (Object)

    Name of method not defined

  • args (Object)

    Arguments passed to method

  • block (Object)


196
197
198
199
200
201
202
203
204
205
206
207
208
# File 'lib/soaspec/exchange.rb', line 196

def method_missing(method_name, *args, &block)
  if method_name[-1] == '=' # A setter method
    if args.first.class < Exchange # This would be prerequisite exchange
      define_singleton_method(method_name[0..-2]) do
        args.first
      end
    else
      self[method_name[0..-2]] = args.first
    end
  else
    super
  end
end

Instance Attribute Details

#exchange_handlerObject

Instance of ExchangeHandler for which this exchange is made



37
38
39
# File 'lib/soaspec/exchange.rb', line 37

def exchange_handler
  @exchange_handler
end

#fail_factory=(value) ⇒ Object (writeonly)

Expect Factory to fail upon trying to create



43
44
45
# File 'lib/soaspec/exchange.rb', line 43

def fail_factory=(value)
  @fail_factory = value
end

#retry_countObject

How many times to retry for a success



39
40
41
# File 'lib/soaspec/exchange.rb', line 39

def retry_count
  @retry_count
end

#test_nameObject

Name used for displaying class



41
42
43
# File 'lib/soaspec/exchange.rb', line 41

def test_name
  @test_name
end

Instance Method Details

#[](path) ⇒ String

Extract value from path api class

Parameters:

  • path (Object)

    Path to return element for api class E.g - for SOAP this is XPath string. For JSON, this is Hash dig Array

Returns:

  • (String)

    Value at path



180
181
182
# File 'lib/soaspec/exchange.rb', line 180

def [](path)
  exchange_handler.value_from_path(response, path.to_s)
end

#[]=(key, value) ⇒ Object

Set a parameter request in the request body. Can be used to build a request over several steps (e.g Cucumber) Will be used with FactoryBot



187
188
189
190
# File 'lib/soaspec/exchange.rb', line 187

def []=(key, value)
  @override_parameters[:body] ||= {}
  @override_parameters[:body][key] = value
end

#default_handler_usedBoolean

Returns Soaspec::ExchangeHandler used by this exchange.

Returns:

  • (Boolean)

    Soaspec::ExchangeHandler used by this exchange



58
59
60
# File 'lib/soaspec/exchange.rb', line 58

def default_handler_used
  nil
end

#dummy_requestBoolean

Dummy request used to make a request without verifying it and ignoring WSDL errors

Returns:

  • (Boolean)

    Always returns true. Unless of course an unexpected exception occurs



160
161
162
163
164
165
166
167
# File 'lib/soaspec/exchange.rb', line 160

def dummy_request
  make_request
  true
rescue Savon::HTTPError
  puts 'Resolver error'
  # This seems to occur first time IP address asks for WSDL
  true
end

#element?(path) ⇒ Boolean

Returns Whether an element exists at the path.

Returns:

  • (Boolean)

    Whether an element exists at the path



170
171
172
173
174
175
# File 'lib/soaspec/exchange.rb', line 170

def element?(path)
  [path]
  true
rescue NoElementAtPath
  false
end

#make_requestResponse

Make request to handler with parameters defined Will retry until success code reached if retry_for_success? is set

Returns:

  • (Response)

    Response from Api handler



107
108
109
110
111
112
113
114
115
116
117
# File 'lib/soaspec/exchange.rb', line 107

def make_request
  Soaspec::SpecLogger.add_to 'Example ' + test_name
  request_params = @override_parameters
  (1..retry_count).each do |count|
    response = exchange_handler.make_request(request_params)
    return response unless retry_for_success?
    return response if (200..299).cover? @exchange_handler.status_code_for(response)
    sleep 0.5
    break response if count == retry_count
  end
end

#method=(method) ⇒ Object

Specify HTTP method to use. Default is :post

Parameters:

  • method (Symbol)

    HTTP method. E.g, :get, :patch



100
101
102
# File 'lib/soaspec/exchange.rb', line 100

def method=(method)
  @override_parameters[:method] = method
end

#methods_for_element(element) ⇒ Object

Parameters:

  • element (String)

    Element to define methods for



63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/soaspec/exchange.rb', line 63

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

#respond_to_missing?(method_name, *args) ⇒ Boolean

Used for setters that are not defined

Returns:

  • (Boolean)


211
212
213
# File 'lib/soaspec/exchange.rb', line 211

def respond_to_missing?(method_name, *args)
  method_name[-1] == '=' || super
end

#responseObject Also known as: call

Returns response object from Api. Will make the request if not made and then cache it for later on For example for SOAP it will be a Savon response response.body (body of response as Hash) response.header (head of response as Hash)



146
147
148
# File 'lib/soaspec/exchange.rb', line 146

def response
  @response ||= make_request
end

#retrieve(name) ⇒ Object

Retrieve the stored value from the Api Handler

Parameters:

  • name (String, Symbol)

    Name of value to retrieve

Returns:

  • (Object)

    value from the Api Handler stored previously



129
130
131
132
133
# File 'lib/soaspec/exchange.rb', line 129

def retrieve(name)
  method = '__stored_val__' + name.to_s
  raise ArgumentError('Value not stored at ') unless exchange_handler.respond_to? method
  exchange_handler.send(method)
end

#retry_for_successObject

Set retry for success variable to true so that request will be retried for retry_count until it’s true



47
48
49
50
# File 'lib/soaspec/exchange.rb', line 47

def retry_for_success
  @retry_for_success = true
  self
end

#retry_for_success?Bool

Returns Whether to keep making request until success code reached.

Returns:

  • (Bool)

    Whether to keep making request until success code reached



53
54
55
# File 'lib/soaspec/exchange.rb', line 53

def retry_for_success?
  @retry_for_success
end

#save!Self

Makes request, caching the response and returning self Used by FactoryBot

Returns:

  • (Self)


218
219
220
221
222
# File 'lib/soaspec/exchange.rb', line 218

def save!
  @retry_for_success = @fail_factory ? false : true
  call
  self
end

#status_codeInteger

Get status code from api class. This is http response for Web Api

Returns:

  • (Integer)

    Status code from api class



154
155
156
# File 'lib/soaspec/exchange.rb', line 154

def status_code
  exchange_handler.status_code_for(response)
end

#store(name, value) ⇒ Object

Stores a value in the api handler that can be accessed by the provided name

Parameters:

  • name (Symbol)

    Name of method to use to access this value within handler

  • value (String)

    Path to value to store



122
123
124
# File 'lib/soaspec/exchange.rb', line 122

def store(name, value)
  exchange_handler.store(name, self[value])
end

#suburl=(url) ⇒ Object

Specify a url to add onto the base_url of the ExchangeHandler used

Parameters:

  • url (String)

    Url to add onto the base_url of the ExchangeHandler used



94
95
96
# File 'lib/soaspec/exchange.rb', line 94

def suburl=(url)
  @override_parameters[:suburl] = url
end

#to_sString

Name describing this class when used with ‘RSpec.describe` This will make the request and store the response

Returns:

  • (String)

    Name given when initializing



138
139
140
# File 'lib/soaspec/exchange.rb', line 138

def to_s
  test_name
end