soaspec 0.1.1 → 0.1.2

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 (57) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +15 -15
  3. data/.gitlab-ci.yml +31 -31
  4. data/.rspec +3 -3
  5. data/.rubocop.yml +2 -2
  6. data/CODE_OF_CONDUCT.md +74 -74
  7. data/ChangeLog +384 -384
  8. data/Gemfile +6 -6
  9. data/LICENSE.txt +21 -21
  10. data/README.md +85 -85
  11. data/Rakefile +24 -24
  12. data/Todo.md +6 -6
  13. data/exe/soaspec +119 -119
  14. data/exe/soaspec-virtual-server +103 -103
  15. data/exe/xml_to_yaml_file +60 -60
  16. data/lib/soaspec.rb +91 -91
  17. data/lib/soaspec/core_ext/hash.rb +83 -83
  18. data/lib/soaspec/exchange.rb +234 -234
  19. data/lib/soaspec/exchange_handlers/exchange_handler.rb +103 -103
  20. data/lib/soaspec/exchange_handlers/handler_accessors.rb +106 -106
  21. data/lib/soaspec/exchange_handlers/rest_accessors.rb +92 -92
  22. data/lib/soaspec/exchange_handlers/rest_handler.rb +311 -311
  23. data/lib/soaspec/exchange_handlers/rest_methods.rb +44 -44
  24. data/lib/soaspec/exchange_handlers/soap_handler.rb +236 -236
  25. data/lib/soaspec/exe_helpers.rb +56 -56
  26. data/lib/soaspec/generator/.rspec.erb +5 -5
  27. data/lib/soaspec/generator/.travis.yml.erb +5 -5
  28. data/lib/soaspec/generator/Gemfile.erb +8 -8
  29. data/lib/soaspec/generator/README.md.erb +29 -29
  30. data/lib/soaspec/generator/Rakefile.erb +19 -19
  31. data/lib/soaspec/generator/config/data/default.yml.erb +1 -1
  32. data/lib/soaspec/generator/lib/blz_service.rb.erb +26 -26
  33. data/lib/soaspec/generator/lib/dynamic_class_content.rb.erb +12 -12
  34. data/lib/soaspec/generator/lib/shared_example.rb.erb +8 -8
  35. data/lib/soaspec/generator/spec/dynamic_soap_spec.rb.erb +12 -12
  36. data/lib/soaspec/generator/spec/soap_spec.rb.erb +51 -51
  37. data/lib/soaspec/generator/spec/spec_helper.rb.erb +20 -20
  38. data/lib/soaspec/generator/template/soap_template.xml +6 -6
  39. data/lib/soaspec/interpreter.rb +40 -40
  40. data/lib/soaspec/matchers.rb +65 -65
  41. data/lib/soaspec/not_found_errors.rb +13 -13
  42. data/lib/soaspec/soaspec_shared_examples.rb +24 -24
  43. data/lib/soaspec/spec_logger.rb +27 -27
  44. data/lib/soaspec/test_server/bank.wsdl +90 -90
  45. data/lib/soaspec/test_server/get_bank.rb +160 -160
  46. data/lib/soaspec/test_server/invoices.rb +27 -27
  47. data/lib/soaspec/test_server/namespace.xml +14 -14
  48. data/lib/soaspec/test_server/note.xml +5 -5
  49. data/lib/soaspec/test_server/puppy_service.rb +20 -20
  50. data/lib/soaspec/test_server/test_attribute.rb +13 -13
  51. data/lib/soaspec/version.rb +2 -2
  52. data/lib/soaspec/wsdl_generator.rb +144 -144
  53. data/soaspec.gemspec +46 -45
  54. data/test.wsdl +116 -116
  55. data/test.xml +10 -10
  56. data/test_wsdl.rb +43 -43
  57. metadata +17 -3
