apricoteatsgorilla 0.5.9 → 0.5.10

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -6,7 +6,11 @@ for working with SOAP services.
6
6
 
7
7
  == Install
8
8
 
9
- $ gem install rubiii-apricoteatsgorilla -s http://gems.github.com
9
+ The gem for Apricot eats Gorilla 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 apricoteatsgorilla
10
14
 
11
15
  == Dependencies
12
16
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.9
1
+ 0.5.10
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{apricoteatsgorilla}
8
- s.version = "0.5.9"
8
+ s.version = "0.5.10"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Daniel Harrington"]
12
- s.date = %q{2009-10-06}
12
+ s.date = %q{2009-10-08}
13
13
  s.description = %q{SOAP communication helper}
14
14
  s.email = %q{me@rubiii.com}
15
15
  s.extra_rdoc_files = [
@@ -31,16 +31,16 @@ Gem::Specification.new do |s|
31
31
  "spec/apricoteatsgorilla/xml_to_hash_spec.rb",
32
32
  "spec/spec_helper.rb"
33
33
  ]
34
- s.has_rdoc = true
35
34
  s.homepage = %q{http://github.com/rubiii/apricoteatsgorilla}
36
35
  s.rdoc_options = ["--charset=UTF-8", "--title", "Apricot eats Gorilla", "--main", "README.rdoc", "--line-numbers", "--inline-source"]
37
36
  s.require_paths = ["lib"]
38
- s.rubygems_version = %q{1.3.1}
37
+ s.rubygems_version = %q{1.3.5}
39
38
  s.summary = %q{SOAP communication helper}
40
39
  s.test_files = [
41
40
  "spec/apricoteatsgorilla/apricoteatsgorilla_spec.rb",
42
41
  "spec/apricoteatsgorilla/hash_to_xml_spec.rb",
43
42
  "spec/apricoteatsgorilla/soap_envelope_spec.rb",
43
+ "spec/apricoteatsgorilla/wsse_spec.rb",
44
44
  "spec/apricoteatsgorilla/xml_node_spec.rb",
45
45
  "spec/apricoteatsgorilla/xml_to_hash_spec.rb",
46
46
  "spec/spec_helper.rb"
@@ -48,7 +48,7 @@ Gem::Specification.new do |s|
48
48
 
49
49
  if s.respond_to? :specification_version then
50
50
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
51
- s.specification_version = 2
51
+ s.specification_version = 3
52
52
 
53
53
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
54
54
  s.add_runtime_dependency(%q<hpricot>, ["= 0.8.241"])
@@ -1,4 +1,4 @@
1
- %w(digest/sha1 rubygems hpricot).each do |gem|
1
+ %w(rubygems hpricot).each do |gem|
2
2
  require gem
3
3
  end
4
4
 
@@ -8,25 +8,20 @@ end
8
8
  # SOAP messages (XML) and Ruby Hashes and comes with some additional helpers
9
9
  # for working with SOAP services.
10
10
  class ApricotEatsGorilla
11
- class << self
12
-
13
- # SOAP dateTime format.
14
- SOAPDateTimeFormat = "%Y-%m-%dT%H:%M:%S"
15
11
 
16
- # SOAP dateTime Regexp.
17
- SOAPDateTimeRegexp = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/
12
+ # SOAP dateTime format.
13
+ SOAPDateTimeFormat = "%Y-%m-%dT%H:%M:%S"
18
14
 
19
- # SOAP namespaces by SOAP version.
20
- SOAPNamespace = {
21
- 1 => "http://schemas.xmlsoap.org/soap/envelope/",
22
- 2 => "http://www.w3.org/2003/05/soap-envelope"
23
- }
15
+ # SOAP dateTime Regexp.
16
+ SOAPDateTimeRegexp = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/
24
17
 
25
- # Namespace for WS Security Secext
26
- WSENamespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
18
+ # SOAP namespaces by SOAP version.
19
+ SOAPNamespace = {
20
+ 1 => "http://schemas.xmlsoap.org/soap/envelope/",
21
+ 2 => "http://www.w3.org/2003/05/soap-envelope"
22
+ }
27
23
 
28
- # Namespace for WS Security Utility
29
- WSUNamespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
24
+ class << self
30
25
 
31
26
  # Flag to enable sorting of Hash keys.
32
27
  attr_accessor :sort_keys
@@ -124,8 +119,11 @@ class ApricotEatsGorilla
124
119
  end
125
120
 
126
121
  # Builds a SOAP request envelope and includes the content of a given
127
- # +block+ into the envelope body. Accepts a Hash of additional +namespaces+
128
- # to set. Also accepts an optional +version+ to specify the SOAP envelope
122
+ # +block+ into the envelope body.
123
+ #
124
+ # Takes an optional Hash of additional +namespaces+ to set on the SOAP envelope.
125
+ # Takes an optional Hash of +wsse+ details for WSSE authentication.
126
+ # Furthermore accepts an optional +version+ to specify the SOAP envelope
129
127
  # namespace to use by SOAP version.
130
128
  #
131
129
  # ==== Examples
@@ -135,22 +133,66 @@ class ApricotEatsGorilla
135
133
  # end
136
134
  #
137
135
  # # => '<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
136
+ # # => <env:Header />
138
137
  # # => <env:Body>
139
138
  # # => <apricot><eats>Gorilla</eats></apricot>
140
139
  # # => </env:Body>
141
140
  # # => </env:Envelope>'
142
141
  #
143
- # ApricotEatsGorilla.soap_envelope(:wsdl => "http://example.com") { "pureText" }
142
+ # Customize namespaces:
143
+ #
144
+ # soap_env = { "xmlns:wsdl" => "http://example.com" }
145
+ # ApricotEatsGorilla.soap_envelope(soap_env)
144
146
  #
145
147
  # # => '<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsdl="http://example.com">
146
- # # => <env:Body>
147
- # # => pureText
148
- # # => </env:Body>
148
+ # # => <env:Header />
149
+ # # => <env:Body />
149
150
  # # => </env:Envelope>'
150
- def soap_envelope(namespaces = {}, wsse = {}, version = 1)
151
- namespaces[:env] ||= SOAPNamespace[version] if SOAPNamespace[version]
151
+ #
152
+ # WSSE authentication (PasswordText):
153
+ #
154
+ # wsse_args = { :username => 'dude', :password => 'secret' }
155
+ # ApricotEatsGorilla.soap_envelope(nil, wsse_args)
156
+ #
157
+ # # => '<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
158
+ # # => <env:Header>
159
+ # # => <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
160
+ # # => <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
161
+ # # => <wsse:Username>dude</wsse:Username>
162
+ # # => <wsse:Password>secret</wsse:Password>
163
+ # # => <wsse:Nonce>c5e4eab16eed977a71fa6797999319e0749b3a70</wsse:Nonce>
164
+ # # => <wsu:Created>2009-10-06T14:48:13</wsu:Created>
165
+ # # => </wsse:UsernameToken>
166
+ # # => </wsse:Security>
167
+ # # => </env:Header>
168
+ # # => <env:Body />
169
+ # # => </env:Envelope>'
170
+ #
171
+ # WSSE authentication (PasswordDigest):
172
+ #
173
+ # wsse_args = { :username => 'dude', :password => 'secret', :digest => true }
174
+ # ApricotEatsGorilla.soap_envelope(nil, wsse_args)
175
+ #
176
+ # # => '<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
177
+ # # => <env:Header>
178
+ # # => <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
179
+ # # => <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
180
+ # # => <wsse:Username>dude</wsse:Username>
181
+ # # => <wsse:Password Type="wsse:PasswordDigest">MTJjYzcyNjY1MDM5MzJmYjZlYzRmMGZhZDY2YTI0MjFiMzYwYzE0ZQ==</wsse:Password>
182
+ # # => <wsse:Nonce>fea0cf847cf2d1f9e402975b359e7268cc3a65d4</wsse:Nonce>
183
+ # # => <wsu:Created>2009-10-06T19:24:30</wsu:Created>
184
+ # # => </wsse:UsernameToken>
185
+ # # => </wsse:Security>
186
+ # # => </env:Header>
187
+ # # => <env:Body />
188
+ # # => </env:Envelope>'
189
+ def soap_envelope(namespaces = nil, wsse = nil, version = 1)
190
+ namespaces = {} unless namespaces.kind_of? Hash
191
+ if namespaces["xmlns:env"].nil? && SOAPNamespace[version]
192
+ namespaces["xmlns:env"] = SOAPNamespace[version]
193
+ end
152
194
 
153
- header = xml_node("env:Header") { soap_header(wsse) }
195
+ header = xml_node("env:Header") { wsse_soap_header(wsse) }
154
196
  body = xml_node("env:Body") { (yield if block_given?) || nil }
155
197
 
156
198
  xml_node("env:Envelope", namespaces) { header + body }
@@ -158,31 +200,17 @@ class ApricotEatsGorilla
158
200
 
159
201
  private
160
202
 
161
- def soap_header(wsse)
162
- return nil if !wsse || wsse.empty?
163
-
164
- now = Time.now
165
- xml_node("wsse:Security", :wsse => WSENamespace) do
166
- xml_node("wsse:UsernameToken", :wsu => WSUNamespace) do
167
- xml_node("wsse:Username") { wsse[:username] } <<
168
- xml_node("wsse:Password") { wsse[:password] } <<
169
- xml_node("wsse:Nonce") { wsse_nonce(now) } <<
170
- xml_node("wsu:Created") { now.strftime(SOAPDateTimeFormat) }
171
- end
203
+ # Returns the SOAP header for WSSE authentication. Expects a Hash with +wsse+
204
+ # details including :username, :password and an optional boolean value for
205
+ # :digest, indicating if passwordDigest should be used.
206
+ def wsse_soap_header(wsse)
207
+ if wsse
208
+ WSSE.soap_header(wsse[:username], wsse[:password], wsse[:digest])
209
+ else
210
+ nil
172
211
  end
173
212
  end
174
213
 
175
- # Returns a random WSSE nonce.
176
- def wsse_nonce(now = nil)
177
- now ||= Time.now
178
- Digest::SHA1.hexdigest(random_string + now.to_i.to_s)
179
- end
180
-
181
- # Returns a random string of a certain +length+.
182
- def random_string(length = 20)
183
- (0...length).map { ("a".."z").to_a[rand(26)] }.join
184
- end
185
-
186
214
  # Translates a single XML root node to a Ruby Hash.
187
215
  def single_xml_root_node_to_hash(root)
188
216
  if root.first.children.nil?
@@ -215,12 +243,9 @@ class ApricotEatsGorilla
215
243
  value = create_hash_value(child)
216
244
 
217
245
  case hash[key]
218
- when Array
219
- hash[key] << value
220
- when nil
221
- hash[key] = value
222
- else
223
- hash[key] = [ hash[key].dup, value ]
246
+ when Array then hash[key] << value
247
+ when nil then hash[key] = value
248
+ else hash[key] = [ hash[key].dup, value ]
224
249
  end
225
250
  end
226
251
 
@@ -273,12 +298,13 @@ class ApricotEatsGorilla
273
298
  # Returns an XML tag with a given +name+. Accepts a +block+ for tag content.
274
299
  # Defaults to returning an empty-element tag in case no block was given.
275
300
  # Also accepts a Hash of +attributes+ to be added to the XML tag.
276
- def xml_node(name, attributes = {})
277
- node = XMLNode.new(name.to_s)
301
+ def xml_node(name, attributes = nil)
302
+ node = XMLNode.new(name.to_s, nodes_to_namespace)
278
303
  node.to_lower_camel_case! unless disable_tag_names_to_lower_camel_case
279
- node.namespace_from_hash!(nodes_to_namespace)
304
+
280
305
  node.attributes = sort_hash_keys(attributes)
281
306
  node.body = yield if block_given?
307
+
282
308
  node.to_tag
283
309
  end
284
310
 
@@ -290,14 +316,10 @@ class ApricotEatsGorilla
290
316
  # Converts XML values to more natural Ruby objects.
291
317
  def map_xml_value(value)
292
318
  case value
293
- when SOAPDateTimeRegexp
294
- DateTime.parse(value)
295
- when "true"
296
- true
297
- when "false"
298
- false
299
- else
300
- value
319
+ when SOAPDateTimeRegexp then DateTime.parse(value)
320
+ when "true" then true
321
+ when "false" then false
322
+ else value
301
323
  end
302
324
  end
303
325
 
@@ -316,7 +338,7 @@ class ApricotEatsGorilla
316
338
 
317
339
  # Returns a sorted version of a given +hash+ if +sort_keys+ is enabled.
318
340
  def sort_hash_keys(hash)
319
- return hash unless sort_keys
341
+ return hash unless hash && sort_keys
320
342
  hash.keys.sort_by { |key| key.to_s }.map { |key| [ key, hash[key] ] }
321
343
  end
322
344
 
@@ -10,6 +10,12 @@ class XMLNode < String
10
10
  # Node body content.
11
11
  attr_writer :body
12
12
 
13
+ # Initializer + expects the node +name+ and an optional Hash of +namespaces+.
14
+ def initialize(name, namespaces = {})
15
+ super(name)
16
+ set_namespace(namespaces)
17
+ end
18
+
13
19
  # Strips the namespace from this node.
14
20
  def strip_namespace!
15
21
  sub!(/.+:(.+)/, '\1')
@@ -27,14 +33,6 @@ class XMLNode < String
27
33
  gsub!(/_(.)/) { $1.upcase }
28
34
  end
29
35
 
30
- # Checks if this node is included in a given Hash of +namespaces+ and
31
- # sets the namespace for this node in case it was found in the Hash.
32
- def namespace_from_hash!(namespaces)
33
- if namespaces && !namespaces.empty?
34
- namespaces.each { |ns, nodes| @namespace = ns if self_included? nodes }
35
- end
36
- end
37
-
38
36
  # Returns this node as an XML tag including a namespace, attributes
39
37
  # and a body in case these values were supplied.
40
38
  def to_tag
@@ -47,6 +45,14 @@ class XMLNode < String
47
45
 
48
46
  private
49
47
 
48
+ # Checks if this node is included in a given Hash of +namespaces+ and
49
+ # sets the namespace for this node in case it was found in the Hash.
50
+ def set_namespace(namespaces)
51
+ if namespaces && !namespaces.empty?
52
+ namespaces.each { |ns, nodes| @namespace = ns if self_included? nodes }
53
+ end
54
+ end
55
+
50
56
  # Returns +true+ if self as a String or a Symbol is included in a
51
57
  # given +array+. Returns +false+ otherwise.
52
58
  def self_included?(array)
@@ -63,7 +69,7 @@ private
63
69
  # in case no attributes were defined.
64
70
  def attributes
65
71
  if @attributes
66
- @attributes.map { |key, value| %Q( xmlns:#{key}="#{value}") }
72
+ @attributes.map { |key, value| " #{key}=\"#{value}\"" }
67
73
  else
68
74
  ""
69
75
  end
@@ -1,3 +1,3 @@
1
- %w(apricoteatsgorilla xml_node).each do |file|
1
+ %w(apricoteatsgorilla xml_node wsse).each do |file|
2
2
  require File.join(File.dirname(__FILE__), "apricoteatsgorilla", file)
3
- end
3
+ end
@@ -12,7 +12,7 @@ describe ApricotEatsGorilla do
12
12
  end
13
13
 
14
14
  it "returns a SOAP envelope with a custom namespace and body content" do
15
- ApricotEatsGorilla.soap_envelope(:wsdl => "http://example.com") do
15
+ ApricotEatsGorilla.soap_envelope("xmlns:wsdl" => "http://example.com") do
16
16
  "<id>123</id>"
17
17
  end.should == '<env:Envelope' <<
18
18
  ' xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"' <<
@@ -22,23 +22,39 @@ describe ApricotEatsGorilla do
22
22
  end
23
23
 
24
24
  it "does not change an already defined SOAP envelope namespace" do
25
- ApricotEatsGorilla.soap_envelope(:env => "http://example.com").should ==
25
+ ApricotEatsGorilla.soap_envelope("xmlns:env" => "http://example.com").should ==
26
26
  '<env:Envelope xmlns:env="http://example.com">' <<
27
27
  '<env:Header />' <<
28
28
  '<env:Body /></env:Envelope>'
29
29
  end
30
30
 
31
31
  it "sets the SOAP envelope namespace for SOAP version 1.2 if requested" do
32
- ApricotEatsGorilla.soap_envelope({}, {}, 2).should ==
32
+ ApricotEatsGorilla.soap_envelope(nil, nil, 2).should ==
33
33
  '<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope">' <<
34
34
  '<env:Header />' <<
35
35
  '<env:Body /></env:Envelope>'
36
36
  end
37
37
 
38
38
  it "does not set a SOAP envelope namespace in case of an invalid SOAP version" do
39
- ApricotEatsGorilla.soap_envelope({}, {}, 123).should ==
39
+ ApricotEatsGorilla.soap_envelope(nil, nil, 123).should ==
40
40
  '<env:Envelope><env:Header /><env:Body /></env:Envelope>'
41
41
  end
42
+
43
+ it "adds WSSE authentication details to the SOAP header" do
44
+ wsse = { :username => "apricot", :password => "gorilla" }
45
+ result = ApricotEatsGorilla.soap_envelope(nil, wsse)
46
+
47
+ ApricotEatsGorilla[result, "//env:Header//wsse:Username"].should == wsse[:username]
48
+ ApricotEatsGorilla[result, "//env:Header//wsse:Password"].should == wsse[:password]
49
+ end
50
+
51
+ it "adds WSSE authentication details for passwordDigest to the SOAP header" do
52
+ wsse = { :username => "apricot", :password => "gorilla", :digest => true }
53
+ result = ApricotEatsGorilla.soap_envelope(nil, wsse)
54
+
55
+ ApricotEatsGorilla[result, "//env:Header//wsse:Username"].should == wsse[:username]
56
+ ApricotEatsGorilla[result, "//env:Header//wsse:Password"].should_not == wsse[:password]
57
+ end
42
58
  end
43
59
 
44
60
  end
@@ -0,0 +1,50 @@
1
+ require File.join(File.dirname(__FILE__), "..", "spec_helper")
2
+
3
+ describe WSSE do
4
+
5
+ # soap_header
6
+ describe "soap_header" do
7
+ before do
8
+ @username = "apricot"
9
+ @password = "gorilla"
10
+ end
11
+
12
+ it "returns a SOAP header for WSSE authentication" do
13
+ xml_header = WSSE.soap_header(@username, @password)
14
+ hash_header = ApricotEatsGorilla[xml_header, "wsse:Security//wsse:UsernameToken"]
15
+
16
+ hash_header[:username].should == @username
17
+ hash_header[:password].should == @password
18
+ hash_header[:nonce].should be_a(String)
19
+ hash_header[:created].should be_a(DateTime)
20
+ end
21
+
22
+ it "returns a SOAP header for WSSE authentication with :digest set to +true+" do
23
+ xml_header = WSSE.soap_header(@username, @password, true)
24
+ hash_header = ApricotEatsGorilla[xml_header, "wsse:Security//wsse:UsernameToken"]
25
+
26
+ hash_header[:username].should == @username
27
+ hash_header[:password].should_not == @password
28
+ hash_header[:nonce].should be_a(String)
29
+ hash_header[:created].should be_a(DateTime)
30
+ end
31
+ end
32
+
33
+ # password_node
34
+ describe "password_node" do
35
+ before do
36
+ @password = "gorilla"
37
+ @created_at = Time.now.strftime(ApricotEatsGorilla::SOAPDateTimeFormat)
38
+ end
39
+
40
+ it "returns a WSSE password node containing the password as plain-text" do
41
+ WSSE.password_node(@password, @created_at).should ==
42
+ "<wsse:Password>" << @password << "</wsse:Password>"
43
+ end
44
+
45
+ it "returns a WSSE password node containing a password digest when :digest was set to +true+" do
46
+ WSSE.password_node(@password, @created_at, true).match(@password).should be_nil
47
+ end
48
+ end
49
+
50
+ end
@@ -2,6 +2,30 @@ require File.join(File.dirname(__FILE__), "..", "spec_helper")
2
2
 
3
3
  describe XMLNode do
4
4
 
5
+ # initialize
6
+ describe "initialize" do
7
+ it "does not require any namespaces" do
8
+ node = XMLNode.new("apricot")
9
+
10
+ node.should == "apricot"
11
+ node.to_tag.should == "<apricot />"
12
+ end
13
+
14
+ it "namespaces the node if it's included in the given Hash of namespaces" do
15
+ node = XMLNode.new("apricot", :wsdl => [ :apricot ])
16
+
17
+ node.should == "apricot"
18
+ node.to_tag.should == "<wsdl:apricot />"
19
+ end
20
+
21
+ it "does nothing if the node is not included in the given Hash of namespaces" do
22
+ node = XMLNode.new("apricot", :wsdl => [ :some_key ])
23
+
24
+ node.should == "apricot"
25
+ node.to_tag.should == "<apricot />"
26
+ end
27
+ end
28
+
5
29
  # strip_namespace!
6
30
  describe "strip_namespace!" do
7
31
  it "strips the namespace from the node" do
@@ -29,25 +53,6 @@ describe XMLNode do
29
53
  end
30
54
  end
31
55
 
32
- # namespace_from_hash!
33
- describe "namespace_from_hash!" do
34
- it "namespaces the node if it's included in the given Hash" do
35
- node = XMLNode.new("apricot")
36
- node.namespace_from_hash!(:wsdl => [ :apricot ])
37
-
38
- node.should == "apricot"
39
- node.to_tag.should == "<wsdl:apricot />"
40
- end
41
-
42
- it "does nothing if the node is not included in the given Hash" do
43
- node = XMLNode.new("apricot")
44
- node.namespace_from_hash!(:wsdl => [ :some_key ])
45
-
46
- node.should == "apricot"
47
- node.to_tag.should == "<apricot />"
48
- end
49
- end
50
-
51
56
  # to_tag
52
57
  describe "to_tag" do
53
58
  it "returns an empty-element tag for a bare node" do
@@ -56,15 +61,13 @@ describe XMLNode do
56
61
  end
57
62
 
58
63
  it "returns a namespaced empty-element tag for a namespaced node" do
59
- node = XMLNode.new("apricot")
60
- node.namespace_from_hash!(:wsdl => [ :apricot ])
61
-
64
+ node = XMLNode.new("apricot", :wsdl => [ :apricot ])
62
65
  node.to_tag.should == "<wsdl:apricot />"
63
66
  end
64
67
 
65
68
  it "returns an empty-element tag with an attribute for an attributed node" do
66
69
  node = XMLNode.new("apricot")
67
- node.attributes = { :wsdl => "http://example.com" }
70
+ node.attributes = { "xmlns:wsdl" => "http://example.com" }
68
71
 
69
72
  node.to_tag.should == '<apricot xmlns:wsdl="http://example.com" />'
70
73
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: apricoteatsgorilla
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.9
4
+ version: 0.5.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Harrington
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-10-06 00:00:00 +02:00
12
+ date: 2009-10-08 00:00:00 +02:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -87,12 +87,13 @@ requirements: []
87
87
  rubyforge_project:
88
88
  rubygems_version: 1.3.5
89
89
  signing_key:
90
- specification_version: 2
90
+ specification_version: 3
91
91
  summary: SOAP communication helper
92
92
  test_files:
93
93
  - spec/apricoteatsgorilla/apricoteatsgorilla_spec.rb
94
94
  - spec/apricoteatsgorilla/hash_to_xml_spec.rb
95
95
  - spec/apricoteatsgorilla/soap_envelope_spec.rb
96
+ - spec/apricoteatsgorilla/wsse_spec.rb
96
97
  - spec/apricoteatsgorilla/xml_node_spec.rb
97
98
  - spec/apricoteatsgorilla/xml_to_hash_spec.rb
98
99
  - spec/spec_helper.rb