savon 0.3.2 → 0.5.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.
Files changed (42) hide show
  1. data/README.textile +68 -0
  2. data/Rakefile +9 -7
  3. data/VERSION +1 -1
  4. data/lib/savon.rb +33 -34
  5. data/lib/savon/client.rb +96 -0
  6. data/lib/savon/core_ext.rb +6 -0
  7. data/lib/savon/core_ext/datetime.rb +8 -0
  8. data/lib/savon/core_ext/hash.rb +65 -0
  9. data/lib/savon/core_ext/object.rb +14 -0
  10. data/lib/savon/core_ext/string.rb +41 -0
  11. data/lib/savon/core_ext/symbol.rb +8 -0
  12. data/lib/savon/core_ext/uri.rb +10 -0
  13. data/lib/savon/request.rb +103 -0
  14. data/lib/savon/soap.rb +71 -0
  15. data/lib/savon/validation.rb +57 -0
  16. data/lib/savon/wsdl.rb +39 -41
  17. data/lib/savon/wsse.rb +111 -0
  18. data/spec/fixtures/multiple_user_response.xml +22 -0
  19. data/spec/fixtures/soap_fault.xml +0 -0
  20. data/spec/fixtures/user_fixture.rb +42 -0
  21. data/spec/fixtures/user_response.xml +4 -2
  22. data/spec/fixtures/user_wsdl.xml +0 -0
  23. data/spec/http_stubs.rb +20 -0
  24. data/spec/savon/client_spec.rb +144 -0
  25. data/spec/savon/core_ext/datetime_spec.rb +12 -0
  26. data/spec/savon/core_ext/hash_spec.rb +146 -0
  27. data/spec/savon/core_ext/object_spec.rb +26 -0
  28. data/spec/savon/core_ext/string_spec.rb +52 -0
  29. data/spec/savon/core_ext/symbol_spec.rb +11 -0
  30. data/spec/savon/core_ext/uri_spec.rb +15 -0
  31. data/spec/savon/request_spec.rb +93 -0
  32. data/spec/savon/savon_spec.rb +37 -0
  33. data/spec/savon/soap_spec.rb +101 -0
  34. data/spec/savon/validation_spec.rb +88 -0
  35. data/spec/savon/wsdl_spec.rb +17 -46
  36. data/spec/savon/wsse_spec.rb +169 -0
  37. data/spec/spec_helper.rb +7 -92
  38. data/spec/spec_helper_methods.rb +29 -0
  39. metadata +68 -20
  40. data/README.rdoc +0 -62
  41. data/lib/savon/service.rb +0 -151
  42. data/spec/savon/service_spec.rb +0 -76
@@ -1,100 +1,15 @@
1
1
  require "rubygems"
2
2
  gem "rspec", ">= 1.2.8"
3
3
  require "spec"
4
- require "rr"
5
- require File.join(File.dirname(__FILE__), "..", "lib", "savon")
4
+ require "mocha"
6
5
 
7
6
  Spec::Runner.configure do |config|
8
- config.mock_with :rr
7
+ config.mock_with :mocha
9
8
  end
10
9
 
11
- module SpecHelper
12
- def some_url
13
- "http://example.com"
14
- end
10
+ require "savon"
11
+ Savon::Request.log = false
15
12
 
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
13
+ require "fixtures/user_fixture"
14
+ require "spec_helper_methods"
15
+ require "http_stubs"
@@ -0,0 +1,29 @@
1
+ class SpecHelper
2
+
3
+ @soap_call_endpoint = "http://services.example.com/UserService"
4
+ @some_endpoint = @soap_call_endpoint + "?wsdl"
5
+ @some_endpoint_uri = URI @some_endpoint
6
+
7
+ @soap_multiple_endpoint = "http://multiple.example.com/UserService"
8
+ @multiple_endpoint = @soap_multiple_endpoint + "?wsdl"
9
+
10
+ @soap_soapfault_endpoint = "http://soapfault.example.com/UserService"
11
+ @soapfault_endpoint = @soap_soapfault_endpoint + "?wsdl"
12
+
13
+ @soap_httperror_endpoint = "http://httperror.example.com/UserService"
14
+ @httperror_endpoint = @soap_httperror_endpoint + "?wsdl"
15
+
16
+ @wsse_security_nodes = ["wsse:Security", "wsse:UsernameToken",
17
+ "wsse:Username", "wsse:Password", "wsse:Nonce", "wsu:Created"]
18
+
19
+ class << self
20
+
21
+ attr_accessor :soap_call_endpoint, :some_endpoint, :some_endpoint_uri,
22
+ :soap_multiple_endpoint , :multiple_endpoint,
23
+ :soap_soapfault_endpoint, :soapfault_endpoint,
24
+ :soap_httperror_endpoint, :httperror_endpoint,
25
+ :wsse_security_nodes
26
+
27
+ end
28
+
29
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: savon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Harrington
@@ -9,28 +9,28 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-11-23 00:00:00 +01:00
12
+ date: 2009-11-29 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
- name: hpricot
16
+ name: builder
17
17
  type: :runtime
