smacks-savon 0.0.91 → 0.1.0

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/README.rdoc CHANGED
@@ -1,11 +1,12 @@
1
1
  = Savon
2
2
 
3
- Savon is a lightweight SOAP client.
3
+ Ruby SOAP client library to enjoy.
4
4
 
5
- Instantiate Savon::Service and pass in the WSDL of the service you would
6
- like to use. Then just call the SOAP service method on your Savon::Service
7
- instance (catched via method_missing) and pass in a Hash of options for the
8
- service method to receive.
5
+ Communicating with a SOAP webservice can be done in two lines of code.
6
+ Instantiate a new Savon::Service passing in the URI to the WSDL of the
7
+ service you would like to use. Then call the SOAP service method on your
8
+ Savon::Service instance (catched via method_missing) and pass in a Hash
9
+ of options for the service method to receive.
9
10
 
10
11
  == Install
11
12
 
@@ -14,43 +15,66 @@ service method to receive.
14
15
  == Dependencies
15
16
 
16
17
  hpricot 0.6.164 (also available for JRuby)
17
- smacks-apricoteatsgorilla >= 0.3.5
18
+ smacks-apricoteatsgorilla >= 0.4.1
18
19
 
19
20
  == How to use
20
21
 
21
- === Usage example
22
+ Instantiate a new Savon::Service instance passing in the WSDL of your service.
22
23
 
23
24
  proxy = Savon::Service.new "http://example.com/ExampleService?wsdl"
25
+
26
+ Call the SOAP service method you would like to choose on your Savon::Service
27
+ instance passing in a Hash of options for the service method to receive.
28
+
24
29
  response = proxy.findExampleById(:id => 123)
25
30
 
26
31
  === Check for available SOAP service methods
27
32
 
33
+ You can use the service_methods method of the WSDL in your Savon::Service
34
+ instance to get a list of available SOAP service methods.
35
+
28
36
  proxy.wsdl.service_methods
29
37
  # => [ "findExampleById", "findExampleByName" ]
30
38
 
31
- === Checking for HTTP and SOAP faults
39
+ === Handle HTTP and SOAP errors
40
+
41
+ Check if the SOAP request was successful.
32
42
 
33
43
  response.success?
34
44
  response.fault?
35
45
 
36
- === Access the fault message and code
46
+ Access the fault message and code.
37
47
 
38
48
  response.fault
39
49
  response.fault_code
40
50
 
41
- === Working with different response formats
51
+ === Different response formats
42
52
 
43
- # raw XML response:
53
+ To work with the response of the service you need to convert the response
54
+ object using one of the following methods.
55
+
56
+ # SOAP response XML:
44
57
  response.to_s
45
58
 
46
59
  # response as a Hash
47
60
  response.to_hash
48
61
 
49
- # response as a Hash starting at a custom root node (via XPath)
50
- response.to_hash("//item")
51
-
52
62
  # response as a Mash
53
63
  response.to_mash
54
64
 
55
- # response as a Mash starting at a custom root node (via XPath)
56
- response.to_mash("//user/email")
65
+ The to_hash and to_mash methods accept an XPath expression (Hpricot search)
66
+ as second parameter to define a custom root node to start translating the
67
+ response XML at.
68
+
69
+ # response as a Hash starting at a custom root node
70
+ response.to_hash("//item")
71
+
72
+ # response as a Mash starting at a custom root node
73
+ response.to_mash("//user/email")
74
+
75
+ === Logging request and response
76
+
77
+ You should specify the logger to use before working with any services.
78
+
79
+ # example for Ruby on Rails
80
+ Savon::Service.logger = RAILS_DEFAULT_LOGGER
data/lib/savon/mash.rb CHANGED
@@ -3,8 +3,8 @@ module Savon
3
3
  # Savon::Mash converts a given Hash into an Object.
4
4
  class Mash
5
5
 
6
- # Loops through a given +hash+, stores each value in an instance variable
7
- # and creates getter and setter methods.
6
+ # Iterates through a given +hash+, stores each value in an instance
7
+ # variable and creates getter and setter methods.
8
8
  #
9
9
  # === Parameters
10
10
  #
@@ -19,9 +19,9 @@ module Savon
19
19
  end
20
20
  end
21
21
 
22
- set_instance_variable key, value
23
- define_reader key
24
- define_writer key
22
+ set_instance_variable(key, value)
23
+ define_reader(key)
24
+ define_writer(key)
25
25
  end
26
26
  end
27
27
 
@@ -5,42 +5,15 @@ require "apricoteatsgorilla"
5
5
  module Savon
6
6
 
7
7
  # Savon::Response represents the HTTP response.
