soaspec 0.2.33 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +15 -15
- data/.gitlab-ci.yml +62 -62
- data/.rspec +3 -3
- data/.rubocop.yml +2 -2
- data/CODE_OF_CONDUCT.md +74 -74
- data/ChangeLog +643 -632
- data/Dockerfile +7 -7
- data/Gemfile +8 -8
- data/LICENSE.txt +21 -21
- data/README.md +253 -231
- data/Rakefile +52 -52
- data/Todo.md +16 -16
- data/exe/soaspec +140 -138
- data/exe/xml_to_yaml_file +43 -43
- data/lib/soaspec.rb +118 -106
- data/lib/soaspec/baseline.rb +82 -22
- data/lib/soaspec/core_ext/hash.rb +44 -44
- data/lib/soaspec/cucumber/generic_steps.rb +94 -94
- data/lib/soaspec/demo.rb +6 -6
- data/lib/soaspec/errors.rb +24 -24
- data/lib/soaspec/exchange/exchange.rb +131 -129
- data/lib/soaspec/exchange/exchange_extractor.rb +105 -90
- data/lib/soaspec/exchange/exchange_properties.rb +28 -28
- data/lib/soaspec/exchange/exchange_repeater.rb +21 -21
- data/lib/soaspec/exchange/request_builder.rb +108 -70
- data/lib/soaspec/exchange/variable_storer.rb +24 -24
- data/lib/soaspec/exchange_handlers/exchange_handler.rb +98 -98
- data/lib/soaspec/exchange_handlers/exchange_handler_defaults.rb +61 -61
- data/lib/soaspec/exchange_handlers/handler_accessors.rb +132 -132
- data/lib/soaspec/exchange_handlers/request/rest_request.rb +77 -59
- data/lib/soaspec/exchange_handlers/request/soap_request.rb +41 -41
- data/lib/soaspec/exchange_handlers/response_extractor.rb +84 -84
- data/lib/soaspec/exchange_handlers/rest_exchanger_factory.rb +111 -111
- data/lib/soaspec/exchange_handlers/rest_handler.rb +307 -307
- data/lib/soaspec/exchange_handlers/rest_methods.rb +65 -65
- data/lib/soaspec/exchange_handlers/rest_parameters.rb +112 -112
- data/lib/soaspec/exchange_handlers/rest_parameters_defaults.rb +42 -42
- data/lib/soaspec/exchange_handlers/soap_handler.rb +241 -241
- data/lib/soaspec/exe_helpers.rb +94 -94
- data/lib/soaspec/generate_server.rb +48 -48
- data/lib/soaspec/generator/.rspec.erb +5 -5
- data/lib/soaspec/generator/.travis.yml.erb +5 -5
- data/lib/soaspec/generator/Gemfile.erb +8 -8
- data/lib/soaspec/generator/README.md.erb +29 -29
- data/lib/soaspec/generator/Rakefile.erb +20 -19
- data/lib/soaspec/generator/config/data/default.yml.erb +2 -2
- data/lib/soaspec/generator/css/bootstrap.css +6833 -6833
- data/lib/soaspec/generator/features/support/env.rb.erb +3 -3
- data/lib/soaspec/generator/generate_exchange.html.erb +47 -47
- data/lib/soaspec/generator/lib/blz_service.rb.erb +26 -26
- data/lib/soaspec/generator/lib/dynamic_class_content.rb.erb +12 -12
- data/lib/soaspec/generator/lib/new_rest_service.rb.erb +56 -56
- data/lib/soaspec/generator/lib/new_soap_service.rb.erb +29 -29
- data/lib/soaspec/generator/lib/package_service.rb.erb +2 -2
- data/lib/soaspec/generator/lib/shared_example.rb.erb +8 -8
- data/lib/soaspec/generator/spec/dynamic_soap_spec.rb.erb +12 -12
- data/lib/soaspec/generator/spec/rest_spec.rb.erb +9 -9
- data/lib/soaspec/generator/spec/soap_spec.rb.erb +51 -51
- data/lib/soaspec/generator/spec/spec_helper.rb.erb +23 -23
- data/lib/soaspec/generator/template/soap_template.xml +6 -6
- data/lib/soaspec/indifferent_hash.rb +9 -9
- data/lib/soaspec/interpreter.rb +70 -70
- data/lib/soaspec/matchers.rb +136 -140
- data/lib/soaspec/o_auth2.rb +142 -142
- data/lib/soaspec/soaspec_shared_examples.rb +26 -26
- data/lib/soaspec/spec_logger.rb +143 -143
- data/lib/soaspec/template_reader.rb +30 -30
- data/lib/soaspec/test_server/bank.wsdl +90 -90
- data/lib/soaspec/test_server/get_bank.rb +166 -166
- data/lib/soaspec/test_server/id_manager.rb +41 -41
- data/lib/soaspec/test_server/invoices.rb +29 -29
- data/lib/soaspec/test_server/namespace.xml +14 -14
- data/lib/soaspec/test_server/note.xml +5 -5
- data/lib/soaspec/test_server/puppy_service.rb +21 -21
- data/lib/soaspec/test_server/test_attribute.rb +14 -14
- data/lib/soaspec/test_server/test_namespace.rb +14 -14
- data/lib/soaspec/version.rb +6 -6
- data/lib/soaspec/virtual_server.rb +193 -190
- data/lib/soaspec/wait.rb +43 -43
- data/lib/soaspec/wsdl_generator.rb +215 -215
- data/soaspec.gemspec +58 -58
- data/test.wsdl +116 -116
- data/test.xml +10 -10
- data/test_wsdl.rb +43 -43
- metadata +3 -3
data/lib/soaspec.rb
CHANGED
@@ -1,106 +1,118 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'rest-client' # REST
|
4
|
-
require 'erb' # Embedded ruby
|
5
|
-
require 'yaml' # Reading yaml
|
6
|
-
require 'rspec' # Testing framework
|
7
|
-
require 'rspec/its'
|
8
|
-
require 'savon' # SOAP
|
9
|
-
require 'nokogiri' # XPath
|
10
|
-
require 'date'
|
11
|
-
require 'jsonpath'
|
12
|
-
|
13
|
-
require 'soaspec/version'
|
14
|
-
require 'soaspec/indifferent_hash'
|
15
|
-
require 'soaspec/o_auth2'
|
16
|
-
require 'soaspec/template_reader'
|
17
|
-
require 'soaspec/exchange_handlers/soap_handler'
|
18
|
-
require 'soaspec/exchange_handlers/exchange_handler'
|
19
|
-
require 'soaspec/exchange_handlers/rest_methods'
|
20
|
-
require 'soaspec/exchange/exchange'
|
21
|
-
require 'soaspec/matchers'
|
22
|
-
require 'soaspec/soaspec_shared_examples'
|
23
|
-
require 'soaspec/core_ext/hash'
|
24
|
-
require 'soaspec/spec_logger'
|
25
|
-
require 'soaspec/exe_helpers'
|
26
|
-
require 'soaspec/exchange_handlers/rest_handler'
|
27
|
-
require 'soaspec/exchange_handlers/handler_accessors'
|
28
|
-
require 'soaspec/interpreter'
|
29
|
-
require 'soaspec/errors'
|
30
|
-
require 'soaspec/wait'
|
31
|
-
require 'soaspec/baseline'
|
32
|
-
|
33
|
-
# Gem for handling SOAP and REST api tests
|
34
|
-
module Soaspec
|
35
|
-
@template_folder = 'templates'
|
36
|
-
@auto_oauth = true
|
37
|
-
@log_warnings = true
|
38
|
-
# @return [String] Folder in which credentials are stored
|
39
|
-
@credentials_folder = 'credentials'
|
40
|
-
|
41
|
-
class
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
#
|
46
|
-
# @return [
|
47
|
-
|
48
|
-
#
|
49
|
-
# @return [
|
50
|
-
attr_accessor :
|
51
|
-
|
52
|
-
#
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
#
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
#
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
@
|
77
|
-
end
|
78
|
-
|
79
|
-
#
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
#
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rest-client' # REST
|
4
|
+
require 'erb' # Embedded ruby
|
5
|
+
require 'yaml' # Reading yaml
|
6
|
+
require 'rspec' # Testing framework
|
7
|
+
require 'rspec/its'
|
8
|
+
require 'savon' # SOAP
|
9
|
+
require 'nokogiri' # XPath
|
10
|
+
require 'date'
|
11
|
+
require 'jsonpath'
|
12
|
+
|
13
|
+
require 'soaspec/version'
|
14
|
+
require 'soaspec/indifferent_hash'
|
15
|
+
require 'soaspec/o_auth2'
|
16
|
+
require 'soaspec/template_reader'
|
17
|
+
require 'soaspec/exchange_handlers/soap_handler'
|
18
|
+
require 'soaspec/exchange_handlers/exchange_handler'
|
19
|
+
require 'soaspec/exchange_handlers/rest_methods'
|
20
|
+
require 'soaspec/exchange/exchange'
|
21
|
+
require 'soaspec/matchers'
|
22
|
+
require 'soaspec/soaspec_shared_examples'
|
23
|
+
require 'soaspec/core_ext/hash'
|
24
|
+
require 'soaspec/spec_logger'
|
25
|
+
require 'soaspec/exe_helpers'
|
26
|
+
require 'soaspec/exchange_handlers/rest_handler'
|
27
|
+
require 'soaspec/exchange_handlers/handler_accessors'
|
28
|
+
require 'soaspec/interpreter'
|
29
|
+
require 'soaspec/errors'
|
30
|
+
require 'soaspec/wait'
|
31
|
+
require 'soaspec/baseline'
|
32
|
+
|
33
|
+
# Gem for handling SOAP and REST api tests
|
34
|
+
module Soaspec
|
35
|
+
@template_folder = 'templates'
|
36
|
+
@auto_oauth = true
|
37
|
+
@log_warnings = true
|
38
|
+
# @return [String] Folder in which credentials are stored
|
39
|
+
@credentials_folder = 'credentials'
|
40
|
+
# @return [ExchangeHandler] handler A class inheriting from Soaspec::ExchangeHandler.
|
41
|
+
# Exchange class uses this to determine how to work
|
42
|
+
@api_handler = nil
|
43
|
+
|
44
|
+
class << self
|
45
|
+
# Folder used to store templates for API calls
|
46
|
+
# @return [String]
|
47
|
+
attr_reader :template_folder
|
48
|
+
# Stores last exchange
|
49
|
+
# @return [Exchange]
|
50
|
+
attr_accessor :last_exchange
|
51
|
+
# Automatically add Authorization header to RestHandler where oauth2 credentials are specified
|
52
|
+
# @return [Boolean] Whether to add authorization header
|
53
|
+
attr_accessor :auto_oauth
|
54
|
+
|
55
|
+
# Folder used to store templates for API calls
|
56
|
+
# Converts folder / folders into an array depending upon string passed
|
57
|
+
def template_folder=(folder)
|
58
|
+
@template_folder = folder.include?('\\') ? folder.split('\\') : folder.split('/')
|
59
|
+
end
|
60
|
+
|
61
|
+
# Credentials folder used to store secret data (not in source control) E.g passwords
|
62
|
+
# Used in oauth2_file command
|
63
|
+
# @return [String] Folder in which credentials are stored
|
64
|
+
attr_accessor :credentials_folder
|
65
|
+
|
66
|
+
# Used so that exchange class knows what context it's in.
|
67
|
+
# @return [ExchangeHandler] handler A class inheriting from Soaspec::ExchangeHandler. Exchange class uses this
|
68
|
+
attr_writer :api_handler
|
69
|
+
|
70
|
+
# @return [ExchangeHandler] handler A class inheriting from Soaspec::ExchangeHandler. Exchange class uses this
|
71
|
+
def api_handler
|
72
|
+
unless @api_handler
|
73
|
+
raise Soaspec::Error, '@exchange_handler not set. ' \
|
74
|
+
'Set either with `Soaspec.api_handler = Handler.new` or within the exchange'
|
75
|
+
end
|
76
|
+
@api_handler
|
77
|
+
end
|
78
|
+
|
79
|
+
# Set whether to transform strings to keys in request automatically.
|
80
|
+
# @return [Boolean]
|
81
|
+
attr_writer :always_use_keys
|
82
|
+
|
83
|
+
# @return [Boolean] Whether to log warnings such as methods that may change usage in the future
|
84
|
+
attr_accessor :log_warnings
|
85
|
+
|
86
|
+
# @return [Boolean] Whether to transform strings to keys in request automatically
|
87
|
+
def always_use_keys?
|
88
|
+
@always_use_keys || true
|
89
|
+
end
|
90
|
+
|
91
|
+
# @return [Boolean] Whether to see params sent to & received from oauth URL
|
92
|
+
def debug_oauth?
|
93
|
+
puts 'Soaspec.debug_oauth? now deprecated. Please use Soaspec::OAuth2.debug_oauth? instead'
|
94
|
+
Soaspec::OAuth2.debug_oauth?
|
95
|
+
end
|
96
|
+
|
97
|
+
# Specify whether to see params sent to and retrieved from oauth.
|
98
|
+
# This will put password in log file, only recommended for debugging
|
99
|
+
# @param [String] set Whether to debug oauth
|
100
|
+
def debug_oauth=(set)
|
101
|
+
puts 'Soaspec.debug_oauth= now deprecated. Please use Soaspec::OAuth2.debug_oauth= instead'
|
102
|
+
Soaspec::OAuth2.debug_oauth = set
|
103
|
+
end
|
104
|
+
|
105
|
+
# Whether to log all API traffic
|
106
|
+
# @param [Boolean] set
|
107
|
+
def log_api_traffic=(set)
|
108
|
+
puts 'Soaspec.log_api_traffic= now deprecated. Please use Soaspec::SpecLogger.log_api_traffic= instead'
|
109
|
+
Soaspec::SpecLogger.log_api_traffic = set
|
110
|
+
end
|
111
|
+
|
112
|
+
# @return [Boolean] Whether to log all API traffic
|
113
|
+
def log_api_traffic?
|
114
|
+
puts 'Soaspec.log_api_traffic? now deprecated. Please use Soaspec::SpecLogger.log_api_traffic? instead'
|
115
|
+
Soaspec::SpecLogger.log_api_traffic?
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
data/lib/soaspec/baseline.rb
CHANGED
@@ -1,23 +1,83 @@
|
|
1
|
-
require_relative 'exe_helpers'
|
2
|
-
|
3
|
-
module Soaspec
|
4
|
-
# Used for defining parameters for recording and asserting against
|
5
|
-
# a baseline
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
1
|
+
require_relative 'exe_helpers'
|
2
|
+
|
3
|
+
module Soaspec
|
4
|
+
# Used for defining parameters for recording and asserting against
|
5
|
+
# a baseline
|
6
|
+
class Baseline
|
7
|
+
include Soaspec::ExeHelpers
|
8
|
+
@folder = File.join('config', 'baseline')
|
9
|
+
|
10
|
+
# @return [Array] List of allowed formats
|
11
|
+
ALLOWED_FORMATS = [:raw, :hash]
|
12
|
+
|
13
|
+
# @return [Exchange] Exchange object to save/assert baseline for
|
14
|
+
attr_accessor :exchange
|
15
|
+
# @return [Symbol] Format in which baseline is stored. Either :raw or :hash
|
16
|
+
attr_accessor :format
|
17
|
+
# @return [String] Name of file including folders describing baseline
|
18
|
+
attr_writer :description
|
19
|
+
|
20
|
+
# @param [Exchange] exchange Exchange object to baseline response for
|
21
|
+
# @param [Symbol] format Format of baseline
|
22
|
+
def initialize(exchange, format)
|
23
|
+
self.exchange = exchange
|
24
|
+
self.format = format
|
25
|
+
unless ALLOWED_FORMATS.include? format
|
26
|
+
raise ArgumentError, "Expected format #{format} to be " \
|
27
|
+
"either #{ALLOWED_FORMATS}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# Compare baseline with expected result. This will create baseline
|
32
|
+
# if not created
|
33
|
+
# @return [Boolean] Whether response matches baseline
|
34
|
+
def matches?
|
35
|
+
if File.exist?(file)
|
36
|
+
actual_content == read_baseline
|
37
|
+
else
|
38
|
+
create_file filename: file, content: content_to_save
|
39
|
+
raise Soaspec::BaselineError,
|
40
|
+
"Created baseline at #{file}. Inspect file to ensure it is
|
41
|
+
correct and rerun to ensure baseline is stable"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Content to save as a baseline
|
46
|
+
def content_to_save
|
47
|
+
format == :raw ? exchange.pretty_response_body : YAML.dump(exchange.to_hash)
|
48
|
+
end
|
49
|
+
|
50
|
+
# @return [String, Hash] Actual response from API
|
51
|
+
def actual_content
|
52
|
+
if format == :hash
|
53
|
+
exchange.to_hash
|
54
|
+
elsif format == :raw
|
55
|
+
exchange.pretty_response_body.strip
|
56
|
+
else
|
57
|
+
raise NotImplementedError, "Format #{format} is not #{ALLOWED_FORMATS}"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# @return [String] Result of reading baseline
|
62
|
+
def read_baseline
|
63
|
+
format == :raw ? File.read(file).strip : YAML.load_file(file)
|
64
|
+
end
|
65
|
+
|
66
|
+
# @return [String] File where baseline is stored
|
67
|
+
def file
|
68
|
+
File.join(self.class.folder,
|
69
|
+
exchange.exchange_handler.to_s.snakecase,
|
70
|
+
"#{description}.#{format == :raw ? exchange.format : 'yml'}")
|
71
|
+
end
|
72
|
+
|
73
|
+
# @return [String] Name of file including folders describing baseline
|
74
|
+
def description
|
75
|
+
@description || exchange.request_parameters.description
|
76
|
+
end
|
77
|
+
|
78
|
+
class << self
|
79
|
+
# @return [String] Folder where baselines are recorded and retrieved
|
80
|
+
attr_accessor :folder
|
81
|
+
end
|
82
|
+
end
|
23
83
|
end
|
@@ -1,44 +1,44 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# Override Hash class with convenience methods
|
4
|
-
class Hash
|
5
|
-
# Transform each key in Hash to a symbol. Privately used by non-self method
|
6
|
-
# @param [Object] value Value inside hash to transform keys under
|
7
|
-
def self.transform_keys_to_symbols(value)
|
8
|
-
return value unless value.is_a?(Hash)
|
9
|
-
|
10
|
-
hash = value.each_with_object({}) { |(k, v), memo| memo[k.to_sym] = Hash.transform_keys_to_symbols(v); }
|
11
|
-
hash
|
12
|
-
end
|
13
|
-
|
14
|
-
# Take keys of hash and transform those to a symbols
|
15
|
-
# @example
|
16
|
-
# hash = { 'a' => 1, 'b' => { c: 4 } }
|
17
|
-
# hash.transform_keys_to_symbols # => { a: 1, b: { c: 4 } }
|
18
|
-
# @return [Hash] Hash will all keys converted to symbols
|
19
|
-
def transform_keys_to_symbols
|
20
|
-
each_with_object({}) { |(k, v), memo| memo[k.to_sym] = Hash.transform_keys_to_symbols(v); }
|
21
|
-
end
|
22
|
-
|
23
|
-
# Value present in nested Hash.
|
24
|
-
# @example
|
25
|
-
# hash = { a: { b: 25 }, c: 3 }
|
26
|
-
# hash.include_value?(25) #=> true
|
27
|
-
# @return [Boolean] Whether value is included in nested Hash
|
28
|
-
def include_value?(value)
|
29
|
-
each_value do |v|
|
30
|
-
return true if v == value
|
31
|
-
next unless v.is_a? Hash
|
32
|
-
|
33
|
-
v.each_value do |v|
|
34
|
-
return true if v == value
|
35
|
-
next unless v.is_a? Hash
|
36
|
-
|
37
|
-
v.each_value do |v|
|
38
|
-
return true if v == value
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
false
|
43
|
-
end
|
44
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Override Hash class with convenience methods
|
4
|
+
class Hash
|
5
|
+
# Transform each key in Hash to a symbol. Privately used by non-self method
|
6
|
+
# @param [Object] value Value inside hash to transform keys under
|
7
|
+
def self.transform_keys_to_symbols(value)
|
8
|
+
return value unless value.is_a?(Hash)
|
9
|
+
|
10
|
+
hash = value.each_with_object({}) { |(k, v), memo| memo[k.to_sym] = Hash.transform_keys_to_symbols(v); }
|
11
|
+
hash
|
12
|
+
end
|
13
|
+
|
14
|
+
# Take keys of hash and transform those to a symbols
|
15
|
+
# @example
|
16
|
+
# hash = { 'a' => 1, 'b' => { c: 4 } }
|
17
|
+
# hash.transform_keys_to_symbols # => { a: 1, b: { c: 4 } }
|
18
|
+
# @return [Hash] Hash will all keys converted to symbols
|
19
|
+
def transform_keys_to_symbols
|
20
|
+
each_with_object({}) { |(k, v), memo| memo[k.to_sym] = Hash.transform_keys_to_symbols(v); }
|
21
|
+
end
|
22
|
+
|
23
|
+
# Value present in nested Hash.
|
24
|
+
# @example
|
25
|
+
# hash = { a: { b: 25 }, c: 3 }
|
26
|
+
# hash.include_value?(25) #=> true
|
27
|
+
# @return [Boolean] Whether value is included in nested Hash
|
28
|
+
def include_value?(value)
|
29
|
+
each_value do |v|
|
30
|
+
return true if v == value
|
31
|
+
next unless v.is_a? Hash
|
32
|
+
|
33
|
+
v.each_value do |v|
|
34
|
+
return true if v == value
|
35
|
+
next unless v.is_a? Hash
|
36
|
+
|
37
|
+
v.each_value do |v|
|
38
|
+
return true if v == value
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
false
|
43
|
+
end
|
44
|
+
end
|
@@ -1,94 +1,94 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'active_support/core_ext/string/inflections'
|
4
|
-
|
5
|
-
# @return [Exchange] Return current or last exchange used in Cucumber
|
6
|
-
def current_exchange
|
7
|
-
@current_exchange ||= Soaspec.last_exchange
|
8
|
-
end
|
9
|
-
|
10
|
-
# Pass in the operation (HTTP method or SOAP operation) in first parameter and api name as second.
|
11
|
-
# API name can be mulitple words and it will be converted to camel case to find the ExchangeHandler class
|
12
|
-
# @example Create an Exchange representing an HTTP 'post' based on the 'Puppy' RestHandler class
|
13
|
-
# I am performing a post on the Puppy API
|
14
|
-
# @example Create an Exchange for a 'get_bank' operation on for a 'Banking' SoapHandler class
|
15
|
-
# I am performing a get_bank on the Banking API
|
16
|
-
Given 'I am performing a {word} on the {string} API' do |operation, api_name|
|
17
|
-
@current_exchange = api_name.tr(' ', '_').camelize.constantize.send operation
|
18
|
-
end
|
19
|
-
|
20
|
-
# Set a parameter in the request body
|
21
|
-
# @example Set the name element in the request body to Charlie
|
22
|
-
# And I set the name to 'Charlie'
|
23
|
-
# @param [String] Element in request body to set
|
24
|
-
# @param [String] Value to set it to
|
25
|
-
Given 'I set the {word} to {string}' do |key, value|
|
26
|
-
current_exchange[key] = value
|
27
|
-
end
|
28
|
-
|
29
|
-
# Add onto the base_url to make a complete url for the test
|
30
|
-
# @example base_url is 'http://petstore.swagger.io/v2' and I want a post to 'http://petstore.swagger.io/v2/pet'
|
31
|
-
# I use the path pet
|
32
|
-
Given 'I use the path {word}' do |suburl|
|
33
|
-
current_exchange.suburl = suburl
|
34
|
-
end
|
35
|
-
|
36
|
-
# Add onto the base_url to make a complete url for the test
|
37
|
-
# @example base_url is 'http://petstore.swagger.io/v2' and I want a post to 'http://petstore.swagger.io/v2/basic.json'
|
38
|
-
# I use the path 'basic.json'
|
39
|
-
Given 'I use the path {string}' do |suburl|
|
40
|
-
current_exchange.suburl = suburl
|
41
|
-
end
|
42
|
-
|
43
|
-
# Add a query parameter for http 'get' requests. e.g. will add '?filter_key=filter_value' onto URL
|
44
|
-
# @example To create a query for '?status=sold'
|
45
|
-
# And I filter 'status' by 'sold'
|
46
|
-
# @example To add a query for 'area' being 'australia' to make a total of '?status=sold&area=austrialia'
|
47
|
-
# And I filter 'area' by 'australia'
|
48
|
-
Given 'I filter {string} by {string}' do |filter_key, filter_value|
|
49
|
-
transformed_key = filter_key.to_sym
|
50
|
-
if current_exchange.override_parameters[:q]
|
51
|
-
current_exchange.override_parameters[:q][transformed_key] = filter_value
|
52
|
-
else
|
53
|
-
current_exchange.override_parameters[:q] = { transformed_key => filter_value }
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
# Add HTTP header 'header_name' as 'header_value'
|
58
|
-
# @example
|
59
|
-
# And I set header 'accept' to 'application/xml'
|
60
|
-
Given 'I set header {string} to {string}' do |header_name, header_value|
|
61
|
-
if current_exchange.override_parameters[:params]
|
62
|
-
current_exchange.override_parameters[:params][header_name] = header_value
|
63
|
-
else
|
64
|
-
current_exchange.override_parameters[:params] = { header_name => header_value }
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
# Make the API call. This is automatically done when any method extracting a response is made. It can be done
|
69
|
-
# explicitly here as it is a meaningful step
|
70
|
-
When 'I make the request' do
|
71
|
-
current_exchange.call
|
72
|
-
end
|
73
|
-
|
74
|
-
# Extract the value from the response that is at the path 'key' and verify it is eq to expected_value
|
75
|
-
# @example Assert response body has at the path 'name', the value 'Charlie'
|
76
|
-
# Then it should have the name 'Charlie'
|
77
|
-
Then 'it should have the {word} {string}' do |key, expected_value|
|
78
|
-
expect(current_exchange[key]).to eq expected_value
|
79
|
-
end
|
80
|
-
|
81
|
-
# Extract the value from the response that is at the path 'key_string' and verify it is eq to expected_value
|
82
|
-
# Conversion is made on key_string to make it one snake case word
|
83
|
-
# @example Assert response body has at the path 'customer_name', the value 'Charlie'
|
84
|
-
# Then it should have the 'customer name' 'Charlie'
|
85
|
-
Then 'it should have the {string} {string}' do |key_string, expected_value|
|
86
|
-
key = key_string.tr(' ', '_')
|
87
|
-
actual_value = current_exchange.respond_to?(key) ? current_exchange.send(key) : current_exchange[key]
|
88
|
-
expect(actual_value.to_s).to eq expected_value
|
89
|
-
end
|
90
|
-
|
91
|
-
# Verify that the HTTP status code is 200..299 and that any defined mandatory elements / mandatory values are as expected
|
92
|
-
Then 'it should be successful' do
|
93
|
-
expect(current_exchange).to be_successful
|
94
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_support/core_ext/string/inflections'
|
4
|
+
|
5
|
+
# @return [Exchange] Return current or last exchange used in Cucumber
|
6
|
+
def current_exchange
|
7
|
+
@current_exchange ||= Soaspec.last_exchange
|
8
|
+
end
|
9
|
+
|
10
|
+
# Pass in the operation (HTTP method or SOAP operation) in first parameter and api name as second.
|
11
|
+
# API name can be mulitple words and it will be converted to camel case to find the ExchangeHandler class
|
12
|
+
# @example Create an Exchange representing an HTTP 'post' based on the 'Puppy' RestHandler class
|
13
|
+
# I am performing a post on the Puppy API
|
14
|
+
# @example Create an Exchange for a 'get_bank' operation on for a 'Banking' SoapHandler class
|
15
|
+
# I am performing a get_bank on the Banking API
|
16
|
+
Given 'I am performing a {word} on the {string} API' do |operation, api_name|
|
17
|
+
@current_exchange = api_name.tr(' ', '_').camelize.constantize.send operation
|
18
|
+
end
|
19
|
+
|
20
|
+
# Set a parameter in the request body
|
21
|
+
# @example Set the name element in the request body to Charlie
|
22
|
+
# And I set the name to 'Charlie'
|
23
|
+
# @param [String] Element in request body to set
|
24
|
+
# @param [String] Value to set it to
|
25
|
+
Given 'I set the {word} to {string}' do |key, value|
|
26
|
+
current_exchange[key] = value
|
27
|
+
end
|
28
|
+
|
29
|
+
# Add onto the base_url to make a complete url for the test
|
30
|
+
# @example base_url is 'http://petstore.swagger.io/v2' and I want a post to 'http://petstore.swagger.io/v2/pet'
|
31
|
+
# I use the path pet
|
32
|
+
Given 'I use the path {word}' do |suburl|
|
33
|
+
current_exchange.suburl = suburl
|
34
|
+
end
|
35
|
+
|
36
|
+
# Add onto the base_url to make a complete url for the test
|
37
|
+
# @example base_url is 'http://petstore.swagger.io/v2' and I want a post to 'http://petstore.swagger.io/v2/basic.json'
|
38
|
+
# I use the path 'basic.json'
|
39
|
+
Given 'I use the path {string}' do |suburl|
|
40
|
+
current_exchange.suburl = suburl
|
41
|
+
end
|
42
|
+
|
43
|
+
# Add a query parameter for http 'get' requests. e.g. will add '?filter_key=filter_value' onto URL
|
44
|
+
# @example To create a query for '?status=sold'
|
45
|
+
# And I filter 'status' by 'sold'
|
46
|
+
# @example To add a query for 'area' being 'australia' to make a total of '?status=sold&area=austrialia'
|
47
|
+
# And I filter 'area' by 'australia'
|
48
|
+
Given 'I filter {string} by {string}' do |filter_key, filter_value|
|
49
|
+
transformed_key = filter_key.to_sym
|
50
|
+
if current_exchange.override_parameters[:q]
|
51
|
+
current_exchange.override_parameters[:q][transformed_key] = filter_value
|
52
|
+
else
|
53
|
+
current_exchange.override_parameters[:q] = { transformed_key => filter_value }
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Add HTTP header 'header_name' as 'header_value'
|
58
|
+
# @example
|
59
|
+
# And I set header 'accept' to 'application/xml'
|
60
|
+
Given 'I set header {string} to {string}' do |header_name, header_value|
|
61
|
+
if current_exchange.override_parameters[:params]
|
62
|
+
current_exchange.override_parameters[:params][header_name] = header_value
|
63
|
+
else
|
64
|
+
current_exchange.override_parameters[:params] = { header_name => header_value }
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Make the API call. This is automatically done when any method extracting a response is made. It can be done
|
69
|
+
# explicitly here as it is a meaningful step
|
70
|
+
When 'I make the request' do
|
71
|
+
current_exchange.call
|
72
|
+
end
|
73
|
+
|
74
|
+
# Extract the value from the response that is at the path 'key' and verify it is eq to expected_value
|
75
|
+
# @example Assert response body has at the path 'name', the value 'Charlie'
|
76
|
+
# Then it should have the name 'Charlie'
|
77
|
+
Then 'it should have the {word} {string}' do |key, expected_value|
|
78
|
+
expect(current_exchange[key]).to eq expected_value
|
79
|
+
end
|
80
|
+
|
81
|
+
# Extract the value from the response that is at the path 'key_string' and verify it is eq to expected_value
|
82
|
+
# Conversion is made on key_string to make it one snake case word
|
83
|
+
# @example Assert response body has at the path 'customer_name', the value 'Charlie'
|
84
|
+
# Then it should have the 'customer name' 'Charlie'
|
85
|
+
Then 'it should have the {string} {string}' do |key_string, expected_value|
|
86
|
+
key = key_string.tr(' ', '_')
|
87
|
+
actual_value = current_exchange.respond_to?(key) ? current_exchange.send(key) : current_exchange[key]
|
88
|
+
expect(actual_value.to_s).to eq expected_value
|
89
|
+
end
|
90
|
+
|
91
|
+
# Verify that the HTTP status code is 200..299 and that any defined mandatory elements / mandatory values are as expected
|
92
|
+
Then 'it should be successful' do
|
93
|
+
expect(current_exchange).to be_successful
|
94
|
+
end
|