soaspec 0.3.2 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6d04d8069ff220fabc590725f88eb322d1346067c16efcdd007d235b55ac2d20
4
- data.tar.gz: b7391039e8f3dd04845b49bba4fba4ca2d50dd444c088ceabc7f515907c2949c
3
+ metadata.gz: c9f6e35bf3fb8a025d3b6b3e7331686c6b1c2c6ab332fc46edf4c63e360e4b37
4
+ data.tar.gz: a1c11edd859c3b71a5f2384cef5437c41ec609a4104df144e6491d3081f588c6
5
5
  SHA512:
6
- metadata.gz: b0ef8082d8e1e24576a0ea9bb9e477e33764a135b994d26e4a52a6a1366f57e8e3e89cb7d22f64914abbac27bce5c04ab21b6e1d9ee7703025539875b7187769
7
- data.tar.gz: c984d69e28910e13171cd588ee98f363f0186b0d46b9ee8144a05964d7089054308f4017d4842ee7b064d25661b42c02d8a69fbf1c7a4c3e23106481819cdb61
6
+ metadata.gz: 74334ea904ce3ff6f131e43b1954945231bb0178aba8867564e7e9056b1f723a9506a500de582fa226d77dc872384a4944306b5dd35ae7766d1d1f0fd5c05af1
7
+ data.tar.gz: 8f9ff7688a0442663faa05a640912b8e4161317597ddd8ea6ad3e6cb7632800b50ed7441fb38caa080782e2f2b2d519d3e07ded33c552179c32514ceeeb21d35
@@ -39,11 +39,13 @@ ruby_2.6:
39
39
  - bundle exec rake
40
40
 
41
41
  cucumber:
42
+ image: samuelgarratt/soaspec
42
43
  stage: test
43
44
  script:
44
45
  - bundle exec cucumber
45
46
 
46
47
  doctest:
48
+ image: samuelgarratt/soaspec
47
49
  stage: test
48
50
  script:
49
51
  - bundle exec rake yard:doctest
@@ -0,0 +1 @@
1
+ --plugin yard-doctest
data/ChangeLog CHANGED
@@ -1,3 +1,10 @@
1
+ Version 0.3.3
2
+ * Enhancement
3
+ * Ability to specify multipart on Soaspec::OAuth2, not always assume it's value
4
+ * Bug Fix
5
+ * SOAP error was calling undefined error
6
+ * SOAP 'format' for 'Exchange' was not being calculated as :xml
7
+
1
8
  Version 0.3.2
2
9
  * Enhancement
3
10
  * Handle 'html' format
data/Dockerfile CHANGED
@@ -1,8 +1,10 @@
1
1
  FROM ruby:2.6
2
- MAINTAINER Samuel Garratt
2
+ LABEL maintainer='Samuel Garratt'
3
+ LABEL description='Dockerfile with soaspec gems preinstalled'
3
4
  LABEL url="https://gitlab.com/samuel-garratt/soaspec/blob/master/Dockerfile"
4
5
  # Simple Dockerfile with gems preinstalled
5
6
  RUN gem install bundler rake soaspec
7
+
6
8
  ENV LANG=en_US.UTF-8
7
9
  ENV LANGUAGE=en_US.UTF-8
8
10
  ENV LC_ALL=en_US.UTF-8
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'exe_helpers'
2
4
 
3
5
  module Soaspec
@@ -8,7 +10,7 @@ module Soaspec
8
10
  @folder = File.join('config', 'baseline')
9
11
 
10
12
  # @return [Array] List of allowed formats
11
- ALLOWED_FORMATS = [:raw, :hash]
13
+ ALLOWED_FORMATS = %i[raw hash].freeze
12
14
 
13
15
  # @return [Exchange] Exchange object to save/assert baseline for
14
16
  attr_accessor :exchange
@@ -80,4 +82,4 @@ module Soaspec
80
82
  attr_accessor :folder
81
83
  end
82
84
  end
83
- end
85
+ end
@@ -22,6 +22,8 @@ module Soaspec
22
22
 
23
23
  # @return [String] Name of the template file to be used in the API request