@@ -1,104 +1,104 @@
1
-
2
- require_relative 'handler_accessors'
3
-
4
- module Soaspec
5
-
6
- # Inherit this for a class describing how to implement a particular exchange.
7
- # Has basic methods common for methods defining RSpec tests in YAML
8
- class ExchangeHandler
9
- extend Soaspec::HandlerAccessors
10
-
11
- # Retrieve the name of the template file to be used in the API request
12
- attr_reader :template_name
13
-
14
- # Explicitly defined elements for which a path has been predefined
15
- def elements
16
- public_methods.select { |i| i[/__custom_path_.+/] }
17
- end
18
-
19
- # Set the default hash representing data to be used in making a request
20
- # This will set the @request_option instance variable too
21
- def default_hash=(hash)
22
- @request_option = :hash
23
- @default_hash = Soaspec.always_use_keys? ? hash.transform_keys_to_symbols : hash
24
- end
25
-
26
- # Set instance variable name
27
- # @param [String, Symbol] name Name used when describing API test
28
- # @param [Hash] options Parameters defining handler. Used in descendants
29
- def initialize(name = self.class.to_s, options = {})
30
- use
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 request option type and the template name
49
- # Erb is used to parse the template file, executing Ruby code in `<%= %>` blocks to work out the final request
50
- # @param [String] name Name of file inside 'template' folder excluding extension
51
- def template_name=(name)
52
- @request_option = :template
53
- @template_name = name
54
- end
55
-
56
- # Will be used in 'success_scenarios' shared examples.
57
- # Set though 'mandatory_elements' method
58
- # @return [Array] Array of symbols specifying element names
59
- def expected_mandatory_elements
60
- []
61
- end
62
-
63
- # Change this through 'mandatory_xpath_values' method to specify xpath results that must be present in the response
64
- # Will be used in 'success_scenarios' shared examples
65
- # @return [Hash] Hash of 'xpath' => 'expected value' pairs
66
- def expected_mandatory_xpath_values
67
- {}
68
- end
69
-
70
- # Change this through 'mandatory_json_values' method to specify json results that must be present in the response
71
- # Will be used in 'success_scenarios' shared examples
72
- # @return [Hash] Hash of 'json/path' => 'expected value' pairs
73
- def expected_mandatory_json_values
74
- {}
75
- end
76
-
77
- # @return [Boolean] Whether all xpaths will be done with XML that is converted to lower case
78
- def convert_to_lower?
79
- false
80
- end
81
-
82
- # Stores a value in a method that can be accessed by the provided name
83
- # @param [Symbol] name Name of method to use to access this value within handler
84
- # @param [String] value Value to store
85
- def store(name, value)
86
- define_singleton_method('__stored_val__' + name.to_s) do
87
- value
88
- end
89
- end
90
-
91
- # Set instance variable and remove it from Hash
92
- def set_remove_key(hash, key)
93
- return unless hash.key? key
94
- __send__("#{key}=", hash[key])
95
- hash.delete key
96
- end
97
-
98
- # @return [Boolean] Whether to remove namespaces in xpath assertion automatically
99
- def strip_namespaces?
100
- false
101
- end
102
-
103
- end
1
+
2
+ require_relative 'handler_accessors'
3
+
4
+ module Soaspec
5
+
6
+ # Inherit this for a class describing how to implement a particular exchange.
7
+ # Has basic methods common for methods defining RSpec tests in YAML
8
+ class ExchangeHandler
9
+ extend Soaspec::HandlerAccessors
10
+
11
+ # Retrieve the name of the template file to be used in the API request
12
+ attr_reader :template_name
13
+
14
+ # Explicitly defined elements for which a path has been predefined
15
+ def elements
16
+ public_methods.select { |i| i[/__custom_path_.+/] }
17
+ end
18
+
19
+ # Set the default hash representing data to be used in making a request
20
+ # This will set the @request_option instance variable too
21
+ def default_hash=(hash)
22
+ @request_option = :hash
23
+ @default_hash = Soaspec.always_use_keys? ? hash.transform_keys_to_symbols : hash
24
+ end
25
+
26
+ # Set instance variable name
27
+ # @param [String, Symbol] name Name used when describing API test
28
+ # @param [Hash] options Parameters defining handler. Used in descendants
29
+ def initialize(name = self.class.to_s, options = {})
30
+ use
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 request option type and the template name
49
+ # Erb is used to parse the template file, executing Ruby code in `<%= %>` blocks to work out the final request
50
+ # @param [String] name Name of file inside 'template' folder excluding extension
51
+ def template_name=(name)
52
+ @request_option = :template
53
+ @template_name = name
54
+ end
55
+
56
+ # Will be used in 'success_scenarios' shared examples.
57
+ # Set though 'mandatory_elements' method
58
+ # @return [Array] Array of symbols specifying element names
59
+ def expected_mandatory_elements
60
+ []
61
+ end
62
+
63
+ # Change this through 'mandatory_xpath_values' method to specify xpath results that must be present in the response
64
+ # Will be used in 'success_scenarios' shared examples
65
+ # @return [Hash] Hash of 'xpath' => 'expected value' pairs
66
+ def expected_mandatory_xpath_values
67
+ {}
68
+ end
69
+
70
+ # Change this through 'mandatory_json_values' method to specify json results that must be present in the response
71
+ # Will be used in 'success_scenarios' shared examples
72
+ # @return [Hash] Hash of 'json/path' => 'expected value' pairs
73
+ def expected_mandatory_json_values
74
+ {}
75
+ end
76
+
77
+ # @return [Boolean] Whether all xpaths will be done with XML that is converted to lower case
78
+ def convert_to_lower?
79
+ false
80
+ end
81
+
82
+ # Stores a value in a method that can be accessed by the provided name
83
+ # @param [Symbol] name Name of method to use to access this value within handler
84
+ # @param [String] value Value to store
85
+ def store(name, value)
86
+ define_singleton_method('__stored_val__' + name.to_s) do
87
+ value
88
+ end
89
+ end
90
+
91
+ # Set instance variable and remove it from Hash
92
+ def set_remove_key(hash, key)
93
+ return unless hash.key? key
94
+ __send__("#{key}=", hash[key])
95
+ hash.delete key
96
+ end
97
+
98
+ # @return [Boolean] Whether to remove namespaces in xpath assertion automatically
99
+ def strip_namespaces?
100
+ false
101
+ end
102
+
103
+ end
104
104
  end
