soaspec 0.2.21 → 0.2.22

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: 2b1028921ecb551ea11797baf3cc3f857a63ffe605b17e14d2fdf96789fc8b12
4
- data.tar.gz: b09a3d92546409cccfc28b2ee29b8207547fab372028605594c1751ccf175044
3
+ metadata.gz: 2f3a41968e523901e869b24522b1fe2c630518239fed2e3600f2e8f5b67a9fb5
4
+ data.tar.gz: f9af632f2e025cccf4da721120ca44e5aed446d0b5b2353e860d347fbfd28594
5
5
  SHA512:
6
- metadata.gz: 2d546e2a961ad5dd77d92587193b6b1cb7bbbcdcd355a4d33f16f84a0f62318e9b45a51607b39fdf7e1ba71e77359bc77f93e224e846ef4212320390e22c7d37
7
- data.tar.gz: aa2d86da44ddcd01187979b43f8021c21bec56627a4796d056a29104da32a4bd992ab9c342aba22471a9b2d1ad90dc843101df5779949839190f0a002185aaaa
6
+ metadata.gz: a1eb7bf52e74e6c355bf5f078707a97998c90c6084caaae85e4647ad3750e1c5daa9f593f1dbb4aa4bc688a410fa1c3c04a13e06037949a53547d1c3b04305f4
7
+ data.tar.gz: 77f6623886cb834aac76e5bdc275bee97260ddec1d0277c7f57bdb042355d45b03e94902900526520d2ffd2b0e05a23c41980d6c5eae11eee8aadf3c0f4375b2
data/ChangeLog CHANGED
@@ -1,3 +1,11 @@
1
+ Version 0.2.22
2
+ * Bug Fix
3
+ * Allow negated version of 'be_successful' to work
4
+ * Fix `Exchange.retry_count` so that it retries after first try the correct number of times
5
+ * Enhancement
6
+ * Make 'value_from_path' and 'values_from_path' methods accessible from 'response' object
7
+ * Get extracting text via RegEx actually working
8
+
1
9
  Version 0.2.21
2
10
  * Enhancement
3
11
  * Enable deprecation warnings to be removed so that they're not annoying with `Soaspec.log_warnings`
@@ -66,12 +66,12 @@ class Exchange
66
66
  def make_request
67
67
  Soaspec::SpecLogger.info 'Example ' + test_name
68
68
  request_params = @override_parameters
69
- (1..retry_count).each do |count|
69
+ (0..retry_count).each do |count|
70
70
  response = exchange_handler.make_request(request_params)
71
71
  return response unless retry_for_success?
72
72
  return response if (200..299).cover? exchange_handler.status_code_for(response)
73
73
 
74
- sleep 0.5
74
+ sleep 0.5 # Time before retrying
75
75
  break response if count == retry_count
76
76
  end
77
77
  end
@@ -90,9 +90,12 @@ class Exchange
90
90
  # response.header (head of response as Hash)
91
91
  # @example For REST it will be a RestClient::Response
92
92
  def response
93
+ require 'forwardable'
93
94
  Soaspec.last_exchange = self
94
95
  @response ||= make_request
95
96
  @response.define_singleton_method(:exchange) { Soaspec.last_exchange } unless @response.respond_to?(:exchange)
97
+ @response.extend Forwardable
98
+ @response.delegate %i[value_from_path values_from_path] => :exchange
96
99
  @response
97
100
  end
98
101
 
@@ -100,7 +103,8 @@ class Exchange
100
103
  # allow easy method chaining
101
104
  def call
102
105
  if Soaspec.log_warnings
103
- warn 'This method will be changed to return "Exchange" object in 0.3. Use "response" method if you want the response object'
106
+ warn 'This "call" method will be changed to return "Exchange" object in 0.3. ' \
107
+ 'Use "response" method if you want the "response" object'
104
108
  end
105
109
  response
106
110
  end
@@ -27,6 +27,8 @@ module Soaspec
27
27
  exchange_handler.value_from_path(response, path.to_s)
28
28
  end
29
29
 
30
+ alias_method :value_from_path, :[]
31
+
30
32
  # Using same path syntax as []. Returns true of false depending on whether an element is found
