Skip to content

Commit

Permalink
WSDL: make merging external schema works correctly (#1023)
Browse files Browse the repository at this point in the history
- Remove $targetNamespace check, as the key in definitions.schemas
already guarantee this. Fix importing schema with <wsdl:import> where
namespace == schema's targetNamespace.
- Also merge attributes from source schema. Otherwise, attributes such
as elementFormDefault="qualified" specified in included schema will not
work properly.
  • Loading branch information
peat-psuwit authored and jsdevel committed Feb 11, 2019
1 parent 0e8a3e6 commit 2f159d0
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 6 deletions.
19 changes: 13 additions & 6 deletions lib/wsdl.js
Expand Up @@ -349,12 +349,19 @@ DocumentationElement.prototype.init = function() {

SchemaElement.prototype.merge = function(source) {
assert(source instanceof SchemaElement);
if (this.$targetNamespace === source.$targetNamespace) {
_.merge(this.complexTypes, source.complexTypes);
_.merge(this.types, source.types);
_.merge(this.elements, source.elements);
_.merge(this.xmlns, source.xmlns);
}

var self = this;

_.merge(this.complexTypes, source.complexTypes);
_.merge(this.types, source.types);
_.merge(this.elements, source.elements);
_.merge(this.xmlns, source.xmlns);

// Merge attributes from source without overwriting our's
_.merge(this, _.pickBy(source, function(value, key) {
return key.startsWith('$') && !self.hasOwnProperty(key);
}));

return this;
};

Expand Down
30 changes: 30 additions & 0 deletions test/wsdl-test.js
Expand Up @@ -200,6 +200,36 @@ wsdlNonStrictTests['should all attributes to root elements'] = function(done) {
});
};

wsdlNonStrictTests['should merge schema with attributes'] = function(done) {
var expectedMsg =
'<peatdef:AskPeat xmlns:peatdef="urn:peat.def" xmlns="urn:peat.def">' +
'<peatdef:Question>How are you?</peatdef:Question>' +
'</peatdef:AskPeat>';

soap.createClient(__dirname + '/wsdl/mergeWithAttributes/main.wsdl', {}, function(err, client) {
assert.ok(!err);
client.AskPeat({ Question: 'How are you?' }, function(err, result) {
assert.equal(client.lastMessage, expectedMsg);
done();
});
});
};

wsdlStrictTests['should merge schema with attributes'] = function(done) {
var expectedMsg =
'<peatdef:AskPeat xmlns:peatdef="urn:peat.def" xmlns="urn:peat.def">' +
'<peatdef:Question>How are you?</peatdef:Question>' +
'</peatdef:AskPeat>';

soap.createClient(__dirname + '/wsdl/mergeWithAttributes/main.wsdl', {}, function(err, client) {
assert.ok(!err);
client.AskPeat({ Question: 'How are you?' }, function(err, result) {
assert.equal(client.lastMessage, expectedMsg);
done();
});
});
};

module.exports = {
'WSDL Parser (strict)': wsdlStrictTests,
'WSDL Parser (non-strict)': wsdlNonStrictTests
Expand Down
27 changes: 27 additions & 0 deletions test/wsdl/mergeWithAttributes/def.xsd
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Notice that targetNamespace matches import's namespace.
Also notice elementFormDefault="qualified". -->
<xsd:schema
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:tns="urn:peat.def"
targetNamespace="urn:peat.def"
elementFormDefault="qualified"
>

<xsd:element name="AskPeat">
<xsd:complexType>
<xs:sequence>
<xsd:element name="Question" type="xsd:string" />
</xs:sequence>
</xsd:complexType>
</xsd:element>

<xsd:element name="AskPeatResponse">
<xsd:complexType>
<xs:sequence>
<xsd:element name="Answer" type="xsd:string" />
</xs:sequence>
</xsd:complexType>
</xsd:element>

</xsd:schema>
47 changes: 47 additions & 0 deletions test/wsdl/mergeWithAttributes/main.wsdl
@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions
targetNamespace="urn:peat"
xmlns:tns="urn:peat"
xmlns:peatdef="urn:peat.def"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
>

<!-- Notice that namespace below matchs targetNamespace in def.xsd, triggering merge. -->
<wsdl:import namespace="urn:peat.def" location="def.xsd" />

<wsdl:message name="AskPeatInput">
<wsdl:part name="body" element="peatdef:AskPeat"/>
</wsdl:message>

<wsdl:message name="AskPeatOutput">
<wsdl:part name="body" element="peatdef:AskPeatResponse"/>
</wsdl:message>

<wsdl:portType name="AskPeatPortType">
<wsdl:operation name="AskPeat">
<wsdl:input message="tns:AskPeatInput"/>
<wsdl:output message="tns:AskPeatOutput"/>
</wsdl:operation>
</wsdl:portType>

<wsdl:binding name="AskPeatSoapBinding" type="tns:AskPeatPortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="AskPeat">
<soap:operation soapAction="urn:peat/AskPeat"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>

<wsdl:service name="AskPeatService">
<wsdl:port name="AskPeatPort" binding="tns:AskPeatSoapBinding">
<soap:address location="http://localhost:15099/peat"/>
</wsdl:port>
</wsdl:service>

</wsdl:definitions>

0 comments on commit 2f159d0

Please sign in to comment.