soaspec 0.0.30 → 0.0.31

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
  SHA1:
3
- metadata.gz: fb181def6480766a52b057843a32f43f12aa1156
4
- data.tar.gz: '0187e411bdbfb2d722063222d2c5e32001979cb6'
3
+ metadata.gz: e08d39845eefbfb87ab3a5b7b8e6ae80fa321d54
4
+ data.tar.gz: 7903a5ab815ef9d56c9b6223b1d945181c57317e
5
5
  SHA512:
6
- metadata.gz: 8760fa3a0f1f639fa86c1c328b7d8afcb1acdd62a28ac87d8c1c4aab98018fdff1a5153ecbb63397339ca163a86275e6f2c8fecf519449aa3e08e0a5fd08f666
7
- data.tar.gz: 63d3ce6daf896b56b3b2585430fba47879c529fb5fde312d44e3fdb948307f2a7d657c29995dfd07c02c9b04cbc945b24d380c7289bdcb15a3f2a7c9fb6a9e20
6
+ metadata.gz: ccf078e392801d2ff1686836701c4ded6afbb2166591ad543c6ba6fa7b54fa0946f637e5bfdb3401b0e90deb105751e01edc2040379295dc280bf64acded3528
7
+ data.tar.gz: 2d8c97db2287c39369b0e6258202a3b446aa4c4e4375fd35af46402daf2bab6d5f260d93934d31852d089073549f5b94b7168ae6b85b99477387055388352b12
data/ChangeLog CHANGED
@@ -1,3 +1,8 @@
1
+ Version 0.0.31 / 2018-3-8
2
+ * Enhancements
3
+ * Compacted unit tests for exchange handler
4
+ * Implemented include_key? and find via xpath for REST handler. See specs
5
+
1
6
  Version 0.0.30 / 2018-3-6
2
7
  * Bug fix
3
8
  * Made generated class file name in soaspec-generate snakecase (was CamelCase)
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- soaspec (0.0.30)
4
+ soaspec (0.0.31)
5
5
  rest-client (>= 2.0)
6
6
  rspec (~> 3.0)
7
7
  rspec-its (>= 1.2.0)
data/lib/soaspec.rb CHANGED
@@ -8,16 +8,18 @@ require 'nokogiri' # XPath
8
8
  require 'date'
9
9
 
10
10
  require 'soaspec/version'
11
- require 'soaspec/basic_soap_handler'
12
- require 'soaspec/exchange_handler'
11
+ require 'soaspec/exchange_handlers/soap_handler'
12
+ require 'soaspec/exchange_handlers/exchange_handler'
13
13
  require 'soaspec/exchange'
14
14
  require 'soaspec/matchers'
15
15
  require 'soaspec/soaspec_shared_examples'
16
16
  require 'soaspec/hash_methods'
17
17
  require 'soaspec/spec_logger'
18
18
  require 'soaspec/exe_helpers'
19
- require 'soaspec/rest_handler'
19
+ require 'soaspec/exchange_handlers/rest_handler'
20
20
  require 'soaspec/accessors'
21
+ require 'soaspec/interpreter'
22
+ require 'soaspec/not_found_errors'
21
23
 
22
24
  # Gem for handling SOAP and REST api tests
23
25
  module Soaspec
@@ -39,7 +39,7 @@ class Exchange
39
39
  end
40
40
 
41
41
  # Extract value from path api class
42
- # @param [String] path Path to return element for api class E.g - for SOAP this is XPath
42
+ # @param [Object] path Path to return element for api class E.g - for SOAP this is XPath string. For JSON, this is Hash dig Array
43
43
  # @return [String] Value at path
44
44
  def [](path)
45
45
  @api_class.value_from_path(self, path)
@@ -9,7 +9,7 @@ module Soaspec
9
9
 
10
10
  # Set instance variable name
11
11
  # @param [String, Symbol] name Name used when describing API test
12
- # @param [Hash] options Parameters defining
12
+ # @param [Hash] options Parameters defining handler. Used in descendants
13
13
  def initialize(name, options)
