savon 1.2.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. data/CHANGELOG.md +119 -104
  2. data/README.md +12 -11
  3. data/Rakefile +0 -6
  4. data/lib/savon.rb +16 -14
  5. data/lib/savon/block_interface.rb +26 -0
  6. data/lib/savon/builder.rb +142 -0
  7. data/lib/savon/client.rb +36 -135
  8. data/lib/savon/header.rb +42 -0
  9. data/lib/savon/http_error.rb +27 -0
  10. data/lib/savon/log_message.rb +23 -25
  11. data/lib/savon/message.rb +35 -0
  12. data/lib/savon/mock.rb +5 -0
  13. data/lib/savon/mock/expectation.rb +70 -0
  14. data/lib/savon/mock/spec_helper.rb +62 -0
  15. data/lib/savon/model.rb +39 -61
  16. data/lib/savon/operation.rb +62 -0
  17. data/lib/savon/options.rb +265 -0
  18. data/lib/savon/qualified_message.rb +49 -0
  19. data/lib/savon/request.rb +92 -0
  20. data/lib/savon/response.rb +97 -0
  21. data/lib/savon/soap_fault.rb +40 -0
  22. data/lib/savon/version.rb +1 -1
  23. data/savon.gemspec +10 -8
  24. data/spec/integration/options_spec.rb +536 -0
  25. data/spec/integration/request_spec.rb +31 -16
  26. data/spec/integration/support/application.rb +80 -0
  27. data/spec/integration/support/server.rb +84 -0
  28. data/spec/savon/builder_spec.rb +81 -0
  29. data/spec/savon/client_spec.rb +90 -488
  30. data/spec/savon/http_error_spec.rb +49 -0
  31. data/spec/savon/log_message_spec.rb +33 -0
  32. data/spec/savon/mock_spec.rb +127 -0
  33. data/spec/savon/model_spec.rb +110 -99
  34. data/spec/savon/observers_spec.rb +92 -0
  35. data/spec/savon/operation_spec.rb +49 -0
  36. data/spec/savon/request_spec.rb +145 -0
  37. data/spec/savon/{soap/response_spec.rb → response_spec.rb} +22 -59
  38. data/spec/savon/soap_fault_spec.rb +94 -0
  39. data/spec/spec_helper.rb +5 -3
  40. data/spec/support/fixture.rb +5 -1
  41. metadata +202 -197
  42. data/lib/savon/config.rb +0 -46
  43. data/lib/savon/error.rb +0 -6
  44. data/lib/savon/hooks/group.rb +0 -68
  45. data/lib/savon/hooks/hook.rb +0 -61
  46. data/lib/savon/http/error.rb +0 -42
  47. data/lib/savon/logger.rb +0 -39
  48. data/lib/savon/null_logger.rb +0 -10
  49. data/lib/savon/soap.rb +0 -21
  50. data/lib/savon/soap/fault.rb +0 -59
  51. data/lib/savon/soap/invalid_response_error.rb +0 -13
  52. data/lib/savon/soap/request.rb +0 -86
  53. data/lib/savon/soap/request_builder.rb +0 -205
  54. data/lib/savon/soap/response.rb +0 -117
  55. data/lib/savon/soap/xml.rb +0 -257
  56. data/spec/savon/config_spec.rb +0 -38
  57. data/spec/savon/hooks/group_spec.rb +0 -71
  58. data/spec/savon/hooks/hook_spec.rb +0 -16
  59. data/spec/savon/http/error_spec.rb +0 -52
  60. data/spec/savon/logger_spec.rb +0 -51
  61. data/spec/savon/savon_spec.rb +0 -33
  62. data/spec/savon/soap/fault_spec.rb +0 -89
  63. data/spec/savon/soap/request_builder_spec.rb +0 -207
  64. data/spec/savon/soap/request_spec.rb +0 -112
  65. data/spec/savon/soap/xml_spec.rb +0 -357
  66. data/spec/savon/soap_spec.rb +0 -16
