3

My SOAP services will be tested with various invalid payloads to confirm the appropriate responses are returned.

Before testing is carried out, i would like to do my own testing on my services. A few of the tests involve removal of a mandatory field. I would like to simulate these tests using zeep, but zeep will not allow me to send a request, giving me a zeep.exceptions.ValidationError if any of the mandatory fields are not present in the data i want to send.

Is there some setting i can configure so that zeep doesn't throw an error for the missing field and sends the invalid request anyway?

example code:

from zeep import Client
from datetime import datetime

wsdl_url = 'http://myservice.com/egservice?wsdl'

payload = {
    'ServiceType': 'EgService',
    'AvailabilityWindow': [
        {'StartDateTime': datetime.now(),
         'EndDateTime': datetime.now(),
         'Validation': 'VALID'}],
    'Confirmation': 'Confirmed',
    'DateTimeStamp': datetime.now()
}  # N.B No ContractID included

soap_client = Client(wsdl_url)
operation = 'myExampleOperation'
with soap_client.settings(raw_response=True):
    response = soap_client.service[operation](**payload)

relevant part of wsdl:

<xs:complexType name="EgMessage">
    <xs:sequence>
        <xs:element name="ServiceType" type="tns:EgMessage_ServiceTypeType"/>
        <xs:element name="ContractID" type="tns:EgMessage_ContractIDType"/>
        <xs:element name="AUI" type="tns:EgMessage_AUIType" minOccurs="0"/>
        <xs:element name="AvailabilityWindow" type="tns:AvailabilityWindowType" maxOccurs="unbounded"/>
        <xs:element name="Confirmation" type="tns:EgMessage_ConfirmationType"/>
        <xs:element name="FileReason" type="tns:EgMessage_FileReasonType" minOccurs="0"/>
        <xs:element name="DateTimeStamp" type="xs:dateTime"/>
</xs:sequence>
</xs:complexType>

traceback:

Traceback (most recent call last):
  File "C:/Users/Thomas.Gabereau/PycharmProjects/pas_rmq/pas_gateway/inbound/test_local_soap.py", line 157, in <module>
    status, fault_field, fault = send_to_grid(soap_client, operation, payload)
  File "C:/Users/Thomas.Gabereau/PycharmProjects/pas_rmq/pas_gateway/inbound/test_local_soap.py", line 129, in send_to_grid
    response = soap_client.service[operation](**payload)
  File "C:\Users\Thomas.Gabereau\PycharmProjects\pas_rmq\venv\lib\site-packages\zeep\proxy.py", line 45, in __call__
    kwargs,
  File "C:\Users\Thomas.Gabereau\PycharmProjects\pas_rmq\venv\lib\site-packages\zeep\wsdl\bindings\soap.py", line 119, in send
    operation, args, kwargs, client=client, options=options
  File "C:\Users\Thomas.Gabereau\PycharmProjects\pas_rmq\venv\lib\site-packages\zeep\wsdl\bindings\soap.py", line 68, in _create
    serialized = operation_obj.create(*args, **kwargs)
  File "C:\Users\Thomas.Gabereau\PycharmProjects\pas_rmq\venv\lib\site-packages\zeep\wsdl\definitions.py", line 215, in create
    return self.input.serialize(*args, **kwargs)
  File "C:\Users\Thomas.Gabereau\PycharmProjects\pas_rmq\venv\lib\site-packages\zeep\wsdl\messages\soap.py", line 74, in serialize
    self.body.render(body, body_value)
  File "C:\Users\Thomas.Gabereau\PycharmProjects\pas_rmq\venv\lib\site-packages\zeep\xsd\elements\element.py", line 231, in render
    self._render_value_item(parent, value, render_path)
  File "C:\Users\Thomas.Gabereau\PycharmProjects\pas_rmq\venv\lib\site-packages\zeep\xsd\elements\element.py", line 255, in _render_value_item
    return self.type.render(node, value, None, render_path)
  File "C:\Users\Thomas.Gabereau\PycharmProjects\pas_rmq\venv\lib\site-packages\zeep\xsd\types\complex.py", line 279, in render
    element.render(parent, element_value, child_path)
  File "C:\Users\Thomas.Gabereau\PycharmProjects\pas_rmq\venv\lib\site-packages\zeep\xsd\elements\indicators.py", line 242, in render
    element.render(parent, element_value, child_path)
  File "C:\Users\Thomas.Gabereau\PycharmProjects\pas_rmq\venv\lib\site-packages\zeep\xsd\elements\element.py", line 225, in render
    self.validate(value, render_path)
  File "C:\Users\Thomas.Gabereau\PycharmProjects\pas_rmq\venv\lib\site-packages\zeep\xsd\elements\element.py", line 280, in validate
    "Missing element %s" % (self.name), path=render_path
zeep.exceptions.ValidationError: Missing element ContractID(myExampleOperation.ContractID)
teebagz
  • 656
  • 1
  • 4
  • 26
  • Can you share your code snippet and stack trace? – theone1one Sep 12 '19 at 15:02
  • I have edited my question with some example code which is accurately representative of my issue . I hope this is sufficient to convey the issue. i thought it best to change some details in case of any chance of potential sensitivity. – teebagz Sep 12 '19 at 15:28
  • The crux of the issue is, though, i think this could be recreated with any operation having a mandatory field, and payload which does not include the mandatory field. – teebagz Sep 12 '19 at 15:38
  • Seems ContractID is mandatory. Try by putting empty string or some random value. – theone1one Sep 19 '19 at 17:37
  • @theone1one thanks but i know it's mandatory. I am asking if there is a way to send the request with the tag missing completely, to cause an error on purpose for testing reasons – teebagz Sep 23 '19 at 12:09

1 Answers1

5

I faced the same issue then found out a solution for this problem. There is a option to skip the validation for mandatory fields.you have to set the value as xsd.skipvalue for the property you want to skip. In your scenario set the value for contractId as xsd.skipvalue in the payload object

from zeep import xsd

payload = {
    'ServiceType': 'EgService',
    'ContractID':xsd.SkipValue,
    'AvailabilityWindow': [
        {'StartDateTime': datetime.now(),
         'EndDateTime': datetime.now(),
         'Validation': 'VALID'}],
    'Confirmation': 'Confirmed',
    'DateTimeStamp': datetime.now()
}   
Mukesh mohan
  • 101
  • 1
  • 6