31
33
  # @return [Boolean] Whether an element exists at the path
32
34
  def element?(path)
@@ -19,12 +19,8 @@ module Soaspec
19
19
  # Set retry_for_success to true, retrying response until a successful status code is returned
20
20
  # @param [Integer] retry_count Times to retry to get a positive response
21
21
  def expect_positive_status(retry_count: 3)
22
- define_method('retry_count') do
23
- retry_count
24
- end
25
- define_method('retry_for_success?') do
26
- true
27
- end
22
+ define_method('retry_count') { retry_count }
23
+ define_method('retry_for_success?') { true }
28
24
  end
29
25
  end
30
26
  end
@@ -6,6 +6,10 @@ module Soaspec
6
6
  class ExchangeHandler
7
7
  extend Soaspec::HandlerAccessors
8
8
 
9
+ def self.use
10
+ new.use
11
+ end
12
+
9
13
  # Retrieve the name of the template file to be used in the API request
10
14
  attr_reader :template_name
11
15
 
@@ -163,6 +163,24 @@ module Soaspec
163
163
  JsonPath.on(response.body, path)
164
164
  end
165
165
 
166
+ # Calculate all JSON path values based on rules. ',', pascal_case
167
+ # @param [RestClient::Response] response Response from API
168
+ # @param [Object] path Xpath, JSONPath or other path identifying how to find element
169
+ # @param [String] attribute Generic attribute to find. Will override path
170
+ # @param [Boolean] not_empty Whether to fail if result is empty
171
+ # @return [Array] Paths to check as first and matching values (List of values matching JSON Path) as second
172
+ def calculated_json_path_matches(path, response, attribute, not_empty: false)
173
+ path = add_pascal_path(path)
174
+ paths_to_check = path.split(',')
175
+ paths_to_check = paths_to_check.map { |path_to_check| prefix_json_path(path_to_check) }
176
+ matching_values = paths_to_check.collect do |path_to_check|
177
+ json_path_values_for(response, path_to_check, attribute: attribute)
178
+ end.reject(&:empty?)
179
+ raise NoElementAtPath, "No value at JSONPath '#{paths_to_check}' in '#{response.body}'" if matching_values.empty? && not_empty
180
+
181
+ matching_values.first
182
+ end
183
+
166
184
  # Based on a exchange, return the value at the provided xpath
167
185
  # If the path does not begin with a '/', a '//' is added to it
168
186
  # @param [RestClient::Response] response Response from API
@@ -179,21 +197,12 @@ module Soaspec
179
197
 
180
198
  return result.attributes[attribute].inner_text
181
199
  when :json
182
- path = add_pascal_path(path)
183
- paths_to_check = path.split(',')
184
- paths_to_check = paths_to_check.map { |path_to_check| prefix_json_path(path_to_check) }
185
- matching_values = paths_to_check.collect do |path_to_check|
186
- json_path_values_for(response, path_to_check, attribute: attribute)
187
- end.reject(&:empty?)
188
- raise NoElementAtPath, "No value at JSONPath '#{paths_to_check}' in '#{response.body}'" if matching_values.empty?
189
-
190
- matching_values.first.first
191
- when :hash
192
- response.dig(path.split('.')) # Use path as Hash dig expression separating params via '.' TODO: Unit test
193
- else
200
+ matching_values = calculated_json_path_matches(path, response, attribute, not_empty: true)
201
+ matching_values.first
202
+ else # Assume this is a String
194
203
  raise NoElementAtPath, 'Response is empty' if response.to_s.empty?
195
204
 
