Skip to content

Commit

Permalink
Merge pull request #312 from timabdulla/array-namespaces-fix
Browse files Browse the repository at this point in the history
Fix namespaces not being properly added to arrays.
  • Loading branch information
jkingdon committed Aug 16, 2012
2 parents c9d1f1b + f3ac4cc commit 3ad2787
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 17 deletions.
2 changes: 1 addition & 1 deletion lib/savon/soap/xml.rb
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ def body_to_xml

def add_namespaces_to_body(hash, path = [input[1].to_s])
return unless hash
return hash if hash.kind_of?(Array)
return hash.map { |value| add_namespaces_to_body(value, path) } if hash.kind_of?(Array)
return hash.to_s unless hash.kind_of? Hash

hash.inject({}) do |newhash, (key, value)|
Expand Down
31 changes: 31 additions & 0 deletions spec/fixtures/wsdl/multiple_namespaces.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,20 @@
</s:sequence>
</s:complexType>
</s:element>
<s:element name="Lookup">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="articles" type="article:ArrayOfArticle" />
</s:sequence>
</s:complexType>
</s:element>
</s:schema>
<s:schema elementFormDefault="qualified" targetNamespace="http://example.com/article">
<s:complexType name="ArrayOfArticle">
<s:sequence>
<s:element minOccurs="0" maxOccurs="unbounded" name="Article" type="article:Article"/>
</s:sequence>
</s:complexType>
<s:complexType name="Article">
<s:sequence>
<s:element minOccurs="0" name="Author" type="s:string"/>
Expand All @@ -35,11 +47,21 @@
<message name="SaveSoapOut">
<part name="parameters" element="actions:SaveResponse"/>
</message>
<message name="LookupSoapIn">
<part name="parameters" element="actions:Lookup"/>
</message>
<message name="LookupSoapOut">
<part name="parameters" element="actions:LookupResponse"/>
</message>
<portType name="ArticleSoap">
<operation name="Save">
<input message="actions:SaveSoapIn"/>
<output message="actions:SaveSoapOut"/>
</operation>
<operation name="Lookup">
<input message="actions:LookupSoapIn"/>
<input message="actions:LookupSoapOut"/>
</operation>
</portType>
<binding name="ArticleSoap" type="actions:ArticleSoap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
Expand All @@ -52,6 +74,15 @@
<soap:body use="literal"/>
</output>
</operation>
<operation name="Lookup">
<soap:operation soapAction="http://example.com/actions.Lookup" style="document"/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
</binding>
<service name="StudyMDL">
<port name="StudyMDLSoap" binding="actions:StudyMDLSoap">
Expand Down
58 changes: 42 additions & 16 deletions spec/savon/client_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -383,29 +383,55 @@
end

context "with an Array of namespaced items" do
let(:client) { Savon::Client.new { wsdl.document = "spec/fixtures/wsdl/taxcloud.xml" } }
context "with a single namespace" do
let(:client) { Savon::Client.new { wsdl.document = "spec/fixtures/wsdl/taxcloud.xml" } }

before do
HTTPI.stubs(:get).returns(new_response(:body => Fixture.wsdl(:taxcloud)))
HTTPI.stubs(:post).returns(new_response)
before do
HTTPI.stubs(:get).returns(new_response(:body => Fixture.wsdl(:taxcloud)))
HTTPI.stubs(:post).returns(new_response)
end

it "should namespaces each Array item as expected" do
HTTPI::Request.any_instance.expects(:body=).with do |value|
xml = Nokogiri::XML(value)
!!xml.at_xpath(".//tc:cartItems/tc:CartItem/tc:ItemID", { "tc" => "http://taxcloud.net" })
end

address = { "Address1" => "888 6th Ave", "Address2" => nil, "City" => "New York", "State" => "NY", "Zip5" => "10001", "Zip4" => nil }
cart_item = { "Index" => 0, "ItemID" => "SKU-TEST", "TIC" => "00000", "Price" => 50.0, "Qty" => 1 }

client.request :lookup, :body => {
"customerID" => 123,
"cartID" => 456,
"cartItems" => { "CartItem" => [cart_item] },
"origin" => address,
"destination" => address
}
end
end

context "with multiple namespaces" do
let(:client) { Savon::Client.new { wsdl.document = "spec/fixtures/wsdl/multiple_namespaces.xml" } }

it "should namespaces each Array item as expected" do
HTTPI::Request.any_instance.expects(:body=).with do |value|
value.include?("<ins0:cartItems><ins0:CartItem>") && value.include?("<tns:ItemID>SKU-TEST</tns:ItemID>")
before do
HTTPI.stubs(:get).returns(new_response(:body => Fixture.wsdl(:multiple_namespaces)))
HTTPI.stubs(:post).returns(new_response)
end

address = { "Address1" => "888 6th Ave", "Address2" => nil, "City" => "New York", "State" => "NY", "Zip5" => "10001", "Zip4" => nil }
cart_item = { "Index" => 0, "ItemID" => "SKU-TEST", "TIC" => "00000", "Price" => 50.0, "Qty" => 1 }
it "should namespace each Array item as expected" do
HTTPI::Request.any_instance.expects(:body=).with do |value|
xml = Nokogiri::XML(value)
namespaces = { "actions" => "http://example.com/actions", "article" => "http://example.com/article" }
!!xml.at_xpath(".//actions:Lookup/actions:articles/article:Article/article:Author", namespaces)
end

client.request :lookup, :body => {
"customerID" => 123,
"cartID" => 456,
"cartItems" => { "CartItem" => [cart_item] },
"origin" => address,
"destination" => address
}
article = { "Author" => "John Smith", "Title" => "Modern SOAP" }
client.request :lookup, :body => {
"articles" => { "Article" => [article] }
}
end
end

end

context "without a WSDL document" do
Expand Down

0 comments on commit 3ad2787

Please sign in to comment.