rubiii-savon 0.2.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 ADDED
@@ -0,0 +1,58 @@
1
+ = Savon
2
+
3
+ Savon::Service is a SOAP client library to enjoy. The goal is to minimize
4
+ the overhead of working with SOAP services and provide a lightweight
5
+ alternative to other libraries.
6
+
7
+ == Install
8
+
9
+ $ gem install smacks-savon -s http://gems.github.com
10
+
11
+ == Dependencies
12
+
13
+ smacks-apricoteatsgorilla >= 0.5.2
14
+ hpricot 0.8.241 (the latest JRuby-compatible version)
15
+
16
+ Hpricot 0.8.241 is also available at: {Apricot eats Gorilla Downloads}[http://github.com/smacks/apricoteatsgorilla/downloads]
17
+
18
+ == How to use
19
+
20
+ Instantiate a new Savon::Service instance passing in the WSDL of your service.
21
+
22
+ proxy = Savon::Service.new("http://example.com/ExampleService?wsdl")
23
+
24
+ Call the SOAP service method of your choice on your Savon::Service instance.
25
+
26
+ response = proxy.get_all_users
27
+
28
+ Or pass in a Hash of options for the SOAP service to receive.
29
+
30
+ response = proxy.find_user_by_id(:id => 123)
31
+
32
+ Or specify a custom XPath-Expression to start translating the SOAP response at.
33
+ By default the response is translated starting at "//return".
34
+
35
+ response = proxy.find_user_by_id(nil, "//user/email")
36
+
37
+ === Check for available SOAP actions
38
+
39
+ Access the WSDL to get an Array of SOAP actions found in the WSDL document.
40
+
41
+ proxy.wsdl.soap_actions
42
+ # => [ "getAllUsers", "findUserById" ]
43
+
44
+ === Handle HTTP error and SOAP faults
45
+
46
+ Savon::Service raises a Savon::SOAPFault in case of a SOAP fault and a
47
+ Savon::HTTPError in case of an HTTP error.
48
+
49
+ === Logging request and response
50
+
51
+ You should specify the logger to use before working with any service.
52
+
53
+ # example for Ruby on Rails
54
+ Savon.logger = RAILS_DEFAULT_LOGGER
55
+
56
+ Of course you can also specify the log level if needed. By default it's set to :debug.
57
+
58
+ Savon.log_level = :info
data/Rakefile ADDED
@@ -0,0 +1,48 @@
1
+ require "rubygems"
2
+ require "rake"
3
+ require "spec/rake/spectask"
4
+ require "rake/rdoctask"
5
+
6
+ task :default => :spec
7
+
8
+ Spec::Rake::SpecTask.new do |spec|
9
+ spec.spec_files = FileList["spec/**/*_spec.rb"]
10
+ spec.spec_opts << "--color"
11
+ end
12
+
13
+ Rake::RDocTask.new do |rdoc|
14
+ rdoc.title = "Savon"
15
+ rdoc.rdoc_dir = "rdoc"
16
+ rdoc.main = "README.rdoc"
17
+ rdoc.rdoc_files.include("README.rdoc", "lib/**/*.rb")
18
+ rdoc.options = ["--line-numbers", "--inline-source"]
19
+ end
20
+
21
+ begin
22
+ require "jeweler"
23
+ Jeweler::Tasks.new do |spec|
24
+ spec.name = "savon"
25
+ spec.author = "Daniel Harrington"
26
+ spec.email = "me@d-harrington.com"
27
+ spec.homepage = "http://github.com/smacks/savon"
28
+ spec.summary = "SOAP client library to enjoy."
29
+ spec.description = spec.summary
30
+
31
+ spec.files = FileList["[A-Z]*", "{lib,spec}/**/*.{rb,xml}"]
32
+
33
+ spec.rdoc_options += [
34
+ "--title", "Savon",
35
+ "--main", "README.rdoc",
36
+ "--line-numbers",
37
+ "--inline-source"
38
+ ]
39
+
40
+ spec.add_runtime_dependency("hpricot", "0.8.241")
41
+ spec.add_runtime_dependency("smacks-apricoteatsgorilla", "0.5.2")
42
+
43
+ spec.add_development_dependency("rspec", ">= 1.2.8")
44
+ spec.add_development_dependency("rr", ">= 0.10.0")
45
+ end
46
+ rescue LoadError
47
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
48
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.0
@@ -0,0 +1,95 @@
1
+ module Savon
2
+
3
+ # == Savon::Service
4
+ #
5
+ # Savon::Service is a SOAP client library to enjoy. The goal is to minimize
6
+ # the overhead of working with SOAP services and provide a lightweight
7
+ # alternative to other libraries.
8
+ #
9
+ # ==== Example
10
+ #
11
+ # proxy = Savon::Service.new("http://example.com/ExampleService?wsdl")
12
+ # response = proxy.find_user_by_id(:id => 123)
13
+ class Service
14
+
15
+ # Initializer expects an +endpoint+ URI.
16
+ def initialize(endpoint)
17
+ raise ArgumentError, "Invalid endpoint: #{endpoint}" unless /^http.+/ === endpoint
18
+ @endpoint = URI(endpoint)
19
+ end
20
+
21
+ # Returns an instance of Savon::WSDL.
22
+ def wsdl
23
+ @wsdl ||= WSDL.new(@endpoint, http)
24
+ end
25
+
26
+ private
27
+
28
+ # Dispatches a SOAP request, handles any HTTP errors and SOAP faults
29
+ # and returns the SOAP response.
30
+ def dispatch(soap_action, soap_body, response_xpath)
31
+ ApricotEatsGorilla.nodes_to_namespace = { :wsdl => wsdl.choice_elements }
32
+ headers, body = build_request_parameters(soap_action, soap_body)
33
+
34
+ Savon.log("SOAP request: #{@endpoint}")
35
+ Savon.log(headers.map { |k, v| "#{k}: #{v}" }.join(", "))
36
+ Savon.log(body)
37
+
38
+ response = http.request_post(@endpoint.path, body, headers)
39
+
40
+ Savon.log("SOAP response (status #{response.code})")
41
+ Savon.log(response.body)
42
+
43
+ soap_fault = ApricotEatsGorilla[response.body, "//soap:Fault"]
44
+ raise_soap_fault(soap_fault) if soap_fault && !soap_fault.empty?
45
+ raise_http_error(response) if response.code.to_i >= 300
46
+
47
+ ApricotEatsGorilla[response.body, response_xpath]
48
+ end
49
+
50
+ # Expects the requested +soap_action+ and +soap_body+ and builds and
51
+ # returns the request header and body to dispatch a SOAP request.
52
+ def build_request_parameters(soap_action, soap_body)
53
+ headers = { "Content-Type" => "text/xml; charset=utf-8", "SOAPAction" => soap_action }
54
+ body = ApricotEatsGorilla.soap_envelope(:wsdl => wsdl.namespace_uri) do
55
+ ApricotEatsGorilla["wsdl:#{soap_action}" => soap_body]
56
+ end
57
+ [headers, body]
58
+ end
59
+
60
+ # Expects a Hash containing information about a SOAP fault and raises
61
+ # a Savon::SOAPFault.
62
+ def raise_soap_fault(soap_fault)
63
+ raise SOAPFault, "#{soap_fault[:faultcode]}: #{soap_fault[:faultstring]}"
64
+ end
65
+
66
+ # Expects a Net::HTTPResponse and raises a Savon::HTTPError.
67
+ def raise_http_error(response)
68
+ raise HTTPError, "#{response.message} (#{response.code}): #{response.body}"
69
+ end
70
+
71
+ # Returns a Net::HTTP instance.
72
+ def http
73
+ @http ||= Net::HTTP.new(@endpoint.host, @endpoint.port)
74
+ end
75
+
76
+ # Catches calls to SOAP actions, checks if the method called was found in
77
+ # the WSDL and dispatches the SOAP action if it's valid. Takes an optional
78
+ # Hash of options to be passed to the SOAP action and an optional XPath-
79
+ # Expression to define a custom XML root node to start parsing the SOAP
80
+ # response at.
81
+ def method_missing(method, *args)
82
+ soap_action = camelize(method)
83
+ super unless wsdl.soap_actions.include? soap_action
84
+ soap_body = args[0] || {}
85
+ response_xpath = args[1] || "//return"
86
+ dispatch(soap_action, soap_body, response_xpath)
87
+ end
88
+
89
+ # Converts a given +string+ from snake_case to lowerCamelCase.
90
+ def camelize(string)
91
+ string.to_s.gsub(/_(.)/) { $1.upcase } if string
92
+ end
93
+
94
+ end
95
+ end
data/lib/savon/wsdl.rb ADDED
@@ -0,0 +1,70 @@
1
+ module Savon
2
+
3
+ # Savon::WSDL represents the WSDL document.
4
+ class WSDL
5
+
6
+ # Returns the namespace URI.
7
+ def namespace_uri
8
+ @namespace ||= parse_namespace_uri
9
+ end
10
+
11
+ # Returns an Array of available SOAP actions.
12
+ def soap_actions
13
+ @soap_actions ||= parse_soap_actions
14
+ end
15
+
16
+ # Returns an Array of choice elements.
17
+ def choice_elements
18
+ @choice_elements ||= parse_choice_elements
19
+ end
20
+
21
+ # Initializer expects the endpoint +uri+ and a Net::HTTP instance (+http+).
22
+ def initialize(uri, http)
23
+ @uri, @http = uri, http
24
+ end
25
+
26
+ # Returns the body of the Net::HTTPResponse from the WSDL request.
27
+ def to_s
28
+ @response ? @response.body : nil
29
+ end
30
+
31
+ private
32
+
33
+ # Returns an Hpricot::Document of the WSDL. Retrieves the WSDL from the
34
+ # endpoint URI in case it wasn't retrieved already.
35
+ def document
36
+ unless @document
37
+ @response = @http.get("#{@uri.path}?#{@uri.query}")
38
+ @document = Hpricot.XML(@response.body)
39
+ raise ArgumentError, "Unable to find WSDL at: #{@uri}" if
40
+ !soap_actions || soap_actions.empty?
41
+ end
42
+ @document
43
+ end
44
+
45
+ # Parses the WSDL for the namespace URI.
46
+ def parse_namespace_uri
47
+ definitions = document.at("//wsdl:definitions")
48
+ definitions.get_attribute("targetNamespace") if definitions
49
+ end
50
+
51
+ # Parses the WSDL for available SOAP actions.
52
+ def parse_soap_actions
53
+ soap_actions = document.search("//soap:operation")
54
+
55
+ soap_actions.collect do |soap_action|
56
+ soap_action.parent.get_attribute("name")
57
+ end if soap_actions
58
+ end
59
+
60
+ # Parses the WSDL for choice elements.
61
+ def parse_choice_elements
62
+ choice_elements = document.search("//xs:choice//xs:element")
63
+
64
+ choice_elements.collect do |choice_element|
65
+ choice_element.get_attribute("ref").sub(/(.+):/, "")
66
+ end if choice_elements
67
+ end
68
+
69
+ end
70
+ end
data/lib/savon.rb ADDED
@@ -0,0 +1,47 @@
1
+ module Savon
2
+
3
+ # Raised by the <tt>on_http_error</tt> method in case of an HTTP error.
4
+ # <tt>on_http_error</tt> may be overwritten to customize error handling.
5
+ class HTTPError < StandardError; end
6
+
7
+ # Raised by the <tt>on_soap_fault</tt> method in case of a SOAP fault.
8
+ # <tt>on_soap_fault</tt> may be overwritten to customize error handling.
9
+ class SOAPFault < StandardError; end
10
+
11
+ # The logger to use.
12
+ @@logger = nil
13
+
14
+ # The log level to use.
15
+ @@log_level = :debug
16
+
17
+ # Sets the logger to use.
18
+ def self.logger=(logger)
19
+ @@logger = logger
20
+ end
21
+
22
+ # Sets the log level to use.
23
+ def self.log_level=(log_level)
24
+ @@log_level = log_level
25
+ end
26
+
27
+ # Logs a given +message+ using the +@@logger+ instance or yields the logger
28
+ # to a given +block+ for logging multiple messages at once.
29
+ def self.log(message = nil)
30
+ if @@logger
31
+ @@logger.send(@@log_level, message) if message
32
+ yield @@logger if block_given?
33
+ end
34
+ end
35
+
36
+ end
37
+
38
+ %w(net/http uri rubygems hpricot).each do |gem|
39
+ require gem
40
+ end
41
+
42
+ #require "apricoteatsgorilla"
43
+ require File.join(File.dirname(__FILE__), "..", "..", "apricoteatsgorilla", "lib", "apricoteatsgorilla")
44
+
45
+ %w(service wsdl).each do |file|
46
+ require File.join(File.dirname(__FILE__), "savon", file)
47
+ end
@@ -0,0 +1,8 @@
1
+ <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
2
+ <soap:Body>
3
+ <soap:Fault>
4
+ <faultcode>soap:Server</faultcode>
5
+ <faultstring>Fault occurred while processing.</faultstring>
6
+ </soap:Fault>
7
+ </soap:Body>
8
+ </soap:Envelope>
@@ -0,0 +1,13 @@
1
+ <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
2
+ <soap:Body>
3
+ <ns2:findUserResponse xmlns:ns2="http://v1_0.ws.user.example.com">
4
+ <return>
5
+ <id>123</id>
6
+ <email>thedude@example.com</email>
7
+ <username>thedude</username>
8
+ <firstname>The</firstname>
9
+ <lastname>Dude</lastname>
10
+ </return>
11
+ </ns2:findUserResponse>
12
+ </soap:Body>
13
+ </soap:Envelope>
@@ -0,0 +1,106 @@
1
+ <wsdl:definitions
2
+ name="UserWebService"
3
+ targetNamespace="http://v1_0.ws.user.example.com"
4
+ xmlns:ns1="http://cxf.apache.org/bindings/xformat"
5
+ xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
6
+ xmlns:tns="http://v1_0.ws.user.example.com"
7
+ xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
8
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema">
9
+
10
+ <wsdl:types>
11
+ <xs:schema
12
+ attributeFormDefault="unqualified"
13
+ elementFormDefault="unqualified"
14
+ targetNamespace="http://v1_0.ws.user.example.com"
15
+ xmlns:tns="http://v1_0.ws.user.example.com"
16
+ xmlns:xs="http://www.w3.org/2001/XMLSchema">
17
+ <xs:element name="findUser" type="tns:findUser" />
18
+ <xs:element name="findUserRequest" type="tns:findUserRequest" />
19
+ <xs:element name="baseFindUserRequest" type="tns:baseFindUserRequest" />
20
+ <xs:element name="idCredential" type="tns:idCredential" />
21
+ <xs:element name="emailCredential" type="tns:emailCredential" />
22
+ <xs:element name="findUserResponse" type="tns:findUserResponse" />
23
+ <xs:element name="userResponse" type="tns:userResponse" />
24
+
25
+ <xs:complexType name="findUser">
26
+ <xs:sequence>
27
+ <xs:element minOccurs="1" name="requestData" type="tns:findUserRequest" />
28
+ </xs:sequence>
29
+ </xs:complexType>
30
+ <xs:complexType name="findUserRequest">
31
+ <xs:complexContent>
32
+ <xs:extension base="tns:baseFindUserRequest">
33
+ <xs:sequence>
34
+ <xs:element minOccurs="0" name="mandant" type="tns:mandant" />
35
+ </xs:sequence>
36
+ </xs:extension>
37
+ </xs:complexContent>
38
+ </xs:complexType>
39
+ <xs:complexType name="baseFindUserRequest">
40
+ <xs:choice>
41
+ <xs:element ref="tns:idCredential" />
42
+ <xs:element ref="tns:emailCredential" />
43
+ </xs:choice>
44
+ </xs:complexType>
45
+ <xs:complexType name="idCredential">
46
+ <xs:sequence>
47
+ <xs:element name="id" type="xs:string" />
48
+ <xs:element name="token" type="xs:string" />
49
+ </xs:sequence>
50
+ </xs:complexType>
51
+ <xs:complexType name="emailCredential">
52
+ <xs:sequence>
53
+ <xs:element name="email" type="xs:string" />
54
+ <xs:element name="token" type="xs:string" />
55
+ </xs:sequence>
56
+ </xs:complexType>
57
+ <xs:complexType name="findUserResponse">
58
+ <xs:sequence>
59
+ <xs:element minOccurs="0" name="return" type="tns:userResponse" />
60
+ </xs:sequence>
61
+ </xs:complexType>
62
+ <xs:complexType name="userResponse">
63
+ <xs:sequence>
64
+ <xs:element minOccurs="0" name="id" type="xs:string" />
65
+ <xs:element minOccurs="0" name="email" type="xs:string" />
66
+ <xs:element minOccurs="0" name="username" type="xs:string" />
67
+ <xs:element minOccurs="0" name="firstname" type="xs:string" />
68
+ <xs:element minOccurs="0" name="lastname" type="xs:string" />
69
+ </xs:sequence>
70
+ </xs:complexType>
71
+ </xs:schema>
72
+ </wsdl:types>
73
+
74
+ <wsdl:message name="findUser">
75
+ <wsdl:part element="tns:findUser" name="parameters"></wsdl:part>
76
+ </wsdl:message>
77
+ <wsdl:message name="findUserResponse">
78
+ <wsdl:part element="tns:findUserResponse" name="parameters"></wsdl:part>
79
+ </wsdl:message>
80
+
81
+ <wsdl:portType name="UserWebService">
82
+ <wsdl:operation name="findUser">
83
+ <wsdl:input message="tns:findUser" name="findUser"></wsdl:input>
84
+ <wsdl:output message="tns:findUserResponse" name="findUserResponse"></wsdl:output>
85
+ </wsdl:operation>
86
+ </wsdl:portType>
87
+
88
+ <wsdl:binding name="UserWebServiceSoapBinding" type="tns:UserWebService">
89
+ <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
90
+ <wsdl:operation name="findUser">
91
+ <soap:operation soapAction="" style="document" />
92
+ <wsdl:input name="findUser">
93
+ <soap:body use="literal" />
94
+ </wsdl:input>
95
+ <wsdl:output name="findUserResponse">
96
+ <soap:body use="literal" />
97
+ </wsdl:output>
98
+ </wsdl:operation>
99
+ </wsdl:binding>
100
+
101
+ <wsdl:service name="UserWebService">
102
+ <wsdl:port binding="tns:UserWebServiceSoapBinding" name="UserWebServicePort">
103
+ <soap:address location="http://example.com/user/1.0/UserService" />
104
+ </wsdl:port>
105
+ </wsdl:service>
106
+ </wsdl:definitions>
@@ -0,0 +1,64 @@
1
+ require File.join(File.dirname(__FILE__), "..", "spec_helper")
2
+
3
+ describe Savon::Service do
4
+ include SpecHelper
5
+
6
+ # initialize
7
+ describe "initialize" do
8
+ it "raises an ArgumentError when called with an invalid endpoint" do
9
+ ["", nil, "invalid", 123].each do |arg|
10
+ lambda { Savon::Service.new(arg) }.should raise_error(ArgumentError)
11
+ end
12
+ end
13
+ end
14
+
15
+ # wsdl
16
+ describe "wsdl" do
17
+ before { @service = new_service_instance }
18
+
19
+ it "returns an instance of Savon::WSDL" do
20
+ @service.wsdl.should be_a(Savon::WSDL)
21
+ end
22
+
23
+ it "returns the exact same Savon::WSDL instance every time" do
24
+ @service.wsdl.should equal(@service.wsdl)
25
+ end
26
+ end
27
+
28
+ # method_missing
29
+ describe "method_missing" do
30
+ before { @service = new_service_instance }
31
+
32
+ it "raises a NoMethodError when called with an invalid soap_action" do
33
+ lambda { @service.invalid_action }.should raise_error(NoMethodError)
34
+ end
35
+
36
+ it "by default returns content from the response using the '//return' XPath" do
37
+ @service.find_user.should == { :firstname => "The", :lastname => "Dude",
38
+ :email => "thedude@example.com", :username => "thedude", :id => "123" }
39
+ end
40
+
41
+ it "returns the content of the response starting at a custom XPath" do
42
+ @service.find_user(nil, "//email").should == "thedude@example.com"
43
+ end
44
+
45
+ it "returns nil if a given XPath does not match anything in the SOAP response" do
46
+ @service.find_user(nil, "//doesNotMatchAnything").should be_nil
47
+ end
48
+
49
+ it "raises a Savon::SOAPFault in case of a SOAP fault" do
50
+ @service = new_service_instance(:soap_fault => true)
51
+ lambda { @service.find_user }.should raise_error(Savon::SOAPFault)
52
+ end
53
+
54
+ it "raises a Savon::HTTPError in case the server returned an error code and no SOAP fault" do
55
+ @service = new_service_instance(:http_error => true)
56
+ lambda { @service.find_user }.should raise_error(Savon::HTTPError)
57
+ end
58
+
59
+ it "raises a Savon::SOAPFault in case the server returned an error code and a SOAP fault" do
60
+ @service = new_service_instance(:soap_fault => true, :http_error => true)
61
+ lambda { @service.find_user }.should raise_error(Savon::SOAPFault)
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,65 @@
1
+ require File.join(File.dirname(__FILE__), "..", "spec_helper")
2
+
3
+ describe Savon::WSDL do
4
+ include SpecHelper
5
+
6
+ #namespace_uri
7
+ describe "namespace_uri" do
8
+ before { @wsdl = new_wsdl }
9
+
10
+ it "returns the namespace URI from the WSDL" do
11
+ @wsdl.namespace_uri == UserFixture.namespace_uri
12
+ end
13
+
14
+ it "returns the same object every time" do
15
+ @wsdl.namespace_uri.should equal(@wsdl.namespace_uri)
16
+ end
17
+ end
18
+
19
+ # soap_actions
20
+ describe "soap_actions" do
21
+ before { @wsdl = new_wsdl }
22
+
23
+ it "returns the SOAP actions from the WSDL" do
24
+ @wsdl.soap_actions == UserFixture.soap_actions
25
+ end
26
+
27
+ it "returns the same object every time" do
28
+ @wsdl.soap_actions.should equal(@wsdl.soap_actions)
29
+ end
30
+ end
31
+
32
+ # choice_elements
33
+ describe "choice_elements" do
34
+ before { @wsdl = new_wsdl }
35
+
36
+ it "returns the choice elements from the WSDL" do
37
+ @wsdl.choice_elements == UserFixture.choice_elements
38
+ end
39
+
40
+ it "returns the same object every time" do
41
+ @wsdl.choice_elements.should equal(@wsdl.choice_elements)
42
+ end
43
+ end
44
+
45
+ # initialize
46
+ describe "initialize" do
47
+ it "expects an endpoint URI and a Net::HTTP instance" do
48
+ @wsdl = Savon::WSDL.new(some_uri, some_http)
49
+ end
50
+ end
51
+
52
+ # to_s
53
+ describe "to_s" do
54
+ before { @wsdl = new_wsdl }
55
+
56
+ it "returns nil before the WSDL document was retrieved" do
57
+ @wsdl.to_s.should be_nil
58
+ end
59
+
60
+ it "returns the response body when available" do
61
+ @wsdl.soap_actions # trigger http request
62
+ @wsdl.to_s.should == UserFixture.user_wsdl
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,100 @@
1
+ require "rubygems"
2
+ gem "rspec", ">= 1.2.8"
3
+ require "spec"
4
+ require "rr"
5
+ require File.join(File.dirname(__FILE__), "..", "lib", "savon")
6
+
7
+ Spec::Runner.configure do |config|
8
+ config.mock_with :rr
9
+ end
10
+
11
+ module SpecHelper
12
+ def some_url
13
+ "http://example.com"
14
+ end
15
+
16
+ def some_uri
17
+ URI(some_url)
18
+ end
19
+
20
+ def some_http
21
+ Net::HTTP.new(some_uri.host, some_uri.port)
22
+ end
23
+
24
+ def new_wsdl
25
+ Savon::WSDL.new(some_uri, UserFixture.http_mock)
26
+ end
27
+
28
+ def new_service_instance(options = {})
29
+ service = Savon::Service.new(some_url)
30
+ service.instance_variable_set("@http", UserFixture.http_mock(options))
31
+ service
32
+ end
33
+ end
34
+
35
+ class UserFixture
36
+ extend RR::Adapters::RRMethods
37
+
38
+ class << self
39
+ include SpecHelper
40
+
41
+ def namespace_uri
42
+ "http://v1_0.ws.user.example.com"
43
+ end
44
+
45
+ def soap_actions
46
+ %w(findUser)
47
+ end
48
+
49
+ def choice_elements
50
+ %w(idCredential emailCredential)
51
+ end
52
+
53
+ def user_wsdl
54
+ load_fixture("user_wsdl.xml")
55
+ end
56
+
57
+ def user_response
58
+ load_fixture("user_response.xml")
59
+ end
60
+
61
+ def soap_fault
62
+ load_fixture("soap_fault.xml")
63
+ end
64
+
65
+ def http_mock(options = {})
66
+ response_body = options[:soap_fault] ? soap_fault : user_response
67
+ response_code = options[:http_error] ? 500 : 200
68
+ response_body = "" if options[:http_error] && !options[:soap_fault]
69
+ generate_http_mock(soap_response_mock(response_body, response_code))
70
+ end
71
+
72
+ private
73
+
74
+ def load_fixture(file)
75
+ file_path = File.join(File.dirname(__FILE__), "fixtures", file)
76
+ IO.readlines(file_path, "").to_s
77
+ end
78
+
79
+ def generate_http_mock(soap_response)
80
+ mock = some_http
81
+ stub(mock).get(anything) { wsdl_response_mock(user_wsdl) }
82
+ stub(mock).request_post(anything, anything, anything) { soap_response }
83
+ mock
84
+ end
85
+
86
+ def wsdl_response_mock(response_body)
87
+ mock = mock()
88
+ stub(mock).body { response_body }
89
+ mock
90
+ end
91
+
92
+ def soap_response_mock(response_body, response_code)
93
+ mock = mock()
94
+ stub(mock).body { response_body }
95
+ stub(mock).code { response_code }
96
+ stub(mock).message { "whatever" }
97
+ mock
98
+ end
99
+ end
100
+ end
metadata ADDED
@@ -0,0 +1,111 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rubiii-savon
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Daniel Harrington
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-08-30 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: hpricot
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - "="
22
+ - !ruby/object:Gem::Version
23
+ version: 0.8.241
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: smacks-apricoteatsgorilla
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.5.2
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: rspec
37
+ type: :development
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 1.2.8
44
+ version:
45
+ - !ruby/object:Gem::Dependency
46
+ name: rr
47
+ type: :development
48
+ version_requirement:
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: 0.10.0
54
+ version:
55
+ description: SOAP client library to enjoy.
56
+ email: me@d-harrington.com
57
+ executables: []
58
+
59
+ extensions: []
60
+
61
+ extra_rdoc_files:
62
+ - README.rdoc
63
+ files:
64
+ - README.rdoc
65
+ - Rakefile
66
+ - VERSION
67
+ - lib/savon.rb
68
+ - lib/savon/service.rb
69
+ - lib/savon/wsdl.rb
70
+ - spec/fixtures/soap_fault.xml
71
+ - spec/fixtures/user_response.xml
72
+ - spec/fixtures/user_wsdl.xml
73
+ - spec/savon/service_spec.rb
74
+ - spec/savon/wsdl_spec.rb
75
+ - spec/spec_helper.rb
76
+ has_rdoc: true
77
+ homepage: http://github.com/smacks/savon
78
+ post_install_message:
79
+ rdoc_options:
80
+ - --charset=UTF-8
81
+ - --title
82
+ - Savon
83
+ - --main
84
+ - README.rdoc
85
+ - --line-numbers
86
+ - --inline-source
87
+ require_paths:
88
+ - lib
89
+ required_ruby_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: "0"
94
+ version:
95
+ required_rubygems_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: "0"
100
+ version:
101
+ requirements: []
102
+
103
+ rubyforge_project:
104
+ rubygems_version: 1.2.0
105
+ signing_key:
106
+ specification_version: 2
107
+ summary: SOAP client library to enjoy.
108
+ test_files:
109
+ - spec/savon/service_spec.rb
110
+ - spec/savon/wsdl_spec.rb
111
+ - spec/spec_helper.rb