soaspec 0.2.33 → 0.3.1

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.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +15 -15
  3. data/.gitlab-ci.yml +62 -62
  4. data/.rspec +3 -3
  5. data/.rubocop.yml +2 -2
  6. data/CODE_OF_CONDUCT.md +74 -74
  7. data/ChangeLog +643 -632
  8. data/Dockerfile +7 -7
  9. data/Gemfile +8 -8
  10. data/LICENSE.txt +21 -21
  11. data/README.md +253 -231
  12. data/Rakefile +52 -52
  13. data/Todo.md +16 -16
  14. data/exe/soaspec +140 -138
  15. data/exe/xml_to_yaml_file +43 -43
  16. data/lib/soaspec.rb +118 -106
  17. data/lib/soaspec/baseline.rb +82 -22
  18. data/lib/soaspec/core_ext/hash.rb +44 -44
  19. data/lib/soaspec/cucumber/generic_steps.rb +94 -94
  20. data/lib/soaspec/demo.rb +6 -6
  21. data/lib/soaspec/errors.rb +24 -24
  22. data/lib/soaspec/exchange/exchange.rb +131 -129
  23. data/lib/soaspec/exchange/exchange_extractor.rb +105 -90
  24. data/lib/soaspec/exchange/exchange_properties.rb +28 -28
  25. data/lib/soaspec/exchange/exchange_repeater.rb +21 -21
  26. data/lib/soaspec/exchange/request_builder.rb +108 -70
  27. data/lib/soaspec/exchange/variable_storer.rb +24 -24
  28. data/lib/soaspec/exchange_handlers/exchange_handler.rb +98 -98
  29. data/lib/soaspec/exchange_handlers/exchange_handler_defaults.rb +61 -61
  30. data/lib/soaspec/exchange_handlers/handler_accessors.rb +132 -132
  31. data/lib/soaspec/exchange_handlers/request/rest_request.rb +77 -59
  32. data/lib/soaspec/exchange_handlers/request/soap_request.rb +41 -41
  33. data/lib/soaspec/exchange_handlers/response_extractor.rb +84 -84
  34. data/lib/soaspec/exchange_handlers/rest_exchanger_factory.rb +111 -111
  35. data/lib/soaspec/exchange_handlers/rest_handler.rb +307 -307
  36. data/lib/soaspec/exchange_handlers/rest_methods.rb +65 -65
  37. data/lib/soaspec/exchange_handlers/rest_parameters.rb +112 -112
  38. data/lib/soaspec/exchange_handlers/rest_parameters_defaults.rb +42 -42
  39. data/lib/soaspec/exchange_handlers/soap_handler.rb +241 -241
  40. data/lib/soaspec/exe_helpers.rb +94 -94
  41. data/lib/soaspec/generate_server.rb +48 -48
  42. data/lib/soaspec/generator/.rspec.erb +5 -5
  43. data/lib/soaspec/generator/.travis.yml.erb +5 -5
  44. data/lib/soaspec/generator/Gemfile.erb +8 -8
  45. data/lib/soaspec/generator/README.md.erb +29 -29
  46. data/lib/soaspec/generator/Rakefile.erb +20 -19
  47. data/lib/soaspec/generator/config/data/default.yml.erb +2 -2
  48. data/lib/soaspec/generator/css/bootstrap.css +6833 -6833
  49. data/lib/soaspec/generator/features/support/env.rb.erb +3 -3
  50. data/lib/soaspec/generator/generate_exchange.html.erb +47 -47
  51. data/lib/soaspec/generator/lib/blz_service.rb.erb +26 -26
  52. data/lib/soaspec/generator/lib/dynamic_class_content.rb.erb +12 -12
  53. data/lib/soaspec/generator/lib/new_rest_service.rb.erb +56 -56
  54. data/lib/soaspec/generator/lib/new_soap_service.rb.erb +29 -29
  55. data/lib/soaspec/generator/lib/package_service.rb.erb +2 -2
  56. data/lib/soaspec/generator/lib/shared_example.rb.erb +8 -8
  57. data/lib/soaspec/generator/spec/dynamic_soap_spec.rb.erb +12 -12
  58. data/lib/soaspec/generator/spec/rest_spec.rb.erb +9 -9
  59. data/lib/soaspec/generator/spec/soap_spec.rb.erb +51 -51
  60. data/lib/soaspec/generator/spec/spec_helper.rb.erb +23 -23
  61. data/lib/soaspec/generator/template/soap_template.xml +6 -6
  62. data/lib/soaspec/indifferent_hash.rb +9 -9
  63. data/lib/soaspec/interpreter.rb +70 -70
  64. data/lib/soaspec/matchers.rb +136 -140
  65. data/lib/soaspec/o_auth2.rb +142 -142
  66. data/lib/soaspec/soaspec_shared_examples.rb +26 -26
  67. data/lib/soaspec/spec_logger.rb +143 -143
  68. data/lib/soaspec/template_reader.rb +30 -30
  69. data/lib/soaspec/test_server/bank.wsdl +90 -90
  70. data/lib/soaspec/test_server/get_bank.rb +166 -166
  71. data/lib/soaspec/test_server/id_manager.rb +41 -41
  72. data/lib/soaspec/test_server/invoices.rb +29 -29
  73. data/lib/soaspec/test_server/namespace.xml +14 -14
  74. data/lib/soaspec/test_server/note.xml +5 -5
  75. data/lib/soaspec/test_server/puppy_service.rb +21 -21
  76. data/lib/soaspec/test_server/test_attribute.rb +14 -14
  77. data/lib/soaspec/test_server/test_namespace.rb +14 -14
  78. data/lib/soaspec/version.rb +6 -6
  79. data/lib/soaspec/virtual_server.rb +193 -190
  80. data/lib/soaspec/wait.rb +43 -43
  81. data/lib/soaspec/wsdl_generator.rb +215 -215
  82. data/soaspec.gemspec +58 -58
  83. data/test.wsdl +116 -116
  84. data/test.xml +10 -10
  85. data/test_wsdl.rb +43 -43
  86. metadata +3 -3
