soaspec 0.2.24 → 0.2.25

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