24
24
  attr_reader :template_name
25
+ # @return [Symbol] Option used to generate Request Body. Either :hash or :template
26
+ attr_accessor :request_option
25
27
 
26
28
  # Explicitly defined elements for which a path has been predefined
27
29
  def elements
@@ -33,7 +35,7 @@ module Soaspec
33
35
  # @param [Hash] _options Parameters defining handler. Used in descendants
34
36
  def initialize(name = self.class.to_s, _options = {})
35
37
  use
36
- @request_option = :hash
38
+ self.request_option = :hash
37
39
  raise ArgumentError, 'Cannot define both template_name and default_hash' if respond_to?(:template_name_value) && respond_to?(:default_hash_value)
38
40
 
39
41
  @template_name = respond_to?(:template_name_value) ? template_name_value : ''
@@ -59,7 +61,7 @@ module Soaspec
59
61
  # This will set the @request_option instance variable too
60
62
  # @param [Hash] hash Hash to send in request body by default
61
63
  def default_hash=(hash)
62
- @request_option = :hash
64
+ self.request_option = :hash
63
65
  @default_hash = Soaspec.always_use_keys? ? hash.transform_keys_to_symbols : hash
64
66
  end
65
67
 
@@ -67,7 +69,7 @@ module Soaspec
67
69
  # Erb is used to parse the template file, executing Ruby code in `<%= %>` blocks to work out the final request
68
70
  # @param [String] name Name of file inside 'template' folder excluding extension
69
71
  def template_name=(name)
70
- @request_option = :template
72
+ self.request_option = :template
71
73
  @template_name = name
72
74
  end
73
75
 
@@ -24,14 +24,40 @@ module Soaspec
24
24
  # Headers. Keys that are `symbols` will be converted from `snake_case` to `Word-Word2`
25
25
  # @return [Hash] Headers sent as part of request
26
26
  attr_accessor :headers
27
+ # @return [Soaspec::RestHandler] RestHandler used for this request
28
+ attr_accessor :rest_handler
29
+
30
+ # Interpret REST parameters given provided parameters and adding defaults, making
31
+ # transformations
32
+ #
33
+ # @param [Hash] request_parameters Parameters used in making a request
34
+ # @return [Hash] Request parameters merged with default values
35
+ def interpret_parameters(request_parameters)
36
+ request_parameters = request_parameters.dup # Must duplicate hash as deletion occurring
37
+ request_parameters[:params] ||= {}
38
+ request_parameters[:method] ||= :post
39
+ suburl = request_parameters[:suburl]
40
+ if suburl
41
+ request_parameters[:suburl] = if suburl.is_a? Array
42
+ suburl.collect(&:to_s).join('/')
43
+ else
44
+ suburl.to_s
45
+ end
46
+ end
47
+ # Use q for query parameters. Nested :params is ugly, long and unclear
48
+ request_parameters[:params] = request_parameters.delete(:q) if request_parameters[:q]
49
+ request_parameters
50
+ end
27
51
 
28
52
  # @param [Hash] overall Overall parameters used in Request
29
53
  # @param [Hash] options Headers and basic auth options
30
- # @param [String] body Body of Request to be sent
31
- def initialize(overall, options, body)
32
- overall_params = overall.dup # Must duplicate hash as deletion occurring
33
- self.body = body
54
+ # @param [Soaspec::RestHandler] rest_handler RestHandler handling creation of this request
55
+ def initialize(overall, options, rest_handler)
56
+ self.rest_handler = rest_handler
57
+ overall_params = interpret_parameters(overall)
58
+ @overall_params = overall_params
34
59
  self.method = overall_params.delete(:method)
60
+ self.body = payload? ? post_data : nil #body
35
61
  self.suburl = overall_params.delete(:suburl)
36
62
  self.test_name = overall_params.delete(:name)
37
63
  self.other_params = overall_params
@@ -42,7 +68,7 @@ module Soaspec
42
68
 
43
69
  # @return [Hash] Query parameters for a REST Request
44
70
  def query
45
- other_params[:q]
71
+ other_params[:params]
46
72
  end
