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

fix(wsdl): array namespace override with colon(:) #1045

Merged
merged 1 commit into from Feb 20, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -36,7 +36,7 @@
"cover": "nyc --reporter=lcov --reporter=html --reporter=text mocha --exit test/*-test.js test/security/*.js",
"coveralls": "cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js -v",
"docs": "typedoc --out docs",
"test": "mocha --timeout 10000 --bail --exit test/*-test.js test/security/*.js"
"test": "mocha --timeout 15000 --bail --exit test/*-test.js test/security/*.js"
},
"keywords": [
"soap"
Expand Down
21 changes: 18 additions & 3 deletions src/wsdl/index.ts
Expand Up @@ -689,10 +689,14 @@ export class WSDL {
// start building out XML string.
if (Array.isArray(obj)) {
var nonSubNameSpace = '';
var emptyNonSubNameSpaceForArray = false;
var nameWithNsRegex = /^([^:]+):([^:]+)$/.exec(name);
if (nameWithNsRegex) {
nonSubNameSpace = nameWithNsRegex[1];
name = nameWithNsRegex[2];
} else if (name[0] === ':') {
emptyNonSubNameSpaceForArray = true;
name = name.substr(1);
}

for (i = 0, n = obj.length; i < n; i++) {
Expand All @@ -702,7 +706,10 @@ export class WSDL {

var body = self.objectToXML(item, name, nsPrefix, nsURI, false, null, schemaObject, nsContext);

var openingTagParts = ['<', appendColon(correctOuterNsPrefix), name, arrayAttr, xmlnsAttrib];
var openingTagParts = ['<', name, arrayAttr, xmlnsAttrib];
if (!emptyNonSubNameSpaceForArray) {
openingTagParts = ['<', appendColon(correctOuterNsPrefix), name, arrayAttr, xmlnsAttrib];
}

if (body === '' && self.options.useEmptyTag) {
// Use empty (self-closing) tags if no contents
Expand All @@ -715,7 +722,11 @@ export class WSDL {
}
parts.push(body);
if (self.options.namespaceArrayElements || i === n - 1) {
parts.push(['</', appendColon(correctOuterNsPrefix), name, '>'].join(''));
if (emptyNonSubNameSpaceForArray) {
parts.push(['</', name, '>'].join(''));
} else {
parts.push(['</', appendColon(correctOuterNsPrefix), name, '>'].join(''));
}
}
}
}
Expand Down Expand Up @@ -874,7 +885,11 @@ export class WSDL {
obj[self.options.attributesKey].xsi_type.xmlns, false, null, null, nsContext);
} else {
if (Array.isArray(child)) {
name = nonSubNameSpace + name;
if(emptyNonSubNameSpace) {
name = ':' + name;
} else {
name = nonSubNameSpace + name;
}
}

value = self.objectToXML(child, name, nsPrefix, nsURI, false, null, null, nsContext);
Expand Down
58 changes: 52 additions & 6 deletions test/client-test.js
Expand Up @@ -94,12 +94,12 @@ var fs = require('fs'),
});
});


