Skip to content

Commit

Permalink
Adjust input parsing (#122)
Browse files Browse the repository at this point in the history
Fixes a regression introduced in #114
  • Loading branch information
pcai authored Oct 27, 2024
1 parent 57a089f commit 1a7bb93
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 21 deletions.
29 changes: 22 additions & 7 deletions lib/wasabi/parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,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']

Expand All @@ -251,9 +252,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
Expand All @@ -262,13 +267,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 }
Expand All @@ -277,6 +275,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)
Expand All @@ -291,6 +290,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]
Expand Down
20 changes: 10 additions & 10 deletions spec/wasabi/document/geotrust_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down
2 changes: 1 addition & 1 deletion spec/wasabi/document/savon295_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
should include(
{
sendsms: {
input: "sendsmsRequest",
input: "sendsms",
output: "sendsmsResponse",
action: "sendsms",
namespace_identifier: "tns"
Expand Down
4 changes: 2 additions & 2 deletions spec/wasabi/parser/no_message_parts_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion spec/wasabi/parser/tradetracker_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 1a7bb93

Please sign in to comment.