47
73
 
48
74
  # @param [String, Symbol] value Message to send to object retrieving a value
@@ -65,13 +91,37 @@ module Soaspec
65
91
  def description
66
92
  suburl_desc = suburl.is_a?(Array) ? File.join(suburl) : suburl
67
93
  query_desc = ''
68
- if query
69
- query.each do |key, value|
70
- query_desc = File.join(query_desc, "#{key}_#{value}")
71
- end
94
+ query&.each do |key, value|
95
+ query_desc = File.join(query_desc, "#{key}_#{value}")
72
96
  end
73
97
  components = [method.to_s, suburl_desc, query_desc, 'response']
74
98
  File.join(*components.collect!(&:to_s))
75
99
  end
100
+
101
+ # @return [Boolean] Whether REST method should have a payload
102
+ def payload?
103
+ case method
104
+ when :post, :patch, :put
105
+ true
106
+ else
107
+ false
108
+ end
109
+ end
110
+
111
+ # TODO: Implement this for this object
112
+ # Work out data to send based upon payload, template_name, or body
113
+ # @return [String] Payload to send in REST request
114
+ def post_data
115
+ option = rest_handler.request_option
116
+ if option == :hash && !@overall_params[:payload]
117
+ @overall_params[:payload] = JSON.generate(rest_handler.hash_used_in_request(@overall_params[:body])).to_s
118
+ elsif option == :template
119
+ test_values = nil
120
+ test_values = @overall_params[:body].dup if @overall_params[:body]
121
+ Soaspec::TemplateReader.new.render_body(rest_handler.template_name, test_values || @overall_params)
122
+ else
123
+ @overall_params[:payload]
124
+ end
125
+ end
76
126
  end
77
127
  end
@@ -16,9 +16,9 @@ module Soaspec
16
16
  return converted.transform_keys_to_symbols if converted.is_a? Hash
17
17
  return converted.map!(&:transform_keys_to_symbols) if converted.is_a? Array
18
18
 
19
- raise 'Incorrect Type produced ' + converted.class
19
+ raise Soaspec::ResponseError, 'Incorrect Type produced ' + converted.class
20
20
  else
21
- raise "Neither XML nor JSON detected. It is #{type}. Don't know how to parse It is #{response.body}"
21
+ raise Soaspec::ResponseError, "Neither XML nor JSON detected. It is #{type}. Don't know how to parse It is #{response.body}"
22
22
  end
23
23
  end
24
24
 
@@ -38,49 +38,12 @@ module Soaspec
38
38
  super
39
39
  set_remove_keys(options, %i[api_username default_hash template_name])
40
40
  @init_options = options
41
- init_merge_options # Call this to verify any issues with options on creating object
41
+ @merged_options ||= init_merge_options # Caches initial merge options
42
42
  end
43
43
 
44
- # @return [Boolean] Whether REST method should have a payload
45
- def payload?(overall_params)
46
- case overall_params[:method]
47
- when :post, :patch, :put
48
- true
49
- else
50
- false
51
- end
52
- end
53
-
54
- # @todo Use this in actually making the request
55
- # At the moment this is just for one to manually view the parameters
56
- # that will be used in making a request
57
- # @return [RestRequest] Parameters used in making a request
44
+ # @return [Soaspec::RestRequest] Parameters used in making a request
58
45
  def request_parameters(override_parameters)
59
- overall_params = interpret_parameters(override_parameters)
60
- request = { overall: overall_params, options: init_merge_options }
61
- request[:body] = post_data(overall_params) if payload?(overall_params)
62
- RestRequest.new(overall_params, init_merge_options, payload?(overall_params) ? post_data(overall_params) : nil)
63
- end
64
-
65
- # Interpret REST parameters given provided parameters and adding defaults, making
66
- # transformations
67
- #
68
- # @param [Hash] request_parameters Parameters used in making a request
69
- # @return [Hash] Request parameters merged with default values
70
- def interpret_parameters(request_parameters)
71
- request_parameters[:params] ||= {}
72
- request_parameters[:method] ||= :post
73
- suburl = request_parameters[:suburl]
74
- if suburl
75
- if suburl.is_a? Array
76
- request_parameters[:suburl] = suburl.collect(&:to_s).join('/')
77
- else
78
- request_parameters[:suburl] = suburl.to_s
79
- end
80
- end
81
- # Use q for query parameters. Nested :params is ugly, long and unclear
82
- request_parameters[:params][:params] = request_parameters[:q] if request_parameters[:q]
83
- request_parameters
46
+ RestRequest.new(override_parameters, @merged_options, self)
84
47
  end