8
- #
9
- # === Checking for HTTP and SOAP faults
10
- #
11
- # response.success?
12
- # response.fault?
13
- #
14
- # === Access the fault message and code
15
- #
16
- # response.fault
17
- # response.fault_code
18
- #
19
- # === Different response formats
20
- #
21
- # # raw XML response:
22
- # response.to_s
23
- #
24
- # # response as a Hash
25
- # response.to_hash
26
- #
27
- # # response as a Hash starting at a custom root node (via XPath)
28
- # response.to_hash("//item")
29
- #
30
- # # response as a Mash
31
- # response.to_mash
32
- #
33
- # # response as a Mash starting at a custom root node (via XPath)
34
- # response.to_mash("//user/email")
35
8
  class Response
36
9
 
37
- # The HTTP/SOAP fault.
10
+ # The HTTP or SOAP fault message.
38
11
  attr_reader :fault
39
12
 
40
- # The HTTP/SOAP fault code.
13
+ # The HTTP or SOAP fault code.
41
14
  attr_reader :fault_code
42
15
 
43
- # Initializer to set the SOAP response.
16
+ # Initializer expects the HTTP response and checks for HTTP or SOAP faults.
44
17
  #
45
18
  # === Parameters
46
19
  #
@@ -55,18 +28,18 @@ module Savon
55
28
  @fault_code.nil?
56
29
  end
57
30
 
58
- # Returns true if the request was not successful, false otherwise.
31
+ # Returns true if there was a HTTP or SOAP fault, false otherwise.
59
32
  def fault?
60
33
  !@fault_code.nil?
61
34
  end
62
35
 
63
36
  # Returns the SOAP response message as a Hash. Call with XPath expession
64
- # to define a custom +root_node+ to start parsing at. Defaults to "//return".
65
- # The root node itself will not be included in the Hash.
37
+ # (Hpricot search) to define a custom +root_node+ to start parsing at.
38
+ # Defaults to "//return". The root node will not be included in the Hash.
66
39
  #
67
40
  # === Parameters
68
41
  #
69
- # * +root_node+ - Optional. Custom root node to start parsing at. Defaults to "//return".
42
+ # * +root_node+ - Optional. Custom root node to start parsing at.
70
43
  def to_hash(root_node = "//return")
71
44
  return nil if fault?
72
45
  ApricotEatsGorilla[@response.body, root_node]
@@ -74,25 +47,25 @@ module Savon
74
47
 
75
48
  # Returns the SOAP response message as a Savon::Mash object. Call with
76
49
  # XPath expession to define a custom +root_node+. Defaults to "//return".
77
- # The root node itself will not be included in the Mash object.
50
+ # The root node will not be included in the Mash object.
78
51
  #
79
52
  # === Parameters
80
53
  #
81
- # * +root_node+ - Optional. Custom root node to start parsing at. Defaults to "//return".
54
+ # * +root_node+ - Optional. Custom root node to start parsing at.
82
55
  def to_mash(root_node = "//return")
83
56
  return nil if fault?
84
57
  hash = to_hash(root_node)
85
58
  Savon::Mash.new(hash)
86
59
  end
87
60
 
88
- # Returns the raw XML response.
61
+ # Returns the SOAP response XML.
89
62
  def to_s
90
63
  @response.body
91
64
  end
92
65
 
93
66
  private
94
67
 
95
- # Checks for and stores HTTP and SOAP fault errors.
68
+ # Checks for HTTP and SOAP faults.
96
69
  def validate
97
70
  if @response.code.to_i >= 300
98
71
  @fault, @fault_code = @response.message, @response.code
data/lib/savon/service.rb CHANGED
@@ -5,54 +5,28 @@ require "apricoteatsgorilla"
5
5
 
6
6
  module Savon
7
7
 
8
- # Savon is a lightweight SOAP client.
8
+ # Ruby SOAP client library to enjoy.
9
9
  #
10
- # Instantiate Savon::Service and pass in the WSDL of the service you would
11
- # like to use. Then just call the SOAP service method on your Savon::Service
12
- # instance (catched via method_missing) and pass in a Hash of options for the
13
- # service method to receive.
14
- #
15
- # === Usage example
16
- #
17
- # proxy = Savon::Service.new "http://example.com/ExampleService?wsdl"
18
- # response = proxy.findExampleById(:id => 123)
19
- #
20
- # === Check for available SOAP service methods
21
- #
22
- # proxy.wsdl.service_methods
23
- # # => [ "findExampleById", "findExampleByName" ]
24
- #
25
- # === Working with different response formats
26
- #
27
- # # raw XML response:
28
- # response.to_s
29
- #
30
- # # response as a Hash
31
- # response.to_hash
32
- #
33
- # # response as a Hash starting at a custom root node (via XPath)
34
- # response.to_hash("//item")
35
- #
36
- # # response as a Mash
37
- # response.to_mash
38
- #
39
- # # response as a Mash starting at a custom root node (via XPath)
40
- # response.to_mash("//user/email")
10
+ # Communicating with a SOAP webservice can be done in two lines of code.
11
+ # Instantiate a new Savon::Service passing in the URI to the WSDL of the
12
+ # service you would like to use. Then call the SOAP service method on your
13
+ # Savon::Service instance (catched via method_missing) and pass in a Hash
14
+ # of options for the service method to receive.
41
15
  class Service