it('should allow passing in XML strings', function (done) {
soap.createClient(__dirname + '/wsdl/default_namespace.wsdl', _.assign({ envelopeKey: 'soapenv' }, meta.options), function (err, client) {
assert.ok(client);
assert.ifError(err);

var xmlStr = '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n\t<head>\n\t\t<title>404 - Not Found</title>\n\t</head>\n\t<body>\n\t\t<h1>404 - Not Found</h1>\n\t\t<script type="text/javascript" src="http://gp1.wpc.edgecastcdn.net/00222B/beluga/pilot_rtm/beluga_beacon.js"></script>\n\t</body>\n</html>';
client.MyOperation({_xml: xmlStr}, function (err, result, raw, soapHeader) {
assert.ok(err);
Expand Down Expand Up @@ -210,7 +210,7 @@ var fs = require('fs'),
}, 'https://127.0.0.1:443');
});


it('should have xml request modified', function (done) {
soap.createClient(__dirname + '/wsdl/default_namespace.wsdl', meta.options, function(err, client) {
assert.ok(client);
Expand All @@ -230,7 +230,7 @@ var fs = require('fs'),
);
}, baseUrl);
});

it('should have the correct extra header in the request', function (done) {
soap.createClient(__dirname + '/wsdl/default_namespace.wsdl', meta.options, function (err, client) {
assert.ok(client);
Expand Down Expand Up @@ -905,6 +905,52 @@ var fs = require('fs'),
});
});

it('shall generate correct payload for methods with array parameter with colon override', function (done) {
soap.createClient(__dirname + '/wsdl/array_namespace_override.wsdl', function(err, client) {
assert.ok(client);
var pathToArrayContainer = 'SampleArrayServiceImplService.SampleArrayServiceImplPort.createWebOrder.input.order';
var arrayParameter = _.get(client.describe(), pathToArrayContainer)['orderDetails[]'];
assert.ok(arrayParameter);
const input = {
':clientId': 'test',
':order': {
':orderDetails': {
':unitNo': 1234,
':items':[{ ':itemDesc': 'item1'}, { ':itemDesc': 'item2'}]
},
},
};
client.createWebOrder(input, function() {
var sentInputContent = client.lastRequest.substring(client.lastRequest.indexOf('<items>'), client.lastRequest.lastIndexOf('</items>') + '</items>'.length);
assert.equal(sentInputContent, '<items><itemDesc>item1</itemDesc></items><items><itemDesc>item2</itemDesc></items>');
done();
});
});
});

it('shall generate correct payload for methods with array parameter with parent namespace', function (done) {
soap.createClient(__dirname + '/wsdl/array_namespace_override.wsdl', function(err, client) {
assert.ok(client);
var pathToArrayContainer = 'SampleArrayServiceImplService.SampleArrayServiceImplPort.createWebOrder.input.order';
var arrayParameter = _.get(client.describe(), pathToArrayContainer)['orderDetails[]'];
assert.ok(arrayParameter);
const input = {
':clientId': 'test',
':order': {
'orderDetails': {
':unitNo': 1234,
'items':[{ ':itemDesc': 'item1'}, { ':itemDesc': 'item2'}]
},
},
};
client.createWebOrder(input, function() {
var sentInputContent = client.lastRequest.substring(client.lastRequest.indexOf('<ns1:items>'), client.lastRequest.lastIndexOf('</ns1:items>') + '</ns1:items>'.length);
assert.equal(sentInputContent, '<ns1:items><itemDesc>item1</itemDesc></ns1:items><ns1:items><itemDesc>item2</itemDesc></ns1:items>');
done();
});
});
});

it('shall generate correct payload for methods with array parameter when individual array elements are not namespaced', function (done) {
// used for servers that cannot aggregate individually namespaced array elements
soap.createClient(__dirname + '/wsdl/list_parameter.wsdl', {disableCache: true, namespaceArrayElements: false}, function(err, client) {
Expand Down Expand Up @@ -1001,7 +1047,7 @@ var fs = require('fs'),
});
});


describe('Client created with createClientAsync', function () {
it('should error on invalid host', function (done) {
soap.createClientAsync('http://localhost:1', meta.options)
Expand Down Expand Up @@ -1057,7 +1103,7 @@ var fs = require('fs'),
done();
});
});

it('should allow customization of request for http client', function (done) {
var myRequest = function () {
};
Expand Down
98 changes: 98 additions & 0 deletions test/wsdl/array_namespace_override.wsdl
@@ -0,0 +1,98 @@
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions name="SampleArrayServiceImplService" targetNamespace="http://service.dummy.com" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://service.dummy.com" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns3="http://schemas.xmlsoap.org/soap/http" xmlns:ns2="http://response.dummy.com" xmlns:ns1="http://request.dummy.com">
<wsdl:types>
<xs:schema targetNamespace="http://service.dummy.com" version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="CreateOrderResponseVO" type="tns:CreateOrderResponseVO"/>
<xs:complexType name="ABaseServiceRequestVO">
<xs:sequence>
<xs:element name="ClientId" nillable="true" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ABaseServiceResponseVO">
<xs:sequence>
<xs:element name="message" nillable="true" type="xs:string"/>
<xs:element name="code" type="xs:int"/>
<xs:element name="subCode" type="xs:int"/>
<xs:element maxOccurs="unbounded" minOccurs="0" name="errors" nillable="true" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="createWebOrderRequest">
<xs:sequence>
<xs:element name="clientId" type="xs:string"/>
<xs:element name="order" type="tns:order"/>
<xs:element minOccurs="0" name="salesNo" nillable="true" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="CreateOrderResponseVO">
<xs:sequence>
<xs:element name="orderNumber" nillable="true" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="order">
<xs:sequence>
<xs:element maxOccurs="unbounded" name="orderDetails" type="tns:orderDetail"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="orderDetail">
<xs:sequence>
<xs:element name="unitNo" type="xs:string"/>
<xs:element maxOccurs="unbounded" name="items" type="tns:itemDetail"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="itemDetail">
<xs:sequence>
<xs:element maxOccurs="unbounded" minOccurs="0" name="markdowns" nillable="true" type="tns:markdown"/>
<xs:element name="itemDesc" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="markdown">
<xs:sequence>
<xs:element name="discountPercent" type="xs:double"/>
<xs:element minOccurs="0" name="couponNo" type="xs:string"/>
<xs:element name="markdownAmt" type="xs:double"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="unqualified" targetNamespace="com.dummy.request" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ns1="http://service.dummy.com" xmlns="com.dummy.request">
<xs:import namespace="http://service.dummy.com"/>
<xs:element name="createWebOrderRequest" type="ns1:createWebOrderRequest"/>
</xs:schema>
<xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://request.dummy.com" xmlns="http://request.dummy.com">
<xsd:import namespace="http://service.dummy.com"/>
<xsd:element name="CreateWebOrderRequest" nillable="true" type="tns:createWebOrderRequest"/>
</xsd:schema>
<xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://response.dummy.com" xmlns="http://response.dummy.com">
<xsd:import namespace="http://service.dummy.com"/>
<xsd:element name="CreateWebOrderResponse" nillable="true" type="tns:CreateOrderResponseVO"/>
</xsd:schema>
</wsdl:types>
<wsdl:message name="createWebOrderResponse">
<wsdl:part element="ns2:CreateWebOrderResponse" name="CreateWebOrderResponse"/>
</wsdl:message>
<wsdl:message name="createWebOrder">
<wsdl:part element="ns1:CreateWebOrderRequest" name="CreateWebOrderRequest"/>
</wsdl:message>
<wsdl:portType name="SampleArraySoapService">
<wsdl:operation name="createWebOrder">
<wsdl:input message="tns:createWebOrder" name="createWebOrder"/>
<wsdl:output message="tns:createWebOrderResponse" name="createWebOrderResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="SampleArrayServiceImplServiceSoapBinding" type="tns:SampleArraySoapService">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="createWebOrder">
<soap:operation soapAction="" style="document"/>
<wsdl:input name="createWebOrder">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="createWebOrderResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="SampleArrayServiceImplService">
<wsdl:port binding="tns:SampleArrayServiceImplServiceSoapBinding" name="SampleArrayServiceImplPort">
<soap:address location="http://www.dummy.com"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>