diff --git a/lib/wasabi/parser.rb b/lib/wasabi/parser.rb index 5381d86..537eb47 100644 --- a/lib/wasabi/parser.rb +++ b/lib/wasabi/parser.rb @@ -153,9 +153,18 @@ def parse_operations # There should be a matching portType for each binding, so we will lookup the input from there. namespace_id, output = output_for(operation) namespace_id, input = input_for(operation) + faults = faults_for(operation) # Store namespace identifier so this operation can be mapped to the proper namespace. - @operations[snakecase_name] = { :action => action, :input => input, :output => output, :namespace_identifier => namespace_id} + @operations[snakecase_name] = { + name: name, + action: action, + input: input, + output: output, + fault: faults.map(&:last), + namespace_identifier: namespace_id + } + @operations[snakecase_name].delete(:fault) if @operations[snakecase_name][:fault].size == 0 elsif !@operations[snakecase_name] @operations[snakecase_name] = { :action => name, :input => name } end @@ -232,74 +241,75 @@ def parse_deferred_types end def input_for(operation) - input_output_for(operation, 'input') + input_output_for(operation, 'input').first end def output_for(operation) - input_output_for(operation, 'output') + input_output_for(operation, 'output').first + end + + def faults_for(operation) + input_output_for(operation, 'fault') end def input_output_for(operation, input_output) operation_name = operation['name'] + results = [] # Look up the input by walking up to portType, then up to the message. - binding_type = operation.parent['type'].to_s.split(':').last if @port_type_operations[binding_type] port_type_operation = @port_type_operations[binding_type][operation_name] end - port_type_input_output = port_type_operation&.element_children&.find { |node| node.name == input_output } + port_type_elements = port_type_operation&.element_children&.select { |node| node.name == input_output } # TODO: Stupid fix for missing support for imports. # Sometimes portTypes are actually included in a separate WSDL. - if port_type_input_output - 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 - port_message_type = port_type_input_output.attribute('message').to_s - end + if port_type_elements&.size + port_type_elements.each_with_index do |port_type_input_output, index| + parts = port_type_input_output.attribute('message').to_s.split(':', 2) + port_message_ns_id, port_message_type = (parts.size == 2 ? parts : [nil, *parts]) - message_ns_id, message_type = nil + message_ns_id, message_type = nil - soap_operation = operation.element_children.find { |node| node.name == 'operation' } + 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 + 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 } - if input_output_element - soap_body_element = input_output_element.element_children.find { |node| node.name == 'body' } - soap_body_parts = soap_body_element['parts'] if soap_body_element - 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.select { |node| node.name == input_output }.at(index) + if input_output_element + soap_body_element = input_output_element.element_children.find { |node| node.name == 'body' } + soap_body_parts = soap_body_element['parts'] if soap_body_element + end - 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) - end + 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) + end - if port_message_part && port_element = port_message_part.attribute('element') - port_message_part = port_element.to_s - if port_message_part.include?(':') - message_ns_id, message_type = port_message_part.split(':') - else - message_type = port_message_part + if port_message_part && port_element = port_message_part.attribute('element') + port_message_part = port_element.to_s + if port_message_part.include?(':') + message_ns_id, message_type = port_message_part.split(':') + else + message_type = port_message_part + end end - end - # Fall back to the name of the binding operation - if message_type - [message_ns_id, message_type] - else - [port_message_ns_id, operation_name] + # Fall back to the name of the binding operation + results.push(message_type ? [message_ns_id, message_type] : [port_message_ns_id, operation_name]) end else - [nil, operation_name] + results.push([nil, operation_name]) end + + results end def schemas diff --git a/spec/wasabi/document/authentication_spec.rb b/spec/wasabi/document/authentication_spec.rb index 0316891..0df13f0 100644 --- a/spec/wasabi/document/authentication_spec.rb +++ b/spec/wasabi/document/authentication_spec.rb @@ -30,7 +30,7 @@ subject { super().operations } it do should == { - :authenticate => { :input => "authenticate", :output => "authenticateResponse", :action => "authenticate", :namespace_identifier => "tns" } + :authenticate => { :name=>"authenticate", :input => "authenticate", :output => "authenticateResponse", :action => "authenticate", :namespace_identifier => "tns" } } end end diff --git a/spec/wasabi/document/geotrust_spec.rb b/spec/wasabi/document/geotrust_spec.rb index 4dddff9..b178eca 100644 --- a/spec/wasabi/document/geotrust_spec.rb +++ b/spec/wasabi/document/geotrust_spec.rb @@ -32,6 +32,7 @@ should include( { get_quick_approver_list: { + name: "GetQuickApproverList", input: "GetQuickApproverList", output: "GetQuickApproverListResponse", action: "GetQuickApproverList", @@ -46,6 +47,7 @@ }, { hello: { + name: "hello", input: "hello", output: "helloResponse", action: "hello", diff --git a/spec/wasabi/document/multiple_namespaces_spec.rb b/spec/wasabi/document/multiple_namespaces_spec.rb index 05c97c9..6494f18 100644 --- a/spec/wasabi/document/multiple_namespaces_spec.rb +++ b/spec/wasabi/document/multiple_namespaces_spec.rb @@ -29,7 +29,7 @@ describe '#operations' do subject { super().operations } it do - is_expected.to match({ :save => { :input => "Save", :output=>"SaveResponse", :action => "http://example.com/actions.Save", :namespace_identifier => "actions", :parameters => { :article => { :name => "article", :type => "Article" } } } }) + is_expected.to match({:save => { :name => "Save", :input => "Save", :output=>"SaveResponse", :action => "http://example.com/actions.Save", :namespace_identifier => "actions", :parameters => { :article => { :name => "article", :type => "Article" } } } }) end end diff --git a/spec/wasabi/document/namespaced_actions_spec.rb b/spec/wasabi/document/namespaced_actions_spec.rb index 01b69ca..d005630 100644 --- a/spec/wasabi/document/namespaced_actions_spec.rb +++ b/spec/wasabi/document/namespaced_actions_spec.rb @@ -32,6 +32,7 @@ should include( { delete_client: { + name: "DeleteClient", input: "Client.Delete", output: "Client.DeleteResponse", action: "http://api.example.com/api/Client.Delete", @@ -40,6 +41,7 @@ }, { get_clients: { + name: "GetClients", input: "User.GetClients", output: "User.GetClientsResponse", action: "http://api.example.com/api/User.GetClients", @@ -48,6 +50,7 @@ }, { get_api_key: { + name: "GetApiKey", input: "User.GetApiKey", output: "User.GetApiKeyResponse", action: "http://api.example.com/api/User.GetApiKey", diff --git a/spec/wasabi/document/no_namespace_spec.rb b/spec/wasabi/document/no_namespace_spec.rb index b3bf3b8..740eaf6 100644 --- a/spec/wasabi/document/no_namespace_spec.rb +++ b/spec/wasabi/document/no_namespace_spec.rb @@ -32,6 +32,7 @@ should include( { get_user_login_by_id: { + name: "GetUserLoginById", input: "GetUserLoginById", output: "GetUserLoginByIdResponse", action: "/api/api/GetUserLoginById", @@ -40,6 +41,7 @@ }, { get_all_contacts: { + name: "GetAllContacts", input: "GetAllContacts", output: "GetAllContactsResponse", action: "/api/api/GetAllContacts", @@ -48,6 +50,7 @@ }, { search_user: { + name: "SearchUser", input: "SearchUser", output: "SearchUserResponse", action: "/api/api/SearchUser", diff --git a/spec/wasabi/document/rpc_spec.rb b/spec/wasabi/document/rpc_spec.rb index a811cc6..dab8baf 100644 --- a/spec/wasabi/document/rpc_spec.rb +++ b/spec/wasabi/document/rpc_spec.rb @@ -13,6 +13,7 @@ should include( { example_operation: { + name: "ExampleOperation", action: "urn:ExampleInterface-ExamplePortType#ExampleOperation", input: "ExampleOperation", output: "ExampleOperation", diff --git a/spec/wasabi/document/savon295_spec.rb b/spec/wasabi/document/savon295_spec.rb index c4c2544..39d401f 100644 --- a/spec/wasabi/document/savon295_spec.rb +++ b/spec/wasabi/document/savon295_spec.rb @@ -13,6 +13,7 @@ should include( { sendsms: { + name: "sendsms", input: "sendsmsRequest", output: "sendsmsResponse", action: "sendsms", diff --git a/spec/wasabi/parser/workday_spec.rb b/spec/wasabi/parser/workday_spec.rb index 9ba37ed..be5becd 100644 --- a/spec/wasabi/parser/workday_spec.rb +++ b/spec/wasabi/parser/workday_spec.rb @@ -15,5 +15,9 @@ it "parses the operations" do expect(subject.operations[:get_customer_invoices][:input]).to eq("Get_Customer_Invoices_Request") end + + it "returns faults" do + expect(subject.operations[:get_customer_invoices][:fault]).to eq(["Validation_Fault", "Processing_Fault"]) + end end end