85
48
 
86
49
  # Override this with 'after_response' within class definition to perform an action
@@ -100,20 +63,19 @@ module Soaspec
100
63
  # @option override_parameters [String] :template_name Path to file to be read via ERB and passed in request body
101
64
  # @return [RestClient::Response] Response from making request
102
65
  def make_request(override_parameters)
103
- @merged_options ||= init_merge_options # TODO: Is this var needed? Can method be passed to resource creation?
104
- test_values = interpret_parameters override_parameters
66
+ req_params = request_parameters override_parameters
105
67
  # In order for ERB to be calculated at correct time, the first time request is made, the resource should be created
106
68
  @resource ||= RestClient::Resource.new(ERB.new(base_url_value).result(binding), @merged_options)
107
- @resource_used = test_values[:suburl] ? @resource[test_values[:suburl]] : @resource
69
+ @resource_used = req_params.suburl ? @resource[req_params.suburl] : @resource
108
70
 
109
71
  self.exception = nil # Remove any previously stored exception
110
72
  begin
111
- response = case test_values[:method]
73
+ response = case req_params.method
112
74
  when :post, :patch, :put
113
- Soaspec::SpecLogger.info("request body: #{post_data(test_values)}")
114
- @resource_used.send(test_values[:method].to_s, post_data(test_values), test_values[:params])
75
+ Soaspec::SpecLogger.info("request body: #{req_params.post_data}")
76
+ @resource_used.send(req_params.method, req_params.post_data, req_params.other_params)
115
77
  else # :get, :delete
116
- @resource_used.send(test_values[:method].to_s, test_values[:params])
78
+ @resource_used.send(req_params.method, req_params.other_params )
117
79
  end
118
80
  rescue RestClient::Exception => e
119
81
  self.exception = e
@@ -126,6 +88,17 @@ module Soaspec
126
88
  response
127
89
  end
128
90
 
91
+ # @param [Hash] override_hash Values to override default hash with
92
+ # @return [Hash] Hash used in REST request based on data conversion
93
+ def hash_used_in_request(override_hash)
94
+ request = override_hash ? @default_hash.merge(override_hash) : @default_hash
95
+ if pascal_keys?
96
+ request.map { |k, v| [convert_to_pascal_case(k.to_s), v] }.to_h
97
+ else
98
+ request
99
+ end
100
+ end
101
+
129
102
  # Add values to here when extending this class to have default REST options.
130
103
  # See rest client resource at https://github.com/rest-client/rest-client for details
131
104
  # It's easier to set headers via 'headers' accessor rather than here
@@ -145,6 +118,7 @@ module Soaspec
145
118
  end
146
119
 
147
120
  # Initialize value of merged options
121
+ # Also called to verify any issues with options on creating object
148
122
  # @return [Hash] Hash of merged options
149
123
  def init_merge_options
150
124
  options = rest_resource_options
@@ -179,6 +153,9 @@ module Soaspec
179
153
  # @return [Boolean] Whether response body contains expected key
180
154
  def include_key?(response, expected)
181
155
  value_from_path(response, expected)
156
+ true
157
+ rescue NoElementAtPath
158
+ false
182
159
  end
183
160
 
184
161
  # @return [Integer] HTTP Status code for response
@@ -270,38 +247,14 @@ module Soaspec
270
247
  end
271
248
  end
272
249
 
273
- # @return [RestClient::Request] Request of API call. Either intended request or actual request
250
+ # @return [RestClient::Request, String] Request of API call. Either intended request or actual request
274
251
  def request(response)
