Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Parse <message> and <portType> in WSDL.

Write integration test (currently pending) for multiple namespaces.
  • Loading branch information...
commit 3d177352480896ab7dd5cfcd72523d39852cc487 1 parent c7324f3
Jim Kingdon authored
View
28 lib/savon/wsdl/parser.rb
@@ -16,6 +16,9 @@ def initialize
@path = []
@operations = {}
@namespaces = {}
+ @messages = {}
+ @input_message = {}
+ @types = {}
@element_form_default = :unqualified
end
@@ -25,6 +28,15 @@ def initialize
# Returns the SOAP operations.
attr_reader :operations
+ # Returns a map from the message name to its element
+ attr_reader :messages
+
+ # Returns a map from the action to its input message name
+ attr_reader :input_message
+
+ # Returns a map from a type name to a hash with type information
+ attr_reader :types
+
# Returns the SOAP endpoint.
attr_reader :endpoint
@@ -48,6 +60,22 @@ def tag_start(tag, attrs)
@section = nil unless @namespaces[namespace].starts_with? "http://schemas.xmlsoap.org/wsdl/soap"
end
+ if @section == :definitions && tag == "message"
+ @current_message = attrs["name"]
+ end
+
+ if @section == :message && tag == "part" && attrs["name"] == "parameters"
+ @messages[@current_message] = attrs["element"].strip_namespace
+ end
+
+ if @section == :portType && tag == "operation"
+ @current_action = attrs["name"]
+ end
+
+ if @section == :portType && tag == "input"
+ @input_message[@current_action] = attrs["message"].strip_namespace
+ end
+
@section = tag.to_sym if Sections.include?(tag) && depth <= 2
@namespace ||= attrs["targetNamespace"] if @section == :definitions
View
61 spec/fixtures/wsdl/multiple_namespaces.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<definitions
+ xmlns="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
+ xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
+ xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
+ xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:s="http://www.w3.org/2001/XMLSchema"
+ xmlns:article="http://example.com/article"
+ xmlns:actions="http://example.com/actions"
+ targetNamespace="http://example.com/actions">
+ <types>
+ <s:schema elementFormDefault="qualified" targetNamespace="http://example.com/actions">
+ <s:element name="Save">
+ <s:complexType>
+ <s:sequence>
+ <s:element name="article" type="article:Article"/>
+ </s:sequence>
+ </s:complexType>
+ </s:element>
+ </s:schema>
+ <s:schema elementFormDefault="qualified" targetNamespace="http://example.com/article">
+ <s:complexType name="Article">
+ <s:sequence>
+ <s:element minOccurs="0" name="Author" type="s:string"/>
+ <s:element minOccurs="0" name="Title" type="s:string"/>
+ </s:sequence>
+ </s:complexType>
+ </s:schema>
+ </types>
+ <message name="SaveSoapIn">
+ <part name="parameters" element="actions:Save"/>
+ </message>
+ <message name="SaveSoapOut">
+ <part name="parameters" element="actions:SaveResponse"/>
+ </message>
+ <portType name="ArticleSoap">
+ <operation name="Save">
+ <input message="actions:SaveSoapIn"/>
+ <output message="actions:SaveSoapOut"/>
+ </operation>
+ </portType>
+ <binding name="ArticleSoap" type="actions:ArticleSoap">
+ <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
+ <operation name="Save">
+ <soap:operation soapAction="http://example.com/actions.Save" 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">
+ <soap:address location="http://example.com:1234/soap"/>
+ </port>
+ </service>
+</definitions>
View
20 spec/savon/client_spec.rb
@@ -268,6 +268,26 @@
end
end
+ context "when the WSDL specifies multiple namespaces" do
+ before do
+ HTTPI.stubs(:get).returns(new_response(:body => Fixture.wsdl(:multiple_namespaces)))
+ HTTPI.stubs(:post).returns(new_response)
+ end
+
+ it "should qualify each element with the appropriate namespace" do
+ pending("lots of work over in parser_spec before we get to this point")
+ HTTPI::Request.any_instance.expects(:body=).with { |value|
+ value.include?("<ns0:Save><ns0:article><ns1:title>Hamlet</ns1:title><ns1:author>Shakespeare</ns1:author></ns0:article></ns0:Save>") &&
+ value.include?('xmlns:ns0="http://example.com/actions"') &&
+ value.include?('xmlns:ns1="http://example.com/article"')
+ }
+
+ client.request :save do |soap|
+ soap.body = {:article => {:title => "Hamlet", :author => "Shakespeare"}}
+ end
+ end
+ end
+
context "without a WSDL document" do
let(:client) do
Savon::Client.new do
View
56 spec/savon/wsdl/parser_spec.rb
@@ -82,6 +82,62 @@
end
end
+ context "with multiple_namespaces.xml" do
+ let(:parser) { new_parser :multiple_namespaces }
+
+ it "can list the messages" do
+ parser.messages.keys.sort.should == ["SaveSoapIn", "SaveSoapOut"]
+ end
+
+ it "can go from message to element" do
+ parser.messages["SaveSoapIn"].should == "Save"
+ end
+
+ it "have an entry in input_message for everything listed" do
+ parser.input_message.keys.should == ["Save"]
+ end
+
+ it "can go from an action to a message" do
+ parser.input_message["Save"].should == "SaveSoapIn"
+ end
+
+ it "can list the types" do
+ pending("not yet implemented")
+ parser.types.keys.sort.should == ["Article", "Save"]
+ end
+#<s:element name="Save">
+# <s:complexType>
+# <s:sequence>
+# <s:element name="article" type="article:Article"/>
+# </s:sequence>
+# </s:complexType>
+# </s:element>
+#{"Save" => {:namespace => "http://example.com/actions", :article => {:namespace => "http://example.com/actions", :type => "article:Article"}},
+
+# <s:schema elementFormDefault="qualified" targetNamespace="http://example.com/article">
+# <s:complexType name="Article">
+# <s:sequence>
+# <s:element minOccurs="0" name="Author" type="s:string"/>
+# <s:element minOccurs="0" name="Title" type="s:string"/>
+ # </s:sequence>
+ # </s:complexType>
+# </s:schema>
+#{"Article" => {:namespace => "http://example.com/article", :author => {:namespace => same}, :title => {:namespace => same}}
+
+
+
+
+
+# Eventually might build up something like this (or might just use the
+# types hash above)
+#{"Save" => {"article" => {:namespace => "ns0", "title" => {:namespace => "ns1"}, "author" => {:namespace => "ns1"}}}
+
+ end
+
+ context "with something other than complexType/Sequence" do
+ it "should not mess with namespaces or try to parse types"
+ end
+
RSpec::Matchers.define :match_operations do |expected|
match do |actual|
actual.should have(expected.keys.size).items
Please sign in to comment.
Something went wrong with that request. Please try again.