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

add fields sequence if it's required (need help) #914

Merged
merged 8 commits into from
Jan 25, 2017
Merged
Show file tree
Hide file tree
Changes from 7 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
57 changes: 57 additions & 0 deletions lib/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,54 @@ Client.prototype._defineMethod = function(method, location) {
};
};

Client.prototype._isSequenceRequired = function(methodName) {
var tns = this.wsdl.definitions.$targetNamespace;
var methodRequestName = _.result(this.wsdl.definitions, 'messages.'+methodName+'.$name');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you add spaces between operators? e.g. 'messages.' + methodName + '...'

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice if we had this failing the build as part of linting too (for another PR if needed).

var args = _.result(this.wsdl.definitions, 'messages.'+methodRequestName+'.parts');
if(typeof args === 'undefined' && typeof _.pick(args, 'params') !== 'undefined') {
return false;
}
if(Object.keys(args).length === 1) {
return false;
}
var complexTypeName = _.result(this.wsdl.definitions, 'messages.'+methodRequestName+'.element.$name');
var modeOfComplexType = _.result(this.wsdl.definitions, 'schemas[\''+tns+'\'].elements.'+complexTypeName+'.children[0].children[0].name');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you break this up so the line is shorter? same comment with spaces around operators

if(modeOfComplexType === 'sequence') {
return true;
}
return false;
};

Client.prototype._setSequenceArgs = function(argsScheme, args) {
var result = {};
if(typeof argsScheme !== 'object') {
return args;
}
for (var partIndex in argsScheme) {
if(typeof args[partIndex] === 'undefined') {
continue;
}
if(typeof argsScheme[partIndex] !== 'object') {
result[partIndex] = args[partIndex];
} else {
result[partIndex] = this._setSequenceArgs(argsScheme[partIndex], args[partIndex]);
}
}
return result;
};

Client.prototype._getArgsScheme = function(methodName) {
var methodRequestName = _.result(this.wsdl.definitions, 'messages.'+methodName+'.$name');
var args = _.result(this.wsdl.definitions, 'messages.'+methodRequestName+'.parts');
if(typeof args === 'undefined' && typeof _.pick(args, 'params') !== 'undefined') {
return [];
}
if(Object.keys(args).length === 1) {
return [];
}
return args;
};