@@ -1,38 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Savon::Config do
4
-
5
- let(:config) {
6
- config = Savon::Config.new
7
- config._logger = Savon::Logger.new
8
- config
9
- }
10
-
11
- describe "#clone" do
12
- it "clones the logger" do
13
- logger = config.logger
14
- clone = config.clone
15
-
16
- logger.should_not equal(clone.logger)
17
- end
18
- end
19
-
20
- it "allows to change the logger" do
21
- logger = Logger.new("/dev/null")
22
- config.logger = logger
23
- config._logger.subject.should equal(logger)
24
- end
25
-
26
- it "allows to change the log level" do
27
- config.log_level = :info
28
- config._logger.level.should == :info
29
- end
30
-
31
- it "allows to enable/disable logging" do
32
- config.log = false
33
- config._logger.should be_a(Savon::NullLogger)
34
- config.log = true
35
- config._logger.should be_a(Savon::Logger)
36
- end
37
-
38
- end
@@ -1,71 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Savon::Hooks::Group do
4
-
5
- let(:group) { subject }
6
-
7
- describe "#empty?" do
8
- it "returns true for an empty group" do
9
- group.should be_empty
10
- end
11
-
12
- it "returns false if the group contains hooks" do
13
- group = Savon::Hooks::Group.new [:some_hook]
14
- group.should_not be_empty
15
- end
16
- end
17
-
18
- describe "#define" do
19
- it "lets you define a new hook" do
20
- group.define(:test_hook, :soap_request)
21
- group.should_not be_empty
22
- end
23
-
24
- it "raises if there is no such hook" do
25
- expect { group.define(:supposed_to_fail, :no_such_hook) }.to raise_error(ArgumentError)
26
- end
27
- end
28
-
29
- describe "#reject" do
30
- it "rejects hooks matching any given id" do
31
- group.define(:remove1, :soap_request)
32
- group.define(:here_to_stay, :soap_request)
33
- group.define(:remove2, :soap_request)
34
- group.count.should == 3
35
-
36
- group.reject(:remove1, :remove2)
37
- group.count.should == 1
38
- end
39
- end
40
-
41
- describe "#fire" do
42
- let(:hook) { lambda {} }
43
- let(:fallback) { lambda {} }
44
-
45
- context "with hooks" do
46
- before do
47
- group.define(:some_hook, :soap_request, &hook)
48
- end
49
-
50
- it "calls the hooks passing any arguments" do
51
- hook.expects(:call).with(:arg1, :arg2)
52
- group.fire(:soap_request, :arg1, :arg2)
53
- end
54
-
55
- it "calls the hooks passing any arguments and the callback" do
56
- hook.expects(:call).with(fallback, :arg)
57
- group.fire(:soap_request, :arg, &fallback)
58
- end
59
- end
60
-
61
- context "without hooks" do
62
- it "executes the callback" do
63
- report = :call
64
- fallback = lambda { report = :back }
65
- group.fire(:soap_request, &fallback)
66
- report.should == :back
67
- end
68
- end
69
- end
70
-
71
- end
@@ -1,16 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Savon::Hooks::Hook do
4
-
5
- let(:hook) { lambda {} }
6
-
7
- describe "#call" do
8
- it "calls the hook" do
9
- hook = Savon::Hooks::Hook.new(:my_hook, :soap_request, &hook)
10
- hook.expects(:call).with(:arg1, :arg2)
11
-
12
- hook.call(:arg1, :arg2)
13
- end
14
- end
15
-
16
- end
@@ -1,52 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Savon::HTTP::Error do
4
- let(:http_error) { Savon::HTTP::Error.new new_response(:code => 404, :body => "Not Found") }
5
- let(:no_error) { Savon::HTTP::Error.new new_response }
6
-
7
- it "should be a Savon::Error" do
8
- Savon::HTTP::Error.should < Savon::Error
9
- end
10
-
11
- describe "#http" do
12
- it "should return the HTTPI::Response" do
13
- http_error.http.should be_an(HTTPI::Response)
14
- end
15
- end
16
-
17
- describe "#present?" do
18
- it "should return true if there was an HTTP error" do
19
- http_error.should be_present
20
- end
21
-
22
- it "should return false unless there was an HTTP error" do
23
- no_error.should_not be_present
24
- end
25
- end
26
-
27
- [:message, :to_s].each do |method|
28
- describe "##{method}" do
29
- it "should return an empty String unless an HTTP error is present" do
30
- no_error.send(method).should == ""
31
- end
32
-
33
- it "should return the HTTP error message" do
34
- http_error.send(method).should == "HTTP error (404): Not Found"
35
- end
36
- end
37
- end
38
-
39
- describe "#to_hash" do
40
- it "should return the HTTP response details as a Hash" do
41
- http_error.to_hash.should == { :code => 404, :headers => {}, :body => "Not Found" }
42
- end
43
- end
44
-
45
- def new_response(options = {})
46
- defaults = { :code => 200, :headers => {}, :body => Fixture.response(:authentication) }
47
- response = defaults.merge options
48
-
49
- HTTPI::Response.new response[:code], response[:headers], response[:body]
50
- end
51
-
52
- end
@@ -1,51 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Savon::Logger do
4
-
5
- let(:logger) { subject }
6
- let(:message) { "<?xml version='1.0'?><hello>world</hello>" }
7
- let(:pretty_message) { Nokogiri::XML(message) }
8
- let(:filtered_message) { Nokogiri::XML("<?xml version='1.0'?><hello>***FILTERED***</hello>") }
9
-
10
- it "logs a given message" do
11
- logger.subject.expects(logger.level).with(message)
12
- logger.log(message)
13
- end
14
-
15
- it "logs a given message (pretty)" do
16
- logger.subject.expects(logger.level).with(pretty_message.to_xml(:indent => 2))
17
- logger.log(message, :pretty => true)
18
- end
19
-
20
- it "logs a given message (filtered)" do
21
- logger.subject.expects(logger.level).with(filtered_message.to_s)
22
- logger.filter << :hello
23
- warn logger.log(message, :filter => true)
24
- end
25
-
26
- it "logs a given message (pretty and filtered)" do
27
- logger.subject.expects(logger.level).with(filtered_message.to_xml(:indent => 2))
28
- logger.filter << :hello
29
- logger.log(message, :pretty => true, :filter => true)
30
- end
31
-
32
- it "defaults to wrap the standard Logger" do
33
- logger.subject.should be_a(Logger)
34
- end
35
-
36
- it "can be configured to use a different Logger" do
37
- MyLogger = Object.new
38
- logger.subject = MyLogger
39
- logger.subject.should == MyLogger
40
- end
41
-
42
- it "defaults to the :debug log level" do
43
- logger.level.should == :debug
44
- end
45
-
46
- it "can be configured to use a different log level" do
47
- logger.level = :info
48
- logger.level.should == :info
49
- end
50
-
51
- end
@@ -1,33 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Savon do
4
-
5
- it "provides a shortcut for creating a new client" do
6
- Savon.client("http://example.com").should be_a(Savon::Client)
7
- end
8
-
9
- it "memoizes the global config" do
10
- Savon.config.should equal(Savon.config)
11
- end
12
-
13
- it "yields the global config to a block" do
14
- Savon.configure do |config|
15
- config.should equal(Savon.config)
16
- end
17
- end
18
-
19
- describe ".config" do
20
- it "defaults to a log facade" do
21
- Savon.config.logger.should be_a(Savon::Logger)
22
- end
23
-
24
- it "defaults to raise errors" do
25
- Savon.config.raise_errors.should be_true
26
- end
27
-
28
- it "defaults to SOAP 1.1" do
29
- Savon.config.soap_version.should == 1
30
- end
31
- end
32
-
33
- end
@@ -1,89 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Savon::SOAP::Fault do
4
- let(:soap_fault) { Savon::SOAP::Fault.new new_response(:body => Fixture.response(:soap_fault)) }
5
- let(:soap_fault2) { Savon::SOAP::Fault.new new_response(:body => Fixture.response(:soap_fault12)) }
6
- let(:another_soap_fault) { Savon::SOAP::Fault.new new_response(:body => Fixture.response(:another_soap_fault)) }
7
- let(:no_fault) { Savon::SOAP::Fault.new new_response }
8
-
9
- it "should be a Savon::Error" do
10
- Savon::SOAP::Fault.should < Savon::Error
11
- end
12
-
13
- describe "#http" do
14
- it "should return the HTTPI::Response" do
15
- soap_fault.http.should be_an(HTTPI::Response)
16
- end
17
- end
18
-
19
- describe "#present?" do
20
- it "should return true if the HTTP response contains a SOAP 1.1 fault" do
21
- soap_fault.should be_present
22
- end
23
-
24
- it "should return true if the HTTP response contains a SOAP 1.2 fault" do
25
- soap_fault2.should be_present
26
- end
27
-
28
- it "should return true if the HTTP response contains a SOAP fault with different namespaces" do
29
- another_soap_fault.should be_present
30
- end
31
-
32
- it "should return false unless the HTTP response contains a SOAP fault" do
33
- no_fault.should_not be_present
34
- end
35
- end
36
-
37
- [:message, :to_s].each do |method|
38
- describe "##{method}" do
39
- it "should return an empty String unless a SOAP fault is present" do
40
- no_fault.send(method).should == ""
41
- end
42
-
43
- it "should return a SOAP 1.1 fault message" do
44
- soap_fault.send(method).should == "(soap:Server) Fault occurred while processing."
45
- end
46
-
47
- it "should return a SOAP 1.2 fault message" do
48
- soap_fault2.send(method).should == "(soap:Sender) Sender Timeout"
49
- end
50
-
51
- it "should return a SOAP fault message (with different namespaces)" do
52
- another_soap_fault.send(method).should == "(ERR_NO_SESSION) Wrong session message"
53
- end
54
- end
55
- end
56
-
57
- describe "#to_hash" do
58
- it "should return the SOAP response as a Hash unless a SOAP fault is present" do
59
- no_fault.to_hash[:authenticate_response][:return][:success].should be_true
60
- end
61
-
62
- it "should return a SOAP 1.1 fault as a Hash" do
63
- soap_fault.to_hash.should == {
64
- :fault => {
65
- :faultstring => "Fault occurred while processing.",
66
- :faultcode => "soap:Server"
67
- }
68
- }
69
- end
70
-
71
- it "should return a SOAP 1.2 fault as a Hash" do
72
- soap_fault2.to_hash.should == {
73
- :fault => {
74
- :detail => { :max_time => "P5M" },
75
- :reason => { :text => "Sender Timeout" },
76
- :code => { :value => "soap:Sender", :subcode => { :value => "m:MessageTimeout" } }
77
- }
78
- }
79
- end
80
- end
81
-
82
- def new_response(options = {})
83
- defaults = { :code => 500, :headers => {}, :body => Fixture.response(:authentication) }
84
- response = defaults.merge options
85
-
86
- HTTPI::Response.new response[:code], response[:headers], response[:body]
87
- end
88
-
89
- end
@@ -1,207 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Savon::SOAP::RequestBuilder do
4
- describe "#request" do
5
- def build_request_builder(operation)
6
- request_builder = Savon::SOAP::RequestBuilder.new(operation)
7
-
8
- request_builder.wsdl.document = Fixture.wsdl(:authentication)
9
- request_builder.soap = soap
10
- request_builder.http = http
11
- request_builder.config = config
12
- request_builder.wsse = wsse
13
-
14
- soap.stubs(:types).returns({})
15
- http.stubs(:headers).returns({})
16
-
17
- request_builder
18
- end
19
-
20
- let(:soap) { stub_everything('soap') }
21
- let(:http) { stub_everything('http') }
22
- let(:config) { stub_everything('config') }
23
- let(:wsse) { stub_everything('wsse') }
24
- let(:request_builder) { build_request_builder(:get_user) }
25
-
26
- before do
27
- Savon::SOAP::Request.stubs(:new).returns(stub_everything('request'))
28
- end
29
-
30
- describe "the configuration of dependencies" do
31
- it "sets the SOAP endpoint to the endpoint specified by the WSDL document" do
32
- endpoint = request_builder.wsdl.endpoint
33
- request_builder.wsdl.expects(:endpoint).returns(endpoint)
34
- soap.expects(:endpoint=).with(endpoint)
35
-
36
- request_builder.request
37
- end
38
-
39
- it "sets the SOAP element form default to the element form default specified by the WSDL document" do
40
- element_form_default = request_builder.wsdl.element_form_default
41
- request_builder.wsdl.expects(:element_form_default).returns(element_form_default)
42
- soap.expects(:element_form_default=).with(element_form_default)
43
-
44
- request_builder.request
45
- end
46
-
47
- it "sets the SOAP WSSE property to the WSSE property of the request builder" do
48
- soap.expects(:wsse=).with(wsse)
49
-
50
- request_builder.request
51
- end
52
-
53
- it "sets the SOAP namespace to the namespace specified by the WSDL document" do
54
- namespace = "http://v1_0.ws.auth.order.example.com/"
55
- soap.expects(:namespace=).with(namespace)
56
-
57
- request_builder.request
58
- end
59
-
60
- it "sets the SOAP namespace identifier to nil" do
61
- namespace_identifier = nil
62
- soap.expects(:namespace_identifier=).with(namespace_identifier)
63
-
64
- request_builder.request
65
- end
66
-
67
- it "sets the SOAP input to result in <getUser>" do
68
- soap_input = [nil, :getUser, {}]
69
- soap.expects(:input=).with(soap_input)
70
-
71
- request_builder.request
72
- end
73
-
74
- context "when the operation namespace is specified by the WSDL" do
75
- before do
76
- request_builder.wsdl.operations[:authenticate][:namespace_identifier] = "tns"
77
- end
78
-
79
- let(:request_builder) { build_request_builder(:authenticate) }
80
-
81
- it "sets the SOAP namespace to the operation's namespace" do
82
- namespace = "http://v1_0.ws.auth.order.example.com/"
83
- soap.expects(:namespace=).with(namespace)
84
-
85
- request_builder.request
86
- end
87
-
88
- it "sets the SOAP namespace identifier to the operation's namespace identifier" do
89
- namespace_identifier = :tns
90
- soap.expects(:namespace_identifier=).with(namespace_identifier)
91
-
92
- request_builder.request
93
- end
94
-
95
- it "sets the SOAP input to include the namespace identifier" do
96
- soap_input = [:tns, :authenticate, {}]
97
- soap.expects(:input=).with(soap_input)
98
-
99
- request_builder.request
100
- end
101
- end
102
-
103
- context "when the operation is a string" do
104
- let(:request_builder) { build_request_builder("get_user") }
105
- it "should set the SOAP input tag to <get_user>" do
106
- soap_input = [nil, :get_user, {}]
107
- soap.expects(:input=).with(soap_input)
108
-
109
- request_builder.request
110
- end
111
- end
112
-
113
- context "when attributes are specified" do
114
- it "should add the attributes to the SOAP input" do
115
- request_builder.attributes = { :active => true }
116
- soap_input = [nil, :getUser, { :active => true }]
117
- soap.expects(:input=).with(soap_input)
118
-
119
- request_builder.request
120
- end
121
- end
122
-
123
- context "when a SOAP action is specified" do
124
- it "sets the SOAPAction header" do
125
- request_builder.soap_action = :test_action
126
- request_builder.request
127
-
128
- http.headers["SOAPAction"].should == %{"test_action"}
129
- end
130
- end
131
-
132
- context "when the namespace identifier is specified" do
133
- before do
134
- @namespace_identifier = :v1
135
- request_builder.namespace_identifier = @namespace_identifier
136
- end
137
-
138
- it "should set the SOAP namespace identifier to the specified identifier" do
139
- soap.expects(:namespace_identifier=).with(@namespace_identifier)
140
-
141
- request_builder.request
142
- end
143
-
144
- it "should set the SOAP input to include the specified identifier" do
145
- soap_input = [@namespace_identifier, :getUser, {}]
146
- soap.expects(:input=).with(soap_input)
147
-
148
- request_builder.request
149
- end
150
-
151
- it "should set the SOAP namespace to the one matched by the specified identifier" do
152
- namespace = "http://v1_0.ws.auth.order.example.com/"
153
- soap.expects(:namespace=).with(namespace)
154
-
155
- request_builder.request
156
- end
157
- end
158
-
159
- it "adds the WSDL document namespaces to the SOAP::XML object" do
160
- request_builder.wsdl.type_namespaces.each do |path, uri|
161
- soap.expects(:use_namespace).with(path, uri)
162
- end
163
-
164
- request_builder.request
165
- end
166
-
167
- it "adds the WSDL document types to the SOAP::XML object" do
168
- request_builder.request
169
-
170
- request_builder.wsdl.type_definitions do |path, type|
171
- soap.types.has_key?(path).should be_true
172
- soap.types[path].should == type
173
- end
174
- end
175
- end
176
-
177
- context "with a post-configuration block given" do
178
- it "executes the block" do
179
- executed = false
180
- blk = lambda { executed = true }
181
-
182
- request_builder.request(&blk)
183
- executed.should == true
184
- end
185
-
186
- it "executes the block post-configuration" do
187
- request_builder.namespace_identifier = :conf
188
- blk = lambda { |rb| rb.soap.namespace_identifier = :blk }
189
-
190
- conf_sequence = sequence('conf_sequence')
191
- soap.expects(:namespace_identifier=).with(:conf).in_sequence(conf_sequence)
192
- soap.expects(:namespace_identifier=).with(:blk).in_sequence(conf_sequence)
193
-
194
- request_builder.request(&blk)
195
- end
196
-
197
- context "when the block has an argument" do
198
- it "yields self to the block" do
199
- request_builder = self.request_builder
200
- blk = lambda { |rb_given| rb_given.should == request_builder }
201
-
202
- request_builder.request(&blk)
203
- end
204
- end
205
- end
206
- end
207
- end