18
18
  version_requirement:
19
19
  version_requirements: !ruby/object:Gem::Requirement
20
20
  requirements:
21
- - - "="
21
+ - - ">="
22
22
  - !ruby/object:Gem::Version
23
- version: 0.8.241
23
+ version: 2.1.2
24
24
  version:
25
25
  - !ruby/object:Gem::Dependency
26
- name: apricoteatsgorilla
26
+ name: crack
27
27
  type: :runtime
28
28
  version_requirement:
29
29
  version_requirements: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "="
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 0.5.13
33
+ version: 0.1.4
34
34
  version:
35
35
  - !ruby/object:Gem::Dependency
36
36
  name: rspec
@@ -43,36 +43,72 @@ dependencies:
43
43
  version: 1.2.8
44
44
  version:
45
45
  - !ruby/object:Gem::Dependency
46
- name: rr
46
+ name: mocha
47
+ type: :development
48
+ version_requirement:
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: 0.9.7
54
+ version:
55
+ - !ruby/object:Gem::Dependency
56
+ name: fakeweb
47
57
  type: :development
48
58
  version_requirement:
49
59
  version_requirements: !ruby/object:Gem::Requirement
50
60
  requirements:
51
61
  - - ">="
52
62
  - !ruby/object:Gem::Version
53
- version: 0.10.0
63
+ version: 1.2.7
54
64
  version:
55
- description: SOAP client library to enjoy
65
+ description: Heavy metal Ruby SOAP client library
56
66
  email: me@rubiii.com
57
67
  executables: []
58
68
 
59
69
  extensions: []
60
70
 
61
71
  extra_rdoc_files:
62
- - README.rdoc
72
+ - README.textile
63
73
  files:
64
- - README.rdoc
74
+ - README.textile
65
75
  - Rakefile
66
76
  - VERSION
67
77
  - lib/savon.rb
68
- - lib/savon/service.rb
78
+ - lib/savon/client.rb
79
+ - lib/savon/core_ext.rb
80
+ - lib/savon/core_ext/datetime.rb
81
+ - lib/savon/core_ext/hash.rb
82
+ - lib/savon/core_ext/object.rb
83
+ - lib/savon/core_ext/string.rb
84
+ - lib/savon/core_ext/symbol.rb
85
+ - lib/savon/core_ext/uri.rb
86
+ - lib/savon/request.rb
87
+ - lib/savon/soap.rb
88
+ - lib/savon/validation.rb
69
89
  - lib/savon/wsdl.rb
90
+ - lib/savon/wsse.rb
91
+ - spec/fixtures/multiple_user_response.xml
70
92
  - spec/fixtures/soap_fault.xml
93
+ - spec/fixtures/user_fixture.rb
71
94
  - spec/fixtures/user_response.xml
72
95
  - spec/fixtures/user_wsdl.xml
73
- - spec/savon/service_spec.rb
96
+ - spec/http_stubs.rb
97
+ - spec/savon/client_spec.rb
98
+ - spec/savon/core_ext/datetime_spec.rb
99
+ - spec/savon/core_ext/hash_spec.rb
100
+ - spec/savon/core_ext/object_spec.rb
101
+ - spec/savon/core_ext/string_spec.rb
102
+ - spec/savon/core_ext/symbol_spec.rb
103
+ - spec/savon/core_ext/uri_spec.rb
104
+ - spec/savon/request_spec.rb
105
+ - spec/savon/savon_spec.rb
106
+ - spec/savon/soap_spec.rb
107
+ - spec/savon/validation_spec.rb
74
108
  - spec/savon/wsdl_spec.rb
109
+ - spec/savon/wsse_spec.rb
75
110
  - spec/spec_helper.rb
111
+ - spec/spec_helper_methods.rb
76
112
  has_rdoc: true
77
113
  homepage: http://github.com/rubiii/savon
78
114
  licenses: []
@@ -82,8 +118,6 @@ rdoc_options:
82
118
  - --charset=UTF-8
83
119
  - --title
84
120
  - Savon
