savon-ng-1.6 2.4.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 (85) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.travis.yml +15 -0
  4. data/.yardopts +6 -0
  5. data/CHANGELOG.md +1024 -0
  6. data/CONTRIBUTING.md +46 -0
  7. data/Gemfile +8 -0
  8. data/LICENSE +20 -0
  9. data/README.md +81 -0
  10. data/Rakefile +14 -0
  11. data/donate.png +0 -0
  12. data/lib/savon/block_interface.rb +26 -0
  13. data/lib/savon/builder.rb +166 -0
  14. data/lib/savon/client.rb +88 -0
  15. data/lib/savon/core_ext/string.rb +29 -0
  16. data/lib/savon/header.rb +70 -0
  17. data/lib/savon/http_error.rb +27 -0
  18. data/lib/savon/log_message.rb +48 -0
  19. data/lib/savon/message.rb +36 -0
  20. data/lib/savon/mock/expectation.rb +71 -0
  21. data/lib/savon/mock/spec_helper.rb +62 -0
  22. data/lib/savon/mock.rb +5 -0
  23. data/lib/savon/model.rb +80 -0
  24. data/lib/savon/operation.rb +127 -0
  25. data/lib/savon/options.rb +330 -0
  26. data/lib/savon/qualified_message.rb +49 -0
  27. data/lib/savon/request.rb +89 -0
  28. data/lib/savon/request_logger.rb +48 -0
  29. data/lib/savon/response.rb +112 -0
  30. data/lib/savon/soap_fault.rb +48 -0
  31. data/lib/savon/version.rb +5 -0
  32. data/lib/savon.rb +27 -0
  33. data/savon.gemspec +47 -0
  34. data/spec/fixtures/gzip/message.gz +0 -0
  35. data/spec/fixtures/response/another_soap_fault.xml +14 -0
  36. data/spec/fixtures/response/authentication.xml +14 -0
  37. data/spec/fixtures/response/header.xml +13 -0
  38. data/spec/fixtures/response/list.xml +18 -0
  39. data/spec/fixtures/response/multi_ref.xml +39 -0
  40. data/spec/fixtures/response/soap_fault.xml +8 -0
  41. data/spec/fixtures/response/soap_fault12.xml +18 -0
  42. data/spec/fixtures/response/taxcloud.xml +1 -0
  43. data/spec/fixtures/ssl/client_cert.pem +16 -0
  44. data/spec/fixtures/ssl/client_encrypted_key.pem +30 -0
  45. data/spec/fixtures/ssl/client_encrypted_key_cert.pem +24 -0
  46. data/spec/fixtures/ssl/client_key.pem +15 -0
  47. data/spec/fixtures/wsdl/authentication.xml +63 -0
  48. data/spec/fixtures/wsdl/betfair.xml +2981 -0
  49. data/spec/fixtures/wsdl/edialog.xml +15416 -0
  50. data/spec/fixtures/wsdl/interhome.xml +2137 -0
  51. data/spec/fixtures/wsdl/lower_camel.xml +52 -0
  52. data/spec/fixtures/wsdl/multiple_namespaces.xml +92 -0
  53. data/spec/fixtures/wsdl/multiple_types.xml +60 -0
  54. data/spec/fixtures/wsdl/taxcloud.xml +934 -0
  55. data/spec/fixtures/wsdl/team_software.xml +1 -0
  56. data/spec/fixtures/wsdl/vies.xml +176 -0
  57. data/spec/fixtures/wsdl/wasmuth.xml +153 -0
  58. data/spec/integration/email_example_spec.rb +32 -0
  59. data/spec/integration/ratp_example_spec.rb +28 -0
  60. data/spec/integration/stockquote_example_spec.rb +28 -0
  61. data/spec/integration/support/application.rb +82 -0
  62. data/spec/integration/support/server.rb +84 -0
  63. data/spec/integration/temperature_example_spec.rb +46 -0
  64. data/spec/integration/zipcode_example_spec.rb +42 -0
  65. data/spec/savon/builder_spec.rb +86 -0
  66. data/spec/savon/client_spec.rb +193 -0
  67. data/spec/savon/core_ext/string_spec.rb +37 -0
  68. data/spec/savon/features/message_tag_spec.rb +61 -0
  69. data/spec/savon/http_error_spec.rb +49 -0
  70. data/spec/savon/log_message_spec.rb +33 -0
  71. data/spec/savon/message_spec.rb +40 -0
  72. data/spec/savon/mock_spec.rb +157 -0
  73. data/spec/savon/model_spec.rb +154 -0
  74. data/spec/savon/observers_spec.rb +92 -0
  75. data/spec/savon/operation_spec.rb +211 -0
  76. data/spec/savon/options_spec.rb +772 -0
  77. data/spec/savon/request_spec.rb +493 -0
  78. data/spec/savon/response_spec.rb +258 -0
  79. data/spec/savon/soap_fault_spec.rb +126 -0
  80. data/spec/spec_helper.rb +30 -0
  81. data/spec/support/endpoint.rb +25 -0
  82. data/spec/support/fixture.rb +39 -0
  83. data/spec/support/integration.rb +9 -0
  84. data/spec/support/stdout.rb +25 -0
  85. metadata +308 -0