14
14
  @name = name
15
15
  end
@@ -18,7 +18,7 @@ module Soaspec
18
18
  # @return [String] Name set upon initialisation
19
19
  def to_s
20
20
  Soaspec::Environment.api_handler = self
21
- @name
21
+ @name.to_s
22
22
  end
23
23
 
24
24
  # Set the request option type and the template name
@@ -1,8 +1,9 @@
1
1
 
2
2
  require_relative 'exchange_handler'
3
- require_relative 'hash_methods'
4
- require_relative 'xpath_not_found'
5
- require_relative 'accessors'
3
+ require_relative '../hash_methods'
4
+ require_relative '../not_found_errors'
5
+ require_relative '../accessors'
6
+ require_relative '../interpreter'
6
7
  require 'json'
7
8
  require 'nori'
8
9
 
@@ -54,16 +55,10 @@ module Soaspec
54
55
  end
55
56
 
56
57
  def name(name)
57
- @test_values = {}
58
58
  @test_name = name
59
59
  self
60
60
  end
61
61
 
62
- def override(request_parameters)
63
- @test_values = request_parameters
64
- self
65
- end
66
-
67
62
  # Used in together with Exchange request that passes such override parameters
68
63
  # @param [Hash] override_parameters Params to characterize REST request
69
64
  def make_request(override_parameters)
@@ -103,25 +98,17 @@ module Soaspec
103
98
  response.body.include? expected
104
99
  end
105
100
 
101
+ # Whether the request found the desired value or not
106
102
  def found?(response)
107
- response.code != 404
103
+ status_code_for(response) != 404
108
104
  end
109
105
 
110
106
  # Convert XML or JSON response into a Hash
111
107
  # @param [String] response Response as a String (either in XML or JSON)
112
108
  # @return [Hash]
113
109
  def extract_hash(response)
114
- raise "Empty Body. Can't assert on it" if response.body.empty?
115
- type = case response.body[0]
116
- when '<'
117
- :xml
118
- when '{'
119
- :json
120
- else
121
- :unknown
122
- end
123
-
124
- case type
110
+ raise ArgumentError("Empty Body. Can't assert on it") if response.body.empty?
111
+ case Interpreter.response_type_for response
125
112
  when :json
126
113
  JSON.parse(response.body).transform_keys_to_symbols
127
114
  when :xml
@@ -132,10 +119,17 @@ module Soaspec
132
119
  end
133
120
  end
134
121
 
122
+ # @return [Boolean] Whether response contains expected value
135
123
  def include_value?(response, expected)
136
124
  extract_hash(response).include_value? expected
137
125
  end
138
126
 
127
+ # @return [Boolean] Whether response body contains expected key
128
+ def include_key?(response, expected)
129
+ extract_hash(response).include_key? expected
130
+ end
131
+
132
+ # @return [Integer] HTTP Status code for response
139
133
  def status_code_for(response)
140
134
  response.code
141
135
  end
@@ -160,23 +154,44 @@ module Soaspec
160
154
  end
161
155
 
162
156
  # Returns the value at the provided xpath
163
- def xpath_value_for(param)
157
+ # @param [Exchange] exchange
158
+ # @param [String] xpath
159
+ # @return [String] Value inside element found through Xpath
160
+ def xpath_value_for(exchange: nil, xpath: nil)
161
+ raise ArgumentError unless exchange && xpath
162
+ response = exchange.response
163
+ raise "Can't perform XPATH if response is not XML" unless Interpreter.response_type_for(response) == :xml
164
164
  result =
165
- if Soaspec::Environment.strip_namespaces? && !param[:xpath].include?(':')
166
- temp_doc = param[:exchange].response.doc
167
- temp_doc.remove_namespaces!
168
- temp_doc.xpath(param[:xpath]).first
169
- else
170
- puts 'no strip' + param[:xpath]
171
- param[:exchange].response.xpath(param[:xpath]).first
172
- end
173
- raise NoElementAtXpath, "No value at Xpath '#{param[:xpath]}'" unless result
165
+ if Soaspec::Environment.strip_namespaces? && !xpath.include?(':')
166
+ temp_doc = Nokogiri.parse response.body
167
+ temp_doc.remove_namespaces!
168
+ temp_doc.xpath(xpath).first
169
+ else
170
+ Nokogiri.parse(response.body).xpath(xpath).first
171
+ end
172
+ raise NoElementAtXpath, "No value at Xpath '#{xpath}'" unless result
174
173
  result.inner_text
