Skip to content

Commit

Permalink
Failing test case for recursive types (#940)
Browse files Browse the repository at this point in the history
* Failing test case for recursive types

Created failing test case for recursive types with the hopes that we can
figure out how to fix it.

* Fix infinite recursion
  • Loading branch information
jpage-godaddy authored and jsdevel committed Jun 10, 2017
1 parent 73fbdbf commit 85c8409
Show file tree
Hide file tree
Showing 3 changed files with 226 additions and 5 deletions.
20 changes: 16 additions & 4 deletions lib/wsdl.js
Original file line number Diff line number Diff line change
Expand Up @@ -1932,10 +1932,22 @@ WSDL.prototype.findSchemaType = function(name, nsURI) {
return schema.complexTypes[name];
};

WSDL.prototype.findChildSchemaObject = function(parameterTypeObj, childName) {
WSDL.prototype.findChildSchemaObject = function(parameterTypeObj, childName, backtrace) {
if (!parameterTypeObj || !childName) {
return null;
}

if (!backtrace) {
backtrace = [];
}

if (backtrace.indexOf(parameterTypeObj) >= 0) {
// We've recursed back to ourselves; break.
return null;
} else {
backtrace = backtrace.concat([parameterTypeObj]);
}

var found = null,
i = 0,
child,
Expand Down Expand Up @@ -1975,13 +1987,13 @@ WSDL.prototype.findChildSchemaObject = function(parameterTypeObj, childName) {
}
var typeDef = this.findSchemaType(typeInfo.name, childNsURI);
if (typeDef) {
return this.findChildSchemaObject(typeDef, childName);
return this.findChildSchemaObject(typeDef, childName, backtrace);
}
}

if (object.children) {
for (i = 0, child; child = object.children[i]; i++) {
found = this.findChildSchemaObject(child, childName);
found = this.findChildSchemaObject(child, childName, backtrace);
if (found) {
break;
}
Expand All @@ -1994,7 +2006,7 @@ WSDL.prototype.findChildSchemaObject = function(parameterTypeObj, childName) {
var foundBase = this.findSchemaType(baseQName.name, childNsURI);

if (foundBase) {
found = this.findChildSchemaObject(foundBase, childName);
found = this.findChildSchemaObject(foundBase, childName, backtrace);

if (found) {
found.$baseNameSpace = childNameSpace;
Expand Down
53 changes: 52 additions & 1 deletion test/client-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -838,7 +838,7 @@ var fs = require('fs'),
});
});

it('shall generate correct payload for methods with array parameter', function(done) {
it('shall generate correct payload for methods with array parameter', function (done) {
soap.createClient(__dirname + '/wsdl/list_parameter.wsdl', function(err, client) {
assert.ok(client);
var pathToArrayContainer = 'TimesheetV201511Mobile.TimesheetV201511MobileSoap.AddTimesheet.input.input.PeriodList';
Expand All @@ -851,6 +851,57 @@ var fs = require('fs'),
});
});
});

it('shall generate correct payload for recursively-defined types', function (done) {
soap.createClient(__dirname + '/wsdl/recursive2.wsdl', function (err, client) {
if (err) {
return void done(err);
}

assert.ok(client);
client.AddAttribute({
"Requests":{
"AddAttributeRequest":[
{
"RequestIdx":1,
"Identifier":{
"SystemNamespace":"bugrepro",
"ResellerId":1,
"CustomerNum":"860692",
"AccountUid":"80a6e559-4d65-11e7-bd5b-0050569a12d7"
},
"Attr":{
"AttributeId":716,
"IsTemplateAttribute":0,
"ReadOnly":0,
"CanBeModified":1,
"Name":"domain",
"AccountElements":{
"AccountElement":[
{
"ElementId":1693,
"Name":"domain",
"Value":"foo",
"ReadOnly":0,
"CanBeModified":1
}
]
}
},
"RequestedBy":"blah",
"RequestedByLogin":"system"
}
]
}
}, function () {
var sentInputContent = client.lastRequest.substring(client.lastRequest.indexOf('<Requests>') + '<Requests>'.length, client.lastRequest.indexOf('</Requests>'));
assert.equal(
sentInputContent,
'<AddAttributeRequest><RequestIdx>1</RequestIdx><Identifier><SystemNamespace>bugrepro</SystemNamespace><ResellerId>1</ResellerId><CustomerNum>860692</CustomerNum><AccountUid>80a6e559-4d65-11e7-bd5b-0050569a12d7</AccountUid></Identifier><Attr><AttributeId>716</AttributeId><IsTemplateAttribute>0</IsTemplateAttribute><ReadOnly>0</ReadOnly><CanBeModified>1</CanBeModified><Name>domain</Name><AccountElements><AccountElement><ElementId>1693</ElementId><Name>domain</Name><Value>foo</Value><ReadOnly>0</ReadOnly><CanBeModified>1</CanBeModified></AccountElement></AccountElements></Attr><RequestedBy>blah</RequestedBy><RequestedByLogin>system</RequestedByLogin></AddAttributeRequest>');
done();
});
});
});
});
});
});
158 changes: 158 additions & 0 deletions test/wsdl/recursive2.wsdl
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://bugrepro.com/account"
xmlns:s="http://www.w3.org/2001/XMLSchema"
xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
targetNamespace="http://bugrepro.com/account"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:types>
<s:schema elementFormDefault="qualified" targetNamespace="http://bugrepro.com/account">
<s:element name="AddAttribute">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="Requests" type="tns:ArrayOfAddAttributeRequest" />
</s:sequence>
</s:complexType>
</s:element>
<s:complexType name="ArrayOfAddAttributeRequest">
<s:sequence>
<s:element minOccurs="0" maxOccurs="unbounded" name="AddAttributeRequest" nillable="true" type="tns:AddAttributeRequest" />
</s:sequence>
</s:complexType>
<s:complexType name="AddAttributeRequest">
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="RequestIdx" type="s:int" />
<s:element minOccurs="0" maxOccurs="1" name="Identifier" type="tns:AccountIdentifier" />
<s:element minOccurs="0" maxOccurs="1" name="Attr" type="tns:AccountAttribute" />
<s:element minOccurs="0" maxOccurs="1" name="RequestedBy" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="RequestedByLogin" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="requestItems" type="tns:ArrayOfRequestItem" />
</s:sequence>
</s:complexType>
<s:complexType name="ArrayOfRequestItem">
<s:sequence>
<s:element minOccurs="0" maxOccurs="unbounded" name="RequestItem" nillable="true" type="tns:RequestItem" />
</s:sequence>
</s:complexType>
<s:complexType name="RequestItem">
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="ItemName" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="ItemValue" type="s:string" />
</s:sequence>
</s:complexType>
<s:complexType name="AccountIdentifier">
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="SystemNamespace" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="ResellerId" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="CustomerNum" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="AccountUid" type="s:string" />
</s:sequence>
</s:complexType>
<s:complexType name="AccountAttribute">
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="AttributeId" type="s:int" />
<s:element minOccurs="0" maxOccurs="1" name="AttributeUid" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="ProductAttributeUid" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="IsTemplateAttribute" type="s:int" />
<s:element minOccurs="0" maxOccurs="1" name="TemplateInternalName" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="Name" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="Status" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="DisplayStatus" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="ReadOnly" type="s:int" />
<s:element minOccurs="1" maxOccurs="1" name="CanBeModified" type="s:int" />
<s:element minOccurs="0" maxOccurs="1" name="AccountElements" type="tns:ArrayOfAccountElement" />
</s:sequence>
</s:complexType>
<s:complexType name="ArrayOfAccountElement">
<s:sequence>
<s:element minOccurs="0" maxOccurs="unbounded" name="AccountElement" nillable="true" type="tns:AccountElement" />
</s:sequence>
</s:complexType>
<s:complexType name="AccountElement">
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="Name" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="Value" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="ElementId" type="s:int" />
<s:element minOccurs="0" maxOccurs="1" name="ElementUid" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="ProductAttributeElementUid" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="Status" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="DisplayStatus" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="ReadOnly" type="s:int" />
<s:element minOccurs="1" maxOccurs="1" name="CanBeModified" type="s:int" />
<s:element minOccurs="0" maxOccurs="1" name="ChildElements" type="tns:ArrayOfAccountElement" />
</s:sequence>
</s:complexType>
<s:element name="AddAttributeResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="AddAttributeResult" type="s:int" />
<s:element minOccurs="0" maxOccurs="1" name="Response" type="tns:ArrayOfOperationResponse" />
<s:element minOccurs="0" maxOccurs="1" name="errors" type="tns:ArrayOfString" />
</s:sequence>
</s:complexType>
</s:element>
<s:complexType name="ArrayOfOperationResponse">
<s:sequence>
<s:element minOccurs="0" maxOccurs="unbounded" name="OperationResponse" nillable="true" type="tns:OperationResponse" />
</s:sequence>
</s:complexType>
<s:complexType name="ArrayOfString">
<s:sequence>
<s:element minOccurs="0" maxOccurs="unbounded" name="string" nillable="true" type="s:string" />
</s:sequence>
</s:complexType>
<s:complexType name="OperationResponse">
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="RequestIdx" type="s:int" />
<s:element minOccurs="1" maxOccurs="1" name="Result" type="s:int" />
<s:element minOccurs="0" maxOccurs="1" name="messages" type="tns:ArrayOfString" />
<s:element minOccurs="0" maxOccurs="1" name="errors" type="tns:ArrayOfString" />
<s:element minOccurs="0" maxOccurs="1" name="items" type="tns:ArrayOfResponseItem" />
</s:sequence>
</s:complexType>
<s:complexType name="ArrayOfResponseItem">
<s:sequence>
<s:element minOccurs="0" maxOccurs="unbounded" name="ResponseItem" nillable="true" type="tns:ResponseItem" />
</s:sequence>
</s:complexType>
<s:complexType name="ResponseItem">
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="ItemName" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="ItemValue" type="s:string" />
</s:sequence>
</s:complexType>
</s:schema>
</wsdl:types>
<wsdl:message name="AddAttributeSoapIn">
<wsdl:part name="parameters" element="tns:AddAttribute" />
</wsdl:message>
<wsdl:message name="AddAttributeSoapOut">
<wsdl:part name="parameters" element="tns:AddAttributeResponse" />
</wsdl:message>
<wsdl:portType name="AccountOperationsSoap">
<wsdl:operation name="AddAttribute">
<wsdl:input message="tns:AddAttributeSoapIn" />
<wsdl:output message="tns:AddAttributeSoapOut" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="AccountOperationsSoap" type="tns:AccountOperationsSoap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="AddAttribute">
<soap:operation soapAction="http://bugrepro.com/account/AddAttribute" style="document" />
<wsdl:input>
<soap:body use="literal" />
<soap:header message="tns:AddAttributeSecureHeader" part="SecureHeader" use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="AccountOperations">
<documentation xmlns="http://schemas.xmlsoap.org/wsdl/" />
<wsdl:port name="AccountOperationsSoap" binding="tns:AccountOperationsSoap">
<soap:address location="http://bugrepro.com/Account/AccountOperations.asmx" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

0 comments on commit 85c8409

Please sign in to comment.