@@ -0,0 +1,71 @@
1
+ require "httpi"
2
+
3
+ module Savon
4
+ class MockExpectation
5
+
6
+ def initialize(operation_name)
7
+ @expected = { :operation_name => operation_name }
8
+ @actual = nil
9
+ end
10
+
11
+ def with(locals)
12
+ @expected[:message] = locals[:message]
13
+ self
14
+ end
15
+
16
+ def returns(response)
17
+ response = { :code => 200, :headers => {}, :body => response } if response.kind_of?(String)
18
+ @response = response
19
+ self
20
+ end
21
+
22
+ def actual(operation_name, builder, globals, locals)
23
+ @actual = {
24
+ :operation_name => operation_name,
25
+ :message => locals[:message]
26
+ }
27
+ end
28
+
29
+ def verify!
30
+ unless @actual
31
+ raise ExpectationError, "Expected a request to the #{@expected[:operation_name].inspect} operation, " \
32
+ "but no request was executed."
33
+ end
34
+
35
+ verify_operation_name!
36
+ verify_message!
37
+ end
38
+
39
+ def response!
40
+ unless @response
41
+ raise ExpectationError, "This expectation was not set up with a response."
42
+ end
43
+
44
+ HTTPI::Response.new(@response[:code], @response[:headers], @response[:body])
45
+ end
46
+
47
+ private
48
+
49
+ def verify_operation_name!
50
+ unless @expected[:operation_name] == @actual[:operation_name]
51
+ raise ExpectationError, "Expected a request to the #{@expected[:operation_name].inspect} operation.\n" \
52
+ "Received a request to the #{@actual[:operation_name].inspect} operation instead."
53
+ end
54
+ end
55
+
56
+ def verify_message!
57
+ return if @expected[:message] == :any
58
+ unless @expected[:message] == @actual[:message]
59
+ expected_message = " with this message: #{@expected[:message].inspect}" if @expected[:message]
60
+ expected_message ||= " with no message."
61
+
62
+ actual_message = " with this message: #{@actual[:message].inspect}" if @actual[:message]
63
+ actual_message ||= " with no message."
64
+
65
+ raise ExpectationError, "Expected a request to the #{@expected[:operation_name].inspect} operation\n#{expected_message}\n" \
66
+ "Received a request to the #{@actual[:operation_name].inspect} operation\n#{actual_message}"
67
+ end
68
+ end
69
+
70
+ end
71
+ end
@@ -0,0 +1,62 @@
1
+ require "savon/mock"
2
+
3
+ module Savon
4
+ module SpecHelper
5
+
6
+ class Interface
7
+
8
+ def mock!
9
+ Savon.observers << self
10
+ end
11
+
12
+ def unmock!
13
+ Savon.observers.clear
14
+ end
15
+
16
+ def expects(operation_name)
17
+ expectation = MockExpectation.new(operation_name)
18
+ expectations << expectation
19
+ expectation
20
+ end
21
+
22
+ def expectations
23
+ @expectations ||= []
24
+ end
25
+
26
+ def notify(operation_name, builder, globals, locals)
27
+ expectation = expectations.shift
28
+
29
+ if expectation
30
+ expectation.actual(operation_name, builder, globals, locals)
31
+
32
+ expectation.verify!
33
+ expectation.response!
34
+ else
35
+ raise ExpectationError, "Unexpected request to the #{operation_name.inspect} operation."
36
+ end
37
+ rescue ExpectationError
38
+ @expectations.clear
39
+ raise
40
+ end
41
+
42
+ def verify!
43
+ return if expectations.empty?
44
+ expectations.each(&:verify!)
45
+ rescue ExpectationError
46
+ @expectations.clear
47
+ raise
48
+ end
49
+
50
+ end
51
+
52
+ def savon
53
+ @savon ||= Interface.new
54
+ end
55
+
56
+ def verify_mocks_for_rspec
57
+ super if defined? super
58
+ savon.verify!
59
+ end
60
+
61
+ end
62
+ end
data/lib/savon/mock.rb ADDED
@@ -0,0 +1,5 @@
1
+ module Savon
2
+ class ExpectationError < StandardError; end
3
+ end
4
+
5
+ require "savon/mock/expectation"
@@ -0,0 +1,80 @@
1
+ module Savon
2
+ module Model
3
+
4
+ def self.extended(base)
5
+ base.setup
6
+ end
7
+
8
+ def setup
9
+ class_operation_module
10
+ instance_operation_module
11
+ end
12
+
13
+ # Accepts one or more SOAP operations and generates both class and instance methods named
14
+ # after the given operations. Each generated method accepts an optional SOAP message Hash.
15
+ def operations(*operations)
16
+ operations.each do |operation|
17
+ define_class_operation(operation)
18
+ define_instance_operation(operation)
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ # Defines a class-level SOAP operation.
25
+ def define_class_operation(operation)
26
+ class_operation_module.module_eval %{
27
+ def #{operation.to_s.snakecase}(locals = {})
28
+ client.call #{operation.inspect}, locals
29
+ end
30
+ }
31
+ end
32
+
33
+ # Defines an instance-level SOAP operation.
34
+ def define_instance_operation(operation)
35
+ instance_operation_module.module_eval %{
36
+ def #{operation.to_s.snakecase}(locals = {})
37
+ self.class.#{operation.to_s.snakecase} locals
38
+ end
39
+ }
40
+ end
41
+
42
+ # Class methods.
43
+ def class_operation_module
44
+ @class_operation_module ||= Module.new {
45
+
46
+ def client(globals = {})
47
+ @client ||= Savon::Client.new(globals)
48
+ rescue InitializationError
49
+ raise_initialization_error!
50
+ end
51
+
52
+ def global(option, *value)
53
+ client.globals[option] = value
54
+ end
55
+
56
+ def raise_initialization_error!
57
+ raise InitializationError,
58
+ "Expected the model to be initialized with either a WSDL document or the SOAP endpoint and target namespace options.\n" \
59
+ "Make sure to setup the model by calling the .client class method before calling the .global method.\n\n" \
60
+ "client(wsdl: '/Users/me/project/service.wsdl') # to use a local WSDL document\n" \
61
+ "client(wsdl: 'http://example.com?wsdl') # to use a remote WSDL document\n" \
62
+ "client(endpoint: 'http://example.com', namespace: 'http://v1.example.com') # if you don't have a WSDL document"
63
+ end
64
+
65
+ }.tap { |mod| extend(mod) }
66
+ end
67
+
68
+ # Instance methods.
69
+ def instance_operation_module
70
+ @instance_operation_module ||= Module.new {
71
+
72
+ def client
73
+ self.class.client
74
+ end
75
+
76
+ }.tap { |mod| include(mod) }
77
+ end
78
+
79
+ end
80
+ end
@@ -0,0 +1,127 @@
1
+ require "savon/options"
2
+ require "savon/block_interface"
3
+ require "savon/request"
4
+ require "savon/builder"
5
+ require "savon/response"
6
+ require "savon/request_logger"
7
+
8
+ module Savon
9
+ class Operation
10
+
11
+ def self.create(operation_name, wsdl, globals)
12
+ if wsdl.document?
13
+ ensure_name_is_symbol! operation_name
14
+ ensure_exists! operation_name, wsdl
15
+ end
16
+
17
+ new(operation_name, wsdl, globals)
18
+ end
19
+
20
+ def self.ensure_exists!(operation_name, wsdl)
21
+ unless wsdl.soap_actions.include? operation_name
22
+ raise UnknownOperationError, "Unable to find SOAP operation: #{operation_name.inspect}\n" \
23
+ "Operations provided by your service: #{wsdl.soap_actions.inspect}"
24
+ end
25
+ end
26
+
27
+ def self.ensure_name_is_symbol!(operation_name)
28
+ unless operation_name.kind_of? Symbol
29
+ raise ArgumentError, "Expected the first parameter (the name of the operation to call) to be a symbol\n" \
30
+ "Actual: #{operation_name.inspect} (#{operation_name.class})"
31
+ end
32
+ end
33
+
34
+ def initialize(name, wsdl, globals)
35
+ @name = name
36
+ @wsdl = wsdl
37
+ @globals = globals
38
+
39
+ @logger = RequestLogger.new(globals)
40
+ end
41
+
42
+ def build(locals = {}, &block)
43
+ set_locals(locals, block)
44
+ Builder.new(@name, @wsdl, @globals, @locals)
45
+ end
46
+
47
+ def call(locals = {}, &block)
48
+ builder = build(locals, &block)
49
+
50
+ response = Savon.notify_observers(@name, builder, @globals, @locals)
51
+ response ||= call_with_logging build_request(builder)
52
+
53
+ raise_expected_httpi_response! unless response.kind_of?(HTTPI::Response)
54
+
55
+ create_response(response)
56
+ end
57
+
58
+ private
59
+
60
+ def create_response(response)
61
+ if multipart_supported?
62
+ Multipart::Response.new(response, @globals, @locals)
63
+ else
64
+ Response.new(response, @globals, @locals)
65
+ end
66
+ end
67
+
68
+ def multipart_supported?
69
+ return false unless @globals[:multipart] || @locals[:multipart]
70
+
71
+ if Savon.const_defined? :Multipart
72
+ true
73
+ else
74
+ raise 'Unable to find Savon::Multipart. Make sure the savon-multipart gem is installed and loaded.'
75
+ end
76
+ end
77
+
78
+ def set_locals(locals, block)
79
+ locals = LocalOptions.new(locals)
80
+ BlockInterface.new(locals).evaluate(block) if block
81
+
82
+ @locals = locals
83
+ end
84
+
85
+ def call_with_logging(request)
86
+ @logger.log(request) { HTTPI.post(request) }
87
+ end
88
+
89
+ def build_request(builder)
90
+ request = SOAPRequest.new(@globals).build(
91
+ :soap_action => soap_action,
92
+ :cookies => @locals[:cookies]
93
+ )
94
+
95
+ request.url = endpoint
96
+ request.body = builder.to_s
97
+
98
+ # TODO: could HTTPI do this automatically in case the header
99
+ # was not specified manually? [dh, 2013-01-04]
100
+ request.headers["Content-Length"] = request.body.bytesize.to_s
101
+
102
+ request
103
+ end
104
+
105
+ def soap_action
106
+ # soap_action explicitly set to something falsy
107
+ return if @locals.include?(:soap_action) && !@locals[:soap_action]
108
+
109
+ # get the soap_action from local options
110
+ soap_action = @locals[:soap_action]
111
+ # with no local option, but a wsdl, ask it for the soap_action
112
+ soap_action ||= @wsdl.soap_action(@name.to_sym) if @wsdl.document?
113
+ # if there is no soap_action up to this point, fallback to a simple default
114
+ soap_action ||= Gyoku.xml_tag(@name, :key_converter => @globals[:convert_request_keys_to])
115
+ end
116
+
117
+ def endpoint
118
+ @globals[:endpoint] || @wsdl.endpoint
119
+ end
120
+
121
+ def raise_expected_httpi_response!
122
+ raise Error, "Observers need to return an HTTPI::Response to mock " \
123
+ "the request or nil to execute the request."
124
+ end
125
+
126
+ end
127
+ end
@@ -0,0 +1,330 @@
1
+ require "logger"
2
+ require "httpi"
3
+
4
+ module Savon
5
+ class Options
6
+
7
+ def initialize(options = {})
8
+ @options = {}
9
+ assign options
10
+ end
11
+
12
+ attr_reader :option_type
13
+
14
+ def [](option)
15
+ @options[option]
16
+ end
17
+
18
+ def []=(option, value)
19
+ value = [value].flatten
20
+ self.send(option, *value)
21
+ end
22
+
23
+ def include?(option)
24
+ @options.key? option
25
+ end
26
+
27
+ private
28
+
29
+ def assign(options)
30
+ options.each do |option, value|
31
+ self.send(option, value)
32
+ end
33
+ end
34
+
35
+ def method_missing(option, _)
36
+ raise UnknownOptionError, "Unknown #{option_type} option: #{option.inspect}"
37
+ end
38
+
39
+ end
40
+
41
+ class GlobalOptions < Options
42
+
43
+ def initialize(options = {})
44
+ @option_type = :global
45
+
46
+ defaults = {
47
+ :encoding => "UTF-8",
48
+ :soap_version => 1,
49
+ :namespaces => {},
50
+ :logger => Logger.new($stdout),
51
+ :log => true,
52
+ :filters => [],
53
+ :pretty_print_xml => false,
54
+ :raise_errors => true,
55
+ :strip_namespaces => true,
56
+ :convert_response_tags_to => lambda { |tag| tag.snakecase.to_sym},
57
+ :multipart => false,
58
+ }
59
+
60
+ options = defaults.merge(options)
61
+
62
+ # this option is a shortcut on the logger which needs to be set
63
+ # before it can be modified to set the option.
64
+ delayed_level = options.delete(:log_level)
65
+
66
+ super(options)
67
+
68
+ log_level(delayed_level) unless delayed_level.nil?
69
+ end
70
+
71
+ # Location of the local or remote WSDL document.
72
+ def wsdl(wsdl_address)
73
+ @options[:wsdl] = wsdl_address
74
+ end
75
+
76
+ # SOAP endpoint.
77
+ def endpoint(endpoint)
78
+ @options[:endpoint] = endpoint
79
+ end
80
+
81
+ # Target namespace.
82
+ def namespace(namespace)
83
+ @options[:namespace] = namespace
84
+ end
85
+
86
+ # The namespace identifer.
87
+ def namespace_identifier(identifier)
88
+ @options[:namespace_identifier] = identifier
89
+ end
90
+
91
+ # Namespaces for the SOAP envelope.
92
+ def namespaces(namespaces)
93
+ @options[:namespaces] = namespaces
94
+ end
95
+
96
+ # Proxy server to use for all requests.
97
+ def proxy(proxy)
98
+ @options[:proxy] = proxy
99
+ end
100
+
101
+ # A Hash of HTTP headers.
102
+ def headers(headers)
103
+ @options[:headers] = headers
104
+ end
105
+
106
+ # Open timeout in seconds.
107
+ def open_timeout(open_timeout)
108
+ @options[:open_timeout] = open_timeout
109
+ end
110
+
111
+ # Read timeout in seconds.
112
+ def read_timeout(read_timeout)
113
+ @options[:read_timeout] = read_timeout
114
+ end
115
+
116
+ # The encoding to use. Defaults to "UTF-8".
117
+ def encoding(encoding)
118
+ @options[:encoding] = encoding
119
+ end
120
+
121
+ # The global SOAP header. Expected to be a Hash or responding to #to_s.
122
+ def soap_header(header)
123
+ @options[:soap_header] = header
124
+ end
125
+
126
+ # Sets whether elements should be :qualified or unqualified.
127
+ # If you need to use this option, please open an issue and make
128
+ # sure to add your WSDL document for debugging.
129
+ def element_form_default(element_form_default)
130
+ @options[:element_form_default] = element_form_default
131
+ end
132
+
133
+ # Can be used to change the SOAP envelope namespace identifier.
134
+ # If you need to use this option, please open an issue and make
135
+ # sure to add your WSDL document for debugging.
136
+ def env_namespace(env_namespace)
137
+ @options[:env_namespace] = env_namespace
138
+ end
139
+
140
+ # Changes the SOAP version to 1 or 2.
141
+ def soap_version(soap_version)
142
+ @options[:soap_version] = soap_version
143
+ end
144
+
145
+ # Whether or not to raise SOAP fault and HTTP errors.
146
+ def raise_errors(raise_errors)
147
+ @options[:raise_errors] = raise_errors
148
+ end
149
+
150
+ # Whether or not to log.
151
+ def log(log)
152
+ HTTPI.log = log
153
+ @options[:log] = log
154
+ end
155
+
156
+ # The logger to use. Defaults to a Savon::Logger instance.
157
+ def logger(logger)
158
+ @options[:logger] = logger
159
+ end
160
+
161
+ # Changes the Logger's log level.
162
+ def log_level(level)
163
+ levels = { :debug => 0, :info => 1, :warn => 2, :error => 3, :fatal => 4 }
164
+
165
+ unless levels.include? level
166
+ raise ArgumentError, "Invalid log level: #{level.inspect}\n" \
167
+ "Expected one of: #{levels.keys.inspect}"
168
+ end
169
+
170
+ @options[:logger].level = levels[level]
171
+ end
172
+
173
+ # A list of XML tags to filter from logged SOAP messages.
174
+ def filters(*filters)
175
+ @options[:filters] = filters.flatten
176
+ end
177
+
178
+ # Whether to pretty print request and response XML log messages.
179
+ def pretty_print_xml(pretty_print_xml)
180
+ @options[:pretty_print_xml] = pretty_print_xml
181
+ end
182
+
183
+ # Specifies the SSL version to use.
184
+ def ssl_version(version)
185
+ @options[:ssl_version] = version
186
+ end
187
+
188
+ # Whether and how to to verify the connection.
189
+ def ssl_verify_mode(verify_mode)
190
+ @options[:ssl_verify_mode] = verify_mode
191
+ end
192
+
193
+ # Sets the cert key file to use.
194
+ def ssl_cert_key_file(file)
195
+ @options[:ssl_cert_key_file] = file
196
+ end
197
+
198
+ # Sets the cert key password to use.
199
+ def ssl_cert_key_password(password)
200
+ @options[:ssl_cert_key_password] = password
201
+ end
202
+
203
+ # Sets the cert file to use.
204
+ def ssl_cert_file(file)
205
+ @options[:ssl_cert_file] = file
206
+ end
207
+
208
+ # Sets the ca cert file to use.
209
+ def ssl_ca_cert_file(file)
210
+ @options[:ssl_ca_cert_file] = file
211
+ end
212
+
213
+ # HTTP basic auth credentials.
214
+ def basic_auth(*credentials)
215
+ @options[:basic_auth] = credentials.flatten
216
+ end
217
+
218
+ # HTTP digest auth credentials.
219
+ def digest_auth(*credentials)
220
+ @options[:digest_auth] = credentials.flatten
221
+ end
222
+
223
+ # NTLM auth credentials.
224
+ def ntlm(*credentials)
225
+ @options[:ntlm] = credentials.flatten
226
+ end
227
+
228
+ # WSSE auth credentials for Akami.
229
+ def wsse_auth(*credentials)
230
+ @options[:wsse_auth] = credentials.flatten
231
+ end
232
+
233
+ # Instruct Akami to enable wsu:Timestamp headers.
234
+ def wsse_timestamp(*timestamp)
235
+ @options[:wsse_timestamp] = timestamp.flatten
236
+ end
237
+
238
+ # Instruct Nori whether to strip namespaces from XML nodes.
239
+ def strip_namespaces(strip_namespaces)
240
+ @options[:strip_namespaces] = strip_namespaces
241
+ end
242
+
243
+ # Tell Gyoku how to convert Hash key Symbols to XML tags.
244
+ # Accepts one of :lower_camelcase, :camelcase, :upcase, or :none.
245
+ def convert_request_keys_to(converter)
246
+ @options[:convert_request_keys_to] = converter
247
+ end
248
+
249
+ # Tell Nori how to convert XML tags from the SOAP response into Hash keys.
250
+ # Accepts a lambda or a block which receives an XML tag and returns a Hash key.
251
+ # Defaults to convert tags to snakecase Symbols.
252
+ def convert_response_tags_to(converter = nil, &block)
253
+ @options[:convert_response_tags_to] = block || converter
254
+ end
255
+
256
+ # Instruct Savon to create a multipart response if available.
257
+ def multipart(multipart)
258
+ @options[:multipart] = multipart
259
+ end
260
+ end
261
+
262
+ class LocalOptions < Options
263
+
264
+ def initialize(options = {})
265
+ @option_type = :local
266
+
267
+ defaults = {
268
+ :advanced_typecasting => true,
269
+ :response_parser => :nokogiri,
270
+ :multipart => false
271
+ }
272
+
273
+ super defaults.merge(options)
274
+ end
275
+
276
+ # The local SOAP header. Expected to be a Hash or respond to #to_s.
277
+ # Will be merged with the global SOAP header if both are Hashes.
278
+ # Otherwise the local option will be prefered.
279
+ def soap_header(header)
280
+ @options[:soap_header] = header
281
+ end
282
+
283
+ # The SOAP message to send. Expected to be a Hash or a String.
284
+ def message(message)
285
+ @options[:message] = message
286
+ end
287
+
288
+ # SOAP message tag (formerly known as SOAP input tag). If it's not set, Savon retrieves the name from
289
+ # the WSDL document (if available). Otherwise, Gyoku converts the operation name into an XML element.
290
+ def message_tag(message_tag)
291
+ @options[:message_tag] = message_tag
292
+ end
293
+
294
+ # Attributes for the SOAP message tag.
295
+ def attributes(attributes)
296
+ @options[:attributes] = attributes
297
+ end
298
+
299
+ # Value of the SOAPAction HTTP header.
300
+ def soap_action(soap_action)
301
+ @options[:soap_action] = soap_action
302
+ end
303
+
304
+ # Cookies to be used for the next request.
305
+ def cookies(cookies)
306
+ @options[:cookies] = cookies
307
+ end
308
+
309
+ # The SOAP request XML to send. Expected to be a String.
310
+ def xml(xml)
311
+ @options[:xml] = xml
312
+ end
313
+
314
+ # Instruct Nori to use advanced typecasting.
315
+ def advanced_typecasting(advanced)
316
+ @options[:advanced_typecasting] = advanced
317
+ end
318
+
319
+ # Instruct Nori to use :rexml or :nokogiri to parse the response.
320
+ def response_parser(parser)
321
+ @options[:response_parser] = parser
322
+ end
323
+
324
+ # Instruct Savon to create a multipart response if available.
325
+ def multipart(multipart)
326
+ @options[:multipart] = multipart
327
+ end
328
+
329
+ end
330
+ end