diff --git a/lib/client.js b/lib/client.js index ade456f20..f5cf64701 100644 --- a/lib/client.js +++ b/lib/client.js @@ -182,6 +182,62 @@ 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'); + 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'); + + 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, @@ -202,6 +258,13 @@ Client.prototype._invoke = function(method, args, location, callback, options, e }, xmlnsSoap = "xmlns:" + envelopeKey + "=\"http://schemas.xmlsoap.org/soap/envelope/\""; + if(this._isSequenceRequired(name)) { + var argsScheme = this._getArgsScheme(name); + if(argsScheme) { + args = this._setSequenceArgs(argsScheme, args); + } + } + 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\""; diff --git a/lib/wsdl.js b/lib/wsdl.js index 8b069ae1c..68b7bfcb2 100644 --- a/lib/wsdl.js +++ b/lib/wsdl.js @@ -2079,7 +2079,7 @@ WSDL.prototype._fromServices = function(services) { }; - +WSDL.prototype._splitQName = splitQName; WSDL.prototype._xmlnsMap = function() { var xmlns = this.definitions.xmlns; diff --git a/test/request-response-samples/readMetadata__should_respect_xsi_type_attribute/soap.wsdl b/test/request-response-samples/readMetadata__should_respect_xsi_type_attribute/soap.wsdl index 3d9e07588..0a63b8bd6 100644 --- a/test/request-response-samples/readMetadata__should_respect_xsi_type_attribute/soap.wsdl +++ b/test/request-response-samples/readMetadata__should_respect_xsi_type_attribute/soap.wsdl @@ -11,7 +11,7 @@ Copyright 2006-2015 Salesforce.com, inc. All Rights Reserved - + diff --git a/test/sequence-test.js b/test/sequence-test.js new file mode 100644 index 000000000..af7d6bedc --- /dev/null +++ b/test/sequence-test.js @@ -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(); + }); + }); + +}); \ No newline at end of file diff --git a/test/wsdl/sequnceexmple.wsdl b/test/wsdl/sequnceexmple.wsdl new file mode 100644 index 000000000..4c33b9537 --- /dev/null +++ b/test/wsdl/sequnceexmple.wsdl @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Generate an indicium. + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file