smacks-savon 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|