soaspec 0.2.23 → 0.2.24

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 (80) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +15 -15
  3. data/.gitlab-ci.yml +33 -33
  4. data/.rspec +3 -3
  5. data/.rubocop.yml +2 -2
  6. data/CODE_OF_CONDUCT.md +74 -74
  7. data/ChangeLog +577 -573
  8. data/Gemfile +6 -6
  9. data/LICENSE.txt +21 -21
  10. data/README.md +230 -230
  11. data/Rakefile +42 -42
  12. data/Todo.md +15 -15
  13. data/exe/soaspec +123 -123
  14. data/exe/xml_to_yaml_file +42 -42
  15. data/lib/soaspec.rb +101 -101
  16. data/lib/soaspec/core_ext/hash.rb +35 -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 +111 -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 +126 -126
  26. data/lib/soaspec/exchange_handlers/handler_accessors.rb +130 -130
  27. data/lib/soaspec/exchange_handlers/response_extractor.rb +82 -82
  28. data/lib/soaspec/exchange_handlers/rest_exchanger_factory.rb +109 -109
  29. data/lib/soaspec/exchange_handlers/rest_handler.rb +259 -259
  30. data/lib/soaspec/exchange_handlers/rest_methods.rb +44 -44
  31. data/lib/soaspec/exchange_handlers/rest_parameters.rb +86 -86
  32. data/lib/soaspec/exchange_handlers/rest_parameters_defaults.rb +21 -21
  33. data/lib/soaspec/exchange_handlers/soap_handler.rb +235 -235
  34. data/lib/soaspec/exe_helpers.rb +92 -92
  35. data/lib/soaspec/generate_server.rb +37 -37
  36. data/lib/soaspec/generator/.rspec.erb +5 -5
  37. data/lib/soaspec/generator/.travis.yml.erb +5 -5
  38. data/lib/soaspec/generator/Gemfile.erb +8 -8
  39. data/lib/soaspec/generator/README.md.erb +29 -29
  40. data/lib/soaspec/generator/Rakefile.erb +19 -19
  41. data/lib/soaspec/generator/config/data/default.yml.erb +2 -2
  42. data/lib/soaspec/generator/css/bootstrap.css +6833 -6833
  43. data/lib/soaspec/generator/generate_exchange.html.erb +35 -35
  44. data/lib/soaspec/generator/lib/blz_service.rb.erb +26 -26
  45. data/lib/soaspec/generator/lib/dynamic_class_content.rb.erb +12 -12
  46. data/lib/soaspec/generator/lib/new_rest_service.rb.erb +51 -51
  47. data/lib/soaspec/generator/lib/new_soap_service.rb.erb +29 -29
  48. data/lib/soaspec/generator/lib/package_service.rb.erb +2 -2
  49. data/lib/soaspec/generator/lib/shared_example.rb.erb +8 -8
  50. data/lib/soaspec/generator/spec/dynamic_soap_spec.rb.erb +12 -12
  51. data/lib/soaspec/generator/spec/rest_spec.rb.erb +9 -9
  52. data/lib/soaspec/generator/spec/soap_spec.rb.erb +51 -51
  53. data/lib/soaspec/generator/spec/spec_helper.rb.erb +23 -23
  54. data/lib/soaspec/generator/template/soap_template.xml +6 -6
  55. data/lib/soaspec/indifferent_hash.rb +7 -7
  56. data/lib/soaspec/interpreter.rb +39 -39
  57. data/lib/soaspec/matchers.rb +114 -114
  58. data/lib/soaspec/not_found_errors.rb +13 -13
  59. data/lib/soaspec/o_auth2.rb +128 -128
  60. data/lib/soaspec/soaspec_shared_examples.rb +24 -24
  61. data/lib/soaspec/spec_logger.rb +121 -121
  62. data/lib/soaspec/template_reader.rb +28 -28
  63. data/lib/soaspec/test_server/bank.wsdl +90 -90
  64. data/lib/soaspec/test_server/get_bank.rb +164 -164
  65. data/lib/soaspec/test_server/id_manager.rb +39 -39
  66. data/lib/soaspec/test_server/invoices.rb +27 -27
  67. data/lib/soaspec/test_server/namespace.xml +14 -14
  68. data/lib/soaspec/test_server/note.xml +5 -5
  69. data/lib/soaspec/test_server/puppy_service.rb +19 -19
  70. data/lib/soaspec/test_server/test_attribute.rb +12 -12
  71. data/lib/soaspec/test_server/test_namespace.rb +12 -12
  72. data/lib/soaspec/version.rb +4 -3
  73. data/lib/soaspec/virtual_server.rb +174 -174
  74. data/lib/soaspec/wait.rb +41 -41
  75. data/lib/soaspec/wsdl_generator.rb +215 -215
  76. data/soaspec.gemspec +53 -53
  77. data/test.wsdl +116 -116
  78. data/test.xml +10 -10
  79. data/test_wsdl.rb +41 -41
  80. metadata +3 -4