Client.prototype._invoke = function(method, args, location, callback, options, extraHeaders) {
var self = this,
name = method.$name,
Expand All @@ -202,6 +250,15 @@ Client.prototype._invoke = function(method, args, location, callback, options, e
},
xmlnsSoap = "xmlns:" + envelopeKey + "=\"http://schemas.xmlsoap.org/soap/envelope/\"";

if(this._isSequenceRequired(name)) {
Copy link
Contributor

@pihvi pihvi May 24, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to revert to v.0.18.0 as this breaks node-soap. When a client is formed from a WSDL and it has an array inside nested object in input like this (the way client.describe() tells):

input: {
   ResourceId: "s:string",
   PeriodList: {
       PeriodType[]: {
            PeriodId: "s:int",
            Status: "s:string",
            DateFrom: "s:dateTime",
            DateTo: "s:dateTime"...

It will ignore given array in input PeriodType: [...], but will accept "PeriodType[]": {} and it will generate malformed XML by generating <PeriodType[]></PeriodType[]> element.

v.0.18.0 Works as expected by accepting PeriodType: [...], also works when this if is disabled if(false && this._isSequenceRequired(name)) {

var argsScheme = this._getArgsScheme(name);
if(argsScheme) {
args = this._setSequenceArgs(argsScheme, args);
}
}


Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

at most there should be one empty line.


if (this.wsdl.options.forceSoap12Headers) {
headers["Content-Type"] = "application/soap+xml; charset=utf-8";
xmlnsSoap = "xmlns:" + envelopeKey + "=\"http://www.w3.org/2003/05/soap-envelope\"";
Expand Down
2 changes: 1 addition & 1 deletion lib/wsdl.js
Original file line number Diff line number Diff line change
Expand Up @@ -2079,7 +2079,7 @@ WSDL.prototype._fromServices = function(services) {

};


WSDL.prototype._splitQName = splitQName;

WSDL.prototype._xmlnsMap = function() {
var xmlns = this.definitions.xmlns;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Copyright 2006-2015 Salesforce.com, inc. All Rights Reserved
<xsd:complexType>
<xsd:sequence>
<xsd:element name="type" type="xsd:string"/>
<xsd:element name="fullNames" minOccurs="0" maxOccurs="unbounded" type="xsd:string"/>
<xsd:element name="fullNames" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
Expand Down
55 changes: 55 additions & 0 deletions test/sequence-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
'use strict';

var fs = require('fs'),
soap = require('..'),
http = require('http'),
assert = require('assert'),
_ = require('lodash'),
sinon = require('sinon'),
wsdl = require('../lib/wsdl');

var sequencedRequest = {
'url': 'https://github.com',
'fileName': 'qwe.txt',
'fileMode': 1,
'forceOverwrite': true,
'username': 'qwert',
'password': 'qwerty',
'base64EncodedCallback': '123'
};

var notSequencedRequest = {
'password': 'qwerty',
'base64EncodedCallback': '123',
'username': 'qwert',
'forceOverwrite': true,
'fileMode': 1,
'fileName': 'qwe.txt',
'url': 'https://github.com'
};

describe('Method args sequence', function() {

it('check if method required sequence args', function(done) {
soap.createClient(__dirname + '/wsdl/rpcexample.wsdl', { suffix: '', options: {} }, function(err, client) {
assert.ok(client);
assert.ok(client._isSequenceRequired('pullFile') === false);

soap.createClient(__dirname + '/wsdl/sequnceexmple.wsdl', { suffix: '', options: {} }, function(err, client) {
assert.ok(client);
assert.ok(client._isSequenceRequired('pullFile') === true);
done();
});
});
});

it('check sort args on sequence required method', function(done) {
soap.createClient(__dirname + '/wsdl/sequnceexmple.wsdl', { suffix: '', options: {} }, function(err, client) {
assert.ok(client);
var sequencedMethodRequest = client._setSequenceArgs(client._getArgsScheme('pullFile'), notSequencedRequest);
assert.ok(JSON.stringify(sequencedMethodRequest) === JSON.stringify(sequencedRequest));
done();
});
});

});
63 changes: 63 additions & 0 deletions test/wsdl/sequnceexmple.wsdl
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns:tns="urn:RpcExample" xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope"
xmlns:SOAP-ENC="http://www.w3.org/2003/05/soap-encoding"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:RpcExample="urn:RpcExample" xmlns:SOAP="http://schemas.xmlsoap.org/wsdl/soap12/"
xmlns:MIME="http://schemas.xmlsoap.org/wsdl/mime/"
xmlns:DIME="http://schemas.xmlsoap.org/ws/2002/04/dime/wsdl/" xmlns:WSDL="http://schemas.xmlsoap.org/wsdl/"
xmlns="http://schemas.xmlsoap.org/wsdl/" name="urn:RpcExample" targetNamespace="urn:RpcExample">
<types>
<schema xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope"
xmlns:SOAP-ENC="http://www.w3.org/2003/05/soap-encoding"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:RpcExample="urn:RpcExample" xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="urn:RpcExample" elementFormDefault="unqualified" attributeFormDefault="unqualified">
<import namespace="http://www.w3.org/2003/05/soap-encoding"/>
<element name="pullFile">
<complexType>
<sequence>
<element name="url" type="xsd:string" minOccurs="1" maxOccurs="1"/>
<element name="fileName" type="xsd:string" minOccurs="1" maxOccurs="1"/>
<element name="fileMode" type="xsd:int" minOccurs="1" maxOccurs="1"/>
<element name="forceOverwrite" type="xsd:boolean" minOccurs="1" maxOccurs="1"/>
<element name="username" type="xsd:string" minOccurs="1" maxOccurs="1"/>
<element name="password" type="xsd:string" minOccurs="1" maxOccurs="1"/>
<element name="base64EncodedCallback" type="xsd:string" minOccurs="1" maxOccurs="1"/>
</sequence>
</complexType>
</element>
</schema>
</types>
<message name="pullFileRequest">
<part name="parameters" element="tns:pullFile"/>
</message>
<message name="pullFileResponse">
<part name="parameters" type="xsd:boolean"/>
</message>
<portType name="RpcExamplePortType">
<operation name="pullFile">
<documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">Generate an indicium.</documentation>
<input message="tns:pullFileRequest"/>
<output message="tns:pullFileResponse"/>
</operation>
</portType>
<binding name="RpcExample" type="tns:RpcExamplePortType">
<SOAP:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="pullFile">
<SOAP:operation style="rpc"/>
<input>
<SOAP:body use="encoded" namespace="urn:RpcExample"
encodingStyle="http://www.w3.org/2003/05/soap-encoding"/>
</input>
<output>
<SOAP:body use="encoded" namespace="urn:RpcExample"
encodingStyle="http://www.w3.org/2003/05/soap-encoding"/>
</output>
</operation>
</binding>
<service name="RpcExample">
<port name="RpcExample" binding="tns:RpcExample">
<SOAP:address location="http://127.0.0.1/"/>
</port>
</service>
</definitions>