42
16
 
43
17
  # The logger to use.
44
18
  @@logger = nil
45
19
 
46
- # The Net::HTTP connection instance to use.
47
- attr_writer :http
48
-
49
- # Initializer sets the WSDL +endpoint+ URI.
20
+ # Initializer expects the WSDL +endpoint+ URI to use and sets up
21
+ # Apricot eats Gorilla.
50
22
  #
51
23
  # ==== Parameters
52
24
  #
53
- # * +endpoint+ - The WSDL endpoint URI.
25
+ # * +endpoint+ - WSDL endpoint URI to use.
54
26
  def initialize(endpoint)
55
27
  @uri = URI(endpoint)
28
+ ApricotEatsGorilla.nodes_to_namespace = wsdl.choice_elements
29
+ ApricotEatsGorilla.node_namespace = "wsdl"
56
30
  end
57
31
 
58
32
  # Returns an instance of the WSDL.
@@ -61,6 +35,11 @@ module Savon
61
35
  @wsdl
62
36
  end
63
37
 
38
+ # Sets the Net::HTTP instance to use.
39
+ def http=(http)
40
+ @http = http
41
+ end
42
+
64
43
  # Sets the logger to use.
65
44
  def self.logger=(logger)
66
45
  @@logger = logger
@@ -68,20 +47,16 @@ module Savon
68
47
 
69
48
  private
70
49
 
71
- # Prepares and processes the SOAP request. Returns a Savon::Response object.
50
+ # Sets up and dispatches the SOAP request. Returns a Savon::Response object.
72
51
  def call_service
73
52
  headers = { "Content-Type" => "text/xml; charset=utf-8", "SOAPAction" => @action }
74
53
 
75
- ApricotEatsGorilla.setup do |s|
76
- s.nodes_to_namespace = wsdl.choice_elements
77
- s.node_namespace = "wsdl"
78
- end
79
54
  body = ApricotEatsGorilla.soap_envelope("wsdl" => wsdl.namespace_uri) do
80
55
  ApricotEatsGorilla["wsdl:#{@action}" => @options]
81
56
  end
82
57
 
83
58
  debug do |logger|
84
- logger.info "Request; #{@uri}"
59
+ logger.info "Requesting #{@uri}"
85
60
  logger.info headers.map { |key, value| "#{key}: #{value}" }.join("\n")
86
61
  logger.info body
87
62
  end
@@ -110,20 +85,19 @@ module Savon
110
85
  end
111
86
  end
112
87
 
113
- # Debug method. Outputs a given +message+ to the defined @@logger or
114
- # yields the @@logger to a +block+ in case one was given.
88
+ # Logs a given +message+ using the @@logger instance or yields the logger
89
+ # to a given +block+ for logging multiple things at once.
115
90
  def debug(message = nil)
116
91
  if @@logger
117
- if message
118
- @@logger.info(message)
119
- end
120
- if block_given?
121
- yield @@logger
122
- end
92
+ @@logger.info(message) if message
93
+ yield @@logger if block_given?
123
94
  end
124
95
  end
125
96
 
126
- # Intercepts calls to SOAP service methods.
97
+ # Method missing catches SOAP service methods called on this object. This
98
+ # is the default way of calling a SOAP service. The given +method+ will be
99
+ # validated against the WSDL and dispatched if available. Values supplied
100
+ # through the optional Hash of +options+ will be send to the service method.
127
101
  #
128
102
  # === Parameters
129
103
  #
data/lib/savon/wsdl.rb CHANGED
@@ -4,7 +4,7 @@ require "hpricot"
4
4
 
5
5
  module Savon
6
6
 
7
- # Savon::Wsdl gets, parses and represents the SOAP-WSDL.
7
+ # Savon::Wsdl gets, parses and represents the WSDL.
8
8
  class Wsdl
9
9
 
10
10
  # The namespace URI.
@@ -21,7 +21,7 @@ module Savon
21
21
  #
22
22
  # === Parameters
23
23
  #
24
- # * +uri+ - The URI to access.
24
+ # * +uri+ - The URI of the WSDL.
25
25
  # * +http+ - The Net::HTTP connection instance to use.
26
26
  def initialize(uri, http)
27
27
  @uri, @http = uri, http
@@ -49,15 +49,13 @@ module Savon
49
49
  end