@@ -1,83 +1,83 @@
1
- module Soaspec
2
- # Methods for extracting aspects of the traffic for a request / response
3
- # in an exchange from the ExchangeHandler that it's tied to
4
- module ExchangeExtractor
5
- # Request of API call. Either intended request or actual request
6
- # @return [Object] Object representing request of API
7
- def request
8
- exchange_handler.request(@response)
9
- end
10
-
11
- # Get status code from api class. This is http response code for Web Api
12
- # @return [Integer] Status code from api class
13
- def status_code
14
- exchange_handler.status_code_for(response)
15
- end
16
-
17
- # Extract value from path api class
18
- # @example Extract unique value
19
- # @exchange['unique_value_name']
20
- # @example Extract value via JSON path
21
- # @exchange['$..path.to.element']
22
- # @example Extract value via XPath
23
- # @exchange['//path/to/element']
24
- # @param [Object] path Path to return element for api class E.g - for SOAP this is XPath string. For JSON, this is Hash dig Array
25
- # @return [String] Value at path
26
- def [](path)
27
- exchange_handler.value_from_path(response, path.to_s)
28
- end
29
-
30
- alias_method :value_from_path, :[]
31
-
32
- # Using same path syntax as []. Returns true of false depending on whether an element is found
33
- # @return [Boolean] Whether an element exists at the path
34
- def element?(path)
35
- self[path]
36
- true
37
- rescue NoElementAtPath
38
- false
39
- end
40
-
41
- # @example Counting items in a JSON list
42
- # # Say there is JSON response {"notes":[{"title":"note1","note":"A note"},{"title":"note2"}]}
43
- # titles = @exchange.values_at_path('$..title')
44
- # expect(titles.count).to eq 2
45
- # expect(titles.first).to eq 'note1'
46
- # @param [String] path XPath, JSONPath to extract value
47
- # @param [String] attribute Attribute to obtain from XML element
48
- # @return [Array] List of values found at path
49
- def values_from_path(path, attribute: nil)
50
- exchange_handler.values_from_path(response, path, attribute: attribute)
51
- end
52
-
53
- # Return the response equivalent of the response. XML, JSON will be converted to a Hash
54
- # @example Counting items in a JSON list
55
- # # Say there is JSON response {"notes":[{"title":"note1","note":"A note"},{"title":"note2"}]}
56
- # hash = @exchange.to_hash
57
- # expect(hash['notes'].count).to eq 2
58
- # expect(hash['notes'].first['title']).to eq 'note1'
59
- # @return [Hash] Hash representing the response of the API
60
- def to_hash
61
- exchange_handler.to_hash(response)
62
- end
63
-
64
- private
65
-
66
- # Used to define methods on an exchange based on what's defined by the ExchangeHandler's methods
67
- # @param [String] element Element to define methods for
68
- def methods_for_element(element)
69
- element_name = element.to_s.split('__custom_path_').last
70
- define_singleton_method(element_name) do
71
- exchange_handler.__send__(element, response) # Forward the call onto handler to retrieve the element for the response
72
- end
73
- define_singleton_method("#{element_name}?") do
74
- begin
75
- __send__ element_name
76
- true
77
- rescue NoElementAtPath
78
- false
79
- end
80
- end
81
- end
82
- end
83
- end
1
+ module Soaspec
2
+ # Methods for extracting aspects of the traffic for a request / response
3
+ # in an exchange from the ExchangeHandler that it's tied to
4
+ module ExchangeExtractor
5
+ # Request of API call. Either intended request or actual request
6
+ # @return [Object] Object representing request of API
7
+ def request
8
+ exchange_handler.request(@response)
9
+ end
10
+
11
+ # Get status code from api class. This is http response code for Web Api
12
+ # @return [Integer] Status code from api class
13
+ def status_code
14
+ exchange_handler.status_code_for(response)
15
+ end
16
+
17
+ # Extract value from path api class
18
+ # @example Extract unique value
19
+ # @exchange['unique_value_name']
20
+ # @example Extract value via JSON path
21
+ # @exchange['$..path.to.element']
22
+ # @example Extract value via XPath
23
+ # @exchange['//path/to/element']
24
+ # @param [Object] path Path to return element for api class E.g - for SOAP this is XPath string. For JSON, this is Hash dig Array
25
+ # @return [String] Value at path
26
+ def [](path)
27
+ exchange_handler.value_from_path(response, path.to_s)
28
+ end
29
+
30
+ alias_method :value_from_path, :[]
31
+
32
+ # Using same path syntax as []. Returns true of false depending on whether an element is found
33
+ # @return [Boolean] Whether an element exists at the path
34
+ def element?(path)
35
+ self[path]
36
+ true
37
+ rescue NoElementAtPath
38
+ false
39
+ end
40
+
41
+ # @example Counting items in a JSON list
42
+ # # Say there is JSON response {"notes":[{"title":"note1","note":"A note"},{"title":"note2"}]}
43
+ # titles = @exchange.values_at_path('$..title')
44
+ # expect(titles.count).to eq 2
45
+ # expect(titles.first).to eq 'note1'
46
+ # @param [String] path XPath, JSONPath to extract value
47
+ # @param [String] attribute Attribute to obtain from XML element
48
+ # @return [Array] List of values found at path
49
+ def values_from_path(path, attribute: nil)
50
+ exchange_handler.values_from_path(response, path, attribute: attribute)
51
+ end
52
+
53
+ # Return the response equivalent of the response. XML, JSON will be converted to a Hash
54
+ # @example Counting items in a JSON list
55
+ # # Say there is JSON response {"notes":[{"title":"note1","note":"A note"},{"title":"note2"}]}
56
+ # hash = @exchange.to_hash
57
+ # expect(hash['notes'].count).to eq 2
58
+ # expect(hash['notes'].first['title']).to eq 'note1'
59
+ # @return [Hash] Hash representing the response of the API
60
+ def to_hash
61
+ exchange_handler.to_hash(response)
62
+ end
63
+
64
+ private
65
+
66
+ # Used to define methods on an exchange based on what's defined by the ExchangeHandler's methods
67
+ # @param [String] element Element to define methods for
68
+ def methods_for_element(element)
69
+ element_name = element.to_s.split('__custom_path_').last
70
+ define_singleton_method(element_name) do
71
+ exchange_handler.__send__(element, response) # Forward the call onto handler to retrieve the element for the response
72
+ end
73
+ define_singleton_method("#{element_name}?") do
74
+ begin
75
+ __send__ element_name
76
+ true
77
+ rescue NoElementAtPath
78
+ false
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -1,26 +1,26 @@
1
- module Soaspec
2
- # Convenience methods to set Exchange specific properties
3
- # Will be used when creating a subclass of Exchange
4
- module ExchangeProperties
5
- # Set default exchange handler for this exchange
6
- # This is helpful for when you need a new exchange handler created for each exchange
7
- # @param [Class] handler_class Class of ExchangeHandler to set Exchange to use
8
- # @param [String] name Name to call handler when it's instantiated (Defaults to class name)
9
- # @param [Hash] params Hash of parameters to set for instance of ExchangeHandler
10
- def default_handler(handler_class, name = handler_class.to_s, params = '')
11
- define_method('default_handler_used') do
12
- params_used = Hash[params.map do |k, param|
13
- [k, param.is_a?(String) ? ERB.new(param).result(binding) : param]
14
- end]
15
- handler_class.new name, params_used
16
- end
17
- end
18
-
19
- # Set retry_for_success to true, retrying response until a successful status code is returned
20
- # @param [Integer] retry_count Times to retry to get a positive response
21
- def expect_positive_status(retry_count: 3)
22
- define_method('retry_count') { retry_count }
23
- define_method('retry_for_success?') { true }
24
- end
25
- end
26
- end
1
+ module Soaspec
2
+ # Convenience methods to set Exchange specific properties
3
+ # Will be used when creating a subclass of Exchange
4
+ module ExchangeProperties
5
+ # Set default exchange handler for this exchange
6
+ # This is helpful for when you need a new exchange handler created for each exchange
7
+ # @param [Class] handler_class Class of ExchangeHandler to set Exchange to use
8
+ # @param [String] name Name to call handler when it's instantiated (Defaults to class name)
9
+ # @param [Hash] params Hash of parameters to set for instance of ExchangeHandler
10
+ def default_handler(handler_class, name = handler_class.to_s, params = '')
11
+ define_method('default_handler_used') do
12
+ params_used = Hash[params.map do |k, param|
13
+ [k, param.is_a?(String) ? ERB.new(param).result(binding) : param]
14
+ end]
15
+ handler_class.new name, params_used
16
+ end
17
+ end
18
+
19
+ # Set retry_for_success to true, retrying response until a successful status code is returned
20
+ # @param [Integer] retry_count Times to retry to get a positive response
21
+ def expect_positive_status(retry_count: 3)
22
+ define_method('retry_count') { retry_count }
23
+ define_method('retry_for_success?') { true }
24
+ end
25
+ end
26
+ end
@@ -1,19 +1,19 @@
1
- module Soaspec
2
- # Ways of repeating an exchange to reach a desired outcome
3
- module ExchangeRepeater
4
- # Wait until the passed block returns true
5
- # @param [Hash] opts Options for this instance
6
- # @option opts [Numeric] :timeout (5) Seconds to wait before timing out.
7
- # @option opts [Numeric] :interval (0.2) Seconds to sleep between polls.
8
- # @option opts [String] :message Exception message if timed out.
9
- # @option opts [Array, Exception] :ignore Exceptions to ignore while polling (default: Error::NoSuchElementError)
10
- # @return [Self] Returns itself so operations can be done on the exchange after it's done waiting
11
- def until(opts = {}, &script)
12
- Soaspec::Wait.until(opts) do
13
- @response = nil # Reset response so it can be made repeatedly
14
- instance_eval(&script)
15
- end
16
- self
17
- end
18
- end
19
- end
1
+ module Soaspec
2
+ # Ways of repeating an exchange to reach a desired outcome
3
+ module ExchangeRepeater
4
+ # Wait until the passed block returns true
5
+ # @param [Hash] opts Options for this instance
6
+ # @option opts [Numeric] :timeout (5) Seconds to wait before timing out.
7
+ # @option opts [Numeric] :interval (0.2) Seconds to sleep between polls.
8
+ # @option opts [String] :message Exception message if timed out.
9
+ # @option opts [Array, Exception] :ignore Exceptions to ignore while polling (default: Error::NoSuchElementError)
10
+ # @return [Self] Returns itself so operations can be done on the exchange after it's done waiting
11
+ def until(opts = {}, &script)
12
+ Soaspec::Wait.until(opts) do
13
+ @response = nil # Reset response so it can be made repeatedly
14
+ instance_eval(&script)
15
+ end
16
+ self
17
+ end
18
+ end
19
+ end
@@ -1,68 +1,68 @@
1
- module Soaspec
2
- # Methods to help build a Request
3
- module RequestBuilder
4
- # Specify a url to add onto the base_url of the ExchangeHandler used
5
- # @param [String] url Url to add onto the base_url of the ExchangeHandler used
6
- def suburl=(url)
7
- @override_parameters[:suburl] = url
8
- end
9
-
10
- # Specify HTTP method to use. Default is :post
11
- # @param [Symbol] method HTTP method. E.g, :get, :patch
12
- def method=(method)
13
- @override_parameters[:method] = method
14
- end
15
-
16
- # Set a parameter request in the request body.
17
- # Can be used to build a request over several steps (e.g Cucumber)
18
- # Will be used with FactoryBot
19
- #
20
- # @example
21
- # exchange['name'] = 'tester'
22
- # # Will set { name: tester } in the response, formatting as JSON or XML depending on REST / SOAP
23
- # @param [String, Symbol] key Name of request element to set
24
- # @param [String] value Value to set request element to
25
- def []=(key, value)
26
- @override_parameters[:body] ||= {}
27
- @override_parameters[:body][key] = value
28
- end
29
-
30
- # Implement undefined setter with []= for FactoryBot to use without needing to define params to set
31
- # @param [Object] method_name Name of method not defined
32
- # @param [Object] args Arguments passed to method
33
- # @param [Object] block Block passed to method
34
- def method_missing(method_name, *args, &block)
35
- set_value = args.first
36
- if method_name[-1] == '=' # A setter method
37
- getter_name = method_name[0..-2]
38
- if set_value.class < Exchange # This would be prerequisite exchange
39
- define_singleton_method(getter_name) { set_value }
40
- self[getter_name] = set_value.id if set_value.respond_to?(:id)
41
- else
42
- self[getter_name] = set_value
43
- end
44
- else
45
- super
46
- end
47
- end
48
-
49
- # Used for setters that are not defined
50
- # @param [String] method_name Name of method
51
- # @param [Array] args List of arguments to method
52
- def respond_to_missing?(method_name, *args)
53
- method_name[-1] == '=' || super
54
- end
55
-
56
- # Makes request, caching the response and returning self
57
- # Used by FactoryBot
58
- # @return [Self] Return itself so methods can be called on itself afterwards
59
- def save!
60
- @retry_for_success = @fail_factory ? false : true
61
- previous_setting = Soaspec.log_warnings
62
- Soaspec.log_warnings = false # Don't log this warning as result of call not being used
63
- call
64
- Soaspec.log_warnings = previous_setting
65
- self
66
- end
67
- end
68
- end
1
+ module Soaspec
2
+ # Methods to help build a Request
3
+ module RequestBuilder
4
+ # Specify a url to add onto the base_url of the ExchangeHandler used
5
+ # @param [String] url Url to add onto the base_url of the ExchangeHandler used
6
+ def suburl=(url)
7
+ @override_parameters[:suburl] = url
8
+ end
9
+
10
+ # Specify HTTP method to use. Default is :post
11
+ # @param [Symbol] method HTTP method. E.g, :get, :patch
12
+ def method=(method)
13
+ @override_parameters[:method] = method
14
+ end
15
+
16
+ # Set a parameter request in the request body.
17
+ # Can be used to build a request over several steps (e.g Cucumber)
18
+ # Will be used with FactoryBot
19
+ #
20
+ # @example
21
+ # exchange['name'] = 'tester'
22
+ # # Will set { name: tester } in the response, formatting as JSON or XML depending on REST / SOAP
23
+ # @param [String, Symbol] key Name of request element to set
24
+ # @param [String] value Value to set request element to
25
+ def []=(key, value)
26
+ @override_parameters[:body] ||= {}
27
+ @override_parameters[:body][key] = value
28
+ end
29
+
30
+ # Implement undefined setter with []= for FactoryBot to use without needing to define params to set
31
+ # @param [Object] method_name Name of method not defined
32
+ # @param [Object] args Arguments passed to method
33
+ # @param [Object] block Block passed to method
34
+ def method_missing(method_name, *args, &block)
35
+ set_value = args.first
36
+ if method_name[-1] == '=' # A setter method
37
+ getter_name = method_name[0..-2]
38
+ if set_value.class < Exchange # This would be prerequisite exchange
39
+ define_singleton_method(getter_name) { set_value }
40
+ self[getter_name] = set_value.id if set_value.respond_to?(:id)
41
+ else
42
+ self[getter_name] = set_value
43
+ end
44
+ else
45
+ super
46
+ end
47
+ end
48
+
49
+ # Used for setters that are not defined
50
+ # @param [String] method_name Name of method
51
+ # @param [Array] args List of arguments to method
52
+ def respond_to_missing?(method_name, *args)
53
+ method_name[-1] == '=' || super
54
+ end
55
+
56
+ # Makes request, caching the response and returning self
57
+ # Used by FactoryBot
58
+ # @return [Self] Return itself so methods can be called on itself afterwards
59
+ def save!
60
+ @retry_for_success = @fail_factory ? false : true
61
+ previous_setting = Soaspec.log_warnings
62
+ Soaspec.log_warnings = false # Don't log this warning as result of call not being used
63
+ call
64
+ Soaspec.log_warnings = previous_setting
65
+ self
66
+ end
67
+ end
68
+ end
@@ -1,22 +1,22 @@
1
- module Soaspec
2
- # Enables Exchange to store and retrieve variables so that one
3
- # exchange can make assertions based on a previous one
4
- module VariableStorer
5
- # Stores a value in the api handler that can be accessed by the provided name
6
- # @param [Symbol] name Name of method to use to access this value within handler
7
- # @param [String] value Path to value to store
8
- def store(name, value)
9
- exchange_handler.store(name, self[value])
10
- end
11
-
12
- # Retrieve the stored value from the Api Handler
13
- # @param [String, Symbol] name Name of value to retrieve
14
- # @return [Object] value from the Api Handler stored previously
15
- def retrieve(name)
16
- method = '__stored_val__' + name.to_s
17
- raise ArgumentError('Value not stored at ') unless exchange_handler.respond_to? method
18
-
19
- exchange_handler.send(method)
20
- end
21
- end
22
- end
1
+ module Soaspec
2
+ # Enables Exchange to store and retrieve variables so that one
3
+ # exchange can make assertions based on a previous one
4
+ module VariableStorer
5
+ # Stores a value in the api handler that can be accessed by the provided name
6
+ # @param [Symbol] name Name of method to use to access this value within handler
7
+ # @param [String] value Path to value to store
8
+ def store(name, value)
9
+ exchange_handler.store(name, self[value])
10
+ end
11
+
12
+ # Retrieve the stored value from the Api Handler
13
+ # @param [String, Symbol] name Name of value to retrieve
14
+ # @return [Object] value from the Api Handler stored previously
15
+ def retrieve(name)
16
+ method = '__stored_val__' + name.to_s
17
+ raise ArgumentError('Value not stored at ') unless exchange_handler.respond_to? method
18
+
19
+ exchange_handler.send(method)
20
+ end
21
+ end
22
+ end
@@ -1,126 +1,126 @@
1
- require_relative 'handler_accessors'
2
-
3
- module Soaspec
4
- # Inherit this for a class describing how to implement a particular exchange.
5
- # Has basic methods common for methods defining RSpec tests in YAML
6
- class ExchangeHandler
7
- extend Soaspec::HandlerAccessors
8
-
9
- def self.use
10
- new.use
11
- end
12
-
13
- # Retrieve the name of the template file to be used in the API request
14
- attr_reader :template_name
15
-
16
- # Explicitly defined elements for which a path has been predefined
17
- def elements
18
- public_methods.select { |i| i[/__custom_path_.+/] }
19
- end
20
-
21
- # Set instance variable name
22
- # @param [String, Symbol] name Name used when describing API test
23
- # @param [Hash] _options Parameters defining handler. Used in descendants
24
- def initialize(name = self.class.to_s, _options = {})
25
- use
26
- @request_option = :hash
27
- raise ArgumentError, 'Cannot define both template_name and default_hash' if respond_to?(:template_name_value) && respond_to?(:default_hash_value)
28
-
29
- @template_name = respond_to?(:template_name_value) ? template_name_value : ''
30
- @default_hash = respond_to?(:default_hash_value) ? default_hash_value : {}
31
- @name = name
32
- end
33
-
34
- # Set Api handler used by Exchange class to this handler
35
- # @return [Self]
36
- def use
37
- Soaspec.api_handler = self
38
- self
39
- end
40
-
41
- # Sets api handler variable globally. This is used in 'Exchange' class
42
- # @return [String] Name set upon initialisation
43
- def to_s
44
- use
45
- @name.to_s
46
- end
47
-
48
- # Set the default hash representing data to be used in making a request
49
- # This will set the @request_option instance variable too
50
- def default_hash=(hash)
51
- @request_option = :hash
52
- @default_hash = Soaspec.always_use_keys? ? hash.transform_keys_to_symbols : hash
53
- end
54
-
55
- # Set the request option type and the template name
56
- # Erb is used to parse the template file, executing Ruby code in `<%= %>` blocks to work out the final request
57
- # @param [String] name Name of file inside 'template' folder excluding extension
58
- def template_name=(name)
59
- @request_option = :template
60
- @template_name = name
61
- end
62
-
63
- # Will be used in 'success_scenarios' shared examples.
64
- # Set though 'mandatory_elements' method
65
- # @return [Array] Array of symbols specifying element names
66
- def expected_mandatory_elements
67
- []
68
- end
69
-
70
- # Change this through 'mandatory_xpath_values' method to specify xpath results that must be present in the response
71
- # Will be used in 'success_scenarios' shared examples
72
- # @return [Hash] Hash of 'xpath' => 'expected value' pairs
73
- def expected_mandatory_xpath_values
74
- {}
75
- end
76
-
77
- # Change this through 'mandatory_json_values' method to specify json results that must be present in the response
78
- # Will be used in 'success_scenarios' shared examples
79
- # @return [Hash] Hash of 'json/path' => 'expected value' pairs
80
- def expected_mandatory_json_values
81
- {}
82
- end
83
-
84
- # @return [Boolean] Whether all xpaths will be done with XML that is converted to lower case
85
- def convert_to_lower?
86
- false
87
- end
88
-
89
- # Stores a value in a method that can be accessed by the provided name
90
- # @param [Symbol] name Name of method to use to access this value within handler
91
- # @param [String] value Value to store
92
- def store(name, value)
93
- define_singleton_method('__stored_val__' + name.to_s) { value }
94
- end
95
-
96
- # Set instance variable for each key in hash remove it from Hash
97
- # @param [Hash] hash with items to remove from
98
- # @param [Array] keys List of keys to remove from hash, setting each one
99
- def set_remove_keys(hash, keys)
100
- keys.each { |key| set_remove_key(hash, key) }
101
- end
102
-
103
- # Set instance variable and remove it from Hash
104
- # @param [Hash] hash Hash to remove/retrieve keys from
105
- # @param [String,Symbol] key Key to remove and to set instance variable for
106
- def set_remove_key(hash, key)
107
- return unless hash.key? key
108
-
109
- __send__("#{key}=", hash[key])
110
- hash.delete key
111
- end
112
-
113
- # @return [Boolean] Whether to remove namespaces in xpath assertion automatically
114
- def strip_namespaces?
115
- false
116
- end
117
-
118
- # Request of API call. Either intended request or actual request
119
- # @param [Object] response Response from calling exchange
120
- def request(response)
121
- return "Request not yet sent Request option is #{@request_option}" unless response
122
-
123
- 'Specific API handler should implement this'
124
- end
125
- end
126
- end
1
+ require_relative 'handler_accessors'
2
+
3
+ module Soaspec
4
+ # Inherit this for a class describing how to implement a particular exchange.
5
+ # Has basic methods common for methods defining RSpec tests in YAML
6
+ class ExchangeHandler
7
+ extend Soaspec::HandlerAccessors
8
+
9
+ def self.use
10
+ new.use
11
+ end
12
+
13
+ # Retrieve the name of the template file to be used in the API request
14
+ attr_reader :template_name
15
+
16
+ # Explicitly defined elements for which a path has been predefined
17
+ def elements
18
+ public_methods.select { |i| i[/__custom_path_.+/] }
19
+ end
20
+
21
+ # Set instance variable name
22
+ # @param [String, Symbol] name Name used when describing API test
23
+ # @param [Hash] _options Parameters defining handler. Used in descendants
24
+ def initialize(name = self.class.to_s, _options = {})
25
+ use
26
+ @request_option = :hash
27
+ raise ArgumentError, 'Cannot define both template_name and default_hash' if respond_to?(:template_name_value) && respond_to?(:default_hash_value)
28
+
29
+ @template_name = respond_to?(:template_name_value) ? template_name_value : ''
30
+ @default_hash = respond_to?(:default_hash_value) ? default_hash_value : {}
31
+ @name = name
32
+ end
33
+
34
+ # Set Api handler used by Exchange class to this handler
35
+ # @return [Self]
36
+ def use
37
+ Soaspec.api_handler = self
38
+ self
39
+ end
40
+
41
+ # Sets api handler variable globally. This is used in 'Exchange' class
42
+ # @return [String] Name set upon initialisation
43
+ def to_s
44
+ use
45
+ @name.to_s
46
+ end
47
+
48
+ # Set the default hash representing data to be used in making a request
49
+ # This will set the @request_option instance variable too
50
+ def default_hash=(hash)
51
+ @request_option = :hash
52
+ @default_hash = Soaspec.always_use_keys? ? hash.transform_keys_to_symbols : hash
53
+ end
54
+
55
+ # Set the request option type and the template name
56
+ # Erb is used to parse the template file, executing Ruby code in `<%= %>` blocks to work out the final request
57
+ # @param [String] name Name of file inside 'template' folder excluding extension
58
+ def template_name=(name)
59
+ @request_option = :template
60
+ @template_name = name
61
+ end
62
+
63
+ # Will be used in 'success_scenarios' shared examples.
64
+ # Set though 'mandatory_elements' method
65
+ # @return [Array] Array of symbols specifying element names
66
+ def expected_mandatory_elements
67
+ []
68
+ end
69
+
70
+ # Change this through 'mandatory_xpath_values' method to specify xpath results that must be present in the response
71
+ # Will be used in 'success_scenarios' shared examples
72
+ # @return [Hash] Hash of 'xpath' => 'expected value' pairs
73
+ def expected_mandatory_xpath_values
74
+ {}
75
+ end
76
+
77
+ # Change this through 'mandatory_json_values' method to specify json results that must be present in the response
78
+ # Will be used in 'success_scenarios' shared examples
79
+ # @return [Hash] Hash of 'json/path' => 'expected value' pairs
80
+ def expected_mandatory_json_values
81
+ {}
82
+ end
83
+
84
+ # @return [Boolean] Whether all xpaths will be done with XML that is converted to lower case
85
+ def convert_to_lower?
86
+ false
87
+ end
88
+
89
+ # Stores a value in a method that can be accessed by the provided name
90
+ # @param [Symbol] name Name of method to use to access this value within handler
91
+ # @param [String] value Value to store
92
+ def store(name, value)
93
+ define_singleton_method('__stored_val__' + name.to_s) { value }
94
+ end
95
+
96
+ # Set instance variable for each key in hash remove it from Hash
97
+ # @param [Hash] hash with items to remove from
98
+ # @param [Array] keys List of keys to remove from hash, setting each one
99
+ def set_remove_keys(hash, keys)
100
+ keys.each { |key| set_remove_key(hash, key) }
101
+ end
102
+
103
+ # Set instance variable and remove it from Hash
104
+ # @param [Hash] hash Hash to remove/retrieve keys from
105
+ # @param [String,Symbol] key Key to remove and to set instance variable for
106
+ def set_remove_key(hash, key)
107
+ return unless hash.key? key
108
+
109
+ __send__("#{key}=", hash[key])
110
+ hash.delete key
111
+ end
112
+
113
+ # @return [Boolean] Whether to remove namespaces in xpath assertion automatically
114
+ def strip_namespaces?
115
+ false
116
+ end
117
+
118
+ # Request of API call. Either intended request or actual request
119
+ # @param [Object] response Response from calling exchange
120
+ def request(response)
121
+ return "Request not yet sent Request option is #{@request_option}" unless response
122
+
123
+ 'Specific API handler should implement this'
124
+ end
125
+ end
126
+ end