175
174
  end
176
175
 
176
+ # Based on a exchange, return the value at the provided xpath
177
+ # If the path does not begin with a '/', a '//' is added to it
178
+ # @param [Exchange] exchange
179
+ # @param [Object] path Xpath or other path identifying how to find element
180
+ # @return [String] Value at Xpath
177
181
  def value_from_path(exchange, path)
178
- path = '//' + path if path[0] != '/'
179
- xpath_value_for(exchange: exchange, xpath: path)
182
+ case Interpreter.response_type_for(exchange.response)
183
+ when :xml
184
+ path = '//' + path if path[0] != '/'
185
+ xpath_value_for(exchange: exchange, xpath: path)
186
+ when :json
187
+ hash = extract_hash exchange.response
188
+ value = hash.dig(*path)
189
+ raise NoElementInHash, "Element in #{hash} not found with path '#{path}'" unless value
190
+ value
191
+ else
192
+ raise 'Unrecognised response message. Neither xml nor json detected'
193
+ end
194
+
180
195
  end
181
196
 
182
197
  end
@@ -1,8 +1,9 @@
1
1
 
2
2
  require_relative 'exchange_handler'
3
- require_relative 'hash_methods'
4
- require_relative 'xpath_not_found'
5
- require_relative 'accessors'
3
+ require_relative '../hash_methods'
4
+ require_relative '../not_found_errors'
5
+ require_relative '../accessors'
6
+ require_relative '../interpreter'
6
7
 
7
8
  module Soaspec
8
9
 
@@ -73,20 +74,16 @@ module Soaspec
73
74
  options.merge! savon_options
74
75
  options.merge!(specific_options)
75
76
  @client = Savon.client(options)
77
+ @default_hash = {}
78
+ @request_option = :hash
76
79
  super
77
80
  end
78
81
 
79
82
  def name(name)
80
- @test_values = {}
81
83
  @test_name = name
82
84
  self
83
85
  end
84
86
 
85
- def override(request_parameters)
86
- @test_values = request_parameters
87
- self
88
- end
89
-
90
87
  # Used in together with Exchange request that passes such override parameters
91
88
  def make_request(override_parameters)
92
89
  test_values = override_parameters # Used in Erb
@@ -101,6 +98,8 @@ module Soaspec
101
98
  end
102
99
  end
103
100
 
101
+ # Set the default hash representing data to be used in making a request
102
+ # This will set the @request_option instance variable too
104
103
  def default_hash=(hash)
105
104
  @request_option = :hash
106
105
  @default_hash = Soaspec::Environment.always_use_keys? ? hash.transform_keys_to_symbols : hash
@@ -119,28 +118,51 @@ module Soaspec
119
118
  end
120
119
  end
121
120
 
121
+ # @return [Boolean] Whether the request found the desired value or not
122
+ def found?(response)
123
+ status_code_for(response) != 404
124
+ end
125
+
126
+ # Response status code for response. '200' indicates a success
127
+ # @param [Savon::Response] response
128
+ # @return [Integer] Status code
122
129
  def status_code_for(response)
123
130
  response.http.code
124
131
  end
125
132
 
133
+ # @return [Boolean] Whether response includes provided string within it
126
134
  def include_in_body?(response, expected)
127
135
  response.to_xml.to_s.include? expected
128
136
  end
129
137
 
138
+ # @return [Boolean] Whether response body contains expected key
139
+ def include_key?(response, expected)
140
+ response.body.include_key? expected
141
+ end
142
+
130
143
  # Returns the value at the provided xpath