275
- return 'Request not yet sent' if response.nil?
252
+ if response.nil?
253
+ return 'Request not yet sent. Call :request_parameters' \
254
+ 'for what will be sent'
255
+ end
276
256
 
277
257
  response.request
278
258
  end
279
-
280
- # Work out data to send based upon payload, template_name, or body
281
- # @return [String] Payload to send in REST request
282
- def post_data(test_values)
283
- data = if @request_option == :hash && !test_values[:payload]
284
- test_values[:payload] = JSON.generate(hash_used_in_request(test_values[:body])).to_s
285
- elsif @request_option == :template
286
- test_values = test_values[:body].dup if test_values[:body]
287
- test_values = IndifferentHash.new(test_values) # Allow test_values to be either Symbol or String
288
- Soaspec::TemplateReader.new.render_body(template_name, binding)
289
- else
290
- test_values[:payload]
291
- end
292
- # Soaspec::SpecLogger.info "Request Empty for '#{@request_option}'" if data.strip.empty?
293
- data
294
- end
295
-
296
- # @param [Hash] override_hash Values to override default hash with
297
- # @return [Hash] Hash used in REST request based on data conversion
298
- def hash_used_in_request(override_hash)
299
- request = override_hash ? @default_hash.merge(override_hash) : @default_hash
300
- if pascal_keys?
301
- request.map { |k, v| [convert_to_pascal_case(k.to_s), v] }.to_h
302
- else
303
- request
304
- end
305
- end
306
259
  end
307
260
  end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+ module Soaspec
3
+ # Default values set in order to make testing easier. Override to fit what you
4
+ # need in testing
5
+ module SoapDefaults
6
+ class << self
7
+ # Default Savon options. See http://savonrb.com/version2/globals.html for details
8
+ # @example Things could go wrong if not set properly
9
+ # env_namespace: :soap, # Change environment namespace
10
+ # namespace_identifier: :tst, # Change namespace element
11
+ # element_form_default: :qualified # Populate each element with namespace
12
+ # namespace: 'http://Extended_namespace.xsd' change root namespace
13
+ # basic_auth: 'user', 'password'
14
+ # @return [Hash] Default Savon options for all BasicSoapHandler
15
+ def options
16
+ {
17
+ ssl_verify_mode: :none, # Easier for testing. Not so secure
18
+ follow_redirects: true, # Necessary for many API calls
19
+ soap_version: 2, # use SOAP 1.2. You will get 415 error if this is incorrect
20
+ raise_errors: false # HTTP errors not cause failure as often negative test scenarios expect not 200 response
21
+ }
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,28 @@
1
+ module Soaspec
2
+ # Singleton methods for assigning Savon globals (http://savonrb.com/version2/globals.html)
3
+ module SoapGlobals
4
+ # Set SOAP WSDL. Use namespace and endpoint if no WSDL defined
5
+ # @param [String] path Path to wsdl, either on network or locally
6
+ def wsdl(path)
7
+ define_method('wsdl') { path }
8
+ end
9
+
10
+ # Set Basic auth
11
+ def basic_auth(user, password)
12
+ define_method('basic_auth') { [user, password] }
13
+ end
14
+
15
+ # SOAP version number. Default is version 1.2
16
+ # @example SOAP Version 1.1
17
+ # soap_version 1
18
+ def soap_version(number)
19
+ define_method('soap_version') { number }
20
+ end
21
+
22
+ %w[raise_errors namespace namespaces endpoint ssl_verify_mode].each do |method|
23
+ define_method(method) do |param|
24
+ define_method(method) { param }
25
+ end
26
+ end
27
+ end
28
+ end
@@ -6,6 +6,8 @@ require_relative '../errors'
6
6
  require_relative 'handler_accessors'
7
7
  require_relative '../interpreter'
8
8
  require_relative 'request/soap_request'
9
+ require_relative 'soap_globals'
10
+ require_relative 'soap_defaults'
9
11
  require 'forwardable'
10
12
 
11
13
  module Soaspec
@@ -22,6 +24,7 @@ module Soaspec
22
24
  class SoapHandler < ExchangeHandler