85
- - --main
86
- - README.rdoc
87
121
  - --line-numbers
88
122
  - --inline-source
89
123
  require_paths:
@@ -106,8 +140,22 @@ rubyforge_project:
106
140
  rubygems_version: 1.3.5
107
141
  signing_key:
108
142
  specification_version: 3
109
- summary: SOAP client library to enjoy
143
+ summary: Heavy metal Ruby SOAP client library
110
144
  test_files:
111
- - spec/spec_helper.rb
112
- - spec/savon/service_spec.rb
145
+ - spec/fixtures/user_fixture.rb
146
+ - spec/http_stubs.rb
147
+ - spec/savon/client_spec.rb
148
+ - spec/savon/core_ext/datetime_spec.rb
149
+ - spec/savon/core_ext/hash_spec.rb
150
+ - spec/savon/core_ext/object_spec.rb
151
+ - spec/savon/core_ext/string_spec.rb
152
+ - spec/savon/core_ext/symbol_spec.rb
153
+ - spec/savon/core_ext/uri_spec.rb
154
+ - spec/savon/request_spec.rb
155
+ - spec/savon/savon_spec.rb
156
+ - spec/savon/soap_spec.rb
157
+ - spec/savon/validation_spec.rb
113
158
  - spec/savon/wsdl_spec.rb