131
- def xpath_value_for(param)
144
+ # @param [Exchange] exchange
145
+ # @param [String] xpath
146
+ # @return [String] Value inside element found through Xpath
147
+ def xpath_value_for(exchange: nil, xpath: nil)
148
+ raise ArgumentError unless exchange && xpath
132
149
  result =
133
- if Soaspec::Environment.strip_namespaces? && !param[:xpath].include?(':')
134
- temp_doc = param[:exchange].response.doc
150
+ if Soaspec::Environment.strip_namespaces? && !xpath.include?(':')
151
+ temp_doc = exchange.response.doc
135
152
  temp_doc.remove_namespaces!
136
- temp_doc.xpath(param[:xpath]).first
153
+ temp_doc.xpath(xpath).first
137
154
  else
138
- param[:exchange].response.xpath(param[:xpath]).first
155
+ exchange.response.xpath(xpath).first
139
156
  end
140
- raise NoElementAtXpath, "No value at Xpath '#{param[:xpath]}'" unless result
157
+ raise NoElementAtXpath, "No value at Xpath '#{xpath}'" unless result
141
158
  result.inner_text
142
159
  end
143
160
 
161
+ # Based on a exchange, return the value at the provided xpath
162
+ # If the path does not begin with a '/', a '//' is added to it
163
+ # @param [Exchange] exchange
164
+ # @param [String] path Xpath
165
+ # @return [String] Value at Xpath
144
166
  def value_from_path(exchange, path)
145
167
  path = '//' + path if path[0] != '/'
146
168
  xpath_value_for(exchange: exchange, xpath: path)
@@ -153,6 +175,7 @@ module Soaspec
153
175
 
154
176
  end
155
177
 
178
+ # Deprecated class name. Will be removed in the future
156
179
  class BasicSoapHandler < SoapHandler
157
180
 
158
181
  def initialize(name, specific_options = {})
@@ -0,0 +1,26 @@
1
+
2
+ # Help interpret the general type of a particular object
3
+ class Interpreter
4
+
5
+ # @param [Object] response API response
6
+ # @return [Symbol] Type of provided response
7
+ def self.response_type_for(response)
8
+ if response.is_a? String
9
+ case response.body[0]
10
+ when '<'
11
+ :xml
12
+ when '{'
13
+ :json
14
+ else
15
+ :unknown
16
+ end
17
+ elsif response.is_a? Hash
18
+ :hash
19
+ elsif response.is_a? Nokogiri::XML::NodeSet
20
+ :xml
21
+ else
22
+ :unknown
23
+ end
24
+ end
25
+
26
+ end
@@ -1,6 +1,6 @@
1
1
 
2
2
  require_relative 'hash_methods'
3
- require_relative 'xpath_not_found'
3
+ require_relative 'not_found_errors'
4
4
 
5
5
  # TODO: Mathcers are specific to SOAP. Make generic for REST and others by using actual.api_class
6
6
 
@@ -10,9 +10,8 @@ RSpec::Matchers.define :contain_value do |expected|
10
10
  expect(actual.api_class.include_value?(actual.response, expected)).to be true
11
11
  end
12
12
 
13
- # TODO: Fix this for REST
14
13
  failure_message do |actual|
15
- "expected that #{actual.response.body} would contain value #{expected}"
14
+ "expected that #{actual.api_class.response_body(actual.response, format: :hash)} would contain value #{expected}"
16
15
  end
17
16
  end
18
17
 
@@ -22,31 +21,30 @@ RSpec::Matchers.define :include_in_body do |expected|
22
21
  expect(actual.api_class.include_in_body?(actual.response, expected)).to be true
23
22
  end
24
23
 
25
- # TODO: Fix this for REST
26
24
  failure_message do |actual|
27
- "expected that #{actual.response.body.to_xml} would contain value #{expected}"
25
+ "expected that #{actual.api_class.response_body(actual.response, format: :xml)} would contain value #{expected}"
28
26
  end
29
27
  end
30
28
 
31
29
  # Whether expected element exists in body
32
30
  RSpec::Matchers.define :contain_key do |expected|
33
31
  match do |actual|