@@ -1,107 +1,107 @@
1
- module Soaspec
2
- # Describes methods test handlers use to easily set attributes
3
- # Some are included in 'success scenarios' and to configure the request sent
4
- module HandlerAccessors
5
-
6
- # Defines expected_mandatory_elements method used in 'success_scenario' shared examples
7
- # to indicate certain elements must be present
8
- # @param [Array] elements Array of symbols specifying expected element names for 'success scenario' in snakecase
9
- #
10
- # @example Inside class
11
- # mandatory_elements :GetWeatherResult
12
- #
13
- # Or for a list
14
- #
15
- # @example Inside class
16
- # mandatory_elements [:GetWeatherResult, :GetResultStatus]
17
- #
18
- # In test
19
- # describe Exchange(:name) do
20
- # it_behaves_like 'success scenario' # Includes checks for mandatory elements
21
- # end
22
- def mandatory_elements(elements)
23
- define_method('expected_mandatory_elements') do
24
- return [elements] if elements.is_a?(String) || elements.is_a?(Symbol)
25
- elements
26
- end
27
- end
28
-
29
- # Defines mandatory xpaths value pairs to be included in 'success scenario' shared example
30
- #
31
- # @example Inside class
32
- # mandatory_xpath_values '//xmlns:GetWeatherResult' => 'Data Not Found'
33
- #
34
- # In test
35
- # describe Exchange(:name) do
36
- # it_behaves_like 'success scenario' # Includes xpath pair validation
37
- # end
38
- #
39
- def mandatory_xpath_values(xpath_value_pairs)
40
- raise ArgumentError('Hash of {xpath => expected values} expected ') unless xpath_value_pairs.is_a? Hash
41
- define_method('expected_mandatory_xpath_values') do
42
- xpath_value_pairs
43
- end
44
- end
45
-
46
- # Defines mandatory json path value pairs to be included in 'success scenario' shared example
47
- #
48
- # @example Inside class
49
- # mandatory_json_values '$..GetWeatherResult' => 'Found'
50
- #
51
- # In test
52
- # describe Exchange(:name) do
53
- # it_behaves_like 'success scenario' # Includes json pair validation
54
- # end
55
- #
56
- def mandatory_json_values(json_value_pairs)
57
- raise ArgumentError("Hash of {'jsonpath' => expected values} expected") unless json_value_pairs.is_a? Hash
58
- define_method('expected_mandatory_json_values') do
59
- json_value_pairs
60
- end
61
- end
62
-
63
- # Links a particular path to a meaningful method that can be accessed from Exchange class.
64
- # This will use the 'value_from_path' method which
65
- # should be implemented by each ExchangeHandler
66
- # @param [String, Symbol] name Method name used to access element
67
- # @param [String, Symbol] path Path to find object (e.g, XPath, JSONPath)
68
- def element(name, path)
69
- define_method("__custom_path_#{name}") do |response|
70
- value_from_path(response, path.to_s)
71
- end
72
- end
73
-
74
- # Links an attribute to a meaningful method that can be accessed from Exchange class.
75
- # This will use the 'value_from_path' method which
76
- # should be implemented by each ExchangeHandler
77
- # @param [String, Symbol] name Method name used to access attribute
78
- # @param [String, nil, Hash] attribute Attribute name. If not set, this will default to @name
79
- def attribute(name, attribute = nil)
80
- attribute_used = attribute ? attribute : name.to_s
81
- define_method("__custom_path_#{name}") do |response|
82
- value_from_path(response, 'implicit', attribute: attribute_used)
83
- end
84
- end
85
-
86
- # All xpath will be done with XML that is converted to lower case
87
- # You must then use lower case in the xpath's to obtain the desired values
88
- def convert_to_lower(set)
89
- return unless set
90
- define_method('convert_to_lower?') do
91
- true
92
- end
93
- end
94
-
95
- # Whether to remove namespaces from response in Xpath assertion automatically
96
- # For why this may not be a good thing in general see
97
- # http://tenderlovemaking.com/2009/04/23/namespaces-in-xml.html
98
- # This will be overridden if xpath has a ':' in it
99
- def strip_namespaces(set)
100
- return unless set
101
- # Whether to remove namespaces in xpath assertion automatically
102
- define_method('strip_namespaces?') do
103
- true
104
- end
105
- end
106
- end
1
+ module Soaspec
2
+ # Describes methods test handlers use to easily set attributes
3
+ # Some are included in 'success scenarios' and to configure the request sent
4
+ module HandlerAccessors
5
+
6
+ # Defines expected_mandatory_elements method used in 'success_scenario' shared examples
7
+ # to indicate certain elements must be present
8
+ # @param [Array] elements Array of symbols specifying expected element names for 'success scenario' in snakecase
9
+ #
10
+ # @example Inside class
11
+ # mandatory_elements :GetWeatherResult
12
+ #
13
+ # Or for a list
14
+ #
15
+ # @example Inside class
16
+ # mandatory_elements [:GetWeatherResult, :GetResultStatus]
17
+ #
18
+ # In test
19
+ # describe Exchange(:name) do
20
+ # it_behaves_like 'success scenario' # Includes checks for mandatory elements
21
+ # end
22
+ def mandatory_elements(elements)
23
+ define_method('expected_mandatory_elements') do
24
+ return [elements] if elements.is_a?(String) || elements.is_a?(Symbol)
25
+ elements
26
+ end
27
+ end
28
+
29
+ # Defines mandatory xpaths value pairs to be included in 'success scenario' shared example
30
+ #
31
+ # @example Inside class
32
+ # mandatory_xpath_values '//xmlns:GetWeatherResult' => 'Data Not Found'
33
+ #
34
+ # In test
35
+ # describe Exchange(:name) do
36
+ # it_behaves_like 'success scenario' # Includes xpath pair validation
37
+ # end
38
+ #
39
+ def mandatory_xpath_values(xpath_value_pairs)
40
+ raise ArgumentError('Hash of {xpath => expected values} expected ') unless xpath_value_pairs.is_a? Hash
41
+ define_method('expected_mandatory_xpath_values') do
42
+ xpath_value_pairs
43
+ end
44
+ end
45
+
46
+ # Defines mandatory json path value pairs to be included in 'success scenario' shared example
47
+ #
48
+ # @example Inside class
49
+ # mandatory_json_values '$..GetWeatherResult' => 'Found'
50
+ #
51
+ # In test
52
+ # describe Exchange(:name) do
53
+ # it_behaves_like 'success scenario' # Includes json pair validation
54
+ # end
55
+ #
56
+ def mandatory_json_values(json_value_pairs)
57
+ raise ArgumentError("Hash of {'jsonpath' => expected values} expected") unless json_value_pairs.is_a? Hash
58
+ define_method('expected_mandatory_json_values') do
59
+ json_value_pairs
60
+ end
61
+ end
62
+
63
+ # Links a particular path to a meaningful method that can be accessed from Exchange class.
64
+ # This will use the 'value_from_path' method which
65
+ # should be implemented by each ExchangeHandler
66
+ # @param [String, Symbol] name Method name used to access element
67
+ # @param [String, Symbol] path Path to find object (e.g, XPath, JSONPath)
68
+ def element(name, path)
69
+ define_method("__custom_path_#{name}") do |response|
70
+ value_from_path(response, path.to_s)
71
+ end
72
+ end
73
+
74
+ # Links an attribute to a meaningful method that can be accessed from Exchange class.
75
+ # This will use the 'value_from_path' method which
76
+ # should be implemented by each ExchangeHandler
77
+ # @param [String, Symbol] name Method name used to access attribute
78
+ # @param [String, nil, Hash] attribute Attribute name. If not set, this will default to @name
79
+ def attribute(name, attribute = nil)
80
+ attribute_used = attribute ? attribute : name.to_s
81
+ define_method("__custom_path_#{name}") do |response|
82
+ value_from_path(response, 'implicit', attribute: attribute_used)
83
+ end
84
+ end
85
+
86
+ # All xpath will be done with XML that is converted to lower case
87
+ # You must then use lower case in the xpath's to obtain the desired values
88
+ def convert_to_lower(set)
89
+ return unless set
90
+ define_method('convert_to_lower?') do
91
+ true
92
+ end
93
+ end
94
+
95
+ # Whether to remove namespaces from response in Xpath assertion automatically
96
+ # For why this may not be a good thing in general see
97
+ # http://tenderlovemaking.com/2009/04/23/namespaces-in-xml.html
98
+ # This will be overridden if xpath has a ':' in it
99
+ def strip_namespaces(set)
100
+ return unless set
101
+ # Whether to remove namespaces in xpath assertion automatically
102
+ define_method('strip_namespaces?') do
103
+ true
104
+ end
105
+ end
106
+ end
107
107
  end
