marshal passed empty object optional params as empty tags

Before, passing an empty suds object as an optional parameter value was treated
the same as not passing that parameter's value or passing it None - the value
would not get marshalled into the constructed SOAP request at all.

Now, user can still not have the value marshalled by passing nothing or None,
but passing an empty object will get marshalled as an actual SOAP request XML
element.

This seems correct as passing an empty object and not passing an object are two
distinct use-cases and there are web-services out there (e.g.
`https://ads.google.com/apis/ads/publisher/v201502/LineItemService?wsdl`) that
do differentiate between the two.

Fixes issue filed on BitBucket under:
`https://bitbucket.org/jurko/suds/issues/81/suds-should-support-an-empty-object`

Kudos to Nicholas Chen (nicholaschen at BitBucket) & Mark Saniscalchi
(msaniscalchi at BitBucket) for reporting the issue and preparing the initial
fix.
This commit is contained in:
Jurko Gospodnetić 2015-07-27 11:04:48 +02:00
parent e346aa2a18
commit 313185c9b4
3 changed files with 65 additions and 3 deletions

View File

@ -177,6 +177,20 @@ version 0.7 (development)
convert any encountered dictionaries to ``suds.sudsobject.Object`` instances
and report an error in case a corresponding XSD type can not be found.
* Now marshalling passed empty object optional params as empty SOAP request XML
elements.
* Before, passing an empty suds object as an optional parameter value was
treated the same as not passing that parameter's value or passing it
``None`` - the value would not get marshalled into the constructed SOAP
request at all.
* Now, user can still not have the value marshalled by passing nothing or
``None``, but passing an empty object will get marshalled as an actual SOAP
request XML element.
* Kudos to Nicholas Chen (nicholaschen at BitBucket) & Mark Saniscalchi
(msaniscalchi at BitBucket) for reporting the issue and preparing the
initial fix.
* Made ``suds`` no longer eat up, log & ignore exceptions raised from registered
user plugins (detected & reported by Ezequiel Ruiz & Bouke Haarsma, patch &
test case contributed by Bouke Haarsma).

View File

@ -20,7 +20,6 @@ Provides appender classes for I{marshalling}.
from suds import *
from suds.mx import *
from suds.sudsobject import footprint
from suds.sudsobject import Object, Property
from suds.sax.element import Element
from suds.sax.text import Text
@ -219,8 +218,6 @@ class ObjectAppender(Appender):
def append(self, parent, content):
object = content.value
if self.optional(content) and footprint(object) == 0:
return
child = self.node(content)
parent.append(child)
for item in object:

View File

@ -795,6 +795,57 @@ def test_optional_parameter_handling():
</Envelope>""" % (xsd_target_namespace,))
def test_optional_parameter_with_empty_object_value():
"""Missing optional parameters should not get passed at all."""
xsd_target_namespace = "I'm a cute little swamp gorilla monster!"
wsdl = testutils.wsdl("""\
<xsd:element name="Wrapper">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:anyType" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>""", input="Wrapper", operation_name="f",
xsd_target_namespace=xsd_target_namespace)
client = testutils.client_from_wsdl(wsdl, nosend=True, prettyxml=True)
service = client.service
# Base line: nothing passed --> nothing marshalled.
_assert_request_content(service.f(), """\
<?xml version="1.0" encoding="UTF-8"?>
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
<Header/>
<Body>
<Wrapper xmlns="%s"/>
</Body>
</Envelope>""" % (xsd_target_namespace,))
# Passing a empty object as an empty dictionary.
_assert_request_content(service.f({}), """\
<?xml version="1.0" encoding="UTF-8"?>
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
<Header/>
<Body>
<Wrapper xmlns="%s">
<value/>
</Wrapper>
</Body>
</Envelope>""" % (xsd_target_namespace,))
# Passing a empty explicitly constructed `suds.sudsobject.Object`.
empty_object = client.factory.create("my_xsd:Wrapper")
_assert_request_content(service.f(empty_object), """\
<?xml version="1.0" encoding="UTF-8"?>
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
<Header/>
<Body>
<Wrapper xmlns="%s">
<value/>
</Wrapper>
</Body>
</Envelope>""" % (xsd_target_namespace,))
def test_SOAP_headers():
"""Rudimentary 'soapheaders' option usage test."""
wsdl = suds.byte_str("""\