apricoteatsgorilla 0.5.9 → 0.5.10

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 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