196
- response.to_s[/path/] # Perform regular expression using path if not XML nor JSON TODO: Unit test
205
+ response.to_s[/#{path}/] # Perform regular expression using path if not XML nor JSON
197
206
  end
198
207
  end
199
208
 
@@ -204,7 +213,9 @@ module Soaspec
204
213
  when :xml
205
214
  xpath_elements_for(response: response, xpath: path, attribute: attribute).map(&:inner_text)
206
215
  when :json
207
- json_path_values_for(response, path, attribute: attribute)
216
+ result = calculated_json_path_matches(path, response, attribute)
217
+ result || []
218
+ # json_path_values_for(response, path, attribute: attribute)
208
219
  else
209
220
  raise "Unable to interpret type of #{response.body}"
210
221
  end
@@ -11,7 +11,7 @@ class Interpreter
11
11
  elsif json?
12
12
  :json
13
13
  else
14
- :unknown
14
+ :string
15
15
  end
16
16
  elsif response.is_a? Hash
17
17
  :hash
@@ -71,9 +71,16 @@ end
71
71
 
72
72
  # Whether response has successful status code and correct mandatory elements and values
73
73
  RSpec::Matchers.define :be_successful do
74
- match do |actual|
74
+ # @param [Exchange, RestClient::Response] actual Object that returns Exchange or is Exchange
75
+ # @return [Exchange] Exchange to use
76
+ def exchange_from(actual)
77
+ actual.respond_to?(:exchange) ? actual.exchange : actual
78
+ end
79
+
80
+ # @param [Exchange, RestClient::Response] exchange Object that returns Exchange or is Exchange
81
+ # @return [Array] List of errors when checking Exchange response is successful
82
+ def collect_errors(exchange)
75
83
  failure_list = []
76
- exchange = actual.respond_to?(:exchange) ? actual.exchange : actual
77
84
  failure_list << "#{exchange.status_code} not valid status code" unless (200..299).cover?(exchange.status_code)
78
85
  exchange.exchange_handler.expected_mandatory_elements.each do |mandatory_element_path|
79
86
  begin
@@ -88,8 +95,20 @@ RSpec::Matchers.define :be_successful do
88
95
  exchange.exchange_handler.expected_mandatory_json_values.each do |path, value|
89
96
  failure_list << "Expected value at json '#{path}' to be '#{value}' but was '#{exchange[path]}'" unless exchange[path] == value
90
97
  end
98
+ failure_list
99
+ end
100
+
101
+ match do |actual|
102
+ exchange = exchange_from actual
103
+ failure_list = collect_errors exchange
91
104
  raise failure_list.to_s unless failure_list.empty?
105
+ true
106
+ end
92
107
 
108
+ match_when_negated do |actual|
109
+ exchange = exchange_from actual
110
+ failure_list = collect_errors exchange
111
+ raise "Expected failure. Status code is #{exchange.status_code}" if failure_list.empty?
93
112
  true
94
113
  end
95
114
  end
@@ -1,3 +1,3 @@
1
1
  module Soaspec
2
- VERSION = '0.2.21'.freeze
2
+ VERSION = '0.2.22'.freeze
3
3
  end
@@ -30,7 +30,7 @@ module Soaspec
30
30
 
31
31
  documentation 'Nothing under /. Go look at /docs' do
32
32
  response 'redirects to the documentation page'
33
- status 303
33
+ status 302
34
34
  end
35
35
  get '/' do
36
36
  redirect '/docs'
@@ -38,6 +38,20 @@ module Soaspec
38
38
 
39
39
  doc_endpoint '/docs'
40
40
 
41
+ documentation 'Simulate server error' do
42
+ status 500
43
+ end
44
+ get '/server_error' do
45
+ [500, {}, 'Internal Server Error']
46
+ end
47
+
48
+ documentation 'Used to verify extract from text response' do
49
+ response 'Plain text with a pattern to match in it'
50
+ end
51
+ get '/text_response' do
52
+ 'This is some text. In here it says ID=12345 to indicate value to obtain'
53
+ end
54
+
41
55
  documentation 'Used to test attributes' do
42
56
  response 'A simple Note XML with a date attribute'
43
57
  end
@@ -63,6 +77,7 @@ module Soaspec
63
77
  JSON.generate(success: Soaspec::TestServer::IdManager.result_for(num, id), id: id)
64
78
  end
65
79
 
80
+ documentation 'Sets status as developed'
66
81
  post '/packages/developed' do
67
82
  Soaspec::TestServer::IdManager.developed = request.body.include?('true')
68
83
  Soaspec::TestServer::IdManager.developed.to_s
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.2.21
4
+ version: 0.2.22
5
5
  platform: ruby
6
6
  authors:
7
7
  - SamuelGarrattIQA
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-03-20 00:00:00.000000000 Z
11
+ date: 2019-03-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler