def test_bare_input_restriction_types(): client_unnamed = testutils.client_from_wsdl( testutils.wsdl("""\ <xsd:element name="Elemento"> <xsd:simpleType> <xsd:restriction base="xsd:string"> <xsd:enumeration value="alfa"/> <xsd:enumeration value="beta"/> <xsd:enumeration value="gamma"/> </xsd:restriction> </xsd:simpleType> </xsd:element>""", input="Elemento", operation_name="f")) client_named = testutils.client_from_wsdl( testutils.wsdl("""\ <xsd:simpleType name="MyType"> <xsd:restriction base="xsd:string"> <xsd:enumeration value="alfa"/> <xsd:enumeration value="beta"/> <xsd:enumeration value="gamma"/> </xsd:restriction> </xsd:simpleType> <xsd:element name="Elemento" type="ns:MyType"/>""", input="Elemento", operation_name="f")) assert not _is_input_wrapped(client_unnamed, "f") assert not _is_input_wrapped(client_named, "f")
def test_bare_input_restriction_types(): client_unnamed = testutils.client_from_wsdl(testutils.wsdl("""\ <xsd:element name="Elemento"> <xsd:simpleType> <xsd:restriction base="xsd:string"> <xsd:enumeration value="alfa"/> <xsd:enumeration value="beta"/> <xsd:enumeration value="gamma"/> </xsd:restriction> </xsd:simpleType> </xsd:element>""", input="Elemento", operation_name="f")) client_named = testutils.client_from_wsdl(testutils.wsdl("""\ <xsd:simpleType name="MyType"> <xsd:restriction base="xsd:string"> <xsd:enumeration value="alfa"/> <xsd:enumeration value="beta"/> <xsd:enumeration value="gamma"/> </xsd:restriction> </xsd:simpleType> <xsd:element name="Elemento" type="ns:MyType"/>""", input="Elemento", operation_name="f")) assert not _is_input_wrapped(client_unnamed, "f") assert not _is_input_wrapped(client_named, "f")
def test_wrapped_sequence_output(): client = testutils.lxmlclient_from_wsdl(testutils.wsdl("""\ <xsd:element name="Wrapper"> <xsd:complexType> <xsd:sequence> <xsd:element name="result1" type="xsd:string"/> <xsd:element name="result2" type="xsd:string"/> <xsd:element name="result3" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element>""", output="Wrapper")) response = client.service.f(__inject=dict(reply=suds.byte_str("""\ <?xml version="1.0"?> <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Body> <Wrapper xmlns="my-namespace"> <result1>Uno</result1> <result2>Due</result2> <result3>Tre</result3> </Wrapper> </Body> </Envelope>"""))) # Check response content. assert len(response) == 3 assert response.result1 == "Uno" assert response.result2 == "Due" assert response.result3 == "Tre" assert_lxml_string_value(response.result1) assert_lxml_string_value(response.result2) assert_lxml_string_value(response.result3) client = testutils.lxmlclient_from_wsdl(testutils.wsdl("""\ <xsd:element name="Wrapper"> <xsd:complexType> <xsd:sequence> <xsd:element name="result1" type="xsd:string"/> <xsd:element name="result2" type="xsd:string"/> <xsd:element name="result3" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element>""", output="Wrapper")) response = client.service.f(__inject=dict(reply=suds.byte_str("""\ <?xml version="1.0"?> <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Body> <Wrapper xmlns="my-namespace"> </Wrapper> </Body> </Envelope>"""))) # Check response content. assert len(response) == 3 assert response.result1 is None assert response.result2 is None assert response.result3 is None
def test_restriction_data_types(): client_unnamed = testutils.client_from_wsdl( testutils.wsdl("""\ <xsd:element name="Elemento"> <xsd:simpleType> <xsd:restriction base="xsd:int"> <xsd:enumeration value="1"/> <xsd:enumeration value="3"/> <xsd:enumeration value="5"/> </xsd:restriction> </xsd:simpleType> </xsd:element>""", output="Elemento")) client_named = testutils.client_from_wsdl( testutils.wsdl("""\ <xsd:simpleType name="MyType"> <xsd:restriction base="xsd:int"> <xsd:enumeration value="1"/> <xsd:enumeration value="3"/> <xsd:enumeration value="5"/> </xsd:restriction> </xsd:simpleType> <xsd:element name="Elemento" type="ns:MyType"/>""", output="Elemento")) client_twice_restricted = testutils.client_from_wsdl( testutils.wsdl("""\ <xsd:simpleType name="MyTypeGeneric"> <xsd:restriction base="xsd:int"> <xsd:enumeration value="1"/> <xsd:enumeration value="2"/> <xsd:enumeration value="3"/> <xsd:enumeration value="4"/> <xsd:enumeration value="5"/> </xsd:restriction> </xsd:simpleType> <xsd:simpleType name="MyType"> <xsd:restriction base="ns:MyTypeGeneric"> <xsd:enumeration value="1"/> <xsd:enumeration value="3"/> <xsd:enumeration value="5"/> </xsd:restriction> </xsd:simpleType> <xsd:element name="Elemento" type="ns:MyType"/>""", output="Elemento")) for client in (client_unnamed, client_named, client_twice_restricted): response = client.service.f(__inject=dict(reply=suds.byte_str("""\ <?xml version="1.0"?> <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Body> <Elemento xmlns="my-namespace">5</Elemento> </Body> </Envelope>"""))) assert response.__class__ is int assert response == 5
def test_restriction_data_types(): client_unnamed = testutils.client_from_wsdl(testutils.wsdl("""\ <xsd:element name="Elemento"> <xsd:simpleType> <xsd:restriction base="xsd:int"> <xsd:enumeration value="1"/> <xsd:enumeration value="3"/> <xsd:enumeration value="5"/> </xsd:restriction> </xsd:simpleType> </xsd:element>""", output="Elemento")) client_named = testutils.client_from_wsdl(testutils.wsdl("""\ <xsd:simpleType name="MyType"> <xsd:restriction base="xsd:int"> <xsd:enumeration value="1"/> <xsd:enumeration value="3"/> <xsd:enumeration value="5"/> </xsd:restriction> </xsd:simpleType> <xsd:element name="Elemento" type="ns:MyType"/>""", output="Elemento")) client_twice_restricted = testutils.client_from_wsdl(testutils.wsdl("""\ <xsd:simpleType name="MyTypeGeneric"> <xsd:restriction base="xsd:int"> <xsd:enumeration value="1"/> <xsd:enumeration value="2"/> <xsd:enumeration value="3"/> <xsd:enumeration value="4"/> <xsd:enumeration value="5"/> </xsd:restriction> </xsd:simpleType> <xsd:simpleType name="MyType"> <xsd:restriction base="ns:MyTypeGeneric"> <xsd:enumeration value="1"/> <xsd:enumeration value="3"/> <xsd:enumeration value="5"/> </xsd:restriction> </xsd:simpleType> <xsd:element name="Elemento" type="ns:MyType"/>""", output="Elemento")) for client in (client_unnamed, client_named, client_twice_restricted): response = client.service.f(__inject=dict(reply=suds.byte_str("""\ <?xml version="1.0"?> <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Body> <Elemento xmlns="my-namespace">5</Elemento> </Body> </Envelope>"""))) assert response.__class__ is int assert response == 5
def test_simple_bare_and_wrapped_output(): # Prepare web service proxies. client_bare = testutils.client_from_wsdl( testutils.wsdl("""\ <xsd:element name="fResponse" type="xsd:string"/>""", output="fResponse")) client_wrapped = testutils.client_from_wsdl( testutils.wsdl("""\ <xsd:element name="Wrapper"> <xsd:complexType> <xsd:sequence> <xsd:element name="fResponse" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element>""", output="Wrapper")) # Make sure suds library inteprets our WSDL definitions as wrapped or bare # output interfaces as expected. assert not _isOutputWrapped(client_bare, "f") assert _isOutputWrapped(client_wrapped, "f") # Both bare & wrapped single parameter output web service operation results # get presented the same way even though the wrapped one actually has an # extra wrapper element around its received output data. data = "The meaning of life." def get_response(client, x): return client.service.f(__inject=dict(reply=suds.byte_str(x))) response_bare = get_response( client_bare, """<?xml version="1.0"?> <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Body> <fResponse xmlns="my-namespace">%s</fResponse> </Body> </Envelope>""" % (data, )) assert response_bare.__class__ is suds.sax.text.Text assert response_bare == data response_wrapped = get_response( client_wrapped, """<?xml version="1.0"?> <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Body> <Wrapper xmlns="my-namespace"> <fResponse>%s</fResponse> </Wrapper> </Body> </Envelope>""" % (data, )) assert response_wrapped.__class__ is suds.sax.text.Text assert response_wrapped == data
def test_enum(): client = testutils.lxmlclient_from_wsdl( testutils.wsdl("""\ <xsd:element name="Wrapper"> <xsd:element name="Size"> <xsd:simpleType name="DataSize"> <xsd:restriction base="xsd:string"> <xsd:enumeration value="1" /> <xsd:enumeration value="2"/> <xsd:enumeration value="3"/> </xsd:restriction> </xsd:simpleType> </xsd:element> </xsd:element>""", output="Wrapper")) response = client.service.f(__inject=dict(reply=suds.byte_str("""\ <?xml version="1.0"?> <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Body> <Wrapper xmlns="my-namespace"> <DataSize>1</DataSize> </Wrapper> </Body> </Envelope>"""))) # Check response content. assert len(response) == 1 assert response.size == 1
def test_avoid_external_XSD_fetching(self): # Prepare document content. xsd_target_namespace = "balancana" wsdl = testutils.wsdl("""\ <xsd:import schemaLocation="suds://imported_xsd"/> <xsd:include schemaLocation="suds://included_xsd"/>""", xsd_target_namespace=xsd_target_namespace) external_xsd_format = """\ <?xml version='1.0' encoding='UTF-8'?> <schema xmlns="http://www.w3.org/2001/XMLSchema"> <element name="external%d" type="string"/> </schema>""" external_xsd1 = b(external_xsd_format % (1,)) external_xsd2 = b(external_xsd_format % (2,)) # Add to cache. cache = MockCache() store1 = MockDocumentStore(wsdl=wsdl, imported_xsd=external_xsd1, included_xsd=external_xsd2) c1 = suds.client.Client("suds://wsdl", cachingpolicy=1, cache=cache, documentStore=store1, transport=MockTransport()) assert store1.mock_log == ["suds://wsdl", "suds://imported_xsd", "suds://included_xsd"] assert len(cache.mock_data) == 1 wsdl_object_id, wsdl_object = next(iteritems(cache.mock_data)) assert wsdl_object.__class__ is suds.wsdl.Definitions # Reuse from cache. cache.mock_log = [] store2 = MockDocumentStore(wsdl=wsdl) c2 = suds.client.Client("suds://wsdl", cachingpolicy=1, cache=cache, documentStore=store2, transport=MockTransport()) assert cache.mock_log == [("get", [wsdl_object_id])] assert store2.mock_log == []
def test_disabling_automated_simple_interface_unwrapping(): client = testutils.client_from_wsdl(testutils.wsdl("""\ <xsd:element name="Wrapper"> <xsd:complexType> <xsd:sequence> <xsd:element name="Elemento" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element>""", output="Wrapper"), unwrap=False) assert not _isOutputWrapped(client, "f") response = client.service.f(__inject=dict(reply=suds.byte_str("""\ <?xml version="1.0"?> <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Body> <Wrapper xmlns="my-namespace"> <Elemento>La-di-da-da-da</Elemento> </Wrapper> </Body> </Envelope>"""))) assert response.__class__.__name__ == "Wrapper" assert len(response.__class__.__bases__) == 1 assert response.__class__.__bases__[0] is suds.sudsobject.Object assert response.Elemento.__class__ is suds.sax.text.Text assert response.Elemento == "La-di-da-da-da"
def test_error_on_send__non_transport(self): e = MyException() t = MockTransport(send_data=e) store = MockDocumentStore(wsdl=testutils.wsdl("", operation_name="g")) client = suds.client.Client("suds://wsdl", documentStore=store, cache=None, transport=t) assert pytest.raises(MyException, client.service.g).value is e
def test_allow_unknown_message_parts(): # Prepare web service proxies. client = testutils.client_from_wsdl(testutils.wsdl("""\ <xsd:element name="Wrapper"> <xsd:complexType> <xsd:sequence> <xsd:element name="fResponse" type="xsd:string"/> <xsd:element name="gResponse" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element>""", output="Wrapper")) client.set_options(allowUnknownMessageParts=True) data = "The meaning of life." def get_response(client, x): return client.service.f(__inject=dict(reply=virtwho.virt.esx.suds.byte_str(x))) response = get_response(client, """<?xml version="1.0"?> <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Body> <Wrapper xmlns="my-namespace"> <fResponse>%s</fResponse> <gResponse></gResponse> <hResponse></hResponse> </Wrapper> </Body> </Envelope>""" % (data,)) assert response.fResponse == data assert response.gResponse == None
def test_operation_request_and_reply(self): xsd_content = '<xsd:element name="Data" type="xsd:string"/>' web_service_URL = "Great minds think alike" xsd_target_namespace = "omicron psi" wsdl = testutils.wsdl(xsd_content, operation_name="pi", xsd_target_namespace=xsd_target_namespace, input="Data", output="Data", web_service_URL=web_service_URL) test_input_data = "Riff-raff" test_output_data = "La-di-da-da-da" store = MockDocumentStore(wsdl=wsdl) transport = MockTransport(send_data=b("""\ <?xml version="1.0"?> <env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"> <env:Body> <Data xmlns="%s">%s</Data> </env:Body> </env:Envelope>""" % (xsd_target_namespace, test_output_data))) client = suds.client.Client("suds://wsdl", documentStore=store, cache=None, transport=transport) assert transport.mock_log == [] reply = client.service.pi(test_input_data) assert len(transport.mock_log) == 1 assert transport.mock_log[0][0] == "send" assert transport.mock_log[0][1][0] == web_service_URL request_message = transport.mock_log[0][1][1] assert b(xsd_target_namespace) in request_message assert b(test_input_data) in request_message assert reply == test_output_data
def test_enum(): client = testutils.lxmlclient_from_wsdl(testutils.wsdl("""\ <xsd:element name="Wrapper"> <xsd:element name="Size"> <xsd:simpleType name="DataSize"> <xsd:restriction base="xsd:string"> <xsd:enumeration value="1" /> <xsd:enumeration value="2"/> <xsd:enumeration value="3"/> </xsd:restriction> </xsd:simpleType> </xsd:element> </xsd:element>""", output="Wrapper")) response = client.service.f(__inject=dict(reply=suds.byte_str("""\ <?xml version="1.0"?> <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Body> <Wrapper xmlns="my-namespace"> <DataSize>1</DataSize> </Wrapper> </Body> </Envelope>"""))) # Check response content. assert len(response) == 1 assert response.size == 1
def test_missing_wrapper_response(): """ Suds library's automatic structure unwrapping should not be applied to interpreting received SOAP Response XML. """ client = testutils.client_from_wsdl( testutils.wsdl("""\ <xsd:element name="Wrapper"> <xsd:complexType> <xsd:sequence> <xsd:element name="fResponse" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element>""", output="Wrapper")) assert _isOutputWrapped(client, "f") response_with_missing_wrapper = client.service.f(__inject=dict( reply=suds.byte_str("""<?xml version="1.0"?> <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Body> <fResponse xmlns="my-namespace">Anything</fResponse> </Body> </Envelope>"""))) assert response_with_missing_wrapper is None
def test_disabling_automated_simple_interface_unwrapping(): xsd_target_namespace = "woof" wsdl = testutils.wsdl("""\ <xsd:element name="Wrapper"> <xsd:complexType> <xsd:sequence> <xsd:element name="Elemento" type="xsd:string"/> </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, unwrap=False) assert not _is_input_wrapped(client, "f") element_data = "Wonderwall" wrapper = client.factory.create("my_xsd:Wrapper") wrapper.Elemento = element_data _assert_request_content( client.service.f(Wrapper=wrapper), """\ <?xml version="1.0" encoding="UTF-8"?> <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Header/> <Body> <Wrapper xmlns="%s"> <Elemento>%s</Elemento> </Wrapper> </Body> </Envelope>""" % (xsd_target_namespace, element_data))
def test_operation_request_and_reply(self): xsd_content = '<xsd:element name="Data" type="xsd:string"/>' web_service_URL = "Great minds think alike" xsd_target_namespace = "omicron psi" wsdl = testutils.wsdl(suds.byte_str(xsd_content), operation_name="pi", xsd_target_namespace=xsd_target_namespace, input="Data", output="Data", web_service_URL=web_service_URL) test_input_data = "Riff-raff" test_output_data = "La-di-da-da-da" store = MockDocumentStore(wsdl=wsdl) transport = MockTransport(send_data=suds.byte_str("""\ <?xml version="1.0"?> <env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"> <env:Body> <Data xmlns="%s">%s</Data> </env:Body> </env:Envelope>""" % (xsd_target_namespace, test_output_data))) client = suds.client.Client("suds://wsdl", documentStore=store, cache=None, transport=transport) assert transport.mock_log == [] reply = client.service.pi(test_input_data) assert len(transport.mock_log) == 1 assert transport.mock_log[0][0] == "send" assert transport.mock_log[0][1][0] == web_service_URL request_message = transport.mock_log[0][1][1] assert suds.byte_str(xsd_target_namespace) in request_message assert suds.byte_str(test_input_data) in request_message assert reply == test_output_data
def test_disabling_automated_simple_interface_unwrapping(): xsd_target_namespace = "woof" wsdl = testutils.wsdl( """\ <xsd:element name="Wrapper"> <xsd:complexType> <xsd:sequence> <xsd:element name="Elemento" type="xsd:string"/> </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, unwrap=False) assert not _is_input_wrapped(client, "f") element_data = "Wonderwall" wrapper = client.factory.create("my_xsd:Wrapper") wrapper.Elemento = element_data _assert_request_content( client.service.f(Wrapper=wrapper), """\ <?xml version="1.0" encoding="UTF-8"?> <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Header/> <Body> <Wrapper xmlns="%s"> <Elemento>%s</Elemento> </Wrapper> </Body> </Envelope>""" % (xsd_target_namespace, element_data), )
def test_avoid_external_XSD_fetching(self): # Prepare document content. xsd_target_namespace = "balancana" wsdl = testutils.wsdl("""\ <xsd:import schemaLocation="suds://imported_xsd"/> <xsd:include schemaLocation="suds://included_xsd"/>""", xsd_target_namespace=xsd_target_namespace) external_xsd_format = """\ <?xml version='1.0' encoding='UTF-8'?> <schema xmlns="http://www.w3.org/2001/XMLSchema"> <element name="external%d" type="string"/> </schema>""" external_xsd1 = suds.byte_str(external_xsd_format % (1,)) external_xsd2 = suds.byte_str(external_xsd_format % (2,)) # Add to cache. cache = MockCache() store1 = MockDocumentStore(wsdl=wsdl, imported_xsd=external_xsd1, included_xsd=external_xsd2) c1 = suds.client.Client("suds://wsdl", cachingpolicy=1, cache=cache, documentStore=store1, transport=MockTransport()) assert store1.mock_log == ["suds://wsdl", "suds://imported_xsd", "suds://included_xsd"] assert len(cache.mock_data) == 1 wsdl_object_id, wsdl_object = next(iteritems(cache.mock_data)) assert wsdl_object.__class__ is suds.wsdl.Definitions # Reuse from cache. cache.mock_log = [] store2 = MockDocumentStore(wsdl=wsdl) c2 = suds.client.Client("suds://wsdl", cachingpolicy=1, cache=cache, documentStore=store2, transport=MockTransport()) assert cache.mock_log == [("get", [wsdl_object_id])] assert store2.mock_log == []
def test_twice_wrapped_parameter(): """ Suds does not recognize 'twice wrapped' data structures and unwraps the external one but keeps the internal wrapping structure in place. """ xsd_target_namespace = "spank me" wsdl = testutils.wsdl("""\ <xsd:element name="Wrapper1"> <xsd:complexType> <xsd:sequence> <xsd:element name="Wrapper2"> <xsd:complexType> <xsd:sequence> <xsd:element name="Elemento" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element>""", input="Wrapper1", operation_name="f", xsd_target_namespace=xsd_target_namespace) client = testutils.client_from_wsdl(wsdl, nosend=True, prettyxml=True) assert _is_input_wrapped(client, "f") # Web service operation calls made with 'valid' parameters. # # These calls are actually illegal and result in incorrectly generated SOAP # requests not matching the relevant WSDL schema. To make them valid we # would need to pass a more complex value instead of a simple string, but # the current simpler solution is good enough for what we want to test # here. value = "A B C" expected_request = """\ <?xml version="1.0" encoding="UTF-8"?> <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Header/> <Body> <Wrapper1 xmlns="%s"> <Wrapper2>%s</Wrapper2> </Wrapper1> </Body> </Envelope>""" % (xsd_target_namespace, value) _assert_request_content(client.service.f(value), expected_request) _assert_request_content(client.service.f(Wrapper2=value), expected_request) # Web service operation calls made with 'invalid' parameters. def test_invalid_parameter(**kwargs): assert len(kwargs) == 1 keyword = next(iterkeys(kwargs)) expected = "f() got an unexpected keyword argument '%s'" % (keyword,) e = pytest.raises(TypeError, client.service.f, **kwargs).value try: assert str(e) == expected finally: del e # explicitly break circular reference chain in Python 3 test_invalid_parameter(Elemento=value) test_invalid_parameter(Wrapper1=value)
def _create_dummy_schema(): """Constructs a new dummy XSD schema instance.""" #TODO: Find out how to construct this XSD schema object directly without # first having to construct a suds.client.Client from a complete WSDL # schema. wsdl = testutils.wsdl('<xsd:element name="dummy"/>', input="dummy") client = testutils.client_from_wsdl(wsdl) return client.wsdl.schema
def test_simple_bare_and_wrapped_output(): # Prepare web service proxies. client_bare = testutils.client_from_wsdl(testutils.wsdl("""\ <xsd:element name="fResponse" type="xsd:string"/>""", output="fResponse")) client_wrapped = testutils.client_from_wsdl(testutils.wsdl("""\ <xsd:element name="Wrapper"> <xsd:complexType> <xsd:sequence> <xsd:element name="fResponse" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element>""", output="Wrapper")) # Make sure suds library inteprets our WSDL definitions as wrapped or bare # output interfaces as expected. assert not _isOutputWrapped(client_bare, "f") assert _isOutputWrapped(client_wrapped, "f") # Both bare & wrapped single parameter output web service operation results # get presented the same way even though the wrapped one actually has an # extra wrapper element around its received output data. data = "The meaning of life." def get_response(client, x): return client.service.f(__inject=dict(reply=suds.byte_str(x))) response_bare = get_response(client_bare, """<?xml version="1.0"?> <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Body> <fResponse xmlns="my-namespace">%s</fResponse> </Body> </Envelope>""" % (data,)) assert response_bare.__class__ is suds.sax.text.Text assert response_bare == data response_wrapped = get_response(client_wrapped, """<?xml version="1.0"?> <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Body> <Wrapper xmlns="my-namespace"> <fResponse>%s</fResponse> </Wrapper> </Body> </Envelope>""" % (data,)) assert response_wrapped.__class__ is suds.sax.text.Text assert response_wrapped == data
def test_error_on_send__transport(self, monkeypatch): monkeypatch.delitem(locals(), "e", False) t = MockTransport(send_data=suds.transport.TransportError("huku", 666)) store = MockDocumentStore(wsdl=testutils.wsdl("", operation_name="g")) client = suds.client.Client("suds://wsdl", documentStore=store, cache=None, transport=t) e = pytest.raises(Exception, client.service.g).value try: assert e.__class__ is Exception assert e.args == ((666, "huku"),) finally: del e # explicitly break circular reference chain in Python 3
def test_external_XSD_transport(self, url, external_reference_tag): xsd_content = '<xsd:%(tag)s schemaLocation="%(url)s"/>' % dict( tag=external_reference_tag, url=url) store = MockDocumentStore(wsdl=testutils.wsdl(xsd_content)) t = MockTransport(open_data=suds.byte_str("""\ <?xml version='1.0' encoding='UTF-8'?> <schema xmlns="http://www.w3.org/2001/XMLSchema"/> """)) suds.client.Client("suds://wsdl", cache=None, documentStore=store, transport=t) assert t.mock_log == [("open", [url])]
def test_document_literal_request_for_single_element_input(xsd, external_element_name, args, request_body): wsdl = testutils.wsdl(xsd, input=external_element_name, xsd_target_namespace="dr. Doolittle", operation_name="f") client = testutils.client_from_wsdl(wsdl, nosend=True, prettyxml=True) _assert_request_content(client.service.f(*args), """\ <?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> <SOAP-ENV:Header/> <SOAP-ENV:Body xmlns="dr. Doolittle">%s</SOAP-ENV:Body> </SOAP-ENV:Envelope>""" % (request_body,))
def test_external_XSD_transport(self, url, external_reference_tag): xsd_content = '<xsd:%(tag)s schemaLocation="%(url)s"/>' % dict( tag=external_reference_tag, url=url) store = MockDocumentStore(wsdl=testutils.wsdl(xsd_content)) t = MockTransport(open_data=b("""\ <?xml version='1.0' encoding='UTF-8'?> <schema xmlns="http://www.w3.org/2001/XMLSchema"/> """)) suds.client.Client("suds://wsdl", cache=None, documentStore=store, transport=t) assert t.mock_log == [("open", [url])]
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_WSDL_import(): wsdl_target_namespace = "bingo-bongo" wsdl = testutils.wsdl("", wsdl_target_namespace=wsdl_target_namespace) wsdl_wrapper = suds.byte_str("""\ <?xml version='1.0' encoding='UTF-8'?> <definitions targetNamespace="%(tns)s" xmlns="http://schemas.xmlsoap.org/wsdl/"> <import namespace="%(tns)s" location="suds://wsdl"/> </definitions>""" % {"tns": wsdl_target_namespace}) store = suds.store.DocumentStore(wsdl=wsdl, wsdl_wrapper=wsdl_wrapper) client = suds.client.Client("suds://wsdl_wrapper", documentStore=store, cache=None, nosend=True) client.service.f()
def test_operation_invoke_with_urlopen_accept_no_content__data(self, status_code): """ suds.client.Client web service operation invocation expecting output data, and for which a corresponding urlopen call raises a HTTPError with status code ACCEPTED or NO_CONTENT, should report this as a TransportError. """ e = self.create_HTTPError(code=status_code) transport = suds.transport.http.HttpTransport() transport.urlopener = MockURLOpenerSaboteur(open_exception=e) wsdl = testutils.wsdl('<xsd:element name="o" type="xsd:string"/>', output="o", operation_name="f") client = testutils.client_from_wsdl(wsdl, transport=transport) pytest.raises(suds.transport.TransportError, client.service.f)
def test_using_cached_WSDL_avoids_store_avoids_transport( self, caching_policy): """ When a client's WSDL schema is located in the cache, it should be read from there instead of fetching its data from the client's document store or using its registered transport. When it is is not located in the cache but can be found in the client's document store, it should be fetched from there but not using the client's registered transport. """ # Add to cache, making sure the WSDL schema is read from the document # store and not fetched using the client's registered transport. cache = MockCache() store1 = MockDocumentStore(umpala=testutils.wsdl("")) c1 = suds.client.Client("suds://umpala", cachingpolicy=caching_policy, cache=cache, documentStore=store1, transport=MockTransport()) assert [x for x, y in cache.mock_log] == ["get", "put"] id = cache.mock_log[0][1][0] assert id == cache.mock_log[1][1][0] assert len(cache.mock_data) == 1 if caching_policy == 0: # Cache contains SAX XML documents. wsdl_document = next(itervalues(cache.mock_data)) assert wsdl_document.__class__ is suds.sax.document.Document wsdl_cached_root = wsdl_document.root() else: # Cache contains complete suds WSDL objects. wsdl = next(itervalues(cache.mock_data)) assert wsdl.__class__ is suds.wsdl.Definitions wsdl_cached_root = wsdl.root assert c1.wsdl.root is wsdl_cached_root # Make certain the same WSDL schema is fetched from the cache and not # using the document store or the transport. cache.mock_log = [] cache.mock_put_config = MockCache.FAIL store2 = MockDocumentStore(mock_fail=True) c2 = suds.client.Client("suds://umpala", cachingpolicy=caching_policy, cache=cache, documentStore=store2, transport=MockTransport()) assert cache.mock_log == [("get", [id])] assert c2.wsdl.root is wsdl_cached_root
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_WSDL_import(): wsdl_target_namespace = "bingo-bongo" wsdl = testutils.wsdl("", wsdl_target_namespace=wsdl_target_namespace) wsdl_wrapper = suds.byte_str( """\ <?xml version='1.0' encoding='UTF-8'?> <definitions targetNamespace="%(tns)s" xmlns="http://schemas.xmlsoap.org/wsdl/"> <import namespace="%(tns)s" location="suds://wsdl"/> </definitions>""" % {"tns": wsdl_target_namespace} ) store = suds.store.DocumentStore(wsdl=wsdl, wsdl_wrapper=wsdl_wrapper) client = suds.client.Client("suds://wsdl_wrapper", documentStore=store, cache=None, nosend=True) client.service.f()
def test_resolving_builtin_types(monkeypatch): _monkeypatch_builtin_XSD_type_registry(monkeypatch) class MockXInteger(XInteger): pass Factory.maptag("osama", MockXInteger) wsdl = testutils.wsdl('<xsd:element name="wu" type="xsd:osama"/>', input="wu") client = testutils.client_from_wsdl(wsdl) element, schema_object = client.sd[0].params[0] assert element.name == "wu" assert element.type == ("osama", "http://www.w3.org/2001/XMLSchema") assert schema_object.__class__ is MockXInteger assert schema_object.name == "osama" assert schema_object.schema is client.wsdl.schema
def test_using_cached_WSDL_avoids_store_avoids_transport(self, caching_policy): """ When a client's WSDL schema is located in the cache, it should be read from there instead of fetching its data from the client's document store or using its registered transport. When it is is not located in the cache but can be found in the client's document store, it should be fetched from there but not using the client's registered transport. """ # Add to cache, making sure the WSDL schema is read from the document # store and not fetched using the client's registered transport. cache = MockCache() store1 = MockDocumentStore(umpala=testutils.wsdl("")) c1 = suds.client.Client( "suds://umpala", cachingpolicy=caching_policy, cache=cache, documentStore=store1, transport=MockTransport() ) assert [x for x, y in cache.mock_log] == ["get", "put"] id = cache.mock_log[0][1][0] assert id == cache.mock_log[1][1][0] assert len(cache.mock_data) == 1 if caching_policy == 0: # Cache contains SAX XML documents. wsdl_document = next(itervalues(cache.mock_data)) assert wsdl_document.__class__ is suds.sax.document.Document wsdl_cached_root = wsdl_document.root() else: # Cache contains complete suds WSDL objects. wsdl = next(itervalues(cache.mock_data)) assert wsdl.__class__ is suds.wsdl.Definitions wsdl_cached_root = wsdl.root assert c1.wsdl.root is wsdl_cached_root # Make certain the same WSDL schema is fetched from the cache and not # using the document store or the transport. cache.mock_log = [] cache.mock_put_config = MockCache.FAIL store2 = MockDocumentStore(mock_fail=True) c2 = suds.client.Client( "suds://umpala", cachingpolicy=caching_policy, cache=cache, documentStore=store2, transport=MockTransport() ) assert cache.mock_log == [("get", [id])] assert c2.wsdl.root is wsdl_cached_root
def init_function_params(self, params, **kwargs): """ Initialize a test in this group with the given parameter definition. Constructs a complete WSDL schema based on the given function parameter definition (defines a single web service operation named 'f' by default), and creates a suds Client object to be used for testing suds's web service operation invocation. An alternate operation name may be given using the 'operation_name' keyword argument. May only be invoked once per test. """ input = '<xsd:element name="Wrapper">%s</xsd:element>' % (params,) assert not hasattr(self, "service") wsdl = testutils.wsdl(input, input="Wrapper", **kwargs) client = testutils.client_from_wsdl(wsdl, nosend=True) self.service = client.service
def init_function_params(self, params, **kwargs): """ Initialize a test in this group with the given parameter definition. Constructs a complete WSDL schema based on the given function parameter definition (defines a single web service operation named 'f' by default), and creates a suds Client object to be used for testing suds's web service operation invocation. An alternate operation name may be given using the 'operation_name' keyword argument. May only be invoked once per test. """ input = '<xsd:element name="Wrapper">%s</xsd:element>' % (params, ) assert not hasattr(self, "service") wsdl = testutils.wsdl(input, input="Wrapper", **kwargs) client = testutils.client_from_wsdl(wsdl, nosend=True) self.service = client.service
def test_wrapped_sequence_output(): client = testutils.client_from_wsdl( testutils.wsdl("""\ <xsd:element name="Wrapper"> <xsd:complexType> <xsd:sequence> <xsd:element name="result1" type="xsd:string"/> <xsd:element name="result2" type="xsd:string"/> <xsd:element name="result3" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element>""", output="Wrapper")) assert _isOutputWrapped(client, "f") response = client.service.f(__inject=dict(reply=suds.byte_str("""\ <?xml version="1.0"?> <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Body> <Wrapper xmlns="my-namespace"> <result1>Uno</result1> <result2>Due</result2> <result3>Tre</result3> </Wrapper> </Body> </Envelope>"""))) # Composite replies always get unmarshalled as a dynamically constructed # class named 'reply'. assert len(response.__class__.__bases__) == 1 assert response.__class__.__name__ == "reply" assert response.__class__.__bases__[0] is suds.sudsobject.Object # Check response content. assert len(response) == 3 assert response.result1 == "Uno" assert response.result2 == "Due" assert response.result3 == "Tre" assert response.result1.__class__ is suds.sax.text.Text assert response.result2.__class__ is suds.sax.text.Text assert response.result3.__class__ is suds.sax.text.Text
def test_operation_invoke_with_urlopen_accept_no_content__no_data(self, status_code): """ suds.client.Client web service operation invocation expecting no output data, and for which a corresponding urlopen call raises a HTTPError with status code ACCEPTED or NO_CONTENT, should treat this as a successful invocation. """ # We are not yet sure that the behaviour checked for in this test is # actually desired. The test is only an 'educated guess' prepared to # demonstrate a related problem in the original suds library # implementation. The original implementation is definitely buggy as # its web service operation invocation raises an AttributeError # exception by attempting to access a non-existing 'None.message' # attribute internally. e = self.create_HTTPError(code=status_code) transport = suds.transport.http.HttpTransport() transport.urlopener = MockURLOpenerSaboteur(open_exception=e) wsdl = testutils.wsdl('<xsd:element name="o" type="xsd:string"/>', output="o", operation_name="f") client = testutils.client_from_wsdl(wsdl, transport=transport) assert client.service.f() is None
def test_wrapped_sequence_output(): client = testutils.client_from_wsdl(testutils.wsdl("""\ <xsd:element name="Wrapper"> <xsd:complexType> <xsd:sequence> <xsd:element name="result1" type="xsd:string"/> <xsd:element name="result2" type="xsd:string"/> <xsd:element name="result3" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element>""", output="Wrapper")) assert _isOutputWrapped(client, "f") response = client.service.f(__inject=dict(reply=suds.byte_str("""\ <?xml version="1.0"?> <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Body> <Wrapper xmlns="my-namespace"> <result1>Uno</result1> <result2>Due</result2> <result3>Tre</result3> </Wrapper> </Body> </Envelope>"""))) # Composite replies always get unmarshalled as a dynamically constructed # class named 'reply'. assert len(response.__class__.__bases__) == 1 assert response.__class__.__name__ == "reply" assert response.__class__.__bases__[0] is suds.sudsobject.Object # Check response content. assert len(response) == 3 assert response.result1 == "Uno" assert response.result2 == "Due" assert response.result3 == "Tre" assert response.result1.__class__ is suds.sax.text.Text assert response.result2.__class__ is suds.sax.text.Text assert response.result3.__class__ is suds.sax.text.Text
def test_missing_wrapper_response(): """ Suds library's automatic structure unwrapping should not be applied to interpreting received SOAP Response XML. """ client = testutils.client_from_wsdl(testutils.wsdl("""\ <xsd:element name="Wrapper"> <xsd:complexType> <xsd:sequence> <xsd:element name="fResponse" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element>""", output="Wrapper")) assert _isOutputWrapped(client, "f") response_with_missing_wrapper = client.service.f(__inject=dict( reply=suds.byte_str("""<?xml version="1.0"?> <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Body> <fResponse xmlns="my-namespace">Anything</fResponse> </Body> </Envelope>"""))) assert response_with_missing_wrapper is None
def test_translation(monkeypatch): """Python <--> XML representation translation on marshall/unmarshall.""" anObject = _Dummy() class MockType(XBuiltin): def __init__(self, *args, **kwargs): self._mock_translate_log = [] super(MockType, self).__init__(*args, **kwargs) def translate(self, value, topython=True): self._mock_translate_log.append((value, topython)) if topython: return anObject return "'ollywood" _monkeypatch_builtin_XSD_type_registry(monkeypatch) Factory.maptag("woof", MockType) namespace = "I'm a little tea pot, short and stout..." wsdl = testutils.wsdl("""\ <xsd:element name="wi" type="xsd:woof"/> <xsd:element name="wo" type="xsd:woof"/>""", input="wi", output="wo", xsd_target_namespace=namespace, operation_name="f") client = testutils.client_from_wsdl(wsdl, nosend=True, prettyxml=True) # Check suds library's XSD schema input parameter information. schema = client.wsdl.schema element_in = schema.elements["wi", namespace] assert element_in.name == "wi" element_out = schema.elements["wo", namespace] assert element_out.name == "wo" schema_object_in = element_in.resolve() schema_object_out = element_out.resolve() assert element_in is client.sd[0].params[0][0] assert schema_object_in is client.sd[0].params[0][1] assert schema_object_in.__class__ is MockType assert schema_object_in._mock_translate_log == [] assert schema_object_out.__class__ is MockType assert schema_object_out._mock_translate_log == [] # Construct operation invocation request - test marshalling. request = client.service.f(55) assert schema_object_in._mock_translate_log == [(55, False)] assert schema_object_out._mock_translate_log == [] CompareSAX.data2data( request.envelope, """\ <?xml version="1.0" encoding="UTF-8"?> <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Header/> <Body> <wi xmlns="%s">'ollywood</wi> </Body> </Envelope>""" % (namespace, )) # Process operation response - test unmarshalling. response = client.service.f(__inject=dict(reply=suds.byte_str("""\ <?xml version="1.0"?> <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Body> <wo xmlns="%s">fri-fru</wo> </Body> </Envelope>""" % (namespace, )))) assert response is anObject assert schema_object_in._mock_translate_log == [(55, False)] assert schema_object_out._mock_translate_log == [("fri-fru", True)]
def test_WSDL_transport(self, url): store = MockDocumentStore() t = MockTransport(open_data=testutils.wsdl("")) suds.client.Client(url, cache=None, documentStore=store, transport=t) assert t.mock_log == [("open", [url])]
def test_nosend_should_avoid_transport_sends(self): wsdl = testutils.wsdl("") t = MockTransport() client = testutils.client_from_wsdl(wsdl, nosend=True, transport=t) client.service.f()
def test_default_transport(self): client = testutils.client_from_wsdl(testutils.wsdl("")) expected = suds.transport.https.HttpAuthenticated assert client.options.transport.__class__ is expected
def client(xsd, *input): wsdl = testutils.wsdl(xsd, input=input, xsd_target_namespace="toolyan", operation_name="f") return testutils.client_from_wsdl(wsdl, nosend=True, prettyxml=True)
def test_invalid_input_parameter_type_handling(): """ Input parameters of invalid type get silently pushed into the constructed SOAP request as strings, even though the constructed SOAP request does not necessarily satisfy requirements set for it in the web service's WSDL schema. It is then left up to the web service implementation to detect and report this error. """ xsd_target_namespace = "1234567890" wsdl = testutils.wsdl("""\ <xsd:complexType name="Freakazoid"> <xsd:sequence> <xsd:element name="freak1" type="xsd:string"/> <xsd:element name="freak2" type="xsd:string"/> <xsd:element name="freak3" type="xsd:string"/> </xsd:sequence> </xsd:complexType> <xsd:element name="Wrapper"> <xsd:complexType> <xsd:sequence> <xsd:element name="p1" type="xsd:string"/> <xsd:element name="anInteger" type="xsd:integer"/> <xsd:element name="p2" type="xsd:string"/> </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) # Passing an unrelated Python type value. class SomeType: def __str__(self): return "Some string representation." _assert_request_content( client.service.f(anInteger=SomeType()), """\ <?xml version="1.0" encoding="UTF-8"?> <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Header/> <Body> <Wrapper xmlns="%s"> <p1/> <anInteger>Some string representation.</anInteger> <p2/> </Wrapper> </Body> </Envelope>""" % (xsd_target_namespace, )) # Passing a value of a WSDL schema defined type. value = client.factory.create("my_xsd:Freakazoid") value.freak1 = "Tiny" value.freak2 = "Miny" value.freak3 = "Mo" _assert_request_content( client.service.f(anInteger=value), """\ <?xml version="1.0" encoding="UTF-8"?> <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Header/> <Body> <Wrapper xmlns="%s"> <p1/> <anInteger> <freak1>Tiny</freak1> <freak2>Miny</freak2> <freak3>Mo</freak3> </anInteger> <p2/> </Wrapper> </Body> </Envelope>""" % (xsd_target_namespace, ))
def test_using_cached_XSD_schema_avoids_store_avoids_transport(self, external_reference_tag, main_WSDL_cached): """ When an imported or included XSD schema is located in the client's cache, it should be read from there instead of fetching its data from the client's document store or using its registered transport. When it is is not located in the cache but can be found in the client's document store, it should be fetched from there but not using the client's registered transport. Note that this test makes sense only when caching raw XML documents (cachingpolicy == 0) and not when caching final WSDL objects (cachingpolicy == 1). """ # Prepare document content. xsd_target_namespace = "my xsd namespace" wsdl = testutils.wsdl('<xsd:%s schemaLocation="suds://external"/>' % ( external_reference_tag,), xsd_target_namespace=xsd_target_namespace) external_schema = b("""\ <?xml version='1.0' encoding='UTF-8'?> <schema xmlns="http://www.w3.org/2001/XMLSchema"> <element name="external" type="string"/> </schema> """) # Imported XSD schema items retain their namespace, while included ones # get merged into the target namespace. external_element_namespace = None if external_reference_tag == "include": external_element_namespace = xsd_target_namespace external_element_id = ("external", external_element_namespace) # Add to cache. cache = MockCache() store1 = MockDocumentStore(wsdl=wsdl, external=external_schema) c1 = suds.client.Client("suds://wsdl", cachingpolicy=0, cache=cache, documentStore=store1, transport=MockTransport()) assert [x for x, y in cache.mock_log] == ["get", "put"] * 2 id_wsdl = cache.mock_log[0][1][0] assert id_wsdl == cache.mock_log[1][1][0] id_xsd = cache.mock_log[2][1][0] assert id_xsd == cache.mock_log[3][1][0] assert len(cache.mock_data) == 2 wsdl_document = cache.mock_data[id_wsdl] assert c1.wsdl.root is wsdl_document.root() # Making sure id_xsd refers to the actual external XSD is a bit tricky # due to the fact that the WSDL object merged in the external XSD # content and lost the reference to the external XSD object itself. As # a workaround we make sure that the XSD schema XML element read from # the XSD object cached as id_xsd matches the one read from the WSDL # object's XSD schema. xsd_imported_document = cache.mock_data[id_xsd] cached_external_element = xsd_imported_document.root().children[0] external_element = c1.wsdl.schema.elements[external_element_id].root assert cached_external_element is external_element # Make certain the same external XSD document is fetched from the cache # and not using the document store or the transport. cache.mock_log = [] if main_WSDL_cached: cache.mock_put_config = MockCache.FAIL store2 = MockDocumentStore(mock_fail=True) else: del cache.mock_data[id_wsdl] assert len(cache.mock_data) == 1 store2 = MockDocumentStore(wsdl=wsdl) c2 = suds.client.Client("suds://wsdl", cachingpolicy=0, cache=cache, documentStore=store2, transport=MockTransport()) expected_cache_operations = [("get", id_wsdl)] if not main_WSDL_cached: expected_cache_operations.append(("put", id_wsdl)) expected_cache_operations.append(("get", id_xsd)) cache_operations = [(x, y[0]) for x, y in cache.mock_log] assert cache_operations == expected_cache_operations if not main_WSDL_cached: assert store2.mock_log == ["suds://wsdl"] assert len(cache.mock_data) == 2 assert cache.mock_data[id_xsd] is xsd_imported_document external_element = c2.wsdl.schema.elements[external_element_id].root assert cached_external_element is external_element
def test_missing_parameters(): """Missing non-optional parameters should get passed as empty values.""" xsd_target_namespace = "plonker" service = _service_from_wsdl( testutils.wsdl("""\ <xsd:element name="Wrapper"> <xsd:complexType> <xsd:sequence> <xsd:element name="aString" type="xsd:string"/> <xsd:element name="anInteger" type="xsd:integer"/> </xsd:sequence> </xsd:complexType> </xsd:element>""", input="Wrapper", operation_name="f", xsd_target_namespace=xsd_target_namespace)) _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"> <aString/> <anInteger/> </Wrapper> </Body> </Envelope>""" % (xsd_target_namespace, )) _assert_request_content( service.f((u("Pero \u017Ddero"))), u("""\ <?xml version="1.0" encoding="UTF-8"?> <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Header/> <Body> <Wrapper xmlns="%s"> <aString>Pero \u017Ddero</aString> <anInteger/> </Wrapper> </Body> </Envelope>""") % (xsd_target_namespace, )) _assert_request_content( service.f(anInteger=666), """\ <?xml version="1.0" encoding="UTF-8"?> <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Header/> <Body> <Wrapper xmlns="%s"> <aString/> <anInteger>666</anInteger> </Wrapper> </Body> </Envelope>""" % (xsd_target_namespace, )) # None value is treated the same as undefined. _assert_request_content( service.f(aString=None, anInteger=666), """\ <?xml version="1.0" encoding="UTF-8"?> <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Header/> <Body> <Wrapper xmlns="%s"> <aString/> <anInteger>666</anInteger> </Wrapper> </Body> </Envelope>""" % (xsd_target_namespace, )) _assert_request_content( service.f(aString="Omega", anInteger=None), """\ <?xml version="1.0" encoding="UTF-8"?> <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Header/> <Body> <Wrapper xmlns="%s"> <aString>Omega</aString> <anInteger/> </Wrapper> </Body> </Envelope>""" % (xsd_target_namespace, ))
def test_translation(monkeypatch): """Python <--> XML representation translation on marshall/unmarshall.""" anObject = _Dummy() class MockType(XBuiltin): def __init__(self, *args, **kwargs): self._mock_translate_log = [] super(MockType, self).__init__(*args, **kwargs) def translate(self, value, topython=True): self._mock_translate_log.append((value, topython)) if topython: return anObject return "'ollywood" _monkeypatch_builtin_XSD_type_registry(monkeypatch) Factory.maptag("woof", MockType) namespace = "I'm a little tea pot, short and stout..." wsdl = testutils.wsdl("""\ <xsd:element name="wi" type="xsd:woof"/> <xsd:element name="wo" type="xsd:woof"/>""", input="wi", output="wo", xsd_target_namespace=namespace, operation_name="f") client = testutils.client_from_wsdl(wsdl, nosend=True, prettyxml=True) # Check suds library's XSD schema input parameter information. schema = client.wsdl.schema element_in = schema.elements["wi", namespace] assert element_in.name == "wi" element_out = schema.elements["wo", namespace] assert element_out.name == "wo" schema_object_in = element_in.resolve() schema_object_out = element_out.resolve() assert element_in is client.sd[0].params[0][0] assert schema_object_in is client.sd[0].params[0][1] assert schema_object_in.__class__ is MockType assert schema_object_in._mock_translate_log == [] assert schema_object_out.__class__ is MockType assert schema_object_out._mock_translate_log == [] # Construct operation invocation request - test marshalling. request = client.service.f(55) assert schema_object_in._mock_translate_log == [(55, False)] assert schema_object_out._mock_translate_log == [] CompareSAX.data2data(request.envelope, """\ <?xml version="1.0" encoding="UTF-8"?> <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Header/> <Body> <wi xmlns="%s">'ollywood</wi> </Body> </Envelope>""" % (namespace,)) # Process operation response - test unmarshalling. response = client.service.f(__inject=dict(reply=suds.byte_str("""\ <?xml version="1.0"?> <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Body> <wo xmlns="%s">fri-fru</wo> </Body> </Envelope>""" % (namespace,)))) assert response is anObject assert schema_object_in._mock_translate_log == [(55, False)] assert schema_object_out._mock_translate_log == [("fri-fru", True)]
def test_named_parameter(): class Tester: def __init__(self, service, expected_xml): self.service = service self.expected_xml = expected_xml def test(self, *args, **kwargs): request = self.service.f(*args, **kwargs) _assert_request_content(request, self.expected_xml) # Test different ways to make the same web service operation call. xsd_target_namespace = "qwerty" service = _service_from_wsdl( testutils.wsdl("""\ <xsd:element name="Wrapper"> <xsd:complexType> <xsd:sequence> <xsd:element name="uno" type="xsd:string"/> <xsd:element name="due" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element>""", input="Wrapper", operation_name="f", xsd_target_namespace=xsd_target_namespace)) t = Tester( service, """\ <?xml version="1.0" encoding="UTF-8"?> <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Header/> <Body> <Wrapper xmlns="%s"> <uno>einz</uno> <due>zwei</due> </Wrapper> </Body> </Envelope>""" % (xsd_target_namespace, )) t.test("einz", "zwei") t.test(uno="einz", due="zwei") t.test(due="zwei", uno="einz") t.test("einz", due="zwei") # The order of parameters in the constructed SOAP request should depend # only on the initial WSDL schema. xsd_target_namespace = "abracadabra" service = _service_from_wsdl( testutils.wsdl("""\ <xsd:element name="Wrapper"> <xsd:complexType> <xsd:sequence> <xsd:element name="due" type="xsd:string"/> <xsd:element name="uno" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element>""", input="Wrapper", operation_name="f", xsd_target_namespace=xsd_target_namespace)) t = Tester( service, """\ <?xml version="1.0" encoding="UTF-8"?> <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Header/> <Body> <Wrapper xmlns="%s"> <due>zwei</due> <uno>einz</uno> </Wrapper> </Body> </Envelope>""" % (xsd_target_namespace, )) t.test("zwei", "einz") t.test(uno="einz", due="zwei") t.test(due="zwei", uno="einz") t.test("zwei", uno="einz")
def test_optional_parameter_handling(): """Missing optional parameters should not get passed at all.""" xsd_target_namespace = "RoOfIe" service = _service_from_wsdl( testutils.wsdl("""\ <xsd:element name="Wrapper"> <xsd:complexType> <xsd:sequence> <xsd:element name="aString" type="xsd:string" minOccurs="0"/> <xsd:element name="anInteger" type="xsd:integer" minOccurs="0"/> </xsd:sequence> </xsd:complexType> </xsd:element>""", input="Wrapper", operation_name="f", xsd_target_namespace=xsd_target_namespace)) _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, )) # None is treated as an undefined value. _assert_request_content( service.f(None), """\ <?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, )) # Empty string values are treated as well defined values. _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"> <aString/> </Wrapper> </Body> </Envelope>""" % (xsd_target_namespace, )) _assert_request_content( service.f("Kiflica"), """\ <?xml version="1.0" encoding="UTF-8"?> <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Header/> <Body> <Wrapper xmlns="%s"> <aString>Kiflica</aString> </Wrapper> </Body> </Envelope>""" % (xsd_target_namespace, )) _assert_request_content( service.f(anInteger=666), """\ <?xml version="1.0" encoding="UTF-8"?> <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Header/> <Body> <Wrapper xmlns="%s"> <anInteger>666</anInteger> </Wrapper> </Body> </Envelope>""" % (xsd_target_namespace, )) _assert_request_content( service.f("Alfa", 9), """\ <?xml version="1.0" encoding="UTF-8"?> <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Header/> <Body> <Wrapper xmlns="%s"> <aString>Alfa</aString> <anInteger>9</anInteger> </Wrapper> </Body> </Envelope>""" % (xsd_target_namespace, ))
def test_array(): client = testutils.lxmlclient_from_wsdl(testutils.wsdl("""\ <xsd:element name="Wrapper"> <xsd:complexType> <xsd:sequence> <xsd:element name="value" type="xsd:string" maxOccurs="unbounded"/> </xsd:sequence> </xsd:complexType> </xsd:element>""", output="Wrapper")) response = client.service.f(__inject=dict(reply=suds.byte_str("""\ <?xml version="1.0"?> <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Body> <Wrapper xmlns="my-namespace"> <value>9</value> <value>18</value> <value>5342</value> </Wrapper> </Body> </Envelope>"""))) # Check response content. assert len(response) == 1 assert isinstance(response.value, list) assert len(response.value) == 3 assert response.value[0] == "9" assert response.value[1] == "18" assert response.value[2] == "5342" assert_lxml_string_value(response.value[0]) assert_lxml_string_value(response.value[1]) assert_lxml_string_value(response.value[2]) client = testutils.lxmlclient_from_wsdl(testutils.wsdl("""\ <xsd:element name="Wrapper"> <xsd:complexType> <xsd:sequence> <xsd:element name="value" type="xsd:int" maxOccurs="unbounded"/> </xsd:sequence> </xsd:complexType> </xsd:element>""", output="Wrapper")) response = client.service.f(__inject=dict(reply=suds.byte_str("""\ <?xml version="1.0"?> <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Body> <Wrapper xmlns="my-namespace"> <value>19</value> </Wrapper> </Body> </Envelope>"""))) # Check response content. assert len(response) == 1 assert isinstance(response.value, list) assert len(response.value) == 1 assert response.value[0] == 19 assert isinstance(response.value[0], int) client = testutils.lxmlclient_from_wsdl(testutils.wsdl("""\ <xsd:element name="Wrapper"> <xsd:complexType> <xsd:sequence> <xsd:element name="value" type="xsd:string" nillable="true" maxOccurs="unbounded"/> </xsd:sequence> </xsd:complexType> </xsd:element>""", output="Wrapper")) response = client.service.f(__inject=dict(reply=suds.byte_str("""\ <?xml version="1.0"?> <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Body> <Wrapper xmlns="my-namespace"> <value /> </Wrapper> </Body> </Envelope>"""))) # Check response content. assert len(response) == 1 assert isinstance(response.value, list) assert len(response.value) == 0