50
50
  end
51
51
 
52
- # Parses the WSDL to find and store the namespace URI.
52
+ # Parses the WSDL for the namespace URI.
53
53
  def parse_namespace_uri
54
54
  node = @doc.at("//wsdl:definitions")
55
- if node
56
- @namespace_uri = node.get_attribute("targetNamespace")
57
- end
55
+ @namespace_uri = node.get_attribute("targetNamespace") if node
58
56
  end
59
57
 
60
- # Parses the WSDL to find and store the available SOAP service methods.
58
+ # Parses the WSDL for available SOAP service methods.
61
59
  def parse_service_methods
62
60
  @service_methods, node = [], @doc.search("//soap:operation")
63
61
  if node
@@ -67,7 +65,7 @@ module Savon
67
65
  end
68
66
  end
69
67
 
70
- # Parses the WSDL to find and store any choice elements.
68
+ # Parses the WSDL for choice elements.
71
69
  def parse_choice_elements
72
70
  @choice_elements, node = [], @doc.search("//xs:choice//xs:element")
73
71
  if node
@@ -1,26 +1,26 @@
1
1
  module SoapResponseFixture
2
2
 
3
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>'
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
13
  end
14
14
 
15
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>'
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
24
  end
25
25
 
26
26
  def soap_fault
data/test/helper.rb CHANGED
@@ -19,15 +19,15 @@ module TestHelper
19
19
  end
20
20
 
21
21
  def service_http_mock(response_body)
22
- http_mock = mock()
23
- http_mock.expects(:get).returns(response_mock(WsdlFactory.new.build))
24
- http_mock.expects(:request_post).returns(response_mock(response_body))
22
+ http_mock = mock("Net::HTTP")
23
+ http_mock.stubs(:get).returns(response_mock(WsdlFactory.new.build))
24
+ http_mock.stubs(:request_post).returns(response_mock(response_body))
25
25
  http_mock
26
26
  end
27
27
 
28
28
  def http_mock(response_body)
29
- http_mock = mock()
30
- http_mock.expects(:get).returns(response_mock(response_body))
29
+ http_mock = mock("Net::HTTP")
30
+ http_mock.stubs(:get).returns(response_mock(response_body))
31
31
  http_mock
32
32
  end
33
33
 
@@ -41,10 +41,7 @@ module TestHelper
41
41
 
42
42
  def build_response_mock(code, message, body = nil)
43
43
  response_mock = mock("Net::HTTPResponse")
44
- response_mock.stubs(
45
- :code => code, :message => message, :content_type => "text/html",
46
- :body => body
47
- )
44
+ response_mock.stubs(:code => code, :message => message, :body => body)
48
45
  response_mock
49
46
  end
50
47
 
@@ -2,8 +2,17 @@ require File.join(File.dirname(__FILE__), "..", "helper")
2
2
 
3
3
  class SavonMashTest < Test::Unit::TestCase
4
4
 
5
- def test_nupsi
6
- assert true
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
7
16
  end
8
17
 
9
18
  end
@@ -7,6 +7,10 @@ class SavonServiceTest < Test::Unit::TestCase
7
7
 
8
8
  context "Savon::Service" do
9
9
  setup do
10
+ @some_factory = WsdlFactory.new
11
+ @some_wsdl = Savon::Wsdl.new(some_uri, http_mock(@some_factory.build))
12
+ Savon::Wsdl.stubs(:new).returns(@some_wsdl)
13
+
10
14
  @service = Savon::Service.new(some_url)
11
15
  @service.http = service_http_mock(some_soap_response)
12
16
  @result = @service.findById
data/test/savon_test.rb CHANGED
@@ -1,5 +1,5 @@
1
- $:.unshift(File.join(File.dirname(__FILE__), 'savon'))
1
+ $:.unshift(File.join(File.dirname(__FILE__), "savon"))
2
+ require "service_test"
3
+ require "response_test"
2
4
  require "mash_test"
3
5
  require "wsdl_test"
4
- require "response_test"
5
- require "service_test"
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.0.91
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Harrington
@@ -30,9 +30,9 @@ dependencies:
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 0.3.8
33
+ version: 0.4.1
34
34
  version:
35
- description: Savon is a lightweight SOAP client.
35
+ description: Ruby SOAP client library to enjoy.
36
36
  email:
37
37
  executables: []
38
38
 
@@ -73,7 +73,7 @@ rubyforge_project:
73
73
  rubygems_version: 1.2.0
74
74
  signing_key:
75
75
  specification_version: 2
76
- summary: Savon is a lightweight SOAP client.
76
+ summary: Ruby SOAP client library to enjoy.
77
77
  test_files:
78
78
  - test/savon_test.rb
79
79
  - test/helper.rb