Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/parse faults #121

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 51 additions & 41 deletions lib/wasabi/parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion spec/wasabi/document/authentication_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions spec/wasabi/document/geotrust_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
should include(
{
get_quick_approver_list: {
name: "GetQuickApproverList",
input: "GetQuickApproverList",
output: "GetQuickApproverListResponse",
action: "GetQuickApproverList",
Expand All @@ -46,6 +47,7 @@
},
{
hello: {
name: "hello",
input: "hello",
output: "helloResponse",
action: "hello",
Expand Down
2 changes: 1 addition & 1 deletion spec/wasabi/document/multiple_namespaces_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
3 changes: 3 additions & 0 deletions spec/wasabi/document/namespaced_actions_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
should include(
{
delete_client: {
name: "DeleteClient",
input: "Client.Delete",
output: "Client.DeleteResponse",
action: "http://api.example.com/api/Client.Delete",
Expand All @@ -40,6 +41,7 @@
},
{
get_clients: {
name: "GetClients",
input: "User.GetClients",
output: "User.GetClientsResponse",
action: "http://api.example.com/api/User.GetClients",
Expand All @@ -48,6 +50,7 @@
},
{
get_api_key: {
name: "GetApiKey",
input: "User.GetApiKey",
output: "User.GetApiKeyResponse",
action: "http://api.example.com/api/User.GetApiKey",
Expand Down
3 changes: 3 additions & 0 deletions spec/wasabi/document/no_namespace_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
should include(
{
get_user_login_by_id: {
name: "GetUserLoginById",
input: "GetUserLoginById",
output: "GetUserLoginByIdResponse",
action: "/api/api/GetUserLoginById",
Expand All @@ -40,6 +41,7 @@
},
{
get_all_contacts: {
name: "GetAllContacts",
input: "GetAllContacts",
output: "GetAllContactsResponse",
action: "/api/api/GetAllContacts",
Expand All @@ -48,6 +50,7 @@
},
{
search_user: {
name: "SearchUser",
input: "SearchUser",
output: "SearchUserResponse",
action: "/api/api/SearchUser",
Expand Down
1 change: 1 addition & 0 deletions spec/wasabi/document/rpc_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
should include(
{
example_operation: {
name: "ExampleOperation",
action: "urn:ExampleInterface-ExamplePortType#ExampleOperation",
input: "ExampleOperation",
output: "ExampleOperation",
Expand Down
1 change: 1 addition & 0 deletions spec/wasabi/document/savon295_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
should include(
{
sendsms: {
name: "sendsms",
input: "sendsmsRequest",
output: "sendsmsResponse",
action: "sendsms",
Expand Down
4 changes: 4 additions & 0 deletions spec/wasabi/parser/workday_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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