@@ -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 << self
42
- # Folder used to store templates for API calls
43
- # @return [String]
44
- attr_reader :template_folder
45
- # Stores last exchange
46
- # @return [Exchange]
47
- attr_accessor :last_exchange
48
- # Automatically add Authorization header to RestHandler where oauth2 credentials are specified
49
- # @return [Boolean] Whether to add authorization header
50
- attr_accessor :auto_oauth
51
-
52
- # Folder used to store templates for API calls
53
- # Converts folder / folders into an array depending upon string passed
54
- def template_folder=(folder)
55
- @template_folder = folder.include?('\\') ? folder.split('\\') : folder.split('/')
56
- end
57
-
58
- # Credentials folder used to store secret data (not in source control) E.g passwords
59
- # Used in oauth2_file command
60
- # @return [String] Folder in which credentials are stored
61
- attr_accessor :credentials_folder
62
-
63
- # Used so that exchange class knows what context it's in.
64
- # @return [ExchangeHandler] handler A class inheriting from Soaspec::ExchangeHandler. Exchange class uses this
65
- attr_accessor :api_handler
66
-
67
- # Set whether to transform strings to keys in request automatically.
68
- # @return [Boolean]
69
- attr_writer :always_use_keys
70
-
71
- # @return [Boolean] Whether to log warnings such as methods that may change usage in the future
72
- attr_accessor :log_warnings
73
-
74
- # @return [Boolean] Whether to transform strings to keys in request automatically
75
- def always_use_keys?
76
- @always_use_keys || true
77
- end
78
-
79
- # @return [Boolean] Whether to see params sent to & received from oauth URL
80
- def debug_oauth?
81
- puts 'Soaspec.debug_oauth? now deprecated. Please use Soaspec::OAuth2.debug_oauth? instead'
82
- Soaspec::OAuth2.debug_oauth?
83
- end
84
-
85
- # Specify whether to see params sent to and retrieved from oauth.
86
- # This will put password in log file, only recommended for debugging
87
- # @param [String] set Whether to debug oauth
88
- def debug_oauth=(set)
89
- puts 'Soaspec.debug_oauth= now deprecated. Please use Soaspec::OAuth2.debug_oauth= instead'
90
- Soaspec::OAuth2.debug_oauth = set
91
- end
92
-
93
- # Whether to log all API traffic
94
- # @param [Boolean] set
95
- def log_api_traffic=(set)
96
- puts 'Soaspec.log_api_traffic= now deprecated. Please use Soaspec::SpecLogger.log_api_traffic= instead'
97
- Soaspec::SpecLogger.log_api_traffic = set
98
- end
99
-
100
- # @return [Boolean] Whether to log all API traffic
101
- def log_api_traffic?
102
- puts 'Soaspec.log_api_traffic? now deprecated. Please use Soaspec::SpecLogger.log_api_traffic? instead'
103
- Soaspec::SpecLogger.log_api_traffic?
104
- end
105
- end
106
- end
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
@@ -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
- module Baseline
7
- @folder = File.join('config', 'baseline')
8
- class << self
9
- # @return [String] Folder where baselines are recorded and retrieved
10
- attr_accessor :folder
11
-
12
- # @param [Exchange] exchange Exchange object to baseline response for
13
- # @return [String] File where baseline is stored
14
- def file(exchange)
15
- File.join(folder,
16
- exchange.exchange_handler.to_s.snakecase,
17
- "#{exchange.request_parameters.flatten.join('_')}.yml")
18
- end
19
-
20
- include Soaspec::ExeHelpers
21
- end
22
- end
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