soaspec 0.1.18 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ChangeLog +11 -0
- data/exe/soaspec +18 -3
- data/lib/soaspec/cucumber/generic_steps.rb +32 -14
- data/lib/soaspec/exchange.rb +2 -27
- data/lib/soaspec/exchange_handlers/exchange_handler.rb +11 -8
- data/lib/soaspec/exchange_handlers/handler_accessors.rb +24 -12
- data/lib/soaspec/exchange_handlers/rest_exchanger_factory.rb +104 -0
- data/lib/soaspec/exchange_handlers/rest_handler.rb +16 -38
- data/lib/soaspec/exchange_handlers/rest_parameters.rb +74 -0
- data/lib/soaspec/exchange_handlers/{rest_accessors_defaults.rb → rest_parameters_defaults.rb} +2 -2
- data/lib/soaspec/exchange_handlers/soap_handler.rb +0 -2
- data/lib/soaspec/exchange_properties.rb +28 -0
- data/lib/soaspec/exe_helpers.rb +3 -1
- data/lib/soaspec/generator/lib/new_rest_service.rb.erb +50 -0
- data/lib/soaspec/generator/lib/new_soap_service.rb.erb +30 -0
- data/lib/soaspec/matchers.rb +24 -1
- data/lib/soaspec/soaspec_shared_examples.rb +1 -1
- data/lib/soaspec/version.rb +1 -1
- metadata +8 -4
- data/lib/soaspec/exchange_handlers/rest_accessors.rb +0 -56
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bfa2bb6212fe0840b7909f7abc36b9d930130edf
|
4
|
+
data.tar.gz: 21bf07ae73063ea5b89cb893b34f4b9dd986c574
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8da4766d8150595c4087ab1a5d4e85194a6731ccaa8720b8d25bf0f6a91d08e049da0e283f5e2ba3212e2789d74b4f4bb893b489eb33f70461bec05aa34fea2d
|
7
|
+
data.tar.gz: 7351a1edd83baa1e2dd74555ec8f8f14c5a5064be0bc81d43cf4034d41c4694eedccb5f6e637e5b2c9dfb0cccf8e4bc6738c5ca034100c02ed0f408e6f97454d
|
data/ChangeLog
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
Version 0.2.0
|
2
|
+
* Exception handling
|
3
|
+
* Raise meaningful exception if REST header value passed is null
|
4
|
+
* Enhancements
|
5
|
+
* `soaspec add` exe to create basic 'rest' or 'soap' service
|
6
|
+
* Add another matcher to check response is successful
|
7
|
+
* Default hash and template_name can now be defined within a class rather than just at an instance of it
|
8
|
+
* Stubs making it clearer what parameters are when looking at code from RubyMine
|
9
|
+
* Basic auth file method on RestHandler for clearer defining of basic auth
|
10
|
+
* Handle ERB in 'base_url' method
|
11
|
+
|
1
12
|
Version 0.1.18
|
2
13
|
* Enhancements
|
3
14
|
* Define 'exchange' method on response object so original exchange can be accessed
|
data/exe/soaspec
CHANGED
@@ -18,10 +18,10 @@ module Soaspec
|
|
18
18
|
`soaspec new` will generate the initial files and folders for starting a testing project using soaspec
|
19
19
|
\x5
|
20
20
|
|
21
|
-
`soaspec new soap` will create example files testing against a
|
21
|
+
`soaspec new soap` will create example files testing against a SOAP service
|
22
22
|
\x5
|
23
23
|
|
24
|
-
`soaspec new rest` will create example files testing against a
|
24
|
+
`soaspec new rest` will create example files testing against a REST service
|
25
25
|
LONGDESC
|
26
26
|
desc 'new [type]', 'Initialize soaspec repository'
|
27
27
|
option :ci, default: 'jenkins', banner: 'What Continuous Integration is used'
|
@@ -43,13 +43,28 @@ module Soaspec
|
|
43
43
|
puts "Run 'rake spec' to run the tests"
|
44
44
|
end
|
45
45
|
|
46
|
+
long_desc <<-LONGDESC
|
47
|
+
`soaspec add rest` will generate the initial files and folders for starting a testing project using soaspec
|
48
|
+
\x5
|
49
|
+
|
50
|
+
`soaspec add soap` will create example files testing against a virtual SOAP service
|
51
|
+
\x5
|
52
|
+
|
53
|
+
LONGDESC
|
54
|
+
desc 'add [type] [name]', 'Add new ExchangeHandler'
|
55
|
+
def add(type = 'rest', name = 'TestService')
|
56
|
+
raise "Type '#{type}' is not available" unless %w[rest soap].include? type
|
57
|
+
@name = name # Use instance variable for ERB
|
58
|
+
create_file(filename: File.join('lib', "#{name.snakecase}.rb"), content: retrieve_contents("lib/new_#{type}_service.rb"))
|
59
|
+
end
|
60
|
+
|
46
61
|
desc 'generate', 'Generate initial test code from wsdl'
|
47
62
|
long_desc <<-LONGDESC
|
48
63
|
`soaspec generate wsdl=wsdl name=ServiceName ` will generate the initial files and folders to test each operation in a wsdl
|
49
64
|
\x5
|
50
65
|
Additionally the auth parameter can be used to use basic authentication to retrieve the WSDL.
|
51
66
|
To do use the following `soaspec generate --auth=basic`
|
52
|
-
|
67
|
+
Note: This is still a work in progress and will only work for a very simple wsdl
|
53
68
|
LONGDESC
|
54
69
|
option :wsdl, required: true, aliases: :w
|
55
70
|
option :name, default: 'Service', aliases: :n
|
@@ -1,49 +1,67 @@
|
|
1
1
|
require 'active_support/core_ext/string/inflections'
|
2
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
|
3
10
|
Given 'I am performing a {word} on the {string} API' do |operation, api_name|
|
4
|
-
@
|
11
|
+
@current_exchange = api_name.tr(' ', '_').camelize.constantize.send operation
|
5
12
|
end
|
6
13
|
|
14
|
+
# Set a parameter in the request body
|
15
|
+
# @param [String] Element in request body to set
|
16
|
+
# @param [String] Value to set it to
|
7
17
|
Given 'I set the {word} to {string}' do |key, value|
|
8
|
-
|
18
|
+
current_exchange[key] = value
|
9
19
|
end
|
10
20
|
|
21
|
+
# Add onto the base_url to make a complete url for the test
|
11
22
|
Given 'I use the path {word}' do |suburl|
|
12
|
-
|
23
|
+
current_exchange.suburl = suburl
|
13
24
|
end
|
14
25
|
|
26
|
+
# Add a query parameter for http 'get' requests. e.g. will add '?filter_key=filter_value' onto URL
|
15
27
|
Given 'I filter {string} by {string}' do |filter_key, filter_value|
|
16
28
|
transformed_key = filter_key.to_sym
|
17
|
-
if
|
18
|
-
|
29
|
+
if current_exchange.override_parameters[:q]
|
30
|
+
current_exchange.override_parameters[:q][transformed_key] = filter_value
|
19
31
|
else
|
20
|
-
|
32
|
+
current_exchange.override_parameters[:q] = { transformed_key => filter_value }
|
21
33
|
end
|
22
34
|
end
|
23
35
|
|
24
|
-
#
|
36
|
+
# Add HTTP header 'header_name' as 'header_value'
|
25
37
|
Given 'I set header {string} to {string}' do |header_name, header_value|
|
26
|
-
if
|
27
|
-
|
38
|
+
if current_exchange.override_parameters[:params]
|
39
|
+
current_exchange.override_parameters[:params][header_name] = header_value
|
28
40
|
else
|
29
|
-
|
41
|
+
current_exchange.override_parameters[:params] = { header_name => header_value }
|
30
42
|
end
|
31
43
|
end
|
32
44
|
|
45
|
+
# Make the API call. This is automatically done when any method extracting a response is made. It can be done
|
46
|
+
# explicitly here as it is a meaningful step
|
33
47
|
When 'I make the request' do
|
34
|
-
|
48
|
+
current_exchange.call
|
35
49
|
end
|
36
50
|
|
51
|
+
# Extract the value from the response that is at the path 'key' and verify it is eq to expected_value
|
37
52
|
Then 'it should have the {word} {string}' do |key, expected_value|
|
38
|
-
expect(
|
53
|
+
expect(current_exchange[key]).to eq expected_value
|
39
54
|
end
|
40
55
|
|
56
|
+
# Extract the value from the response that is at the path 'key_string' and verify it is eq to expected_value
|
57
|
+
# Conversion is made on key_string to make it one snake case word
|
41
58
|
Then 'it should have the {string} {string}' do |key_string, expected_value|
|
42
59
|
key = key_string.tr(' ', '_')
|
43
|
-
actual_value =
|
60
|
+
actual_value = current_exchange.respond_to?(key) ? current_exchange.send(key) : current_exchange[key]
|
44
61
|
expect(actual_value.to_s).to eq expected_value
|
45
62
|
end
|
46
63
|
|
64
|
+
# Verify that the HTTP status code is 200..299 and that any defined mandatory elements / mandatory values are as expected
|
47
65
|
Then 'it should be successful' do
|
48
|
-
expect(
|
66
|
+
expect(current_exchange).to be_successful
|
49
67
|
end
|
data/lib/soaspec/exchange.rb
CHANGED
@@ -1,36 +1,11 @@
|
|
1
1
|
require_relative '../soaspec'
|
2
|
-
|
3
|
-
# Convenience methods to set Exchange specific properties
|
4
|
-
module ExchangeAccessors
|
5
|
-
|
6
|
-
# Set default exchange handler for this exchange
|
7
|
-
# This is helpful for when you need a new exchange handler created for each exchange
|
8
|
-
def default_handler(handler_class, name = handler_class.to_s, params = '')
|
9
|
-
define_method('default_handler_used') do
|
10
|
-
params_used = Hash[params.map do |k, param|
|
11
|
-
[k, param.is_a?(String) ? ERB.new(param).result(binding) : param]
|
12
|
-
end]
|
13
|
-
handler_class.new name, params_used
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
# Set retry_for_success to true, retrying response until a successful status code is returned
|
18
|
-
def expect_positive_status(retry_count: 3)
|
19
|
-
define_method('retry_count') do
|
20
|
-
retry_count
|
21
|
-
end
|
22
|
-
define_method('retry_for_success?') do
|
23
|
-
true
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
end
|
2
|
+
require_relative 'exchange_properties'
|
28
3
|
|
29
4
|
# This represents a request / response pair
|
30
5
|
# Essentially, params in the exchange that are set are related to the request
|
31
6
|
# What is returned is related to the response
|
32
7
|
class Exchange
|
33
|
-
extend
|
8
|
+
extend ExchangeProperties
|
34
9
|
|
35
10
|
# Instance of ExchangeHandler for which this exchange is made
|
36
11
|
attr_accessor :exchange_handler
|
@@ -16,18 +16,15 @@ module Soaspec
|
|
16
16
|
public_methods.select { |i| i[/__custom_path_.+/] }
|
17
17
|
end
|
18
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
19
|
# Set instance variable name
|
27
20
|
# @param [String, Symbol] name Name used when describing API test
|
28
21
|
# @param [Hash] options Parameters defining handler. Used in descendants
|
29
22
|
def initialize(name = self.class.to_s, options = {})
|
30
23
|
use
|
24
|
+
@request_option = :hash
|
25
|
+
raise ArgumentError, 'Cannot define both template_name and default_hash' if respond_to?(:template_name_value) && respond_to?(:default_hash_value)
|
26
|
+
@template_name = respond_to?(:template_name_value) ? template_name_value : ''
|
27
|
+
@default_hash = respond_to?(:default_hash_value) ? default_hash_value : {}
|
31
28
|
@name = name
|
32
29
|
end
|
33
30
|
|
@@ -45,6 +42,13 @@ module Soaspec
|
|
45
42
|
@name.to_s
|
46
43
|
end
|
47
44
|
|
45
|
+
# Set the default hash representing data to be used in making a request
|
46
|
+
# This will set the @request_option instance variable too
|
47
|
+
def default_hash=(hash)
|
48
|
+
@request_option = :hash
|
49
|
+
@default_hash = Soaspec.always_use_keys? ? hash.transform_keys_to_symbols : hash
|
50
|
+
end
|
51
|
+
|
48
52
|
# Set the request option type and the template name
|
49
53
|
# Erb is used to parse the template file, executing Ruby code in `<%= %>` blocks to work out the final request
|
50
54
|
# @param [String] name Name of file inside 'template' folder excluding extension
|
@@ -112,6 +116,5 @@ module Soaspec
|
|
112
116
|
return "Request not yet sent Request option is #{@request_option}" unless response
|
113
117
|
'Specific API handler should implement this'
|
114
118
|
end
|
115
|
-
|
116
119
|
end
|
117
120
|
end
|
@@ -38,9 +38,7 @@ module Soaspec
|
|
38
38
|
#
|
39
39
|
def mandatory_xpath_values(xpath_value_pairs)
|
40
40
|
raise ArgumentError('Hash of {xpath => expected values} expected ') unless xpath_value_pairs.is_a? Hash
|
41
|
-
define_method('expected_mandatory_xpath_values')
|
42
|
-
xpath_value_pairs
|
43
|
-
end
|
41
|
+
define_method('expected_mandatory_xpath_values') { xpath_value_pairs }
|
44
42
|
end
|
45
43
|
|
46
44
|
# Defines mandatory json path value pairs to be included in 'success scenario' shared example
|
@@ -55,9 +53,7 @@ module Soaspec
|
|
55
53
|
#
|
56
54
|
def mandatory_json_values(json_value_pairs)
|
57
55
|
raise ArgumentError("Hash of {'jsonpath' => expected values} expected") unless json_value_pairs.is_a? Hash
|
58
|
-
define_method('expected_mandatory_json_values')
|
59
|
-
json_value_pairs
|
60
|
-
end
|
56
|
+
define_method('expected_mandatory_json_values') { json_value_pairs }
|
61
57
|
end
|
62
58
|
|
63
59
|
# Links a particular path to a meaningful method that can be accessed from Exchange class.
|
@@ -75,7 +71,7 @@ module Soaspec
|
|
75
71
|
# This will use the 'value_from_path' method which
|
76
72
|
# should be implemented by each ExchangeHandler
|
77
73
|
# @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
|
74
|
+
# @param [String, nil, Hash] attribute Attribute name to extract from xml. If not set, this will default to @name
|
79
75
|
def attribute(name, attribute = nil)
|
80
76
|
attribute_used = attribute ? attribute : name.to_s
|
81
77
|
define_method("__custom_path_#{name}") do |response|
|
@@ -87,9 +83,7 @@ module Soaspec
|
|
87
83
|
# You must then use lower case in the xpath's to obtain the desired values
|
88
84
|
def convert_to_lower(set)
|
89
85
|
return unless set
|
90
|
-
define_method('convert_to_lower?')
|
91
|
-
true
|
92
|
-
end
|
86
|
+
define_method('convert_to_lower?') { true }
|
93
87
|
end
|
94
88
|
|
95
89
|
# Whether to remove namespaces from response in Xpath assertion automatically
|
@@ -99,8 +93,26 @@ module Soaspec
|
|
99
93
|
def strip_namespaces(set)
|
100
94
|
return unless set
|
101
95
|
# Whether to remove namespaces in xpath assertion automatically
|
102
|
-
define_method('strip_namespaces?')
|
103
|
-
|
96
|
+
define_method('strip_namespaces?') { true }
|
97
|
+
end
|
98
|
+
|
99
|
+
# Set the default hash representing data to be used in making a request
|
100
|
+
# This will set the @request_option instance variable too
|
101
|
+
# @param [Hash] hash Default hash of request
|
102
|
+
def default_hash(hash)
|
103
|
+
define_method('default_hash_value') do
|
104
|
+
@request_option = :hash
|
105
|
+
Soaspec.always_use_keys? ? hash.transform_keys_to_symbols : hash
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# Set the request option type and the template name
|
110
|
+
# Erb is used to parse the template file, executing Ruby code in `<%= %>` blocks to work out the final request
|
111
|
+
# @param [String] name Name of file inside 'template' folder excluding extension
|
112
|
+
def template_name(name)
|
113
|
+
define_method('template_name_value') do
|
114
|
+
@request_option = :template
|
115
|
+
name
|
104
116
|
end
|
105
117
|
end
|
106
118
|
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
module Soaspec
|
2
|
+
# Convenience methods for once off usage of a REST request
|
3
|
+
module RestExchangeFactory
|
4
|
+
# Make REST Exchange with 'post' method within this Handler context
|
5
|
+
# @param [Hash, String] params Exchange parameters. If String is used it will be for the request payload
|
6
|
+
# @option override_parameters [Hash] :params Extra parameters (E.g. headers)
|
7
|
+
# @option override_parameters [String] suburl URL appended to base_url of class
|
8
|
+
# @option override_parameters [Hash] :q Query for REST
|
9
|
+
# Following are for the body of the request
|
10
|
+
# @option override_parameters [Hash] :body Hash to be converted to JSON in request body
|
11
|
+
# @option override_parameters [String] :payload String to be passed directly in request body
|
12
|
+
# @option override_parameters [String] :template_name Path to file to be read via ERB and passed in request body
|
13
|
+
# @return [Exchange] Instance of Exchange class. Assertions are made by default on the response body
|
14
|
+
def post(params = {})
|
15
|
+
# This is a stub, used for indexing, source code below
|
16
|
+
end
|
17
|
+
|
18
|
+
# Make REST Exchange with 'patch' method within this Handler context
|
19
|
+
# @param [Hash, String] params Exchange parameters. If String is used it will be for the request payload
|
20
|
+
# @option override_parameters [Hash] :params Extra parameters (E.g. headers)
|
21
|
+
# @option override_parameters [String] suburl URL appended to base_url of class
|
22
|
+
# @option override_parameters [Hash] :q Query for REST
|
23
|
+
# Following are for the body of the request
|
24
|
+
# @option override_parameters [Hash] :body Hash to be converted to JSON in request body
|
25
|
+
# @option override_parameters [String] :payload String to be passed directly in request body
|
26
|
+
# @option override_parameters [String] :template_name Path to file to be read via ERB and passed in request body
|
27
|
+
# @return [Exchange] Instance of Exchange class. Assertions are made by default on the response body
|
28
|
+
def patch(params)
|
29
|
+
# This is a stub, used for indexing, source code below
|
30
|
+
end
|
31
|
+
|
32
|
+
# Make REST Exchange with 'put' method within this Handler context
|
33
|
+
# @param [Hash, String] params Exchange parameters. If String is used it will be for the request payload
|
34
|
+
# @option override_parameters [Hash] :params Extra parameters (E.g. headers)
|
35
|
+
# @option override_parameters [String] suburl URL appended to base_url of class
|
36
|
+
# @option override_parameters [Hash] :q Query for REST
|
37
|
+
# Following are for the body of the request
|
38
|
+
# @option override_parameters [Hash] :body Hash to be converted to JSON in request body
|
39
|
+
# @option override_parameters [String] :payload String to be passed directly in request body
|
40
|
+
# @option override_parameters [String] :template_name Path to file to be read via ERB and passed in request body
|
41
|
+
# @return [Exchange] Instance of Exchange class. Assertions are made by default on the response body
|
42
|
+
def put(params = {})
|
43
|
+
# This is a stub, used for indexing, source code below
|
44
|
+
end
|
45
|
+
|
46
|
+
# Make REST Exchange with 'get' method within this Handler context.
|
47
|
+
# If merely a string is passed it will be used as the URL appended to base_url. Otherwise a Hash is expected
|
48
|
+
# @param [Hash, String] params Exchange parameters. If String is used it will be for suburl
|
49
|
+
# @option override_parameters [Hash] :params Extra parameters (E.g. headers)
|
50
|
+
# @option override_parameters [String] suburl URL appended to base_url of class
|
51
|
+
# @option override_parameters [Hash] :q Query for REST
|
52
|
+
# Following are for the body of the request
|
53
|
+
# @option override_parameters [Hash] :body Hash to be converted to JSON in request body
|
54
|
+
# @option override_parameters [String] :payload String to be passed directly in request body
|
55
|
+
# @option override_parameters [String] :template_name Path to file to be read via ERB and passed in request body
|
56
|
+
# @return [Exchange] Instance of Exchange class. Assertions are made by default on the response body
|
57
|
+
def get(params = {})
|
58
|
+
# This is a stub, used for indexing, source code below
|
59
|
+
end
|
60
|
+
|
61
|
+
# Make REST Exchange with 'delete' method within this Handler context.
|
62
|
+
# If merely a string is passed it will be used as the URL appended to base_url. Otherwise a Hash is expected
|
63
|
+
# @param [Hash, String] params Exchange parameters. If String is used it will be for suburl
|
64
|
+
# @option override_parameters [Hash] :params Extra parameters (E.g. headers)
|
65
|
+
# @option override_parameters [String] suburl URL appended to base_url of class
|
66
|
+
# @option override_parameters [Hash] :q Query for REST
|
67
|
+
# Following are for the body of the request
|
68
|
+
# @option override_parameters [Hash] :body Hash to be converted to JSON in request body
|
69
|
+
# @option override_parameters [String] :payload String to be passed directly in request body
|
70
|
+
# @option override_parameters [String] :template_name Path to file to be read via ERB and passed in request body
|
71
|
+
# @return [Exchange] Instance of Exchange class. Assertions are made by default on the response body
|
72
|
+
def delete(params = {})
|
73
|
+
# This is a stub, used for indexing, source code below
|
74
|
+
end
|
75
|
+
|
76
|
+
methods = %w[post patch put get delete]
|
77
|
+
|
78
|
+
methods.each do |rest_method|
|
79
|
+
# Make REST Exchange within this Handler context
|
80
|
+
# @param [Hash, String] params Exchange parameters.
|
81
|
+
# @return [Exchange] Instance of Exchange class. Assertions are made by default on the response body
|
82
|
+
define_method(rest_method) do |params = {}|
|
83
|
+
unless params.is_a? Hash
|
84
|
+
params = case rest_method
|
85
|
+
when 'get', 'delete'
|
86
|
+
{ suburl: params.to_s }
|
87
|
+
when 'post', 'put', 'patch'
|
88
|
+
{ payload: params.to_s }
|
89
|
+
else
|
90
|
+
raise "'#{params}' needs to be a 'Hash' but is a #{params.class}"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
params[:name] ||= rest_method
|
94
|
+
exchange_params = { name: params[:name] }
|
95
|
+
if params[:template_name]
|
96
|
+
exchange_params[:template_name] = params[:template_name]
|
97
|
+
params.delete :template_name
|
98
|
+
end
|
99
|
+
new(exchange_params)
|
100
|
+
Exchange.new(params[:name], method: rest_method.to_sym, **params)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
require_relative 'exchange_handler'
|
2
|
-
require_relative '
|
2
|
+
require_relative 'rest_parameters'
|
3
|
+
require_relative 'rest_parameters_defaults'
|
4
|
+
require_relative 'rest_exchanger_factory'
|
3
5
|
require_relative '../core_ext/hash'
|
4
6
|
require_relative '../not_found_errors'
|
5
7
|
require_relative 'handler_accessors'
|
@@ -8,13 +10,15 @@ require 'json'
|
|
8
10
|
require 'jsonpath'
|
9
11
|
require 'nori'
|
10
12
|
require 'erb'
|
13
|
+
require 'hashie/extensions/indifferent_access'
|
11
14
|
|
12
15
|
module Soaspec
|
13
16
|
|
14
17
|
# Wraps around Savon client defining default values dependent on the soap request
|
15
18
|
class RestHandler < ExchangeHandler
|
16
|
-
extend Soaspec::
|
17
|
-
include Soaspec::
|
19
|
+
extend Soaspec::RestParameters
|
20
|
+
include Soaspec::RestParametersDefaults
|
21
|
+
extend Soaspec::RestExchangeFactory
|
18
22
|
|
19
23
|
# User used in making API calls
|
20
24
|
attr_accessor :api_username
|
@@ -23,7 +27,6 @@ module Soaspec
|
|
23
27
|
# @param [Hash] options Options defining REST request. base_url, default_hash
|
24
28
|
def initialize(name = self.class.to_s, options = {})
|
25
29
|
raise "Base URL not set! Please set in class with 'base_url' method" unless base_url_value
|
26
|
-
@default_hash = {}
|
27
30
|
if name.is_a?(Hash) && options == {} # If name is not set, use first parameter as the options hash
|
28
31
|
options = name
|
29
32
|
name = self.class.to_s
|
@@ -31,6 +34,7 @@ module Soaspec
|
|
31
34
|
super
|
32
35
|
set_remove_keys(options, %i[api_username default_hash template_name])
|
33
36
|
@init_options = options
|
37
|
+
init_merge_options # Call this to verify any issues with options on creating object
|
34
38
|
end
|
35
39
|
|
36
40
|
# Used in together with Exchange request that passes such override parameters
|
@@ -43,6 +47,7 @@ module Soaspec
|
|
43
47
|
# @option override_parameters [Hash] :body Hash to be converted to JSON in request body
|
44
48
|
# @option override_parameters [String] :payload String to be passed directly in request body
|
45
49
|
# @option override_parameters [String] :template_name Path to file to be read via ERB and passed in request body
|
50
|
+
# @return [RestClient::Response] Response from making request
|
46
51
|
def make_request(override_parameters)
|
47
52
|
@merged_options ||= init_merge_options
|
48
53
|
test_values = override_parameters
|
@@ -82,7 +87,10 @@ module Soaspec
|
|
82
87
|
# Perform ERB on each header value
|
83
88
|
# @return [Hash] Hash from 'rest_client_headers' passed through ERB
|
84
89
|
def parse_headers
|
85
|
-
Hash[rest_client_headers.map
|
90
|
+
Hash[rest_client_headers.map do |header_name, header_value|
|
91
|
+
raise ArgumentError, "Header '#{header_name}' is null. Headers are #{rest_client_headers}" if header_value.nil?
|
92
|
+
[header_name, ERB.new(header_value).result(binding)]
|
93
|
+
end]
|
86
94
|
end
|
87
95
|
|
88
96
|
# Convert snakecase to PascalCase
|
@@ -95,6 +103,7 @@ module Soaspec
|
|
95
103
|
# @return [Hash] Hash of merged options
|
96
104
|
def init_merge_options
|
97
105
|
options = rest_resource_options
|
106
|
+
options.merge! basic_auth_params if respond_to? :basic_auth_params
|
98
107
|
options[:headers] ||= {}
|
99
108
|
options[:headers].merge! parse_headers
|
100
109
|
if Soaspec.auto_oauth && respond_to?(:access_token)
|
@@ -250,9 +259,10 @@ module Soaspec
|
|
250
259
|
# Work out data to send based upon payload, template_name, or body
|
251
260
|
# @return [String] Payload to send in REST request
|
252
261
|
def post_data(test_values)
|
253
|
-
data = if test_values[:body]
|
262
|
+
data = if @request_option == :hash && test_values[:body]
|
254
263
|
test_values[:payload] = JSON.generate(hash_used_in_request(test_values[:body])).to_s
|
255
264
|
elsif @request_option == :template
|
265
|
+
test_values = test_values[:body].dup if test_values[:body]
|
256
266
|
Soaspec::TemplateReader.new.render_body(template_name, binding)
|
257
267
|
else
|
258
268
|
test_values[:payload]
|
@@ -270,37 +280,5 @@ module Soaspec
|
|
270
280
|
request
|
271
281
|
end
|
272
282
|
end
|
273
|
-
|
274
|
-
# Convenience methods for once off usage of a REST request
|
275
|
-
class << self
|
276
|
-
|
277
|
-
methods = %w[post patch put get delete]
|
278
|
-
|
279
|
-
methods.each do |rest_method|
|
280
|
-
# Make REST Exchange within this Handler context
|
281
|
-
# @param [Hash, String] params Exchange parameters. If String is used it will be for suburl
|
282
|
-
# @return [Exchange] Instance of Exchange class. Assertions are made by default on the response body
|
283
|
-
define_method(rest_method) do |params = {}|
|
284
|
-
unless params.is_a? Hash
|
285
|
-
params = case rest_method
|
286
|
-
when 'get', 'delete'
|
287
|
-
{ suburl: params.to_s }
|
288
|
-
when 'post', 'put', 'patch'
|
289
|
-
{ payload: params.to_s }
|
290
|
-
else
|
291
|
-
params
|
292
|
-
end
|
293
|
-
end
|
294
|
-
params[:name] ||= rest_method
|
295
|
-
exchange_params = { name: params[:name] }
|
296
|
-
if params[:template_name]
|
297
|
-
exchange_params[:template_name] = params[:template_name]
|
298
|
-
params.delete :template_name
|
299
|
-
end
|
300
|
-
new(exchange_params)
|
301
|
-
Exchange.new(params[:name], method: rest_method.to_sym, **params)
|
302
|
-
end
|
303
|
-
end
|
304
|
-
end
|
305
283
|
end
|
306
284
|
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module Soaspec
|
2
|
+
# Methods to define parameters specific to REST handler
|
3
|
+
module RestParameters
|
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
|
+
raise ArgumentError, "Base Url passed must be a String for #{self} but was #{url.class}" unless url.is_a?(String)
|
9
|
+
define_method('base_url_value') { ERB.new(url).result(binding) }
|
10
|
+
end
|
11
|
+
|
12
|
+
# Will create access_token method based on passed parameters
|
13
|
+
# @param [Hash] params OAuth 2 parameters
|
14
|
+
# @param_value [token_url] URL to retrieve OAuth token from. @Note this can be set globally instead of here
|
15
|
+
# @param_value [client_id] Client ID
|
16
|
+
# @param_value [client_secret] Client Secret
|
17
|
+
# @param_value [username] Username used in password grant
|
18
|
+
# @param_value [password] Password used in password grant
|
19
|
+
# @param_value [security_token] Security Token used in password grant
|
20
|
+
def oauth2(params)
|
21
|
+
# @!method oauth_obj Object to handle oauth2
|
22
|
+
define_method('oauth_obj') { OAuth2.new(params, api_username) }
|
23
|
+
# @!method access_token Retrieve OAuth2 access token
|
24
|
+
define_method('access_token') { oauth_obj.access_token }
|
25
|
+
# @!method instance_url Retrieve instance url from OAuth request
|
26
|
+
define_method('instance_url') { oauth_obj.response['instance_url'] }
|
27
|
+
end
|
28
|
+
|
29
|
+
# Pass path to YAML file containing OAuth2 parameters
|
30
|
+
# @param [String] path_to_filename Will have Soaspec.credentials_folder appended to it if set
|
31
|
+
def oauth2_file(path_to_filename)
|
32
|
+
oauth2 load_credentials_hash(path_to_filename)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Define basic authentication
|
36
|
+
# @param [String] user Username to use
|
37
|
+
# @param [String] password Password to use
|
38
|
+
def basic_auth(user: nil, password: nil)
|
39
|
+
raise ArgumentError, "Must pass both 'user' and 'password' for #{self}" unless user && password
|
40
|
+
define_method('basic_auth_params') do
|
41
|
+
{ user: user, password: password }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Pass path to YAML file containing Basic Auth parameters (i.e, both username and password)
|
46
|
+
# @param [String] path_to_filename Will have Soaspec.credentials_folder appended to it if set
|
47
|
+
def basic_auth_file(path_to_filename)
|
48
|
+
basic_auth load_credentials_hash(path_to_filename)
|
49
|
+
end
|
50
|
+
|
51
|
+
# @param [Hash] headers Hash of REST headers used in RestClient
|
52
|
+
def headers(headers)
|
53
|
+
define_method('rest_client_headers') { headers }
|
54
|
+
end
|
55
|
+
|
56
|
+
# Convert each key from snake_case to PascalCase
|
57
|
+
def pascal_keys(set)
|
58
|
+
define_method('pascal_keys?') { set }
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
# Load credentials hash from a YAML using Soaspec.credentials_folder if set, adding '.yml' if not set
|
64
|
+
# @return [Hash] Hash with credentials in it
|
65
|
+
def load_credentials_hash(filename)
|
66
|
+
raise ArgumentError, "Filename passed must be a String for #{self} but was #{filename.class}" unless filename.is_a?(String)
|
67
|
+
full_path = Soaspec.credentials_folder ? File.join(Soaspec.credentials_folder, filename) : filename
|
68
|
+
full_path += '.yml' unless full_path.end_with?('.yml') # Automatically add 'yml' extension
|
69
|
+
file_hash = YAML.load_file(full_path)
|
70
|
+
raise "File at #{full_path} is not a hash" unless file_hash.is_a? Hash
|
71
|
+
file_hash.transform_keys_to_symbols
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -73,8 +73,6 @@ module Soaspec
|
|
73
73
|
# Setup object to handle communicating with a particular SOAP WSDL
|
74
74
|
# @param [Hash] options Options defining SOAP request. WSDL, authentication, see http://savonrb.com/version2/globals.html for list of options
|
75
75
|
def initialize(name = self.class.to_s, options = {})
|
76
|
-
@default_hash = {}
|
77
|
-
@request_option = :hash
|
78
76
|
if name.is_a?(Hash) && options == {} # If name is not set
|
79
77
|
options = name
|
80
78
|
name = self.class.to_s
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# Convenience methods to set Exchange specific properties
|
2
|
+
# Will be used when creating a subclass of Exchange
|
3
|
+
module ExchangeProperties
|
4
|
+
|
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
|
+
def expect_positive_status(retry_count: 3)
|
21
|
+
define_method('retry_count') do
|
22
|
+
retry_count
|
23
|
+
end
|
24
|
+
define_method('retry_for_success?') do
|
25
|
+
true
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/soaspec/exe_helpers.rb
CHANGED
@@ -31,7 +31,9 @@ module Soaspec
|
|
31
31
|
end
|
32
32
|
|
33
33
|
# Retrieve default file contents based on filename
|
34
|
-
|
34
|
+
# @param [String] filename Filename within 'lib/generator' to file retrieve contents from
|
35
|
+
# @param [Boolean] erb Whether to process file with ERB
|
36
|
+
def retrieve_contents(filename, erb = true)
|
35
37
|
default_file = File.join(File.dirname(__FILE__), 'generator', filename + (erb ? '.erb' : ''))
|
36
38
|
contents = File.read(default_file)
|
37
39
|
erb ? ERB.new(contents).result(binding) : contents
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# This class represent REST Api calls for the <%= @name %> API
|
2
|
+
class <%= @name %> < Soaspec::RestHandler
|
3
|
+
## Defining request
|
4
|
+
|
5
|
+
# All requests to <%= @name %> will start with this url
|
6
|
+
# TODO: Change this mandatory base_url to the url that all requests to this service start with
|
7
|
+
# base_url "https://my_host/api/<%= ENV['environment'] %>/api_name" # ERB can be used to make this dynamic based on environment
|
8
|
+
|
9
|
+
# Headers that will be sent by default using this Handler
|
10
|
+
# If symbol is used, they'll be converted to standard HTTP headers
|
11
|
+
# headers accept: 'application/json', content_type: 'application/json'
|
12
|
+
|
13
|
+
# Filename of oauth2 file to use for oauth2 parameters. 'Soaspec.credentials_folder' can be set to globally defined a folder with credentials
|
14
|
+
# This will add a default 'Authorization: Bearer access_token' header if 'Authorization' is not specified in headers
|
15
|
+
# The '.yml' extension will be added automatically if not present.
|
16
|
+
# oauth2_file 'filename.yml'
|
17
|
+
|
18
|
+
# Filename of YAML with basic auth parameters in it 'Soaspec.credentials_folder' can be set to globally defined a folder with credentials
|
19
|
+
# It is of the format
|
20
|
+
# user: 'username'
|
21
|
+
# password: 'password'
|
22
|
+
# basic_auth_file 'basic_auth.yml' # Load YAML file with basic auth credentials in it
|
23
|
+
|
24
|
+
### Request Body
|
25
|
+
|
26
|
+
# Filename of template to be used. This is within 'Soaspec.template_folder' folder
|
27
|
+
# template_name 'filename'
|
28
|
+
|
29
|
+
# Default hash to be used in request that will be converted to JSON. This can be overriden and added to by each Exchange using this class
|
30
|
+
# default_hash a: 1, b: 2
|
31
|
+
|
32
|
+
## Extracting response
|
33
|
+
|
34
|
+
# Use this to extract the value of either a JSON (JSONPath) or XML (Xpath) element. 'element_name' is the method that will be
|
35
|
+
# generated on an Exchange to obtain it
|
36
|
+
# element :element_name, 'element_path'
|
37
|
+
|
38
|
+
# Use this to extract an attribute from XML. If the name of the method and the attribute name are the same then only one parameter is
|
39
|
+
# needed
|
40
|
+
# attribute(:attribute_method_name, 'name_of_attribute')
|
41
|
+
|
42
|
+
## Creating verifications for success response
|
43
|
+
|
44
|
+
# Values that must have a certain value for 'success scenario' shared example
|
45
|
+
# mandatory_json_values '$..status' => 'available'
|
46
|
+
|
47
|
+
# Elements that must be in the response for 'success scenario' shared example
|
48
|
+
# Below will expect an element at the path 'tags' to be present
|
49
|
+
# mandatory_elements :tags
|
50
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# This class represent SOAP Api calls for the <%= @name %> API
|
2
|
+
class <%= @name %> < Soaspec::SoapHandler
|
3
|
+
# Wsdl for <%= @name %>
|
4
|
+
def savon_options
|
5
|
+
{
|
6
|
+
# wsdl 'https://my_host/api?wsdl' TODO: Change this to the wsdl that this SOAP service uses
|
7
|
+
}
|
8
|
+
end
|
9
|
+
|
10
|
+
## Verifying on response
|
11
|
+
|
12
|
+
# Values that must have a certain value for 'success scenario' shared example
|
13
|
+
# mandatory_json_values '$..status' => 'available'
|
14
|
+
|
15
|
+
# Elements that must be in the response for 'success scenario' shared example
|
16
|
+
# Below will expect an element at the path 'tags' to be present
|
17
|
+
# mandatory_elements :tags
|
18
|
+
|
19
|
+
# Use this to extract the value of either a JSON (JSONPath) or XML (Xpath) element. 'element_name' is the method that will be
|
20
|
+
# generated on an Exchange to obtain it
|
21
|
+
# element :element_name, 'element_path'
|
22
|
+
|
23
|
+
# Use this to extract an attribute from XML. If the name of the method and the attribute name are the same then only one parameter is
|
24
|
+
# needed
|
25
|
+
# attribute(:attribute_method_name, 'name_of_attribute')
|
26
|
+
|
27
|
+
# Set an attribute on the root XML element
|
28
|
+
# root_attributes 'Version' => '1'
|
29
|
+
|
30
|
+
end
|
data/lib/soaspec/matchers.rb
CHANGED
@@ -62,5 +62,28 @@ RSpec::Matchers.define :be_found do
|
|
62
62
|
failure_message do |exchange|
|
63
63
|
"expected result #{exchange.response} to be found. Status code is #{exchange.response.code}"
|
64
64
|
end
|
65
|
+
end
|
65
66
|
|
66
|
-
|
67
|
+
# Whether response has successful status code and correct mandatory elements and values
|
68
|
+
RSpec::Matchers.define :be_successful do
|
69
|
+
match do |actual|
|
70
|
+
failure_list = []
|
71
|
+
exchange = actual.respond_to?(:exchange) ? actual.exchange : actual
|
72
|
+
failure_list << "#{exchange.status_code} not valid status code" unless (200..299).cover?(exchange.status_code)
|
73
|
+
exchange.exchange_handler.expected_mandatory_elements.each do |mandatory_element_path|
|
74
|
+
begin
|
75
|
+
exchange[mandatory_element_path]
|
76
|
+
rescue NoElementAtPath => error
|
77
|
+
failure_list << error.message
|
78
|
+
end
|
79
|
+
end
|
80
|
+
exchange.exchange_handler.expected_mandatory_xpath_values.each do |path, value|
|
81
|
+
failure_list << "Expected value at xpath '#{path}' to be '#{value}' but was '#{exchange[path]}'" unless exchange[path] == value
|
82
|
+
end
|
83
|
+
exchange.exchange_handler.expected_mandatory_json_values.each do |path, value|
|
84
|
+
failure_list << "Expected value at json '#{path}' to be '#{value}' but was '#{exchange[path]}'" unless exchange[path] == value
|
85
|
+
end
|
86
|
+
raise failure_list.to_s unless failure_list.empty?
|
87
|
+
true
|
88
|
+
end
|
89
|
+
end
|
@@ -17,7 +17,7 @@ shared_examples_for 'success scenario' do
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
described_class.exchange_handler.expected_mandatory_json_values.each do |xpath, value|
|
20
|
-
it "has
|
20
|
+
it "has json '#{xpath}' equal to '#{value}'" do
|
21
21
|
expect(described_class).to have_xpath_value(xpath => value)
|
22
22
|
end
|
23
23
|
end
|
data/lib/soaspec/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: soaspec
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- SamuelGarrattIQA
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-11-
|
11
|
+
date: 2018-11-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -361,11 +361,13 @@ files:
|
|
361
361
|
- lib/soaspec/exchange.rb
|
362
362
|
- lib/soaspec/exchange_handlers/exchange_handler.rb
|
363
363
|
- lib/soaspec/exchange_handlers/handler_accessors.rb
|
364
|
-
- lib/soaspec/exchange_handlers/
|
365
|
-
- lib/soaspec/exchange_handlers/rest_accessors_defaults.rb
|
364
|
+
- lib/soaspec/exchange_handlers/rest_exchanger_factory.rb
|
366
365
|
- lib/soaspec/exchange_handlers/rest_handler.rb
|
367
366
|
- lib/soaspec/exchange_handlers/rest_methods.rb
|
367
|
+
- lib/soaspec/exchange_handlers/rest_parameters.rb
|
368
|
+
- lib/soaspec/exchange_handlers/rest_parameters_defaults.rb
|
368
369
|
- lib/soaspec/exchange_handlers/soap_handler.rb
|
370
|
+
- lib/soaspec/exchange_properties.rb
|
369
371
|
- lib/soaspec/exe_helpers.rb
|
370
372
|
- lib/soaspec/generator/.rspec.erb
|
371
373
|
- lib/soaspec/generator/.travis.yml.erb
|
@@ -375,6 +377,8 @@ files:
|
|
375
377
|
- lib/soaspec/generator/config/data/default.yml.erb
|
376
378
|
- lib/soaspec/generator/lib/blz_service.rb.erb
|
377
379
|
- lib/soaspec/generator/lib/dynamic_class_content.rb.erb
|
380
|
+
- lib/soaspec/generator/lib/new_rest_service.rb.erb
|
381
|
+
- lib/soaspec/generator/lib/new_soap_service.rb.erb
|
378
382
|
- lib/soaspec/generator/lib/package_service.rb.erb
|
379
383
|
- lib/soaspec/generator/lib/shared_example.rb.erb
|
380
384
|
- lib/soaspec/generator/spec/dynamic_soap_spec.rb.erb
|
@@ -1,56 +0,0 @@
|
|
1
|
-
require_relative 'rest_accessors_defaults'
|
2
|
-
|
3
|
-
module Soaspec
|
4
|
-
# Accessors specific to REST handler
|
5
|
-
module RestAccessors
|
6
|
-
|
7
|
-
# Defines method 'base_url_value' containing base URL used in REST requests
|
8
|
-
# @param [String] url Base Url to use in REST requests. Suburl is appended to this
|
9
|
-
def base_url(url)
|
10
|
-
define_method('base_url_value') do
|
11
|
-
url
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
# Will create access_token method based on passed parameters
|
16
|
-
# @param [Hash] params OAuth 2 parameters
|
17
|
-
# @param_value [token_url] URL to retrieve OAuth token from. @Note this can be set globally instead of here
|
18
|
-
# @param_value [client_id] Client ID
|
19
|
-
# @param_value [client_secret] Client Secret
|
20
|
-
# @param_value [username] Username used in password grant
|
21
|
-
# @param_value [password] Password used in password grant
|
22
|
-
# @param_value [security_token] Security Token used in password grant
|
23
|
-
def oauth2(params)
|
24
|
-
# @!method oauth_obj Object to handle oauth2
|
25
|
-
define_method('oauth_obj') { OAuth2.new(params, api_username) }
|
26
|
-
# @!method access_token Retrieve OAuth2 access token
|
27
|
-
define_method('access_token') { oauth_obj.access_token }
|
28
|
-
# @!method instance_url Retrieve instance url from OAuth request
|
29
|
-
define_method('instance_url') { oauth_obj.response['instance_url'] }
|
30
|
-
end
|
31
|
-
|
32
|
-
# Pass path to YAML file containing OAuth2 parameters
|
33
|
-
# @param [String] path_to_filename Will have Soaspec.credentials_folder appended to it if set
|
34
|
-
def oauth2_file(path_to_filename)
|
35
|
-
full_path = Soaspec.credentials_folder ? File.join(Soaspec.credentials_folder, path_to_filename) : path_to_filename
|
36
|
-
full_path += '.yml' unless full_path.end_with?('.yml')
|
37
|
-
file_hash = YAML.load_file(full_path)
|
38
|
-
raise 'File at ' + full_path + ' is not a hash ' unless file_hash.is_a? Hash
|
39
|
-
oauth2 file_hash
|
40
|
-
end
|
41
|
-
|
42
|
-
# @param [Hash] headers Hash of REST headers used in RestClient
|
43
|
-
def headers(headers)
|
44
|
-
define_method('rest_client_headers') do
|
45
|
-
headers
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
# Convert each key from snake_case to PascalCase
|
50
|
-
def pascal_keys(set)
|
51
|
-
define_method('pascal_keys?') do
|
52
|
-
set
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|