diff --git a/lib/wasabi/parser.rb b/lib/wasabi/parser.rb index c6f1b69..b73c671 100644 --- a/lib/wasabi/parser.rb +++ b/lib/wasabi/parser.rb @@ -238,6 +238,7 @@ def output_for(operation) input_output_for(operation, 'output') end + # @return [namespace_id, message_type] def input_output_for(operation, input_output) operation_name = operation['name'] @@ -250,9 +251,13 @@ def input_output_for(operation, input_output) port_type_input_output = port_type_operation&.element_children&.find { |node| node.name == input_output } + # find the message for the portType operation + # if there is no message, we will use the operation name as the message name + # TODO: Stupid fix for missing support for imports. # Sometimes portTypes are actually included in a separate WSDL. if port_type_input_output + # If the message attribute contains a colon, it means the message is namespaced. if port_type_input_output.attribute('message').to_s.include? ':' port_message_ns_id, port_message_type = port_type_input_output.attribute('message').to_s.split(':') else @@ -261,13 +266,6 @@ def input_output_for(operation, input_output) message_ns_id, message_type = nil - soap_operation = operation.element_children.find { |node| node.name == 'operation' } - - if soap_operation.nil? || soap_operation['style'] != 'rpc' - message_ns_id = port_message_ns_id - message_type = port_message_type - end - # When there is a parts attribute in soap:body element, we should use that value # to look up the message part from messages array. input_output_element = operation.element_children.find { |node| node.name == input_output } @@ -276,6 +274,7 @@ def input_output_for(operation, input_output) soap_body_parts = soap_body_element['parts'] if soap_body_element end + # look for any message part that matches the soap body parts message = @messages[port_message_type] port_message_part = message&.element_children&.find do |node| soap_body_parts.nil? ? (node.name == "part") : (node.name == "part" && node["name"] == soap_body_parts) @@ -290,6 +289,22 @@ def input_output_for(operation, input_output) end end + # If the message is not found, we should use the operation name as the message name for document style operations + # applies only to output + if input_output == 'output' + # if the operation is document style and theres no port_message_part, we should use the operation_name + soap_operation = operation.element_children.find { |node| node.name == 'operation' } + if message_type.nil? && (soap_operation.nil? || soap_operation['style'] != 'rpc') + if port_message_part.nil? + message_ns_id = port_message_ns_id + message_type = operation_name + else + message_ns_id = port_message_ns_id + message_type = port_message_type + end + end + end + # Fall back to the name of the binding operation if message_type [message_ns_id, message_type] diff --git a/spec/wasabi/document/geotrust_spec.rb b/spec/wasabi/document/geotrust_spec.rb index 4dddff9..f580c7b 100644 --- a/spec/wasabi/document/geotrust_spec.rb +++ b/spec/wasabi/document/geotrust_spec.rb @@ -5,35 +5,35 @@ describe Wasabi::Document do context "with: geotrust.wsdl" do - subject { Wasabi::Document.new fixture(:geotrust).read } + let(:document) { Wasabi::Document.new(fixture(:geotrust).read) } describe '#namespace' do - subject { super().namespace } - it { should == "http://api.geotrust.com/webtrust/query" } + subject { document.namespace } + it { should eq "http://api.geotrust.com/webtrust/query" } end describe '#endpoint' do - subject { super().endpoint } - it { should == URI("https://test-api.geotrust.com:443/webtrust/query.jws") } + subject { document.endpoint } + it { should eq URI("https://test-api.geotrust.com:443/webtrust/query.jws") } end describe '#element_form_default' do - subject { super().element_form_default } - it { should == :qualified } + subject { document.element_form_default } + it { should be :qualified } end it 'has 2 operations' do - expect(subject.operations.size).to eq(2) + expect(document.operations.size).to eq(2) end describe '#operations' do - subject { super().operations } + subject { document.operations } it do should include( { get_quick_approver_list: { input: "GetQuickApproverList", - output: "GetQuickApproverListResponse", + output: "GetQuickApproverList", action: "GetQuickApproverList", namespace_identifier: "s1", parameters: { diff --git a/spec/wasabi/document/savon295_spec.rb b/spec/wasabi/document/savon295_spec.rb index c4c2544..ad4bb55 100644 --- a/spec/wasabi/document/savon295_spec.rb +++ b/spec/wasabi/document/savon295_spec.rb @@ -13,7 +13,7 @@ should include( { sendsms: { - input: "sendsmsRequest", + input: "sendsms", output: "sendsmsResponse", action: "sendsms", namespace_identifier: "tns" diff --git a/spec/wasabi/parser/no_message_parts_spec.rb b/spec/wasabi/parser/no_message_parts_spec.rb index c07302a..5f94bc7 100644 --- a/spec/wasabi/parser/no_message_parts_spec.rb +++ b/spec/wasabi/parser/no_message_parts_spec.rb @@ -15,7 +15,7 @@ it 'falls back to using the message type in the port element' do # Operation's input has no part element in the message, so using the message type. - expect(subject.operations[:save][:input]).to eq("SaveSoapIn") + expect(subject.operations[:save][:input]).to eq("Save") # Operation's output has part element in the message, so using part element's type. expect(subject.operations[:save][:output]).to eq('SaveResponse') @@ -26,7 +26,7 @@ end it 'gracefully handles port messages without a colon' do - expect(subject.operations[:delete][:input]).to eq("DeleteSoapIn") + expect(subject.operations[:delete][:input]).to eq("Delete") expect(subject.operations[:delete][:output]).to eq('DeleteResponse') expect(subject.operations[:delete][:namespace_identifier]).to be_nil end diff --git a/spec/wasabi/parser/tradetracker_spec.rb b/spec/wasabi/parser/tradetracker_spec.rb index 67b2ab1..d11c455 100644 --- a/spec/wasabi/parser/tradetracker_spec.rb +++ b/spec/wasabi/parser/tradetracker_spec.rb @@ -13,7 +13,7 @@ let(:xml) { fixture(:tradetracker).read } it 'parses the operations' do - expect(subject.operations[:get_feeds][:input]).to eq("GetFeedsMessage") + expect(subject.operations[:get_feeds][:input]).to eq("getFeeds") end end end