34
- expect(actual.response.body.include_key?(expected)).to be true
32
+ expect(actual.api_class.include_key?(actual.response, expected)).to be true
35
33
  end
36
34
 
37
35
  failure_message do |actual|
38
- "expected that #{actual.response.body} would contain key #{expected}"
36
+ "expected that #{actual.api_class.response_body(actual.response, format: :hash)} would contain key #{expected}"
39
37
  end
40
38
  end
41
39
 
42
40
  # Whether an element exists at expected xpath
43
41
  RSpec::Matchers.define :have_element_at_xpath do |xpath|
44
42
  match do |exchange|
45
- expect { exchange[xpath] }.to_not raise_error
43
+ expect { exchange[xpath] }.to_not raise_error # Error will be raised if XPath returns no value
46
44
  end
47
45
 
48
46
  failure_message do |actual|
49
- "expected that #{actual.response.to_xml} would have element at xpath '#{xpath}'"
47
+ "expected that #{actual.api_class.response_body(actual.response, format: :xml)} would have element at xpath '#{xpath}'"
50
48
  end
51
49
  end
52
50
 
@@ -0,0 +1,14 @@
1
+
2
+ # Raised to represent when there's no element at an Xpath
3
+ class NoElementAtXpath < StandardError
4
+ def initialize(msg="No element at Xpath found")
5
+ super
6
+ end
7
+ end
8
+
9
+ # Did not find any element by provided key in the Hash
10
+ class NoElementInHash < StandardError
11
+ def initialize(msg='No element in Hash found')
12
+ super
13
+ end
14
+ end
@@ -10,7 +10,7 @@ shared_examples_for 'success scenario' do
10
10
  expect(described_class).to contain_key mandatory_element
11
11
  end
12
12
  end
13
- # TODO: Remove this. Handle depracated method temporariliy
13
+ # TODO: Remove this. Handle deprecated method temporarily
14
14
  described_class.api_class.mandatory_elements.each do |mandatory_element|
15
15
  puts "Overriding 'mandatory_elements' deprecated. Use new 'expected_mandatory_elements' instead of overriding this method"
16
16
  it mandatory_element do
@@ -1,3 +1,3 @@
1
1
  module Soaspec
2
- VERSION = '0.0.30'
2
+ VERSION = '0.0.31'
3
3
  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.0.30
4
+ version: 0.0.31
5
5
  platform: ruby
6
6
  authors:
7
7
  - SamuelGarrattIQA
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-03-06 00:00:00.000000000 Z
11
+ date: 2018-03-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -152,17 +152,18 @@ files:
152
152
  - exe/xml_to_yaml_file
153
153
  - lib/soaspec.rb
154
154
  - lib/soaspec/accessors.rb
155
- - lib/soaspec/basic_soap_handler.rb
156
155
  - lib/soaspec/exchange.rb
157
- - lib/soaspec/exchange_handler.rb
156
+ - lib/soaspec/exchange_handlers/exchange_handler.rb
157
+ - lib/soaspec/exchange_handlers/rest_handler.rb
158
+ - lib/soaspec/exchange_handlers/soap_handler.rb
158
159
  - lib/soaspec/exe_helpers.rb
159
160
  - lib/soaspec/hash_methods.rb
161
+ - lib/soaspec/interpreter.rb
160
162
  - lib/soaspec/matchers.rb
161
- - lib/soaspec/rest_handler.rb
163
+ - lib/soaspec/not_found_errors.rb
162
164
  - lib/soaspec/soaspec_shared_examples.rb
163
165
  - lib/soaspec/spec_logger.rb
164
166
  - lib/soaspec/version.rb
165
- - lib/soaspec/xpath_not_found.rb
166
167
  - soaspec.gemspec
167
168
  - template/soap_template.xml
168
169
  - test.wsdl
@@ -1,7 +0,0 @@
1
-
2
- # Raised to represent when there's no element at an Xpath
3
- class NoElementAtXpath < StandardError
4
- def initialize(msg="No element Xpath not found")
5
- super
6
- end
7
- end