159
+ - spec/savon/wsse_spec.rb
160
+ - spec/spec_helper.rb
161
+ - spec/spec_helper_methods.rb
@@ -1,62 +0,0 @@
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
- The gem for Savon is in the {gemcutter}[http://gemcutter.org] repository.
10
- Please follow the steps on their website to set up your rubygems installation.
11
- Afterwards you can install the gem like this:
12
-
13
- $ gem install savon
14
-
15
- == Dependencies
16
-
17
- rubiii-apricoteatsgorilla >= 0.5.10
18
- hpricot 0.8.241 (the latest JRuby-compatible version)
19
-
20
- Hpricot 0.8.241 is also available at: {Apricot eats Gorilla Downloads}[http://github.com/rubiii/apricoteatsgorilla/downloads]
21
-
22
- == How to use
23
-
24
- Instantiate a new Savon::Service instance passing in the WSDL of your service.
25
-
26
- proxy = Savon::Service.new("http://example.com/ExampleService?wsdl")
27
-
28
- Call the SOAP service method of your choice on your Savon::Service instance.
29
-
30
- response = proxy.get_all_users
31
-
32
- Or pass in a Hash of options for the SOAP service to receive.
33
-
34
- response = proxy.find_user_by_id(:id => 123)
35
-
36
- Or specify a custom XPath-Expression to start translating the SOAP response at.
37
- By default the response is translated starting at "//return".
38
-
39
- response = proxy.find_user_by_id(nil, "//user/email")
40
-
41
- === Check for available SOAP actions
42
-
43
- Access the WSDL to get an Array of SOAP actions found in the WSDL document.
44
-
45
- proxy.wsdl.soap_actions
46
- # => [ "getAllUsers", "findUserById" ]
47
-
48
- === Handle HTTP error and SOAP faults
49
-
50
- Savon::Service raises a Savon::SOAPFault in case of a SOAP fault and a
51
- Savon::HTTPError in case of an HTTP error.
52
-
53
- === Logging request and response
54
-
55
- You should specify the logger to use before working with any service.
56
-
57
- # example for Ruby on Rails
58
- Savon.logger = RAILS_DEFAULT_LOGGER
59
-
60
- Of course you can also specify the log level if needed. By default it's set to :debug.
61
-
62
- Savon.log_level = :info
@@ -1,151 +0,0 @@
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
- # Supported SOAP versions.
16
- SOAPVersions = [1, 2]
17
-
18
- # Content-Types by SOAP version.
19
- ContentType = { 1 => "text/xml", 2 => "application/soap+xml" }
20
-
21
- # Accessor for the WSSE username.
22
- attr_accessor :wsse_username
23
-
24
- # Accessor for the WSSE password.
25
- attr_accessor :wsse_password
26
-
27
- # Sets whether the WSSE password should be encrypted.
28
- attr_writer :wsse_digest
29
-
30
- # Sets whether the response should be returned as is.
31
- attr_writer :pure_response
32
-
33
- # Initializer expects an +endpoint+ URI and takes an optional SOAP +version+.
34
- def initialize(endpoint, version = 1)
35
- raise ArgumentError, "Invalid endpoint: #{endpoint}" unless /^http.+/ === endpoint
36
- raise ArgumentError, "Invalid version: #{version}" unless SOAPVersions.include? version
37
- @endpoint = URI(endpoint)
38
- @version = version
39
- @ssl = /^https.+/ === endpoint
40
- end
41
-
42
- # Returns an instance of Savon::WSDL.
43
- def wsdl
44
- @wsdl ||= WSDL.new(@endpoint, http)
45
- end
46
-
47
- # Returns whether the WSSE password should be encrypted. Defaults to +false+.
48
- def wsse_digest?
49
- @wsse_digest == true
50
- end
51
-
52
- # Returns whether the response should be returned as is. Defaults to +false+.
53
- def pure_response?
54
- @pure_response == true
55
- end
56
-
57
- private
58
-
59
- # Dispatches a SOAP request, handles any HTTP errors and SOAP faults
60
- # and returns the SOAP response.
61
- def dispatch(soap_action, soap_body, response_xpath)
62
- ApricotEatsGorilla.nodes_to_namespace = { :wsdl => wsdl.choice_elements }
63
- headers, body = build_request_parameters(soap_action, soap_body)
64
-
65
- Savon.log("SOAP request: #{@endpoint}")
66
- Savon.log(headers.map { |k, v| "#{k}: #{v}" }.join(", "))
67
- Savon.log(body)
68
-
69
- response = http.request_post(@endpoint.path, body, headers)
70
-
71
- Savon.log("SOAP response (status #{response.code}):")
72
- Savon.log(response.body)
73
-
74
- soap_fault = ApricotEatsGorilla[response.body, "//soap:Fault"]
75
- raise_soap_fault(soap_fault) if soap_fault && !soap_fault.empty?
76
- raise_http_error(response) if response.code.to_i >= 300
77
-
78
- if pure_response?
79
- response.body
80
- else
81
- ApricotEatsGorilla[response.body, response_xpath]
82
- end
83
- end
84
-
85
- # Expects the requested +soap_action+ and +soap_body+ and builds and
86
- # returns the request header and body to dispatch a SOAP request.
87
- def build_request_parameters(soap_action, soap_body)
88
- headers = { "Content-Type" => ContentType[@version], "SOAPAction" => soap_action }
89
- namespaces = { "xmlns:wsdl" => wsdl.namespace_uri }
90
-
91
- body = ApricotEatsGorilla.soap_envelope(namespaces, wsse, @version) do
92
- ApricotEatsGorilla["wsdl:#{soap_action}" => soap_body]
93
- end
94
- [headers, body]
95
- end
96
-
97
- # Returns the WSSE arguments if :wsse_username and :wsse_password are set.
98
- def wsse
99
- if @wsse_username && @wsse_password
100
- { :username => @wsse_username, :password => @wsse_password, :digest => wsse_digest? }
101
- else
102
- nil
103
- end
104
- end
105
-
106
- # Expects a Hash containing information about a SOAP fault and raises
107
- # a Savon::SOAPFault.
108
- def raise_soap_fault(soap_fault)
109
- message = case @version
110
- when 1
111
- "#{soap_fault[:faultcode]}: #{soap_fault[:faultstring]}"
112
- else
113
- "#{soap_fault[:code][:value]}: #{soap_fault[:reason][:text]}"
114
- end
115
- raise SOAPFault, message
116
- end
117
-
118
- # Expects a Net::HTTPResponse and raises a Savon::HTTPError.
119
- def raise_http_error(response)
120
- raise HTTPError, "#{response.message} (#{response.code}): #{response.body}"
121
- end
122
-
123
- # Returns a Net::HTTP instance.
124
- def http
125
- unless @http
126
- @http ||= Net::HTTP.new(@endpoint.host, @endpoint.port)
127
- @http.use_ssl = true if @ssl
128
- end
129
- @http
130
- end
131
-
132
- # Catches calls to SOAP actions, checks if the method called was found in
133
- # the WSDL and dispatches the SOAP action if it's valid. Takes an optional
134
- # Hash of options to be passed to the SOAP action and an optional XPath-
135
- # Expression to define a custom XML root node to start parsing the SOAP
136
- # response at.
137
- def method_missing(method, *args)
138
- soap_action = camelize(method)
139
- super unless wsdl.soap_actions.include? soap_action
140
- soap_body = args[0] || {}
141
- response_xpath = args[1] || "//return"
142
- dispatch(soap_action, soap_body, response_xpath)
143
- end
144
-
145
- # Converts a given +string+ from snake_case to lowerCamelCase.
146
- def camelize(string)
147
- string.to_s.gsub(/_(.)/) { $1.upcase } if string
148
- end
149
-
150
- end
151
- end