23
25
  extend Soaspec::SoapAccessors
24
26
  extend Forwardable
27
+ extend Soaspec::SoapGlobals
25
28
 
26
29
  delegate [:operations] => :client
27
30
 
@@ -29,6 +32,17 @@ module Soaspec
29
32
  attr_accessor :client
30
33
  # SOAP Operation to use by default
31
34
  attr_accessor :operation
35
+ # @return [Hash] List of Savon globals
36
+ attr_writer :savon_globals
37
+
38
+ def savon_globals
39
+ @savon_globals = {}
40
+ %i[wsdl basic_auth soap_version raise_errors namespace namespaces endpoint
41
+ ssl_verify_mode].each do |global|
42
+ @savon_globals.merge!(global => send(global)) if respond_to? global
43
+ end
44
+ @savon_globals
45
+ end
32
46
 
33
47
  # Attributes set at the root XML element of SOAP request
34
48
  def request_root_attributes; end
@@ -43,23 +57,6 @@ module Soaspec
43
57
  }
44
58
  end
45
59
 
46
- # Default Savon options. See http://savonrb.com/version2/globals.html for details
47
- # @example Things could go wrong if not set properly
48
- # env_namespace: :soap, # Change environment namespace
49
- # namespace_identifier: :tst, # Change namespace element
50
- # element_form_default: :qualified # Populate each element with namespace
51
- # namespace: 'http://Extended_namespace.xsd' change root namespace
52
- # basic_auth: 'user', 'password'
53
- # @return [Hash] Default Savon options for all BasicSoapHandler
54
- def default_options
55
- {
56
- ssl_verify_mode: :none, # Easier for testing. Not so secure
57
- follow_redirects: true, # Necessary for many API calls
58
- soap_version: 2, # use SOAP 1.2. You will get 415 error if this is incorrect
59
- raise_errors: false # HTTP errors not cause failure as often negative test scenarios expect not 200 response
60
- }
61
- end
62
-
63
60
  # Add values to here when extending this class to have default Savon options.
64
61
  # See http://savonrb.com/version2/globals.html for details
65
62
  # @return [Hash] Savon options adding to & overriding defaults
@@ -77,14 +74,17 @@ module Soaspec
77
74
  end
78
75
  super
79
76
  set_remove_keys(options, %i[operation default_hash template_name])
80
- merged_options = Soaspec::SpecLogger.log_api_traffic? ? default_options.merge(logging_options) : default_options
77
+ merged_options = SoapDefaults.options
78
+ merged_options.merge!(logging_options) if Soaspec::SpecLogger.log_api_traffic?
81
79
  merged_options.merge! savon_options
80
+ puts 'globals' + savon_globals.to_s
81
+ merged_options.merge! savon_globals
82
82
  merged_options.merge!(options)
83
83
  self.client = Savon.client(merged_options)
84
84
  end
85
85
 
86
86
  # @param [Hash] override_parameters Parameters for building the request
87
- # @return [Hash] Parameters used in making a request
87
+ # @return [SoapRequest] Parameters used in making a request
88
88
  def request_parameters(override_parameters)
89
89
  SoapRequest.new(operation, request_body_params(override_parameters), @request_option)
90
90
  end
@@ -97,7 +97,7 @@ module Soaspec
97
97
  test_values.transform_keys_to_symbols if Soaspec.always_use_keys?
98
98
  if @request_option == :template
99
99
  test_values = IndifferentHash.new(test_values) # Allow test_values to be either Symbol or String
100
- { xml: Soaspec::TemplateReader.new.render_body(template_name, binding) }
100
+ { xml: Soaspec::TemplateReader.new.render_body(template_name, test_values) }
101
101
  elsif @request_option == :hash
102
102
  { message: @default_hash.merge(test_values), attributes: request_root_attributes }
103
103
  end
@@ -111,7 +111,7 @@ module Soaspec
111
111
  begin
112
112
  client.call request.operation, request.body # request_body_params(request_parameters)
113
113
  rescue Savon::HTTPError => e
114
- soap_error
114
+ e
115
115
  end
