soaspec 0.2.8 → 0.2.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitlab-ci.yml +0 -17
- data/ChangeLog +6 -0
- data/Gemfile +2 -2
- data/README.md +42 -9
- data/Rakefile +1 -1
- data/exe/soaspec +9 -14
- data/exe/xml_to_yaml_file +3 -3
- data/images/basic_demo.gif +0 -0
- data/lib/soaspec.rb +9 -19
- data/lib/soaspec/core_ext/hash.rb +10 -12
- data/lib/soaspec/cucumber/generic_steps.rb +1 -1
- data/lib/soaspec/exchange.rb +4 -1
- data/lib/soaspec/exchange_handlers/exchange_handler.rb +5 -4
- data/lib/soaspec/exchange_handlers/handler_accessors.rb +7 -3
- data/lib/soaspec/exchange_handlers/response_extractor.rb +55 -0
- data/lib/soaspec/exchange_handlers/rest_exchanger_factory.rb +1 -1
- data/lib/soaspec/exchange_handlers/rest_handler.rb +16 -43
- data/lib/soaspec/exchange_handlers/rest_methods.rb +1 -2
- data/lib/soaspec/exchange_handlers/rest_parameters.rb +6 -2
- data/lib/soaspec/exchange_handlers/rest_parameters_defaults.rb +1 -1
- data/lib/soaspec/exchange_handlers/soap_handler.rb +6 -10
- data/lib/soaspec/exchange_properties.rb +1 -2
- data/lib/soaspec/exe_helpers.rb +7 -9
- data/lib/soaspec/indifferent_hash.rb +1 -1
- data/lib/soaspec/interpreter.rb +1 -3
- data/lib/soaspec/matchers.rb +1 -2
- data/lib/soaspec/o_auth2.rb +2 -1
- data/lib/soaspec/spec_logger.rb +54 -12
- data/lib/soaspec/template_reader.rb +2 -1
- data/lib/soaspec/test_server/get_bank.rb +5 -5
- data/lib/soaspec/test_server/id_manager.rb +1 -3
- data/lib/soaspec/test_server/invoices.rb +0 -1
- data/lib/soaspec/test_server/puppy_service.rb +0 -1
- data/lib/soaspec/test_server/test_attribute.rb +0 -1
- data/lib/soaspec/version.rb +2 -2
- data/lib/soaspec/virtual_server.rb +1 -1
- data/lib/soaspec/wait.rb +1 -1
- data/lib/soaspec/wsdl_generator.rb +11 -3
- data/soaspec.gemspec +7 -2
- data/test_wsdl.rb +4 -7
- metadata +54 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 17d2693e9fd08ec36b86235d2fd0a5991ef252a3
|
4
|
+
data.tar.gz: 68ec551ebe49f36c211a9fd856c3b5b669f3b5f8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 718d1fde689c36a4e96fc0ac61645151de132c3202a7213e21a8adad01c48b0aa6a76cfb057597c86b6e0e31177ef69dfcf88139e2f9285ad93c9e279b14c872
|
7
|
+
data.tar.gz: 7f2808840766e5ae179efc5ae3afd3e9d91364f92bc3196db8b7432df29df3bd0e19eef5d149bea6a817198468ee075dfcca5a2b26a120dc6e9aff2d8425ab76
|
data/.gitlab-ci.yml
CHANGED
@@ -19,23 +19,6 @@ cucumber:
|
|
19
19
|
script:
|
20
20
|
- bundle exec cucumber
|
21
21
|
|
22
|
-
code_quality:
|
23
|
-
image: ruby:2.5
|
24
|
-
variables:
|
25
|
-
DOCKER_DRIVER: overlay2
|
26
|
-
allow_failure: true
|
27
|
-
services:
|
28
|
-
- docker:stable-dind
|
29
|
-
script:
|
30
|
-
- export SP_VERSION=$(echo "$CI_SERVER_VERSION" | sed 's/^\([0-9]*\)\.\([0-9]*\).*/\1-\2-stable/')
|
31
|
-
- docker run
|
32
|
-
--env SOURCE_CODE="$PWD"
|
33
|
-
--volume "$PWD":/code
|
34
|
-
--volume /var/run/docker.sock:/var/run/docker.sock
|
35
|
-
"registry.gitlab.com/gitlab-org/security-products/codequality:$SP_VERSION" /code
|
36
|
-
artifacts:
|
37
|
-
paths: [gl-code-quality-report.json]
|
38
|
-
|
39
22
|
pages:
|
40
23
|
stage: deploy
|
41
24
|
dependencies:
|
data/ChangeLog
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
Version 0.2.9
|
2
|
+
* Enhancements
|
3
|
+
* More documentation in README.md
|
4
|
+
* Started breaking up massive RestHandler more
|
5
|
+
* Allow one output logs to STDOUT through Soaspec::SpecLogger.output_to_terminal = true
|
6
|
+
|
1
7
|
Version 0.2.8
|
2
8
|
* Bug Fix
|
3
9
|
* RSpec-its dependency produces a conflict. Remove specific version reference
|
data/Gemfile
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
source
|
1
|
+
source 'https://rubygems.org'
|
2
2
|
|
3
|
-
git_source(:gitlab) { |
|
3
|
+
git_source(:gitlab) { |_repo_name| 'https://gitlab.com/samuel-garratt/soaspec' }
|
4
4
|
|
5
5
|
# Specify your gem's dependencies in soaspec.gemspec
|
6
6
|
gemspec
|
data/README.md
CHANGED
@@ -1,6 +1,13 @@
|
|
1
1
|
# Soaspec
|
2
2
|
|
3
3
|
This gem helps to represent multiple API tests against a backend briefly, concisely and clearly.
|
4
|
+
|
5
|
+
![Soaspec example](images/basic_demo.gif)
|
6
|
+
> Example showing how a REST 'get' call can be made and it's response extracted.
|
7
|
+
|
8
|
+
[![Build Status](https://gitlab.com/samuel-garratt/soaspec/badges/master/build.svg)](https://gitlab.com/samuel-garratt/soaspec/pipelines)
|
9
|
+
[![Coverage](https://gitlab.com/samuel-garratt/soaspec/badges/master/coverage.svg)](https://samuel-garratt.gitlab.io/soaspec)
|
10
|
+
|
4
11
|
It is essentially a wrapper around the Savon and RestClient gems, adding useful functionality including
|
5
12
|
|
6
13
|
* Creating multiple API calls from the same base configuration through the use of an `ExchangeHandler` class
|
@@ -13,8 +20,6 @@ It is essentially a wrapper around the Savon and RestClient gems, adding useful
|
|
13
20
|
* Accessing and utilising `oauth2` access tokens
|
14
21
|
* Hosting a `virtual_server` that simulates REST & SOAP responses from an API
|
15
22
|
|
16
|
-
[![Build Status](https://gitlab.com/samuel-garratt/soaspec/badges/master/build.svg)](https://gitlab.com/samuel-garratt/soaspec/pipelines)
|
17
|
-
[![Coverage](https://gitlab.com/samuel-garratt/soaspec/badges/master/coverage.svg)](https://samuel-garratt.gitlab.io/soaspec)
|
18
23
|
## Installation
|
19
24
|
|
20
25
|
Add this line to your application's Gemfile:
|
@@ -72,13 +77,18 @@ For example:
|
|
72
77
|
```ruby
|
73
78
|
# Classes are set up through inheriting from either `Soaspec::RestHandler` or `Soaspec::SoapHandler`
|
74
79
|
class PuppyService < Soaspec::RestHandler
|
80
|
+
# Set default headers for all `Exchanges` using this class
|
81
|
+
headers accept: 'application/json', content_type: 'application/json'
|
75
82
|
|
76
|
-
|
83
|
+
# URL for which all requests using this class will start with
|
84
|
+
base_url 'http://petstore.swagger.io/v2/pet'
|
77
85
|
|
78
|
-
|
86
|
+
# Accessing parts of a response
|
79
87
|
|
80
|
-
|
81
|
-
element :
|
88
|
+
# Define a method 'id' that can be obtained with either XPATH '//id' or JSONPath '$..id'
|
89
|
+
element :id, :id
|
90
|
+
# Define method to obtain a category id through JSON Path
|
91
|
+
element :category_id, '$..category.id'
|
82
92
|
end
|
83
93
|
```
|
84
94
|
|
@@ -91,17 +101,40 @@ Upon initialization of the Exchange object (or later on through setters), parame
|
|
91
101
|
Most getters of the `Exchange` are on the response & will implicitly trigger the API request to be made.
|
92
102
|
Once this request has been made, all following accessors of the response will just use the response of the previous request made.
|
93
103
|
|
94
|
-
For example, to create a http post using the above `ExchangeHandler` and
|
104
|
+
For example, to create a http post using the above `ExchangeHandler` and get parts of it's response.
|
95
105
|
```ruby
|
96
|
-
exchange = PuppyService.post(body: { status: 'sold' }) # The 'body' key will convert it's value from a Hash to JSON
|
97
106
|
# Create a new Exchange that will post to 'http://petstore.swagger.io/v2/pet' with JSON { "status": "sold" }
|
107
|
+
# The 'body' key will convert it's value from a Hash to JSON
|
108
|
+
exchange = PuppyService.post(body: { status: 'sold' })
|
109
|
+
|
110
|
+
# This will trigger the request to be made & return the response, in this case a RestClient::Response object
|
111
|
+
response = exchange.response
|
112
|
+
# This will reuse the response already received return a value at JSON path $..category.id, throwing an exception if not found
|
98
113
|
exchange.category_id
|
99
|
-
# This will
|
114
|
+
# This will do the same but using path directly in code
|
115
|
+
exchange['$..category.id']
|
116
|
+
# Get the HTTP status code of the response
|
117
|
+
exchange.status_code
|
100
118
|
```
|
101
119
|
|
102
120
|
See [Request Body Parameters](https://gitlab.com/samuel-garratt/soaspec/wikis/RequestBodyParameters) for more details on setting a request body.
|
103
121
|
See [Creating an Exchange](https://gitlab.com/samuel-garratt/soaspec/wikis/CreatingExchange) for details on how to create an Exchange.
|
104
122
|
|
123
|
+
### Virtual Server
|
124
|
+
|
125
|
+
Soaspec includes a virtual server that returns REST and SOAP responses that can be used when learning or experimenting with API testing.
|
126
|
+
The gem itself uses this to test it's own functionality.
|
127
|
+
|
128
|
+
To start the server, after installing the gem, type
|
129
|
+
|
130
|
+
```
|
131
|
+
soaspec virtual_server [port_num]
|
132
|
+
```
|
133
|
+
|
134
|
+
By default it runs on port 4999. This will be used if `port_num` is empty.
|
135
|
+
|
136
|
+
You can look at the documentation for the web services provided at the rool url (e.g `localhost:4999`).
|
137
|
+
|
105
138
|
### RSpec
|
106
139
|
|
107
140
|
For example:
|
data/Rakefile
CHANGED
data/exe/soaspec
CHANGED
@@ -1,16 +1,13 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
|
4
3
|
require 'thor'
|
5
4
|
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
6
5
|
require 'savon'
|
7
6
|
require 'soaspec'
|
8
7
|
|
9
8
|
module Soaspec
|
10
|
-
|
11
9
|
# Common executable for Soaspec
|
12
10
|
class Exe < Thor
|
13
|
-
|
14
11
|
include Soaspec::ExeHelpers
|
15
12
|
include Soaspec::WsdlGenerator
|
16
13
|
|
@@ -54,6 +51,7 @@ module Soaspec
|
|
54
51
|
desc 'add [type] [name]', 'Add new ExchangeHandler'
|
55
52
|
def add(type = 'rest', name = 'TestService')
|
56
53
|
raise "Type '#{type}' is not available" unless %w[rest soap].include? type
|
54
|
+
|
57
55
|
@name = name # Use instance variable for ERB
|
58
56
|
create_file filename: File.join('lib', "#{name.snakecase}.rb"),
|
59
57
|
content: retrieve_contents(File.join('lib', "new_#{type}_service.rb"))
|
@@ -87,30 +85,27 @@ module Soaspec
|
|
87
85
|
@wsdl_doc = Savon.client(**savon_options).wsdl
|
88
86
|
@wsdl_schemas = @wsdl_doc.parser.schemas
|
89
87
|
|
90
|
-
|
91
|
-
create_file filename: 'Gemfile', ignore_if_present: true
|
88
|
+
create_files %w[Rakefile Gemfile README.md spec/spec_helper.rb], ignore_if_present: true
|
92
89
|
create_file(filename: '.rspec')
|
93
90
|
create_file(filename: '.travis.yml') if options[:ci] == 'travis'
|
94
|
-
create_file filename: 'README.md', ignore_if_present: true
|
95
|
-
create_file filename: 'spec/spec_helper.rb', ignore_if_present: true
|
96
91
|
create_folder 'logs'
|
97
92
|
create_file filename: "lib/#{options[:name].snakecase}.rb", content: class_content
|
98
93
|
|
99
94
|
# Files according to WSDL
|
100
|
-
@wsdl_doc.operations.each do |operation,
|
95
|
+
@wsdl_doc.operations.each do |operation, op_details|
|
101
96
|
puts "Creating files for operation: #{operation}"
|
102
97
|
@content = "default:\n"
|
103
98
|
@use_camel_case = false
|
104
|
-
puts 'Message params: ' +
|
99
|
+
puts 'Message params: ' + op_details.to_s
|
105
100
|
# From namespace identifier, find namespace, and for that find schemaLocation xsd and use that to build request
|
106
|
-
if
|
107
|
-
|
108
|
-
@use_camel_case = true
|
101
|
+
if op_details[:parameters]
|
102
|
+
op_details[:parameters].each do |element, details|
|
103
|
+
@use_camel_case = true unless /[[:upper:]]/.match(element.to_s[0]).nil?
|
109
104
|
@content += " #{element.to_s.snakecase}: #{fill_in_field_from_type(details[:type])} # #{details[:type]} \n"
|
110
105
|
# TODO: If details is a Hash need to loop again
|
111
106
|
end
|
112
107
|
end
|
113
|
-
wsdl_to_yaml_for root_elements_for(
|
108
|
+
wsdl_to_yaml_for root_elements_for(op_details)
|
114
109
|
params = []
|
115
110
|
params << 'convert_request_keys_to: :camelcase' if @use_camel_case
|
116
111
|
params_string = params == [] ? '' : ', ' + params.join(', ')
|
@@ -133,4 +128,4 @@ module Soaspec
|
|
133
128
|
end
|
134
129
|
end
|
135
130
|
|
136
|
-
Soaspec::Exe.start(ARGV)
|
131
|
+
Soaspec::Exe.start(ARGV)
|
data/exe/xml_to_yaml_file
CHANGED
@@ -4,7 +4,7 @@ require 'xmlsimple'
|
|
4
4
|
require 'yaml'
|
5
5
|
require 'fileutils'
|
6
6
|
|
7
|
-
$LOAD_PATH.unshift File.join(File.dirname(__FILE__),
|
7
|
+
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
8
8
|
|
9
9
|
require 'soaspec'
|
10
10
|
|
@@ -28,7 +28,7 @@ end
|
|
28
28
|
def clean_up_yaml(yaml_string)
|
29
29
|
yaml_string = yaml_string.gsub(/\R+(\s*)-/, '').gsub(/{}/, "''") # Remove arrays, {} -> ''
|
30
30
|
# Insert new line where there are 2 ':' on 1 line. Issue from first gsub
|
31
|
-
yaml_string.gsub(/:(\s)(\w*):/){|s| s.insert(1, "\n")}
|
31
|
+
yaml_string.gsub(/:(\s)(\w*):/) { |s| s.insert(1, "\n") }
|
32
32
|
end
|
33
33
|
|
34
34
|
if ARGV[0]
|
@@ -39,4 +39,4 @@ if ARGV[0]
|
|
39
39
|
create_file(filename: ARGV[1] || default_output_file, content: yaml_file)
|
40
40
|
else
|
41
41
|
puts 'usage: xml_to_yaml_file [input.xml] [output.yml] '
|
42
|
-
end
|
42
|
+
end
|
Binary file
|
data/lib/soaspec.rb
CHANGED
@@ -36,7 +36,6 @@ require 'soaspec/wait'
|
|
36
36
|
|
37
37
|
# Gem for handling SOAP and REST api tests
|
38
38
|
module Soaspec
|
39
|
-
|
40
39
|
@template_folder = 'templates'
|
41
40
|
@auto_oauth = true
|
42
41
|
|
@@ -59,31 +58,21 @@ module Soaspec
|
|
59
58
|
# Folder used to store credentials
|
60
59
|
# Used in auth2_file command
|
61
60
|
# @param [String] folder
|
62
|
-
|
63
|
-
@credentials_folder = folder
|
64
|
-
end
|
61
|
+
attr_writer :credentials_folder
|
65
62
|
|
66
63
|
# Credentials folder used to store secret data (not in source control) E.g passwords
|
67
|
-
|
68
|
-
@credentials_folder
|
69
|
-
end
|
64
|
+
attr_reader :credentials_folder
|
70
65
|
|
71
66
|
# Used so that exchange class knows what context it's in
|
72
67
|
# @param [ExchangeHandler] handler A class inheriting from Soaspec::ExchangeHandler. Exchange class uses this
|
73
|
-
|
74
|
-
@api_handler = handler
|
75
|
-
end
|
68
|
+
attr_writer :api_handler
|
76
69
|
|
77
70
|
# Exchange Handler class currently being used
|
78
|
-
|
79
|
-
@api_handler
|
80
|
-
end
|
71
|
+
attr_reader :api_handler
|
81
72
|
|
82
73
|
# Set whether to transform strings to keys in request automatically
|
83
74
|
# @param [Boolean] use_keys
|
84
|
-
|
85
|
-
@always_use_keys = use_keys
|
86
|
-
end
|
75
|
+
attr_writer :always_use_keys
|
87
76
|
|
88
77
|
# @return [Boolean] Whether to transform strings to keys in request automatically
|
89
78
|
def always_use_keys?
|
@@ -97,13 +86,14 @@ module Soaspec
|
|
97
86
|
|
98
87
|
# Whether to log all API traffic
|
99
88
|
def log_api_traffic=(set)
|
100
|
-
|
101
|
-
|
89
|
+
puts 'Soaspec.log_api_traffic= now deprecated. Please use Soaspec::SpecLogger.log_api_traffic= instead'
|
90
|
+
Soaspec::SpecLogger.log_api_traffic = set
|
102
91
|
end
|
103
92
|
|
104
93
|
# @return [Boolean] Whether to log all API traffic
|
105
94
|
def log_api_traffic?
|
106
|
-
|
95
|
+
puts 'Soaspec.log_api_traffic? now deprecated. Please use Soaspec::SpecLogger.log_api_traffic? instead'
|
96
|
+
Soaspec::SpecLogger.log_api_traffic?
|
107
97
|
end
|
108
98
|
end
|
109
99
|
end
|
@@ -1,28 +1,25 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
1
|
# Override Hash class with convience methods
|
5
2
|
class Hash
|
6
|
-
|
7
3
|
# Transform each key in Hash to a symbol. Privately used by non-self method
|
8
4
|
def self.transform_keys_to_symbols(value)
|
9
|
-
return value
|
10
|
-
|
11
|
-
|
5
|
+
return value unless value.is_a?(Hash)
|
6
|
+
|
7
|
+
hash = value.each_with_object({}) { |(k, v), memo| memo[k.to_sym] = Hash.transform_keys_to_symbols(v); }
|
8
|
+
hash
|
12
9
|
end
|
13
10
|
|
14
11
|
# Take keys of hash and transform those to a symbols
|
15
12
|
def transform_keys_to_symbols
|
16
|
-
|
13
|
+
each_with_object({}) { |(k, v), memo| memo[k.to_sym] = Hash.transform_keys_to_symbols(v); }
|
17
14
|
end
|
18
15
|
|
19
16
|
# Returns all keys that have a particular value within a nested Hash
|
20
17
|
def find_all_values_for(key)
|
21
18
|
result = []
|
22
19
|
result << self[key]
|
23
|
-
|
24
|
-
|
25
|
-
|
20
|
+
values.each do |hash_value|
|
21
|
+
# next if hash_value.is_a? Array
|
22
|
+
#
|
26
23
|
if hash_value.is_a?(Array)
|
27
24
|
hash_value.each do |array_element|
|
28
25
|
result += array_element.find_all_values_for(key) if array_element.is_a? Hash
|
@@ -42,9 +39,11 @@ class Hash
|
|
42
39
|
each_value do |v|
|
43
40
|
return true if v == value
|
44
41
|
next unless v.is_a? Hash
|
42
|
+
|
45
43
|
v.each_value do |v|
|
46
44
|
return true if v == value
|
47
45
|
next unless v.is_a? Hash
|
46
|
+
|
48
47
|
v.each_value do |v|
|
49
48
|
return true if v == value
|
50
49
|
end
|
@@ -79,5 +78,4 @@ class Hash
|
|
79
78
|
end
|
80
79
|
end
|
81
80
|
end
|
82
|
-
|
83
81
|
end
|
data/lib/soaspec/exchange.rb
CHANGED
@@ -62,6 +62,7 @@ class Exchange
|
|
62
62
|
# As a last resort this uses the global parameter. The handler should be set straight before an exchange is made to use this
|
63
63
|
@exchange_handler ||= default_handler_used || Soaspec.api_handler
|
64
64
|
raise '@exchange_handler not set. Set either with `Soaspec.api_handler = Handler.new` or within the exchange' unless @exchange_handler
|
65
|
+
|
65
66
|
@fail_factory = nil
|
66
67
|
@override_parameters = override_parameters
|
67
68
|
@retry_for_success = false
|
@@ -91,6 +92,7 @@ class Exchange
|
|
91
92
|
response = exchange_handler.make_request(request_params)
|
92
93
|
return response unless retry_for_success?
|
93
94
|
return response if (200..299).cover? @exchange_handler.status_code_for(response)
|
95
|
+
|
94
96
|
sleep 0.5
|
95
97
|
break response if count == retry_count
|
96
98
|
end
|
@@ -109,6 +111,7 @@ class Exchange
|
|
109
111
|
def retrieve(name)
|
110
112
|
method = '__stored_val__' + name.to_s
|
111
113
|
raise ArgumentError('Value not stored at ') unless exchange_handler.respond_to? method
|
114
|
+
|
112
115
|
exchange_handler.send(method)
|
113
116
|
end
|
114
117
|
|
@@ -230,4 +233,4 @@ class Exchange
|
|
230
233
|
end
|
231
234
|
self
|
232
235
|
end
|
233
|
-
end
|
236
|
+
end
|
@@ -1,8 +1,6 @@
|
|
1
|
-
|
2
1
|
require_relative 'handler_accessors'
|
3
2
|
|
4
3
|
module Soaspec
|
5
|
-
|
6
4
|
# Inherit this for a class describing how to implement a particular exchange.
|
7
5
|
# Has basic methods common for methods defining RSpec tests in YAML
|
8
6
|
class ExchangeHandler
|
@@ -19,10 +17,11 @@ module Soaspec
|
|
19
17
|
# Set instance variable name
|
20
18
|
# @param [String, Symbol] name Name used when describing API test
|
21
19
|
# @param [Hash] options Parameters defining handler. Used in descendants
|
22
|
-
def initialize(name = self.class.to_s,
|
20
|
+
def initialize(name = self.class.to_s, _options = {})
|
23
21
|
use
|
24
22
|
@request_option = :hash
|
25
23
|
raise ArgumentError, 'Cannot define both template_name and default_hash' if respond_to?(:template_name_value) && respond_to?(:default_hash_value)
|
24
|
+
|
26
25
|
@template_name = respond_to?(:template_name_value) ? template_name_value : ''
|
27
26
|
@default_hash = respond_to?(:default_hash_value) ? default_hash_value : {}
|
28
27
|
@name = name
|
@@ -102,6 +101,7 @@ module Soaspec
|
|
102
101
|
# Set instance variable and remove it from Hash
|
103
102
|
def set_remove_key(hash, key)
|
104
103
|
return unless hash.key? key
|
104
|
+
|
105
105
|
__send__("#{key}=", hash[key])
|
106
106
|
hash.delete key
|
107
107
|
end
|
@@ -114,7 +114,8 @@ module Soaspec
|
|
114
114
|
# Request of API call. Either intended request or actual request
|
115
115
|
def request(response)
|
116
116
|
return "Request not yet sent Request option is #{@request_option}" unless response
|
117
|
+
|
117
118
|
'Specific API handler should implement this'
|
118
119
|
end
|
119
120
|
end
|
120
|
-
end
|
121
|
+
end
|
@@ -2,7 +2,6 @@ module Soaspec
|
|
2
2
|
# Describes methods test handlers use to easily set attributes
|
3
3
|
# Some are included in 'success scenarios' and to configure the request sent
|
4
4
|
module HandlerAccessors
|
5
|
-
|
6
5
|
# Defines expected_mandatory_elements method used in 'success_scenario' shared examples
|
7
6
|
# to indicate certain elements must be present
|
8
7
|
# @param [Array] elements Array of symbols specifying expected element names for 'success scenario' in snakecase
|
@@ -22,6 +21,7 @@ module Soaspec
|
|
22
21
|
def mandatory_elements(elements)
|
23
22
|
define_method('expected_mandatory_elements') do
|
24
23
|
return [elements] if elements.is_a?(String) || elements.is_a?(Symbol)
|
24
|
+
|
25
25
|
elements
|
26
26
|
end
|
27
27
|
end
|
@@ -38,6 +38,7 @@ module Soaspec
|
|
38
38
|
#
|
39
39
|
def mandatory_xpath_values(xpath_value_pairs)
|
40
40
|
raise ArgumentError('Hash of {xpath => expected values} expected ') unless xpath_value_pairs.is_a? Hash
|
41
|
+
|
41
42
|
define_method('expected_mandatory_xpath_values') { xpath_value_pairs }
|
42
43
|
end
|
43
44
|
|
@@ -53,6 +54,7 @@ module Soaspec
|
|
53
54
|
#
|
54
55
|
def mandatory_json_values(json_value_pairs)
|
55
56
|
raise ArgumentError("Hash of {'jsonpath' => expected values} expected") unless json_value_pairs.is_a? Hash
|
57
|
+
|
56
58
|
define_method('expected_mandatory_json_values') { json_value_pairs }
|
57
59
|
end
|
58
60
|
|
@@ -73,7 +75,7 @@ module Soaspec
|
|
73
75
|
# @param [String, Symbol] name Method name used to access attribute
|
74
76
|
# @param [String, nil, Hash] attribute Attribute name to extract from xml. If not set, this will default to @name
|
75
77
|
def attribute(name, attribute = nil)
|
76
|
-
attribute_used = attribute
|
78
|
+
attribute_used = attribute || name.to_s
|
77
79
|
define_method("__custom_path_#{name}") do |response|
|
78
80
|
value_from_path(response, 'implicit', attribute: attribute_used)
|
79
81
|
end
|
@@ -83,6 +85,7 @@ module Soaspec
|
|
83
85
|
# You must then use lower case in the xpath's to obtain the desired values
|
84
86
|
def convert_to_lower(set)
|
85
87
|
return unless set
|
88
|
+
|
86
89
|
define_method('convert_to_lower?') { true }
|
87
90
|
end
|
88
91
|
|
@@ -92,6 +95,7 @@ module Soaspec
|
|
92
95
|
# This will be overridden if xpath has a ':' in it
|
93
96
|
def strip_namespaces(set)
|
94
97
|
return unless set
|
98
|
+
|
95
99
|
# Whether to remove namespaces in xpath assertion automatically
|
96
100
|
define_method('strip_namespaces?') { true }
|
97
101
|
end
|
@@ -116,4 +120,4 @@ module Soaspec
|
|
116
120
|
end
|
117
121
|
end
|
118
122
|
end
|
119
|
-
end
|
123
|
+
end
|