Skip to content

Commit

Permalink
fix(wsdl): array namespace override with colon(:)
Browse files Browse the repository at this point in the history
Currently, the colon override(:) for array attribute is not preserved and thus
by default the parent namespace or override provided namespace is used for array
attribute.

To handle this scenario/edge case, colon(:) is preserved for array attribute as
well. `:array` will not have any namespace as normal attribute.
  • Loading branch information
RishikeshDarandale committed Feb 20, 2019
1 parent 9aed566 commit 650fcc2
Show file tree
Hide file tree
Showing 3 changed files with 168 additions and 9 deletions.
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>

0 comments on commit 650fcc2

Please sign in to comment.