116
116
  end
117
117
 
@@ -213,14 +213,19 @@ module Soaspec
213
213
 
214
214
  # Convenience methods for once off usage of a SOAP request
215
215
  class << self
216
+ # @return [Array] List of operations WSDL can perform
217
+ def operations
218
+ operation_class = new('Get operations')
219
+ operation_class.operations
220
+ end
221
+
216
222
  # Implement undefined setter with []= for FactoryBot to use without needing to define params to set
217
223
  # @param [Object] method_name Name of method not defined
218
224
  # @param [Object] args Arguments passed to method
219
225
  # @param [Object] block
220
226
  def method_missing(method_name, *args, &block)
221
- tmp_class = new(method_name)
222
- operations = tmp_class.operations
223
227
  if operations.include? method_name
228
+ tmp_class = new(method_name)
224
229
  tmp_class.operation = method_name
225
230
  exchange = Exchange.new(method_name, *args)
226
231
  exchange.exchange_handler = tmp_class
@@ -231,9 +236,9 @@ module Soaspec
231
236
  end
232
237
  end
233
238
 
239
+ # Override respond_to_missing so that any method name that is an operation
240
+ # can be used
234
241
  def respond_to_missing?(method_name, *args)
235
- tmp_class = new(args)
236
- operations = tmp_class.operations
237
242
  operations.include?(method_name) || super
238
243
  end
239
244
  end
@@ -15,7 +15,8 @@ class Interpreter
15
15
  @xml_errors = nil
16
16
  @json_errors = nil
17
17
  @response = response
18
- if @response.is_a? String
18
+ case @response
19
+ when String
19
20
  if xml?
20
21
  :xml
21
22
  elsif json?
@@ -25,10 +26,8 @@ class Interpreter
25
26
  else
26
27
  :string
27
28
  end
28
- elsif response.is_a? Hash
29
- :hash
30
- elsif response.is_a?(Nokogiri::XML::NodeSet) || response.is_a?(Nokogiri::XML::Document)
31
- :xml
29
+ when Hash then :hash
30
+ when Nokogiri::XML::NodeSet, Nokogiri::XML::Document, Savon::Response then :xml
32
31
  else
33
32
  :unknown
34
33
  end
@@ -25,19 +25,20 @@ RSpec::Matchers.define :include_in_body do |expected|
25
25
  end
26
26
  end
27
27
 
28
- # Whether an element exists at expected xpath
29
- RSpec::Matchers.define :have_element_at_path do |xpath|
28
+ # Whether an element exists at expected path
29
+ RSpec::Matchers.define :have_element_at_path do |path|
30
30
  match do |object|
31
31
  # Object like `response` returns the Exchange object from which a path can be obtained
32
32
  exchange = object.respond_to?(:exchange) ? object.exchange : object
33
- expect { exchange[xpath] }.to_not raise_error # Error will be raised if Path returns no value
33
+ exchange.element? path # [xpath]
34
+ # expect { exchange[xpath] }.to_not raise_error # Error will be raised if Path returns no value
34
35
  end
35
36
 
36
37
  # TODO: Would be better to print failure message
37
38
  failure_message do |object|
38
39
  # Object like `response` returns the Exchange object from which a path can be obtained
39
40
  exchange = object.respond_to?(:exchange) ? object.exchange : object
40
- "expected that #{exchange.exchange_handler.response_body(exchange.response, format: :raw)} would have element at path '#{xpath}'"
41
+ "expected that #{exchange.exchange_handler.response_body(exchange.response, format: :raw)} would have element at path '#{path}'"
41
42
  end
42
43
  end
43
44
 
@@ -76,7 +77,6 @@ end
76
77
  # @param [Symbol] format Format to save the baseline as. Default is :raw. Use :hash
77
78
  # to store as hash which will ignore order in comparison
78
79
  RSpec::Matchers.define :match_baseline do |format = :raw|
79
-
80
80
  match do |exchange|
81
81
  Soaspec::Baseline.new(exchange, format).matches?
82
82
  end
