soaspec 0.2.21 → 0.2.22
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 +4 -4
- data/ChangeLog +8 -0
- data/lib/soaspec/exchange/exchange.rb +7 -3
- data/lib/soaspec/exchange/exchange_extractor.rb +2 -0
- data/lib/soaspec/exchange/exchange_properties.rb +2 -6
- data/lib/soaspec/exchange_handlers/exchange_handler.rb +4 -0
- data/lib/soaspec/exchange_handlers/rest_handler.rb +25 -14
- data/lib/soaspec/interpreter.rb +1 -1
- data/lib/soaspec/matchers.rb +21 -2
- data/lib/soaspec/version.rb +1 -1
- data/lib/soaspec/virtual_server.rb +16 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2f3a41968e523901e869b24522b1fe2c630518239fed2e3600f2e8f5b67a9fb5
|
4
|
+
data.tar.gz: f9af632f2e025cccf4da721120ca44e5aed446d0b5b2353e860d347fbfd28594
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
(
|
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.
|
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')
|
23
|
-
|
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
|
@@ -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
|
-
|
183
|
-
|
184
|
-
|
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[
|
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
|
-
|
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
|
data/lib/soaspec/interpreter.rb
CHANGED
data/lib/soaspec/matchers.rb
CHANGED
@@ -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
|
-
|
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
|
data/lib/soaspec/version.rb
CHANGED
@@ -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
|
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.
|
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-
|
11
|
+
date: 2019-03-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|