smacks-savon 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.
- data/lib/savon/response.rb +102 -44
- data/lib/savon/service.rb +46 -43
- data/lib/savon/wsdl.rb +0 -5
- data/lib/savon.rb +1 -2
- data/test/fixtures/soap_response_fixture.rb +75 -0
- data/test/helper.rb +1 -1
- data/test/savon/response_test.rb +123 -110
- data/test/savon_test.rb +1 -2
- metadata +3 -5
- data/lib/savon/mash.rb +0 -61
- data/test/fixtures/soap_response.rb +0 -34
- data/test/savon/mash_test.rb +0 -18
data/lib/savon/response.rb
CHANGED
@@ -4,77 +4,135 @@ require "apricoteatsgorilla"
|
|
4
4
|
|
5
5
|
module Savon
|
6
6
|
|
7
|
-
# Savon::Response represents the HTTP response.
|
7
|
+
# Savon::Response validates and represents the HTTP/SOAP response.
|
8
8
|
class Response
|
9
9
|
|
10
|
-
# The
|
11
|
-
|
10
|
+
# The core (inherited) methods to shadow.
|
11
|
+
@@core_methods_to_shadow = [:id]
|
12
|
+
|
13
|
+
# Returns the core methods to shadow.
|
14
|
+
def self.core_methods_to_shadow
|
15
|
+
@@core_methods_to_shadow
|
16
|
+
end
|
12
17
|
|
13
|
-
#
|
18
|
+
# Sets the core +methods+ to shadow.
|
19
|
+
def self.core_methods_to_shadow=(methods)
|
20
|
+
@@core_methods_to_shadow = methods if methods.kind_of? Array
|
21
|
+
end
|
22
|
+
|
23
|
+
# Returns the error code.
|
14
24
|
attr_reader :error_code
|
15
25
|
|
16
|
-
#
|
17
|
-
|
18
|
-
|
19
|
-
#
|
20
|
-
#
|
21
|
-
|
22
|
-
|
23
|
-
|
26
|
+
# Returns the error message.
|
27
|
+
attr_reader :error_message
|
28
|
+
|
29
|
+
# Initializer expects the +source+ to initialize from. Sets up the instance
|
30
|
+
# from a given Net::HTTPResponse or a Hash depending on the given +source+.
|
31
|
+
# May be called with a custom +root_node+ to start parsing the response at
|
32
|
+
# in case the given +source+ is a Net::HTTPResponse.
|
33
|
+
def initialize(source, root_node = nil)
|
34
|
+
if source.kind_of? Hash
|
35
|
+
initialize_from_hash source
|
36
|
+
elsif source.respond_to? :body
|
37
|
+
initialize_from_response source, root_node
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Returns the value from a given +key+ from the response Hash.
|
42
|
+
def [](key)
|
43
|
+
value_from_hash(key)
|
24
44
|
end
|
25
45
|
|
26
|
-
# Returns true
|
46
|
+
# Returns +true+ in case the request was successful, +false+ otherwise
|
47
|
+
# or +nil+ in case there's no request at all.
|
27
48
|
def success?
|
49
|
+
return nil unless @response
|
28
50
|
@error_code.nil?
|
29
51
|
end
|
30
52
|
|
31
|
-
# Returns
|
53
|
+
# Returns +false+ in case the request was not successful, +false+ otherwise
|
54
|
+
# or +nil+ in case there's no request at all.
|
32
55
|
def error?
|
56
|
+
return nil unless @response
|
33
57
|
!@error_code.nil?
|
34
58
|
end
|
35
59
|
|
36
|
-
# Returns the
|
37
|
-
|
38
|
-
|
39
|
-
#
|
40
|
-
# === Parameters
|
41
|
-
#
|
42
|
-
# * +root_node+ - Optional. Custom root node to start parsing at.
|
43
|
-
def to_hash(root_node = "//return")
|
44
|
-
return nil if error?
|
45
|
-
ApricotEatsGorilla[@response.body, root_node]
|
60
|
+
# Returns the response Hash.
|
61
|
+
def to_hash
|
62
|
+
@hash
|
46
63
|
end
|
47
64
|
|
48
|
-
# Returns the
|
49
|
-
# XPath expession to define a custom +root_node+. Defaults to "//return".
|
50
|
-
# The root node will not be included in the Mash object.
|
51
|
-
#
|
52
|
-
# === Parameters
|
53
|
-
#
|
54
|
-
# * +root_node+ - Optional. Custom root node to start parsing at.
|
55
|
-
def to_mash(root_node = "//return")
|
56
|
-
return nil if error?
|
57
|
-
hash = to_hash(root_node)
|
58
|
-
Savon::Mash.new(hash)
|
59
|
-
end
|
60
|
-
|
61
|
-
# Returns the SOAP response XML.
|
65
|
+
# Returns the response body in case there is any, +nil+ otherwise.
|
62
66
|
def to_s
|
67
|
+
return nil unless @response
|
63
68
|
@response.body
|
64
69
|
end
|
65
70
|
|
71
|
+
# Intercepts calls to missing methods and returns values from the response
|
72
|
+
# Hash in case the name of the missing +method+ matches one of its key.
|
73
|
+
# Returns a new Savon::Response instance containing the value or returns
|
74
|
+
# the actual value in case it is not a Hash.
|
75
|
+
def method_missing(method, *args)
|
76
|
+
value = value_from_hash method
|
77
|
+
return value unless value.kind_of? Hash
|
78
|
+
Savon::Response.new value
|
79
|
+
end
|
80
|
+
|
66
81
|
private
|
67
82
|
|
68
|
-
#
|
69
|
-
|
83
|
+
# Initializes the instance from a Net::HTTPResponse. Validates the +response+
|
84
|
+
# against HTTP errors and SOAP faults. Continues to translate the response
|
85
|
+
# body into a Hash and delegates to initializing the instance from this Hash
|
86
|
+
# in case the request was successful. An optional +root_node+ to start parsing
|
87
|
+
# the response at might be supplied.
|
88
|
+
def initialize_from_response(response, root_node = nil)
|
89
|
+
@response = response
|
90
|
+
validate_response
|
91
|
+
|
92
|
+
if success?
|
93
|
+
root_node ||= "//return"
|
94
|
+
hash = ApricotEatsGorilla[@response.body, root_node]
|
95
|
+
initialize_from_hash hash
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# Initializes the instance from a given +hash+.
|
100
|
+
def initialize_from_hash(hash)
|
101
|
+
@hash = hash
|
102
|
+
shadow_core_methods
|
103
|
+
end
|
104
|
+
|
105
|
+
# Validates the response against HTTP errors and SOAP faults and sets the
|
106
|
+
# +error_code+ and +error_message+ in case the request was not successful.
|
107
|
+
def validate_response
|
70
108
|
if @response.code.to_i >= 300
|
71
|
-
@error_message
|
109
|
+
@error_message = @response.message
|
110
|
+
@error_code = @response.code
|
72
111
|
else
|
73
|
-
soap_fault =
|
74
|
-
|
75
|
-
|
112
|
+
soap_fault = ApricotEatsGorilla[@response.body, "//soap:Fault"]
|
113
|
+
unless soap_fault.nil?
|
114
|
+
@error_message = soap_fault[:faultstring]
|
115
|
+
@error_code = soap_fault[:faultcode]
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
# Dynamically defines methods from the Array of +@@core_methods_to_shadow+
|
121
|
+
# to "shadow" inherited methods. Returns a value from the response Hash in
|
122
|
+
# case a matching public method and a key from the Hash could be found.
|
123
|
+
def shadow_core_methods
|
124
|
+
@@core_methods_to_shadow.each do |method|
|
125
|
+
if self.public_methods.include?(method.to_s) && value_from_hash(method)
|
126
|
+
self.class.send(:define_method, method) { value_from_hash(method) }
|
127
|
+
end
|
76
128
|
end
|
77
129
|
end
|
78
130
|
|
131
|
+
# Returns a value from the response Hash. Tries to convert the given +key+
|
132
|
+
# into a Symbol or a String to find the value to return.
|
133
|
+
def value_from_hash(key)
|
134
|
+
@hash[key.to_sym] || @hash[key.to_s]
|
135
|
+
end
|
136
|
+
|
79
137
|
end
|
80
138
|
end
|
data/lib/savon/service.rb
CHANGED
@@ -14,24 +14,23 @@ module Savon
|
|
14
14
|
# of options for the service method to receive.
|
15
15
|
class Service
|
16
16
|
|
17
|
-
# The logger to use.
|
17
|
+
# The logger instance to use.
|
18
18
|
@@logger = nil
|
19
19
|
|
20
|
-
#
|
21
|
-
|
22
|
-
|
23
|
-
#
|
24
|
-
#
|
25
|
-
# * +endpoint+ - WSDL endpoint URI to use.
|
20
|
+
# The log level to use.
|
21
|
+
@@log_level = :debug
|
22
|
+
|
23
|
+
# Initializer expects the WSDL +endpoint+ URI and defines nodes to
|
24
|
+
# namespace for Apricot eats Gorilla.
|
26
25
|
def initialize(endpoint)
|
27
26
|
@uri = URI(endpoint)
|
28
27
|
ApricotEatsGorilla.nodes_to_namespace = wsdl.choice_elements
|
29
28
|
ApricotEatsGorilla.node_namespace = "wsdl"
|
30
29
|
end
|
31
30
|
|
32
|
-
# Returns an instance of the
|
31
|
+
# Returns an instance of the Savon::Wsdl.
|
33
32
|
def wsdl
|
34
|
-
@wsdl = Savon::Wsdl.new(@uri, http)
|
33
|
+
@wsdl = Savon::Wsdl.new(@uri, http) unless @wsdl
|
35
34
|
@wsdl
|
36
35
|
end
|
37
36
|
|
@@ -40,73 +39,77 @@ module Savon
|
|
40
39
|
@http = http
|
41
40
|
end
|
42
41
|
|
43
|
-
# Sets the logger to use.
|
42
|
+
# Sets the logger instance to use.
|
44
43
|
def self.logger=(logger)
|
45
44
|
@@logger = logger
|
46
45
|
end
|
47
46
|
|
47
|
+
# Sets the log level to use.
|
48
|
+
def self.log_level=(log_level)
|
49
|
+
@@log_level = log_level
|
50
|
+
end
|
51
|
+
|
48
52
|
private
|
49
53
|
|
50
|
-
#
|
51
|
-
def
|
52
|
-
headers = { "Content-Type" => "text/xml; charset=utf-8", "SOAPAction" => @
|
54
|
+
# Constructs and dispatches the SOAP request. Returns a Savon::Response.
|
55
|
+
def dispatch(root_node = nil)
|
56
|
+
headers = { "Content-Type" => "text/xml; charset=utf-8", "SOAPAction" => @soap_action }
|
53
57
|
|
54
58
|
body = ApricotEatsGorilla.soap_envelope("wsdl" => wsdl.namespace_uri) do
|
55
|
-
ApricotEatsGorilla["wsdl:#{@
|
59
|
+
ApricotEatsGorilla["wsdl:#{@soap_action}" => @options]
|
56
60
|
end
|
57
61
|
|
58
62
|
debug do |logger|
|
59
|
-
logger.
|
60
|
-
logger.
|
61
|
-
logger.
|
63
|
+
logger.send @@log_level, "Requesting #{@uri}"
|
64
|
+
logger.send @@log_level, headers.map { |key, value| "#{key}: #{value}" }.join("\n")
|
65
|
+
logger.send @@log_level, body
|
62
66
|
end
|
63
|
-
response =
|
67
|
+
response = http.request_post(@uri.path, body, headers)
|
64
68
|
debug do |logger|
|
65
|
-
logger.
|
66
|
-
logger.
|
69
|
+
logger.send @@log_level, "Response (Status #{response.code}):"
|
70
|
+
logger.send @@log_level, response.body
|
67
71
|
end
|
68
|
-
Savon::Response.new
|
72
|
+
Savon::Response.new response, root_node
|
69
73
|
end
|
70
74
|
|
71
75
|
# Returns the Net::HTTP instance to use.
|
72
76
|
def http
|
73
77
|
if @http.nil?
|
74
|
-
raise ArgumentError, "Invalid endpoint URI" unless @uri.scheme
|
78
|
+
raise ArgumentError, "Invalid endpoint URI: #{@uri}" unless @uri.scheme
|
75
79
|
@http = Net::HTTP.new(@uri.host, @uri.port)
|
76
80
|
end
|
77
81
|
@http
|
78
82
|
end
|
79
83
|
|
80
|
-
# Checks if the requested SOAP
|
81
|
-
# Raises an ArgumentError in case it
|
82
|
-
def
|
83
|
-
unless wsdl.service_methods.include? @
|
84
|
-
raise ArgumentError, "Invalid service method
|
84
|
+
# Checks if the requested SOAP action was found on the WSDL.
|
85
|
+
# Raises an ArgumentError in case it was not found.
|
86
|
+
def validate_soap_action
|
87
|
+
unless wsdl.service_methods.include? @soap_action
|
88
|
+
raise ArgumentError, "Invalid service method: #{@soap_action}"
|
85
89
|
end
|
86
90
|
end
|
87
91
|
|
88
|
-
# Logs a given +message+ using the
|
89
|
-
# to a given +block+ for logging multiple
|
92
|
+
# Logs a given +message+ using the +@@logger+ instance or yields the logger
|
93
|
+
# to a given +block+ for logging multiple messages at once.
|
90
94
|
def debug(message = nil)
|
91
95
|
if @@logger
|
92
|
-
@@logger.
|
96
|
+
@@logger.send(@@log_level, message) if message
|
93
97
|
yield @@logger if block_given?
|
94
98
|
end
|
95
99
|
end
|
96
100
|
|
97
|
-
#
|
98
|
-
# is the default way of calling a SOAP
|
99
|
-
#
|
100
|
-
#
|
101
|
-
#
|
102
|
-
#
|
103
|
-
#
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
call_service
|
101
|
+
# Catches SOAP actions called on the Savon::Service instance.
|
102
|
+
# This is the default way of calling a SOAP action.
|
103
|
+
#
|
104
|
+
# The given +method+ will be validated against available SOAP actions found
|
105
|
+
# on the WSDL and dispatched if available. Options for the SOAP action to
|
106
|
+
# receive can be given through the optional Hash of +options+. A custom
|
107
|
+
# +root_node+ to start parsing the SOAP response at might be supplied as well.
|
108
|
+
def method_missing(method, options = {}, root_node = nil)
|
109
|
+
@soap_action = ApricotEatsGorilla.to_lower_camel_case(method)
|
110
|
+
@options = options
|
111
|
+
validate_soap_action
|
112
|
+
dispatch(root_node)
|
110
113
|
end
|
111
114
|
|
112
115
|
end
|
data/lib/savon/wsdl.rb
CHANGED
@@ -18,11 +18,6 @@ module Savon
|
|
18
18
|
|
19
19
|
# Initializer expects an endpoint +uri+ and an +http+ connection instance,
|
20
20
|
# then gets and parses the WSDL at the given URI.
|
21
|
-
#
|
22
|
-
# === Parameters
|
23
|
-
#
|
24
|
-
# * +uri+ - The URI of the WSDL.
|
25
|
-
# * +http+ - The Net::HTTP connection instance to use.
|
26
21
|
def initialize(uri, http)
|
27
22
|
@uri, @http = uri, http
|
28
23
|
get_wsdl
|
data/lib/savon.rb
CHANGED
@@ -0,0 +1,75 @@
|
|
1
|
+
module SoapResponseFixture
|
2
|
+
|
3
|
+
def some_response_hash
|
4
|
+
{
|
5
|
+
:authentication => {
|
6
|
+
:user => "example",
|
7
|
+
:password => "secret"
|
8
|
+
},
|
9
|
+
:success => true,
|
10
|
+
:tokens => ["abc", "xyz", "123"]
|
11
|
+
}
|
12
|
+
end
|
13
|
+
|
14
|
+
def response_hash_with_id
|
15
|
+
some_response_hash.dup.update :id => "shadow_id"
|
16
|
+
end
|
17
|
+
|
18
|
+
def response_hash_with_inspect
|
19
|
+
some_response_hash.dup.update :inspect => "shadow_inspect"
|
20
|
+
end
|
21
|
+
|
22
|
+
def some_soap_response
|
23
|
+
build_soap_response
|
24
|
+
end
|
25
|
+
|
26
|
+
def soap_response_with_id
|
27
|
+
build_soap_response '<id>shadow_id</id>'
|
28
|
+
end
|
29
|
+
|
30
|
+
def soap_response_with_inspect
|
31
|
+
build_soap_response '<inspect>shadow_inspect</inspect>'
|
32
|
+
end
|
33
|
+
|
34
|
+
def soap_fault_response
|
35
|
+
'<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">' <<
|
36
|
+
'<soap:Body>' <<
|
37
|
+
'<soap:Fault>' <<
|
38
|
+
'<faultcode>' << soap_fault_code << '</faultcode>' <<
|
39
|
+
'<faultstring>' << soap_fault << '</faultstring>' <<
|
40
|
+
'</soap:Fault>' <<
|
41
|
+
'</soap:Body>' <<
|
42
|
+
'</soap:Envelope>'
|
43
|
+
end
|
44
|
+
|
45
|
+
def soap_fault
|
46
|
+
"Failed to authenticate client."
|
47
|
+
end
|
48
|
+
|
49
|
+
def soap_fault_code
|
50
|
+
"soap:Server"
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def build_soap_response(mixin = "")
|
56
|
+
'<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">' <<
|
57
|
+
'<soap:Body>' <<
|
58
|
+
'<ns2:result xmlns:ns2="http://example.com/">' <<
|
59
|
+
'<return>' <<
|
60
|
+
'<authentication>' <<
|
61
|
+
'<user>example</user>' <<
|
62
|
+
'<password>secret</password>' <<
|
63
|
+
'</authentication>' <<
|
64
|
+
mixin <<
|
65
|
+
'<success>true</success>' <<
|
66
|
+
'<tokens>abc</tokens>' <<
|
67
|
+
'<tokens>xyz</tokens>' <<
|
68
|
+
'<tokens>123</tokens>' <<
|
69
|
+
'</return>' <<
|
70
|
+
'</ns2:result>' <<
|
71
|
+
'</soap:Body>' <<
|
72
|
+
'</soap:Envelope>'
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
data/test/helper.rb
CHANGED
@@ -6,7 +6,7 @@ require "apricoteatsgorilla"
|
|
6
6
|
|
7
7
|
require File.join(File.dirname(__FILE__), "..", "lib", "savon")
|
8
8
|
require File.join(File.dirname(__FILE__), "factories", "wsdl")
|
9
|
-
require File.join(File.dirname(__FILE__), "fixtures", "
|
9
|
+
require File.join(File.dirname(__FILE__), "fixtures", "soap_response_fixture")
|
10
10
|
|
11
11
|
module TestHelper
|
12
12
|
|
data/test/savon/response_test.rb
CHANGED
@@ -5,116 +5,129 @@ class SavonResponseTest < Test::Unit::TestCase
|
|
5
5
|
include TestHelper
|
6
6
|
include SoapResponseFixture
|
7
7
|
|
8
|
-
context "Savon::Response
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
8
|
+
context "A Savon::Response instance" do
|
9
|
+
|
10
|
+
context "initialized with a Net::HTTPResponse containing a successful SOAP response" do
|
11
|
+
setup do
|
12
|
+
ApricotEatsGorilla.sort_keys = true
|
13
|
+
Savon::Response.core_methods_to_shadow = [:id] # set to default
|
14
|
+
@response = Savon::Response.new response_mock(some_soap_response)
|
15
|
+
end
|
16
|
+
|
17
|
+
should "return that the request was successful" do
|
18
|
+
assert_equal true, @response.success?
|
19
|
+
assert_equal false, @response.error?
|
20
|
+
end
|
21
|
+
|
22
|
+
should "return nil for error_code and error_message" do
|
23
|
+
assert_nil @response.error_code
|
24
|
+
assert_nil @response.error_message
|
25
|
+
end
|
26
|
+
|
27
|
+
should "return the SOAP response XML when calling to_s" do
|
28
|
+
assert_equal some_soap_response, @response.to_s
|
29
|
+
end
|
30
|
+
|
31
|
+
should "return the Hash translated from the SOAP response XML when calling to_hash" do
|
32
|
+
assert_kind_of Hash, @response.to_hash
|
33
|
+
assert_equal some_response_hash, @response.to_hash
|
34
|
+
end
|
35
|
+
|
36
|
+
should "return a Hash for Hash values accessed through []" do
|
37
|
+
assert_kind_of Hash, @response[:authentication]
|
38
|
+
assert_equal some_response_hash[:authentication], @response[:authentication]
|
39
|
+
end
|
40
|
+
|
41
|
+
should "return the actual value for values other than Hashes through []" do
|
42
|
+
assert_kind_of TrueClass, @response[:success]
|
43
|
+
assert_kind_of Array, @response[:tokens]
|
44
|
+
assert_equal some_response_hash[:success], @response[:success]
|
45
|
+
assert_equal some_response_hash[:tokens], @response[:tokens]
|
46
|
+
end
|
47
|
+
|
48
|
+
should "return nil when trying to access a not-existing key from the Hash" do
|
49
|
+
assert_nil @response.some_undefined_key
|
50
|
+
end
|
51
|
+
|
52
|
+
should "return a Savon::Response for Hash values accessed through method_missing" do
|
53
|
+
assert_kind_of Savon::Response, @response.authentication
|
54
|
+
end
|
55
|
+
|
56
|
+
should "return the actual value for values other than Hashes through method_missing" do
|
57
|
+
assert_kind_of TrueClass, @response.success
|
58
|
+
assert_kind_of Array, @response.tokens
|
59
|
+
assert_equal some_response_hash[:success], @response.success
|
60
|
+
assert_equal some_response_hash[:tokens], @response.tokens
|
61
|
+
end
|
62
|
+
|
63
|
+
should "by default shadow the :id method if it was found in the Hash" do
|
64
|
+
response_with_id = Savon::Response.new response_mock(soap_response_with_id)
|
65
|
+
assert_equal response_hash_with_id[:id], response_with_id.id
|
66
|
+
end
|
67
|
+
|
68
|
+
should "shadow user-specified core methods in case they were found in the Hash" do
|
69
|
+
Savon::Response.core_methods_to_shadow = [:inspect]
|
70
|
+
response_with_inspect = Savon::Response.new response_mock(soap_response_with_inspect)
|
71
|
+
|
72
|
+
assert_equal response_hash_with_inspect[:inspect], response_with_inspect.inspect
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context "initialized with a Hash" do
|
77
|
+
setup do
|
78
|
+
ApricotEatsGorilla.sort_keys = true
|
79
|
+
Savon::Response.core_methods_to_shadow = [:id] # set to default
|
80
|
+
@response = Savon::Response.new some_response_hash
|
81
|
+
end
|
82
|
+
|
83
|
+
should "return nil for HTTP::Response-specific methods" do
|
84
|
+
assert_nil @response.success?
|
85
|
+
assert_nil @response.error?
|
86
|
+
assert_nil @response.error_code
|
87
|
+
assert_nil @response.error_message
|
88
|
+
assert_nil @response.to_s
|
89
|
+
end
|
90
|
+
|
91
|
+
should "return the given Hash when calling to_hash" do
|
92
|
+
assert_kind_of Hash, @response.to_hash
|
93
|
+
assert_equal some_response_hash, @response.to_hash
|
94
|
+
end
|
95
|
+
|
96
|
+
should "return a Hash for Hash values accessed through []" do
|
97
|
+
assert_kind_of Hash, @response[:authentication]
|
98
|
+
assert_equal some_response_hash[:authentication], @response[:authentication]
|
99
|
+
end
|
100
|
+
|
101
|
+
should "return the actual value for values other than Hashes through []" do
|
102
|
+
assert_kind_of TrueClass, @response[:success]
|
103
|
+
assert_kind_of Array, @response[:tokens]
|
104
|
+
assert_equal some_response_hash[:success], @response[:success]
|
105
|
+
assert_equal some_response_hash[:tokens], @response[:tokens]
|
106
|
+
end
|
107
|
+
|
108
|
+
should "return a Savon::Response for Hash values accessed through method_missing" do
|
109
|
+
assert_kind_of Savon::Response, @response.authentication
|
110
|
+
end
|
111
|
+
|
112
|
+
should "return the actual value for values other than Hashes through method_missing" do
|
113
|
+
assert_kind_of TrueClass, @response.success
|
114
|
+
assert_kind_of Array, @response.tokens
|
115
|
+
assert_equal some_response_hash[:success], @response.success
|
116
|
+
assert_equal some_response_hash[:tokens], @response.tokens
|
117
|
+
end
|
118
|
+
|
119
|
+
should "by default shadow the :id method if it was found in the Hash" do
|
120
|
+
hash_with_id = response_hash_with_id
|
121
|
+
@response = Savon::Response.new hash_with_id
|
122
|
+
assert_equal hash_with_id[:id], @response.id
|
123
|
+
end
|
124
|
+
|
125
|
+
should "shadow user-specified core methods in case they were found in the Hash" do
|
126
|
+
Savon::Response.core_methods_to_shadow = [:inspect]
|
127
|
+
response_with_inspect = Savon::Response.new response_hash_with_inspect
|
128
|
+
|
129
|
+
assert_equal response_hash_with_inspect[:inspect], response_with_inspect.inspect
|
130
|
+
end
|
118
131
|
end
|
119
132
|
|
120
133
|
end
|
data/test/savon_test.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: smacks-savon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Harrington
|
@@ -30,7 +30,7 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.4.
|
33
|
+
version: 0.4.3
|
34
34
|
version:
|
35
35
|
description: Ruby SOAP client library to enjoy.
|
36
36
|
email:
|
@@ -46,7 +46,6 @@ files:
|
|
46
46
|
- lib/savon/service.rb
|
47
47
|
- lib/savon/wsdl.rb
|
48
48
|
- lib/savon/response.rb
|
49
|
-
- lib/savon/mash.rb
|
50
49
|
has_rdoc: true
|
51
50
|
homepage: http://github.com/smacks/savon
|
52
51
|
post_install_message:
|
@@ -78,8 +77,7 @@ test_files:
|
|
78
77
|
- test/savon_test.rb
|
79
78
|
- test/helper.rb
|
80
79
|
- test/factories/wsdl.rb
|
81
|
-
- test/fixtures/
|
80
|
+
- test/fixtures/soap_response_fixture.rb
|
82
81
|
- test/savon/service_test.rb
|
83
82
|
- test/savon/response_test.rb
|
84
83
|
- test/savon/wsdl_test.rb
|
85
|
-
- test/savon/mash_test.rb
|
data/lib/savon/mash.rb
DELETED
@@ -1,61 +0,0 @@
|
|
1
|
-
module Savon
|
2
|
-
|
3
|
-
# Savon::Mash converts a given Hash into an Object.
|
4
|
-
class Mash
|
5
|
-
|
6
|
-
# Iterates through a given +hash+, stores each value in an instance
|
7
|
-
# variable and creates getter and setter methods.
|
8
|
-
#
|
9
|
-
# === Parameters
|
10
|
-
#
|
11
|
-
# * +hash+ - The Hash to convert.
|
12
|
-
def initialize(hash)
|
13
|
-
hash.each do |key,value|
|
14
|
-
value = Savon::Mash.new(value) if value.is_a? Hash
|
15
|
-
|
16
|
-
if value.is_a? Array
|
17
|
-
value = value.map do |item|
|
18
|
-
if item.is_a?(Hash) then Savon::Mash.new(item) else item end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
set_instance_variable(key, value)
|
23
|
-
define_reader(key)
|
24
|
-
define_writer(key)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
private
|
29
|
-
|
30
|
-
# Sets and instance variable with a given +name+ and +value+.
|
31
|
-
#
|
32
|
-
# === Parameters
|
33
|
-
#
|
34
|
-
# * +name+ - Name of the instance variable.
|
35
|
-
# * +value+ - Value of the instance variable.
|
36
|
-
def set_instance_variable(name, value)
|
37
|
-
self.instance_variable_set("@#{name}", value)
|
38
|
-
end
|
39
|
-
|
40
|
-
# Defines a reader method for a given instance +variable+.
|
41
|
-
#
|
42
|
-
# === Parameters
|
43
|
-
#
|
44
|
-
# * +variable+ - Name of the instance variable.
|
45
|
-
def define_reader(variable)
|
46
|
-
method = proc { self.instance_variable_get("@#{variable}") }
|
47
|
-
self.class.send(:define_method, variable, method)
|
48
|
-
end
|
49
|
-
|
50
|
-
# Defines a writer method for a given instance +variable+.
|
51
|
-
#
|
52
|
-
# === Parameters
|
53
|
-
#
|
54
|
-
# * +variable+ - Name of the instance variable.
|
55
|
-
def define_writer(variable)
|
56
|
-
method = proc { |value| self.instance_variable_set("@#{variable}", value) }
|
57
|
-
self.class.send(:define_method, "#{variable}=", method)
|
58
|
-
end
|
59
|
-
|
60
|
-
end
|
61
|
-
end
|
@@ -1,34 +0,0 @@
|
|
1
|
-
module SoapResponseFixture
|
2
|
-
|
3
|
-
def some_soap_response
|
4
|
-
'<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">' <<
|
5
|
-
'<soap:Body>' <<
|
6
|
-
'<ns2:result xmlns:ns2="http://example.com/">' <<
|
7
|
-
'<return>' <<
|
8
|
-
'<token>secret</token>' <<
|
9
|
-
'</return>' <<
|
10
|
-
'</ns2:result>' <<
|
11
|
-
'</soap:Body>' <<
|
12
|
-
'</soap:Envelope>'
|
13
|
-
end
|
14
|
-
|
15
|
-
def soap_fault_response
|
16
|
-
'<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">' <<
|
17
|
-
'<soap:Body>' <<
|
18
|
-
'<soap:Fault>' <<
|
19
|
-
'<faultcode>' << soap_fault_code << '</faultcode>' <<
|
20
|
-
'<faultstring>' << soap_fault << '</faultstring>' <<
|
21
|
-
'</soap:Fault>' <<
|
22
|
-
'</soap:Body>' <<
|
23
|
-
'</soap:Envelope>'
|
24
|
-
end
|
25
|
-
|
26
|
-
def soap_fault
|
27
|
-
"Failed to authenticate client."
|
28
|
-
end
|
29
|
-
|
30
|
-
def soap_fault_code
|
31
|
-
"soap:Server"
|
32
|
-
end
|
33
|
-
|
34
|
-
end
|
data/test/savon/mash_test.rb
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), "..", "helper")
|
2
|
-
|
3
|
-
class SavonMashTest < Test::Unit::TestCase
|
4
|
-
|
5
|
-
context "Creating a new Savon::Mash" do
|
6
|
-
context "with a simple Hash" do
|
7
|
-
should "return a Mash object matching the given Hash" do
|
8
|
-
hash = { :some => { :simple => "test" } }
|
9
|
-
mash = Savon::Mash.new(hash)
|
10
|
-
|
11
|
-
assert_respond_to(mash, :some)
|
12
|
-
assert_respond_to(mash, :simple)
|
13
|
-
assert_equal "test", mash.some.simple
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
end
|