@@ -132,11 +132,21 @@ module Soaspec
132
132
  payload.merge(if params[:password] && params[:username]
133
133
  {
134
134
  grant_type: 'password', username: params[:username],
135
- password: password, multipart: true
136
- }
135
+ password: password
136
+ }.merge multipart true
137
137
  else
138
- { grant_type: 'client_credentials' }
138
+ { grant_type: 'client_credentials' }.merge multipart false
139
139
  end)
140
140
  end
141
+
142
+ private
143
+
144
+ # @param [Boolean] default Default value for multipart
145
+ # @return [Hash] Multipart set to true if not set and is grant_type password
146
+ def multipart(default)
147
+ return { multipart: true } if (params[:multipart].nil? && default) || params[:multipart]
148
+
149
+ {}
150
+ end
141
151
  end
142
152
  end
@@ -15,7 +15,11 @@ module Soaspec
15
15
 
16
16
  # @param [String] template_name File where template is stored
17
17
  # @return [String] Body of template after determining test_values
18
- def render_body(template_name, binding)
18
+ def render_body(template_name, test_values)
19
+ test_values = IndifferentHash.new(test_values) # Allow test_values to be either Symbol or String
20
+ test_values&.each do |key, value|
21
+ instance_variable_set("@#{key}", value)
22
+ end
19
23
  self.template_name = template_name
20
24
  unless File.exist? file_location
21
25
  raise "Cannot see file at #{file_location}. "\
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Soaspec
4
4
  # @return [String] Version of the gem
5
- VERSION = '0.3.2'
5
+ VERSION = '0.3.3'
6
6
  end
@@ -102,6 +102,11 @@ module Soaspec
102
102
  Soaspec::TestServer::IdManager.developed.to_s
103
103
  end
104
104
 
105
+ documentation 'Sends back params received'
106
+ get '/echoer' do
107
+ params.to_s
108
+ end
109
+
105
110
  # Used for simple testing of posing
106
111
  documentation 'Simply sends the response body back'
107
112
  post '/echoer' do
@@ -192,14 +197,14 @@ module Soaspec
192
197
 
193
198
  documentation 'HTML doc that is not valid HTML'
194
199
  get '/html_doc' do
195
- <<-HTML
196
- <!doctype html>
197
- <html lang="en">
198
- <head></head>
199
- <body>
200
- <h1>Heading</h1>
201
- </body>
202
- </html>
200
+ <<~HTML
201
+ <!doctype html>
202
+ <html lang="en">
203
+ <head></head>
204
+ <body>
205
+ <h1>Heading</h1>
206
+ </body>
207
+ </html>
203
208
  HTML
204
209
  end
205
210
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: soaspec
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - SamuelGarrattIQA
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-10-01 00:00:00.000000000 Z
11
+ date: 2019-11-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -459,6 +459,7 @@ files:
459
459
  - ".gitlab-ci.yml"
460
460
  - ".rspec"
461
461
  - ".rubocop.yml"
462
+ - ".yardopts"
462
463
  - CODE_OF_CONDUCT.md
463
464
  - ChangeLog
464
465
  - Dockerfile
@@ -492,6 +493,8 @@ files:
492
493
  - lib/soaspec/exchange_handlers/rest_methods.rb
493
494
  - lib/soaspec/exchange_handlers/rest_parameters.rb
494
495
  - lib/soaspec/exchange_handlers/rest_parameters_defaults.rb
496
+ - lib/soaspec/exchange_handlers/soap_defaults.rb
497
+ - lib/soaspec/exchange_handlers/soap_globals.rb
495
498
  - lib/soaspec/exchange_handlers/soap_handler.rb
496
499
  - lib/soaspec/exe_helpers.rb
497
500
  - lib/soaspec/generate_server.rb
@@ -558,7 +561,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
558
561
  - !ruby/object:Gem::Version
559
562
  version: '0'
560
563
  requirements: []
561
- rubygems_version: 3.0.4
564
+ rubygems_version: 3.0.6
562
565
  signing_key:
563
566
  specification_version: 4
564
567
  summary: Helps to create tests for 'SOAP' or 'REST' apis