soaspec 0.3.2 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
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