@@ -1,93 +1,93 @@
1
- module Soaspec
2
- # Accessors specific to REST handler
3
- module RestAccessors
4
-
5
- # Defines method 'base_url_value' containing base URL used in REST requests
6
- # @param [String] url Base Url to use in REST requests. Suburl is appended to this
7
- def base_url(url)
8
- define_method('base_url_value') do
9
- url
10
- end
11
- end
12
-
13
- # Will create access_token method based on passed parameters
14
- # @param [Hash] params Params client_id: nil, client_secret: nil, token_url: nil, username: nil, password: nil, security_token: nil
15
- def oauth2(params)
16
- # Payload to add to o-auth request dependent on params provided
17
- define_method('oauth_payload') do |updated_params|
18
- payload = { client_id: updated_params[:client_id], client_secret: updated_params[:client_secret] }
19
- payload.merge(if updated_params[:password] && updated_params[:username]
20
- {
21
- grant_type: 'password',
22
- username: updated_params[:username],
23
- password: updated_params[:security_token] ? (updated_params[:password] + updated_params[:security_token]) : updated_params[:password],
24
- multipart: true
25
- }
26
- else
27
- { grant_type: 'client_credentials' }
28
- end)
29
- end
30
- # Method to send request to get oauth token based on parameters
31
- define_method('oauth_response') do
32
- raise 'client_id and client_secret not set' unless params[:client_id] && params[:client_secret]
33
- params[:username] = api_username || ERB.new(params[:username]).result(binding) if params[:username]
34
- params[:security_token] = ERB.new(params[:security_token]).result(binding) if params[:security_token]
35
- params[:token_url] = ERB.new(params[:token_url]).result(binding) if params[:token_url]
36
- params[:password] = ERB.new(params[:password]).result(binding) if params[:password]
37
- payload = oauth_payload(params)
38
- request_message = if Soaspec.debug_oauth?
39
- "request_params: #{payload}"
40
- else
41
- params[:username] ? "User '#{params[:username]}'" : 'client_credentials'
42
- end
43
- Soaspec::SpecLogger.info request_message
44
- retry_count = 0
45
- begin
46
- response = RestClient.post(params[:token_url], payload, cache_control: 'no_cache', verify_ssl: false)
47
- rescue RestClient::Exception => e
48
- Soaspec::SpecLogger.info("oauth_error: #{e.message}")
49
- Soaspec::SpecLogger.info("oauth_response: #{e.response}")
50
- retry_count += 1
51
- retry if retry_count < 3
52
- raise e
53
- end
54
- if Soaspec.debug_oauth?
55
- Soaspec::SpecLogger.info("response_headers: #{response.headers}")
56
- Soaspec::SpecLogger.info("response_body: #{response.body}")
57
- end
58
- JSON.parse(response)
59
- end
60
-
61
- define_method('access_token') do
62
- oauth_response['access_token']
63
- end
64
- define_method('instance_url') do
65
- oauth_response['instance_url']
66
- end
67
- end
68
-
69
- # Pass path to YAML file containing OAuth2 parameters
70
- # @param [String] path_to_filename Will have Soaspec.credentials_folder appended to it if set
71
- def oauth2_file(path_to_filename)
72
- full_path = Soaspec.credentials_folder ? File.join(Soaspec.credentials_folder, path_to_filename + '.yml') : path_to_filename + '.yml'
73
- file_hash = YAML.load_file(full_path)
74
- raise 'File at ' + full_path + ' is not a hash ' unless file_hash.is_a? Hash
75
- oauth_hash = file_hash.transform_keys_to_symbols
76
- oauth2 **oauth_hash
77
- end
78
-
79
- # @param [Hash] headers Hash of REST headers used in RestClient
80
- def headers(headers)
81
- define_method('rest_client_headers') do
82
- headers
83
- end
84
- end
85
-
86
- # Convert each key from snake_case to PascalCase
87
- def pascal_keys(set)
88
- define_method('pascal_keys?') do
89
- set
90
- end
91
- end
92
- end
1
+ module Soaspec
2
+ # Accessors specific to REST handler
3
+ module RestAccessors
4
+
5
+ # Defines method 'base_url_value' containing base URL used in REST requests
6
+ # @param [String] url Base Url to use in REST requests. Suburl is appended to this
7
+ def base_url(url)
8
+ define_method('base_url_value') do
9
+ url
10
+ end
11
+ end
12
+
13
+ # Will create access_token method based on passed parameters
14
+ # @param [Hash] params Params client_id: nil, client_secret: nil, token_url: nil, username: nil, password: nil, security_token: nil
15
+ def oauth2(params)
16
+ # Payload to add to o-auth request dependent on params provided
17
+ define_method('oauth_payload') do |updated_params|
18
+ payload = { client_id: updated_params[:client_id], client_secret: updated_params[:client_secret] }
19
+ payload.merge(if updated_params[:password] && updated_params[:username]
20
+ {
21
+ grant_type: 'password',
22
+ username: updated_params[:username],
23
+ password: updated_params[:security_token] ? (updated_params[:password] + updated_params[:security_token]) : updated_params[:password],
24
+ multipart: true
25
+ }
26
+ else
27
+ { grant_type: 'client_credentials' }
28
+ end)
29
+ end
30
+ # Method to send request to get oauth token based on parameters
31
+ define_method('oauth_response') do
32
+ raise 'client_id and client_secret not set' unless params[:client_id] && params[:client_secret]
33
+ params[:username] = api_username || ERB.new(params[:username]).result(binding) if params[:username]
34
+ params[:security_token] = ERB.new(params[:security_token]).result(binding) if params[:security_token]
35
+ params[:token_url] = ERB.new(params[:token_url]).result(binding) if params[:token_url]
36
+ params[:password] = ERB.new(params[:password]).result(binding) if params[:password]
37
+ payload = oauth_payload(params)
38
+ request_message = if Soaspec.debug_oauth?
39
+ "request_params: #{payload}"
40
+ else
41
+ params[:username] ? "User '#{params[:username]}'" : 'client_credentials'
42
+ end
43
+ Soaspec::SpecLogger.info request_message
44
+ retry_count = 0
45
+ begin
46
+ response = RestClient.post(params[:token_url], payload, cache_control: 'no_cache', verify_ssl: false)
47
+ rescue RestClient::Exception => e
48
+ Soaspec::SpecLogger.info("oauth_error: #{e.message}")
49
+ Soaspec::SpecLogger.info("oauth_response: #{e.response}")
50
+ retry_count += 1
51
+ retry if retry_count < 3
52
+ raise e
53
+ end
54
+ if Soaspec.debug_oauth?
55
+ Soaspec::SpecLogger.info("response_headers: #{response.headers}")
56
+ Soaspec::SpecLogger.info("response_body: #{response.body}")
57
+ end
58
+ JSON.parse(response)
59
+ end
60
+
61
+ define_method('access_token') do
62
+ oauth_response['access_token']
63
+ end
64
+ define_method('instance_url') do
65
+ oauth_response['instance_url']
66
+ end
67
+ end
68
+
69
+ # Pass path to YAML file containing OAuth2 parameters
70
+ # @param [String] path_to_filename Will have Soaspec.credentials_folder appended to it if set
71
+ def oauth2_file(path_to_filename)
72
+ full_path = Soaspec.credentials_folder ? File.join(Soaspec.credentials_folder, path_to_filename + '.yml') : path_to_filename + '.yml'
73
+ file_hash = YAML.load_file(full_path)
74
+ raise 'File at ' + full_path + ' is not a hash ' unless file_hash.is_a? Hash
75
+ oauth_hash = file_hash.transform_keys_to_symbols
76
+ oauth2 **oauth_hash
77
+ end
78
+
79
+ # @param [Hash] headers Hash of REST headers used in RestClient
80
+ def headers(headers)
81
+ define_method('rest_client_headers') do
82
+ headers
83
+ end
84
+ end
85
+
86
+ # Convert each key from snake_case to PascalCase
87
+ def pascal_keys(set)
88
+ define_method('pascal_keys?') do
89
+ set
90
+ end
91
+ end
92
+ end
93
93
  end