# -*- coding: utf-8 -*-



# This program is free software; you can redistribute it and/or modify

# it under the terms of the (LGPL) GNU Lesser General Public License as

# published by the Free Software Foundation; either version 3 of the

# License, or (at your option) any later version.

#

# This program is distributed in the hope that it will be useful,

# but WITHOUT ANY WARRANTY; without even the implied warranty of

# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

# GNU Library Lesser General Public License for more details at

# ( http://www.gnu.org/licenses/lgpl.html ).

#

# You should have received a copy of the GNU Lesser General Public License

# along with this program; if not, write to the Free Software

# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

# written by: Jurko Gospodnetić ( jurko.gospodnetic@pke.hr )



"""

General suds Python library unit tests.



Implemented using the 'pytest' testing framework.



This whole module should be refactored into more specialized modules as more

tests get added to it and it acquires more structure.



"""



if __name__ == "__main__":

    from . import __init__

    __init__.runUsingPyTest(globals())





import suds

import tests



import pytest



import re

import xml.sax





# TODO: Update the current choice parameter handling implementation to make

# this test pass.

@pytest.mark.xfail

def test_choice_parameter_implementation_inconsistencies():

    """

    Choice parameter support implementation needs to be cleaned up.



    If you declare a message part's element of a simple type X, or you define

    it as a complex type having a single member of type X, and suds has been

    configured to automatically unwrap such single-member complex types, the

    web service proxy object's constructed function declarations should match.

    They should both accept a single parameter of type X.



    However the current choice support implementation causes only the 'complex'

    case to get an additional 'choice' flag information to be included in the

    constructed parameter definition structure.



    """

    client = lambda x, y : tests.client_from_wsdl(tests.wsdl_input(x, y))



    client_simple_short = client("""\

      <xsd:element name="Elemento" type="xsd:string" />""", "Elemento")



    client_simple_long = client("""\

      <xsd:element name="Elemento">

        <xsd:simpleType>

          <xsd:restriction base="xsd:string" />

        </xsd:simpleType>

      </xsd:element>""", "Elemento")



    client_complex_wrapped = client("""\

      <xsd:element name="Wrapper">

        <xsd:complexType>

          <xsd:sequence>

            <xsd:element name="Elemento" type="xsd:string" />

          </xsd:sequence>

        </xsd:complexType>

      </xsd:element>""", "Wrapper")



    method_param = lambda x : x.sd[0].ports[0][1][0][1][0]

    method_param_simple_short = method_param(client_simple_short)

    method_param_simple_long = method_param(client_simple_long)

    method_param_complex_wrapped = method_param(client_complex_wrapped)



    assert len(method_param_simple_short) == len(method_param_simple_long)

    assert len(method_param_simple_long) == len(method_param_complex_wrapped)





def test_converting_client_to_string_must_not_raise_an_exception():

    client = tests.client_from_wsdl(suds.byte_str(

        "<?xml version='1.0' encoding='UTF-8'?><root />"))

    str(client)





def test_converting_metadata_to_string():

    client = tests.client_from_wsdl(suds.byte_str("""\

<?xml version='1.0' encoding='UTF-8'?>

<wsdl:definitions targetNamespace="my-namespace"

xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

xmlns:ns="my-namespace"

xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">

  <wsdl:types>

    <xsd:schema targetNamespace="my-namespace"

    elementFormDefault="qualified"

    attributeFormDefault="unqualified"

    xmlns:xsd="http://www.w3.org/2001/XMLSchema">

      <xsd:complexType name="AAA">

        <xsd:sequence>

          <xsd:element name="u1" type="xsd:string" />

          <xsd:element name="u2" type="xsd:string" />

          <xsd:element name="u3" type="xsd:string" />

        </xsd:sequence>

      </xsd:complexType>

    </xsd:schema>

  </wsdl:types>

  <wsdl:portType name="dummyPortType">

  </wsdl:portType>

  <wsdl:binding name="dummy" type="ns:dummyPortType">

    <soap:binding style="document"

    transport="http://schemas.xmlsoap.org/soap/http" />

  </wsdl:binding>

  <wsdl:service name="dummy">

    <wsdl:port name="dummy" binding="ns:dummy">

      <soap:address location="https://localhost/dummy" />

    </wsdl:port>

  </wsdl:service>

</wsdl:definitions>

"""))

    # Metadata with empty content.

    metadata = client.wsdl.__metadata__

    assert len(metadata) == 0

    assert "<empty>" == str(metadata)



    # Metadata with non-empty content.

    metadata = client.factory.create("AAA").__metadata__

    assert len(metadata) == 2

    metadata_string = str(metadata)

    assert re.search(" sxtype = ", metadata_string)

    assert re.search(" ordering\[\] = ", metadata_string)





def test_empty_invalid_wsdl(monkeypatch):

    wsdl = suds.byte_str("")

    monkeypatch.delitem(locals(), "e", False)

    e = pytest.raises(xml.sax.SAXParseException, tests.client_from_wsdl, wsdl)

    assert e.value.getMessage() == "no element found"





def test_empty_valid_wsdl():

    client = tests.client_from_wsdl(suds.byte_str(

        "<?xml version='1.0' encoding='UTF-8'?><root />"))

    assert not client.wsdl.services, "No service definitions must be read "  \

        "from an empty WSDL."





def test_enumeration_type_string_should_contain_its_value():

    client = tests.client_from_wsdl(suds.byte_str("""\

<?xml version='1.0' encoding='UTF-8'?>

<wsdl:definitions targetNamespace="my-namespace"

xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

xmlns:ns="my-namespace"

xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">

  <wsdl:types>

    <xsd:schema targetNamespace="my-namespace"

    elementFormDefault="qualified"

    attributeFormDefault="unqualified"

    xmlns:xsd="http://www.w3.org/2001/XMLSchema">

      <xsd:simpleType name="AAA">

        <xsd:restriction base="xsd:string">

          <xsd:enumeration value="One" />

          <xsd:enumeration value="Two" />

          <xsd:enumeration value="Thirty-Two" />

        </xsd:restriction>

      </xsd:simpleType>

    </xsd:schema>

  </wsdl:types>

  <wsdl:portType name="dummyPortType">

  </wsdl:portType>

  <wsdl:binding name="dummy" type="ns:dummyPortType">

    <soap:binding style="document"

    transport="http://schemas.xmlsoap.org/soap/http" />

  </wsdl:binding>

  <wsdl:service name="dummy">

    <wsdl:port name="dummy" binding="ns:dummy">

      <soap:address location="https://localhost/dummy" />

    </wsdl:port>

  </wsdl:service>

</wsdl:definitions>

"""))

    enumeration_data = client.wsdl.schema.types["AAA", "my-namespace"]

    # Legend:

    #   eX - enumeration element.

    #   aX - ancestry for the enumeration element.

    (e1, a1), (e2, a2), (e3, a3) = enumeration_data

    assert isinstance(e1, suds.xsd.sxbasic.Enumeration)

    assert isinstance(e2, suds.xsd.sxbasic.Enumeration)

    assert isinstance(e3, suds.xsd.sxbasic.Enumeration)

    assert e1.name == "One"

    assert e2.name == "Two"

    assert e3.name == "Thirty-Two"

    #   Python 3 output does not include a trailing L after long integer

    # output, while Python 2 does. For example: 0x12345678 is output as

    # 0x12345678L in Python 2 and simply as 0x12345678 in Python 3.

    assert re.match('<Enumeration:0x[0-9a-f]+L? name="One" />$', e1.str())

    assert re.match('<Enumeration:0x[0-9a-f]+L? name="Two" />$', e2.str())

    assert re.match('<Enumeration:0x[0-9a-f]+L? name="Thirty-Two" />$',

        e3.str())





def test_function_parameters_global_sequence_in_a_sequence():

    client = tests.client_from_wsdl(suds.byte_str("""\

<?xml version='1.0' encoding='UTF-8'?>

<wsdl:definitions targetNamespace="my-namespace"

xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

xmlns:ns="my-namespace"

xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">

  <wsdl:types>

    <xsd:schema targetNamespace="my-namespace"

    elementFormDefault="qualified"

    attributeFormDefault="unqualified"

    xmlns:xsd="http://www.w3.org/2001/XMLSchema">

      <xsd:complexType name="UngaBunga">

        <xsd:sequence>

          <xsd:element name="u1" type="xsd:string" />

          <xsd:element name="u2" type="xsd:string" />

          <xsd:element name="u3" type="xsd:string" />

        </xsd:sequence>

      </xsd:complexType>

      <xsd:element name="Elemento">

        <xsd:complexType>

          <xsd:sequence>

            <xsd:element name="x1" type="xsd:string" />

            <xsd:element name="x2" type="UngaBunga" />

            <xsd:element name="x3" type="xsd:string" />

          </xsd:sequence>

        </xsd:complexType>

      </xsd:element>

    </xsd:schema>

  </wsdl:types>

  <wsdl:message name="fRequestMessage">

    <wsdl:part name="parameters" element="ns:Elemento" />

  </wsdl:message>

  <wsdl:portType name="dummyPortType">

    <wsdl:operation name="f">

      <wsdl:input message="ns:fRequestMessage" />

    </wsdl:operation>

  </wsdl:portType>

  <wsdl:binding name="dummy" type="ns:dummyPortType">

    <soap:binding style="document"

    transport="http://schemas.xmlsoap.org/soap/http" />

    <wsdl:operation name="f">

      <soap:operation soapAction="f" style="document" />

      <wsdl:input><soap:body use="literal" /></wsdl:input>

      <wsdl:output><soap:body use="literal" /></wsdl:output>

    </wsdl:operation>

  </wsdl:binding>

  <wsdl:service name="dummy">

    <wsdl:port name="dummy" binding="ns:dummy">

      <soap:address location="https://localhost/dummy" />

    </wsdl:port>

  </wsdl:service>

</wsdl:definitions>

"""))



    service = client.sd[0]

    assert len(service.types) == 1



    # Method parameters as read from the service definition.

    assert len(service.params) == 3

    assert service.params[0][0].name == "x1"

    assert service.params[0][0].type == _string_type

    assert isinstance(service.params[0][1], suds.xsd.sxbuiltin.XString)

    assert service.params[1][0].name == "x2"

    assert service.params[1][0].type == ("UngaBunga", "my-namespace")

    assert isinstance(service.params[1][1], suds.xsd.sxbasic.Complex)

    assert service.params[2][0].name == "x3"

    assert service.params[2][0].type == _string_type

    assert isinstance(service.params[2][1], suds.xsd.sxbuiltin.XString)



    # Method parameters as read from a method object.

    assert len(service.ports) == 1

    port, methods = service.ports[0]

    assert len(methods) == 1

    method_name, method_params = methods[0]

    assert method_name == "f"

    assert len(method_params) == 3

    assert method_params[0][0] == "x1"

    assert method_params[0][1] is service.params[0][0]

    assert method_params[1][0] == "x2"

    assert method_params[1][1] is service.params[1][0]

    assert method_params[2][0] == "x3"

    assert method_params[2][1] is service.params[2][0]





def test_function_parameters_local_choice():

    client = tests.client_from_wsdl(suds.byte_str("""\

<?xml version='1.0' encoding='UTF-8'?>

<wsdl:definitions targetNamespace="my-namespace"

xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

xmlns:ns="my-namespace"

xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">

  <wsdl:types>

    <xsd:schema targetNamespace="my-namespace"

    elementFormDefault="qualified"

    attributeFormDefault="unqualified"

    xmlns:xsd="http://www.w3.org/2001/XMLSchema">

      <xsd:element name="Elemento">

        <xsd:complexType>

          <xsd:choice>

            <xsd:element name="u1" type="xsd:string" />

            <xsd:element name="u2" type="xsd:string" />

          </xsd:choice>

        </xsd:complexType>

      </xsd:element>

    </xsd:schema>

  </wsdl:types>

  <wsdl:message name="fRequestMessage">

    <wsdl:part name="parameters" element="ns:Elemento" />

  </wsdl:message>

  <wsdl:portType name="dummyPortType">

    <wsdl:operation name="f">

      <wsdl:input message="ns:fRequestMessage" />

    </wsdl:operation>

  </wsdl:portType>

  <wsdl:binding name="dummy" type="ns:dummyPortType">

    <soap:binding style="document"

    transport="http://schemas.xmlsoap.org/soap/http" />

    <wsdl:operation name="f">

      <soap:operation soapAction="f" style="document" />

      <wsdl:input><soap:body use="literal" /></wsdl:input>

      <wsdl:output><soap:body use="literal" /></wsdl:output>

    </wsdl:operation>

  </wsdl:binding>

  <wsdl:service name="dummy">

    <wsdl:port name="dummy" binding="ns:dummy">

      <soap:address location="https://localhost/dummy" />

    </wsdl:port>

  </wsdl:service>

</wsdl:definitions>

"""))



    service = client.sd[0]

    assert not service.types



    # Method parameters as read from the service definition.

    assert len(service.params) == 2

    assert service.params[0][0].name == "u1"

    assert service.params[0][0].type == _string_type

    assert isinstance(service.params[0][1], suds.xsd.sxbuiltin.XString)

    assert service.params[1][0].name == "u2"

    assert service.params[1][0].type == _string_type

    assert isinstance(service.params[1][1], suds.xsd.sxbuiltin.XString)



    # Method parameters as read from a method object.

    assert len(service.ports) == 1

    port, methods = service.ports[0]

    assert len(methods) == 1

    method_name, method_params = methods[0]

    assert method_name == "f"

    assert len(method_params) == 2

    assert method_params[0][0] == "u1"

    assert method_params[0][1] is service.params[0][0]

    assert method_params[1][0] == "u2"

    assert method_params[1][1] is service.params[1][0]



    # Construct method parameter element object.

    paramOut = client.factory.create("Elemento")

    _assert_dynamic_type(paramOut, "Elemento")

    assert not paramOut.__keylist__





def test_function_parameters_local_choice_in_a_sequence():

    client = tests.client_from_wsdl(suds.byte_str("""\

<?xml version='1.0' encoding='UTF-8'?>

<wsdl:definitions targetNamespace="my-namespace"

xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

xmlns:ns="my-namespace"

xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">

  <wsdl:types>

    <xsd:schema targetNamespace="my-namespace"

    elementFormDefault="qualified"

    attributeFormDefault="unqualified"

    xmlns:xsd="http://www.w3.org/2001/XMLSchema">

      <xsd:element name="Elemento">

        <xsd:complexType>

          <xsd:sequence>

            <xsd:element name="x1" type="xsd:string" />

            <xsd:element name="x2">

              <xsd:complexType>

                <xsd:choice>

                  <xsd:element name="u1" type="xsd:string" />

                  <xsd:element name="u2" type="xsd:string" />

                  <xsd:element name="u3" type="xsd:string" />

                </xsd:choice>

              </xsd:complexType>

            </xsd:element>

            <xsd:element name="x3" type="xsd:string" />

          </xsd:sequence>

        </xsd:complexType>

      </xsd:element>

    </xsd:schema>

  </wsdl:types>

  <wsdl:message name="fRequestMessage">

    <wsdl:part name="parameters" element="ns:Elemento" />

  </wsdl:message>

  <wsdl:portType name="dummyPortType">

    <wsdl:operation name="f">

      <wsdl:input message="ns:fRequestMessage" />

    </wsdl:operation>

  </wsdl:portType>

  <wsdl:binding name="dummy" type="ns:dummyPortType">

    <soap:binding style="document"

    transport="http://schemas.xmlsoap.org/soap/http" />

    <wsdl:operation name="f">

      <soap:operation soapAction="f" style="document" />

      <wsdl:input><soap:body use="literal" /></wsdl:input>

      <wsdl:output><soap:body use="literal" /></wsdl:output>

    </wsdl:operation>

  </wsdl:binding>

  <wsdl:service name="dummy">

    <wsdl:port name="dummy" binding="ns:dummy">

      <soap:address location="https://localhost/dummy" />

    </wsdl:port>

  </wsdl:service>

</wsdl:definitions>

"""))



    service = client.sd[0]

    assert not service.types



    # Method parameters as read from the service definition.

    assert len(service.params) == 3

    assert service.params[0][0].name == "x1"

    assert service.params[0][0].type == _string_type

    assert isinstance(service.params[0][1], suds.xsd.sxbuiltin.XString)

    assert service.params[1][0].name == "x2"

    assert service.params[1][0].type is None

    assert isinstance(service.params[1][1], suds.xsd.sxbasic.Element)

    assert service.params[2][0].name == "x3"

    assert service.params[2][0].type == _string_type

    assert isinstance(service.params[2][1], suds.xsd.sxbuiltin.XString)



    # Method parameters as read from a method object.

    assert len(service.ports) == 1

    port, methods = service.ports[0]

    assert len(methods) == 1

    method_name, method_params = methods[0]

    assert method_name == "f"

    assert len(method_params) == 3

    assert method_params[0][0] == "x1"

    assert method_params[0][1] is service.params[0][0]

    assert method_params[1][0] == "x2"

    assert method_params[1][1] is service.params[1][0]

    assert method_params[2][0] == "x3"

    assert method_params[2][1] is service.params[2][0]



    # Construct method parameter element object.

    paramOut = client.factory.create("Elemento")

    _assert_dynamic_type(paramOut, "Elemento")

    assert paramOut.x1 is None

    _assert_dynamic_type(paramOut.x2, "x2")

    assert not paramOut.x2.__keylist__

    assert paramOut.x3 is None



    # Construct method parameter objects with a locally defined type.

    paramIn = client.factory.create("Elemento.x2")

    _assert_dynamic_type(paramIn, "x2")

    assert not paramOut.x2.__keylist__

    assert paramIn is not paramOut.x2





def test_function_parameters_local_sequence_in_a_sequence():

    client = tests.client_from_wsdl(suds.byte_str("""\

<?xml version='1.0' encoding='UTF-8'?>

<wsdl:definitions targetNamespace="my-namespace"

xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

xmlns:ns="my-namespace"

xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">

  <wsdl:types>

    <xsd:schema targetNamespace="my-namespace"

    elementFormDefault="qualified"

    attributeFormDefault="unqualified"

    xmlns:xsd="http://www.w3.org/2001/XMLSchema">

      <xsd:element name="Elemento">

        <xsd:complexType>

          <xsd:sequence>

            <xsd:element name="x1" type="xsd:string" />

            <xsd:element name="x2">

              <xsd:complexType>

                <xsd:sequence>

                  <xsd:element name="u1" type="xsd:string" />

                  <xsd:element name="u2" type="xsd:string" />

                  <xsd:element name="u3" type="xsd:string" />

                </xsd:sequence>

              </xsd:complexType>

            </xsd:element>

            <xsd:element name="x3" type="xsd:string" />

          </xsd:sequence>

        </xsd:complexType>

      </xsd:element>

    </xsd:schema>

  </wsdl:types>

  <wsdl:message name="fRequestMessage">

    <wsdl:part name="parameters" element="ns:Elemento" />

  </wsdl:message>

  <wsdl:portType name="dummyPortType">

    <wsdl:operation name="f">

      <wsdl:input message="ns:fRequestMessage" />

    </wsdl:operation>

  </wsdl:portType>

  <wsdl:binding name="dummy" type="ns:dummyPortType">

    <soap:binding style="document"

    transport="http://schemas.xmlsoap.org/soap/http" />

    <wsdl:operation name="f">

      <soap:operation soapAction="f" style="document" />

      <wsdl:input><soap:body use="literal" /></wsdl:input>

      <wsdl:output><soap:body use="literal" /></wsdl:output>

    </wsdl:operation>

  </wsdl:binding>

  <wsdl:service name="dummy">

    <wsdl:port name="dummy" binding="ns:dummy">

      <soap:address location="https://localhost/dummy" />

    </wsdl:port>

  </wsdl:service>

</wsdl:definitions>

"""))



    service = client.sd[0]

    assert not service.types



    # Method parameters as read from the service definition.

    assert len(service.params) == 3

    assert service.params[0][0].name == "x1"

    assert service.params[0][0].type == _string_type

    assert isinstance(service.params[0][1], suds.xsd.sxbuiltin.XString)

    assert service.params[1][0].name == "x2"

    assert service.params[1][0].type is None

    assert isinstance(service.params[1][1], suds.xsd.sxbasic.Element)

    assert service.params[2][0].name == "x3"

    assert service.params[2][0].type == _string_type

    assert isinstance(service.params[2][1], suds.xsd.sxbuiltin.XString)



    # Method parameters as read from a method object.

    assert len(service.ports) == 1

    port, methods = service.ports[0]

    assert len(methods) == 1

    method_name, method_params = methods[0]

    assert method_name == "f"

    assert len(method_params) == 3

    assert method_params[0][0] == "x1"

    assert method_params[0][1] is service.params[0][0]

    assert method_params[1][0] == "x2"

    assert method_params[1][1] is service.params[1][0]

    assert method_params[2][0] == "x3"

    assert method_params[2][1] is service.params[2][0]



    # Construct method parameter element object.

    paramOut = client.factory.create("Elemento")

    _assert_dynamic_type(paramOut, "Elemento")

    assert paramOut.x1 is None

    _assert_dynamic_type(paramOut.x2, "x2")

    assert paramOut.x2.u1 is None

    assert paramOut.x2.u2 is None

    assert paramOut.x2.u3 is None

    assert paramOut.x3 is None



    # Construct method parameter objects with a locally defined type.

    paramIn = client.factory.create("Elemento.x2")

    _assert_dynamic_type(paramIn, "x2")

    assert paramIn.u1 is None

    assert paramIn.u2 is None

    assert paramIn.u3 is None

    assert paramIn is not paramOut.x2





def test_function_parameters_sequence_in_a_choice():

    client = tests.client_from_wsdl(suds.byte_str("""\

<?xml version='1.0' encoding='UTF-8'?>

<wsdl:definitions targetNamespace="my-namespace"

xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

xmlns:ns="my-namespace"

xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">

  <wsdl:types>

    <xsd:schema targetNamespace="my-namespace"

    elementFormDefault="qualified"

    attributeFormDefault="unqualified"

    xmlns:xsd="http://www.w3.org/2001/XMLSchema">

      <xsd:element name="Choice">

        <xsd:complexType>

          <xsd:choice>

            <xsd:element name="a1" type="xsd:string" />

            <xsd:element name="sequence">

              <xsd:complexType>

                <xsd:sequence>

                  <xsd:element name="e1" type="xsd:string" />

                  <xsd:element name="e2" type="xsd:string" />

                  <xsd:element name="e3" type="xsd:string" />

                </xsd:sequence>

              </xsd:complexType>

            </xsd:element>

            <xsd:element name="a2" type="xsd:string" />

          </xsd:choice>

        </xsd:complexType>

      </xsd:element>

    </xsd:schema>

  </wsdl:types>

  <wsdl:message name="fRequestMessage">

    <wsdl:part name="parameters" element="ns:Choice" />

  </wsdl:message>

  <wsdl:portType name="dummyPortType">

    <wsdl:operation name="f">

      <wsdl:input message="ns:fRequestMessage" />

    </wsdl:operation>

  </wsdl:portType>

  <wsdl:binding name="dummy" type="ns:dummyPortType">

    <soap:binding style="document"

    transport="http://schemas.xmlsoap.org/soap/http" />

    <wsdl:operation name="f">

      <soap:operation soapAction="f" style="document" />

      <wsdl:input><soap:body use="literal" /></wsdl:input>

      <wsdl:output><soap:body use="literal" /></wsdl:output>

    </wsdl:operation>

  </wsdl:binding>

  <wsdl:service name="dummy">

    <wsdl:port name="dummy" binding="ns:dummy">

      <soap:address location="https://localhost/dummy" />

    </wsdl:port>

  </wsdl:service>

</wsdl:definitions>

"""))



    # Input #1.

    request = _construct_SOAP_request(client, 'f', a1="Wackadoodle")

    assert tests.compare_xml_to_string(request, """\

<?xml version="1.0" encoding="UTF-8"?>

<SOAP-ENV:Envelope xmlns:ns0="my-namespace" xmlns:ns1="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">

   <SOAP-ENV:Header/>

   <ns1:Body>

      <ns0:Choice>

         <ns0:a1>Wackadoodle</ns0:a1>

      </ns0:Choice>

   </ns1:Body>

</SOAP-ENV:Envelope>""")



    # Input #2.

    param = client.factory.create("Choice.sequence")

    param.e2 = "Wackadoodle"

    request = _construct_SOAP_request(client, 'f', sequence=param)

    assert tests.compare_xml_to_string(request, """\

<?xml version="1.0" encoding="UTF-8"?>

<SOAP-ENV:Envelope xmlns:ns0="my-namespace" xmlns:ns1="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">

   <SOAP-ENV:Header/>

   <ns1:Body>

      <ns0:Choice>

         <ns0:sequence>

            <ns0:e1/>

            <ns0:e2>Wackadoodle</ns0:e2>

            <ns0:e3/>

         </ns0:sequence>

      </ns0:Choice>

   </ns1:Body>

</SOAP-ENV:Envelope>""")





def test_function_parameters_sequence_in_a_choice_in_a_sequence():

    client = tests.client_from_wsdl(suds.byte_str("""\

<?xml version='1.0' encoding='UTF-8'?>

<wsdl:definitions targetNamespace="my-namespace"

xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

xmlns:ns="my-namespace"

xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">

  <wsdl:types>

    <xsd:schema targetNamespace="my-namespace"

    elementFormDefault="qualified"

    attributeFormDefault="unqualified"

    xmlns:xsd="http://www.w3.org/2001/XMLSchema">

      <xsd:element name="External">

        <xsd:complexType>

          <xsd:sequence>

            <xsd:element name="choice">

              <xsd:complexType>

                <xsd:choice>

                  <xsd:element name="a1" type="xsd:string" />

                  <xsd:element name="sequence">

                    <xsd:complexType>

                      <xsd:sequence>

                        <xsd:element name="e1" type="xsd:string" />

                        <xsd:element name="e2" type="xsd:string" />

                        <xsd:element name="e3" type="xsd:string" />

                      </xsd:sequence>

                    </xsd:complexType>

                  </xsd:element>

                  <xsd:element name="a2" type="xsd:string" />

                </xsd:choice>

              </xsd:complexType>

            </xsd:element>

          </xsd:sequence>

        </xsd:complexType>

      </xsd:element>

    </xsd:schema>

  </wsdl:types>

  <wsdl:message name="fRequestMessage">

    <wsdl:part name="parameters" element="ns:External" />

  </wsdl:message>

  <wsdl:portType name="dummyPortType">

    <wsdl:operation name="f">

      <wsdl:input message="ns:fRequestMessage" />

    </wsdl:operation>

  </wsdl:portType>

  <wsdl:binding name="dummy" type="ns:dummyPortType">

    <soap:binding style="document"

    transport="http://schemas.xmlsoap.org/soap/http" />

    <wsdl:operation name="f">

      <soap:operation soapAction="f" style="document" />

      <wsdl:input><soap:body use="literal" /></wsdl:input>

      <wsdl:output><soap:body use="literal" /></wsdl:output>

    </wsdl:operation>

  </wsdl:binding>

  <wsdl:service name="dummy">

    <wsdl:port name="dummy" binding="ns:dummy">

      <soap:address location="https://localhost/dummy" />

    </wsdl:port>

  </wsdl:service>

</wsdl:definitions>

"""))



    # Construct input parameters.

    param = client.factory.create("External.choice")

    param.sequence = client.factory.create("External.choice.sequence")

    param.sequence.e2 = "Wackadoodle"



    # Construct a SOAP request containing our input parameters.

    request = _construct_SOAP_request(client, 'f', param)

    assert tests.compare_xml_to_string(request, """\

<?xml version="1.0" encoding="UTF-8"?>

<SOAP-ENV:Envelope xmlns:ns0="my-namespace" xmlns:ns1="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">

   <SOAP-ENV:Header/>

   <ns1:Body>

      <ns0:External>

         <ns0:choice>

            <ns0:sequence>

               <ns0:e1/>

               <ns0:e2>Wackadoodle</ns0:e2>

               <ns0:e3/>

            </ns0:sequence>

         </ns0:choice>

      </ns0:External>

   </ns1:Body>

</SOAP-ENV:Envelope>""")





def test_function_parameters_strings():

    client = tests.client_from_wsdl(suds.byte_str("""\

<?xml version='1.0' encoding='UTF-8'?>

<wsdl:definitions targetNamespace="my-namespace"

xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

xmlns:ns="my-namespace"

xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">

  <wsdl:types>

    <xsd:schema targetNamespace="my-namespace"

    elementFormDefault="qualified"

    attributeFormDefault="unqualified"

    xmlns:xsd="http://www.w3.org/2001/XMLSchema">

      <xsd:element name="Elemento">

        <xsd:complexType>

          <xsd:sequence>

            <xsd:element name="x1" type="xsd:string" />

            <xsd:element name="x2" type="xsd:string" />

            <xsd:element name="x3" type="xsd:string" />

          </xsd:sequence>

        </xsd:complexType>

      </xsd:element>

    </xsd:schema>

  </wsdl:types>

  <wsdl:message name="fRequestMessage">

    <wsdl:part name="parameters" element="ns:Elemento" />

  </wsdl:message>

  <wsdl:portType name="dummyPortType">

    <wsdl:operation name="f">

      <wsdl:input message="ns:fRequestMessage" />

    </wsdl:operation>

  </wsdl:portType>

  <wsdl:binding name="dummy" type="ns:dummyPortType">

    <soap:binding style="document"

    transport="http://schemas.xmlsoap.org/soap/http" />

    <wsdl:operation name="f">

      <soap:operation soapAction="f" style="document" />

      <wsdl:input><soap:body use="literal" /></wsdl:input>

      <wsdl:output><soap:body use="literal" /></wsdl:output>

    </wsdl:operation>

  </wsdl:binding>

  <wsdl:service name="dummy">

    <wsdl:port name="dummy" binding="ns:dummy">

      <soap:address location="https://localhost/dummy" />

    </wsdl:port>

  </wsdl:service>

</wsdl:definitions>

"""))



    service = client.sd[0]

    assert not service.types



    # Method parameters as read from the service definition.

    assert len(service.params) == 3

    assert service.params[0][0].name == "x1"

    assert service.params[0][0].type == _string_type

    assert isinstance(service.params[0][1], suds.xsd.sxbuiltin.XString)

    assert service.params[1][0].name == "x2"

    assert service.params[1][0].type == _string_type

    assert isinstance(service.params[1][1], suds.xsd.sxbuiltin.XString)

    assert service.params[2][0].name == "x3"

    assert service.params[2][0].type == _string_type

    assert isinstance(service.params[2][1], suds.xsd.sxbuiltin.XString)



    # Method parameters as read from a method object.

    assert len(service.ports) == 1

    port, methods = service.ports[0]

    assert len(methods) == 1

    method_name, method_params = methods[0]

    assert method_name == "f"

    assert len(method_params) == 3

    assert method_params[0][0] == "x1"

    assert method_params[0][1] is service.params[0][0]

    assert method_params[1][0] == "x2"

    assert method_params[1][1] is service.params[1][0]

    assert method_params[2][0] == "x3"

    assert method_params[2][1] is service.params[2][0]





def test_global_enumeration():

    client = tests.client_from_wsdl(suds.byte_str("""\

<?xml version='1.0' encoding='UTF-8'?>

<wsdl:definitions targetNamespace="my-namespace"

xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

xmlns:ns="my-namespace"

xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">

  <wsdl:types>

    <xsd:schema targetNamespace="my-namespace"

    elementFormDefault="qualified"

    attributeFormDefault="unqualified"

    xmlns:xsd="http://www.w3.org/2001/XMLSchema">

      <xsd:simpleType name="AAA">

        <xsd:restriction base="xsd:string">

          <xsd:enumeration value="One" />

          <xsd:enumeration value="Two" />

          <xsd:enumeration value="Thirty-Two" />

        </xsd:restriction>

      </xsd:simpleType>

    </xsd:schema>

  </wsdl:types>

  <wsdl:portType name="dummyPortType">

  </wsdl:portType>

  <wsdl:binding name="dummy" type="ns:dummyPortType">

    <soap:binding style="document"

    transport="http://schemas.xmlsoap.org/soap/http" />

  </wsdl:binding>

  <wsdl:service name="dummy">

    <wsdl:port name="dummy" binding="ns:dummy">

      <soap:address location="https://localhost/dummy" />

    </wsdl:port>

  </wsdl:service>

</wsdl:definitions>

"""))



    assert len(client.sd) == 1

    service = client.sd[0]



    assert len(service.types) == 1

    for typeTuple in service.types:

        # Tuple containing the same object twice.

        assert len(typeTuple) == 2

        assert typeTuple[0] is typeTuple[1]



    aType = service.types[0][0]

    assert isinstance(aType, suds.xsd.sxbasic.Simple)

    assert aType.name == "AAA"

    assert aType.enum()

    assert aType.mixed()

    assert aType.restriction()

    assert not aType.choice()

    assert not aType.sequence()



    assert len(aType.rawchildren) == 1

    assert isinstance(aType.rawchildren[0], suds.xsd.sxbasic.Restriction)

    assert aType.rawchildren[0].ref == _string_type



    enum = client.factory.create("AAA")

    assert enum.One == "One"

    assert enum.Two == "Two"

    assert getattr(enum, "Thirty-Two") == "Thirty-Two"





def test_global_sequence_in_a_global_sequence():

    client = tests.client_from_wsdl(suds.byte_str("""\

<?xml version='1.0' encoding='UTF-8'?>

<wsdl:definitions targetNamespace="my-namespace"

xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

xmlns:ns="my-namespace"

xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">

  <wsdl:types>

    <xsd:schema targetNamespace="my-namespace"

    elementFormDefault="qualified"

    attributeFormDefault="unqualified"

    xmlns:xsd="http://www.w3.org/2001/XMLSchema">

      <xsd:complexType name="Oklahoma">

        <xsd:sequence>

          <xsd:element name="c1" type="xsd:string" />

          <xsd:element name="c2" type="xsd:string" />

          <xsd:element name="c3" type="xsd:string" />

        </xsd:sequence>

      </xsd:complexType>

      <xsd:complexType name="Wackadoodle">

        <xsd:sequence>

          <xsd:element name="x1" type="xsd:string" />

          <xsd:element name="x2" type="Oklahoma" />

          <xsd:element name="x3" type="xsd:string" />

        </xsd:sequence>

      </xsd:complexType>

    </xsd:schema>

  </wsdl:types>

  <wsdl:portType name="dummyPortType">

  </wsdl:portType>

  <wsdl:binding name="dummy" type="ns:dummyPortType">

    <soap:binding style="document"

    transport="http://schemas.xmlsoap.org/soap/http" />

  </wsdl:binding>

  <wsdl:service name="dummy">

    <wsdl:port name="dummy" binding="ns:dummy">

      <soap:address location="https://localhost/dummy" />

    </wsdl:port>

  </wsdl:service>

</wsdl:definitions>

"""))



    service = client.sd[0]



    assert len(service.types) == 2

    for typeTuple in service.types:

        # Tuple containing the same object twice.

        assert len(typeTuple) == 2

        assert typeTuple[0] is typeTuple[1]



    aTypeIn = service.types[0][0]

    assert isinstance(aTypeIn, suds.xsd.sxbasic.Complex)

    assert aTypeIn.name == "Oklahoma"

    assert not aTypeIn.sequence()

    assert aTypeIn.rawchildren[0].sequence()



    aTypeOut = service.types[1][0]

    assert isinstance(aTypeOut, suds.xsd.sxbasic.Complex)

    assert aTypeOut.name == "Wackadoodle"

    assert not aTypeOut.sequence()

    assert aTypeOut.rawchildren[0].sequence()



    assert len(aTypeOut.rawchildren) == 1

    children = aTypeOut.children()

    assert isinstance(children, list)

    assert len(children) == 3

    assert children[0][0].name == "x1"

    assert children[0][0].type == _string_type

    assert children[1][0].name == "x2"

    assert children[1][0].type == ("Oklahoma", "my-namespace")

    assert children[2][0].name == "x3"

    assert children[2][0].type == _string_type



    sequenceOut = client.factory.create("Wackadoodle")

    _assert_dynamic_type(sequenceOut, "Wackadoodle")

    assert sequenceOut.__metadata__.sxtype is aTypeOut

    assert sequenceOut.x1 is None

    sequenceIn = sequenceOut.x2

    assert sequenceOut.x3 is None

    _assert_dynamic_type(sequenceIn, "Oklahoma")

    assert sequenceIn.__metadata__.sxtype is aTypeIn

    assert sequenceIn.c1 is None

    assert sequenceIn.c2 is None

    assert sequenceIn.c3 is None





def test_global_string_sequence():

    client = tests.client_from_wsdl(suds.byte_str("""\

<?xml version='1.0' encoding='UTF-8'?>

<wsdl:definitions targetNamespace="my-namespace"

xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

xmlns:ns="my-namespace"

xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">

  <wsdl:types>

    <xsd:schema targetNamespace="my-namespace"

    elementFormDefault="qualified"

    attributeFormDefault="unqualified"

    xmlns:xsd="http://www.w3.org/2001/XMLSchema">

      <xsd:complexType name="Oklahoma">

        <xsd:sequence>

          <xsd:element name="c1" type="xsd:string" />

          <xsd:element name="c2" type="xsd:string" />

          <xsd:element name="c3" type="xsd:string" />

        </xsd:sequence>

      </xsd:complexType>

    </xsd:schema>

  </wsdl:types>

  <wsdl:portType name="dummyPortType">

  </wsdl:portType>

  <wsdl:binding name="dummy" type="ns:dummyPortType">

    <soap:binding style="document"

    transport="http://schemas.xmlsoap.org/soap/http" />

  </wsdl:binding>

  <wsdl:service name="dummy">

    <wsdl:port name="dummy" binding="ns:dummy">

      <soap:address location="https://localhost/dummy" />

    </wsdl:port>

  </wsdl:service>

</wsdl:definitions>

"""))



    service = client.sd[0]



    assert len(service.types) == 1

    for typeTuple in service.types:

        # Tuple containing the same object twice.

        assert len(typeTuple) == 2

        assert typeTuple[0] is typeTuple[1]



    aType = service.types[0][0]

    assert isinstance(aType, suds.xsd.sxbasic.Complex)

    assert aType.name == "Oklahoma"

    assert not aType.choice()

    assert not aType.enum()

    assert not aType.mixed()

    assert not aType.restriction()

    assert not aType.sequence()



    assert len(aType.rawchildren) == 1

    sequence_node = aType.rawchildren[0]

    assert isinstance(sequence_node, suds.xsd.sxbasic.Sequence)

    assert sequence_node.sequence()

    assert len(sequence_node) == 3

    sequence_items = sequence_node.children()

    assert isinstance(sequence_items, list)

    assert len(sequence_items) == 3

    assert sequence_items[0][0].name == "c1"

    assert sequence_items[0][0].type == _string_type

    assert sequence_items[1][0].name == "c2"

    assert sequence_items[1][0].type == _string_type

    assert sequence_items[2][0].name == "c3"

    assert sequence_items[2][0].type == _string_type



    sequence = client.factory.create("Oklahoma")

    getattr(sequence, "c1")

    getattr(sequence, "c2")

    getattr(sequence, "c3")

    pytest.raises(AttributeError, getattr, sequence, "nonExistingChild")

    assert sequence.c1 is None

    assert sequence.c2 is None

    assert sequence.c3 is None

    sequence.c1 = "Pero"

    sequence.c3 = "Zdero"

    assert sequence.c1 == "Pero"

    assert sequence.c2 is None

    assert sequence.c3 == "Zdero"





def test_local_sequence_in_a_global_sequence():

    client = tests.client_from_wsdl(suds.byte_str("""\

<?xml version='1.0' encoding='UTF-8'?>

<wsdl:definitions targetNamespace="my-namespace"

xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

xmlns:ns="my-namespace"

xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">

  <wsdl:types>

    <xsd:schema targetNamespace="my-namespace"

    elementFormDefault="qualified"

    attributeFormDefault="unqualified"

    xmlns:xsd="http://www.w3.org/2001/XMLSchema">

      <xsd:complexType name="Wackadoodle">

        <xsd:sequence>

          <xsd:element name="x1">

              <xsd:complexType name="Oklahoma">

                <xsd:sequence>

                  <xsd:element name="c1" type="xsd:string" />

                  <xsd:element name="c2" type="xsd:string" />

                  <xsd:element name="c3" type="xsd:string" />

                </xsd:sequence>

              </xsd:complexType>

          </xsd:element>

          <xsd:element name="x2">

              <xsd:complexType>

                <xsd:sequence>

                  <xsd:element name="s" type="xsd:string" />

                </xsd:sequence>

              </xsd:complexType>

          </xsd:element>

        </xsd:sequence>

      </xsd:complexType>

    </xsd:schema>

  </wsdl:types>

  <wsdl:portType name="dummyPortType">

  </wsdl:portType>

  <wsdl:binding name="dummy" type="ns:dummyPortType">

    <soap:binding style="document"

    transport="http://schemas.xmlsoap.org/soap/http" />

  </wsdl:binding>

  <wsdl:service name="dummy">

    <wsdl:port name="dummy" binding="ns:dummy">

      <soap:address location="https://localhost/dummy" />

    </wsdl:port>

  </wsdl:service>

</wsdl:definitions>

"""))



    service = client.sd[0]

    assert len(service.types) == 1



    aTypeOut = service.types[0][0]

    assert isinstance(aTypeOut, suds.xsd.sxbasic.Complex)

    assert aTypeOut.name == "Wackadoodle"

    assert not aTypeOut.sequence()

    assert aTypeOut.rawchildren[0].sequence()



    children = aTypeOut.children()

    assert isinstance(children, list)

    assert len(children) == 2

    aTypeIn1 = children[0][0]

    assert isinstance(aTypeIn1, suds.xsd.sxbasic.Element)

    assert not aTypeIn1.sequence()

    assert aTypeIn1.rawchildren[0].rawchildren[0].sequence()

    aTypeIn2 = children[1][0]

    assert isinstance(aTypeIn2, suds.xsd.sxbasic.Element)

    assert not aTypeIn2.sequence()

    assert aTypeIn2.rawchildren[0].rawchildren[0].sequence()

    assert aTypeIn1.rawchildren[0].name == "Oklahoma"

    assert aTypeIn1.rawchildren[0].type is None

    namespace1 = aTypeIn1.rawchildren[0].namespace()

    assert namespace1 == ("ns", "my-namespace")

    assert aTypeIn2.rawchildren[0].name is None

    assert aTypeIn2.rawchildren[0].type is None

    assert aTypeIn1.rawchildren[0].namespace() is namespace1



    sequenceOut = client.factory.create("Wackadoodle")

    _assert_dynamic_type(sequenceOut, "Wackadoodle")

    assert sequenceOut.__metadata__.sxtype is aTypeOut

    sequenceIn1 = sequenceOut.x1

    sequenceIn2 = sequenceOut.x2

    _assert_dynamic_type(sequenceIn1, "x1")

    _assert_dynamic_type(sequenceIn2, "x2")

    assert sequenceIn1.__metadata__.sxtype is aTypeIn1

    assert sequenceIn2.__metadata__.sxtype is aTypeIn2

    assert sequenceIn1.c1 is None

    assert sequenceIn1.c2 is None

    assert sequenceIn1.c3 is None

    assert sequenceIn2.s is None





def test_no_trailing_comma_in_function_prototype_description_string__0():

    client = tests.client_from_wsdl(suds.byte_str("""\

<?xml version='1.0' encoding='UTF-8'?>

<wsdl:definitions targetNamespace="my-namespace"

xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

xmlns:ns="my-namespace"

xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">

  <wsdl:types>

    <xsd:schema targetNamespace="my-namespace"

    elementFormDefault="qualified"

    attributeFormDefault="unqualified"

    xmlns:xsd="http://www.w3.org/2001/XMLSchema">

      <xsd:element name="InputData">

        <xsd:complexType>

          <xsd:sequence />

        </xsd:complexType>

      </xsd:element>

    </xsd:schema>

  </wsdl:types>

  <wsdl:message name="fRequestMessage">

    <wsdl:part name="parameters" element="ns:InputData" />

  </wsdl:message>

  <wsdl:portType name="dummyPortType">

    <wsdl:operation name="f">

      <wsdl:input message="ns:fRequestMessage" />

    </wsdl:operation>

  </wsdl:portType>

  <wsdl:binding name="dummy" type="ns:dummyPortType">

    <soap:binding style="document"

    transport="http://schemas.xmlsoap.org/soap/http" />

    <wsdl:operation name="f">

      <soap:operation soapAction="f" style="document" />

      <wsdl:input><soap:body use="literal" /></wsdl:input>

      <wsdl:output><soap:body use="literal" /></wsdl:output>

    </wsdl:operation>

  </wsdl:binding>

  <wsdl:service name="dummy">

    <wsdl:port name="dummy" binding="ns:dummy">

      <soap:address location="https://localhost/dummy" />

    </wsdl:port>

  </wsdl:service>

</wsdl:definitions>

"""))

    s = str(client)

    assert " f()\n" in s





def test_no_trailing_comma_in_function_prototype_description_string__1():

    client = tests.client_from_wsdl(suds.byte_str("""\

<?xml version='1.0' encoding='UTF-8'?>

<wsdl:definitions targetNamespace="my-namespace"

xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

xmlns:ns="my-namespace"

xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">

  <wsdl:types>

    <xsd:schema targetNamespace="my-namespace"

    elementFormDefault="qualified"

    attributeFormDefault="unqualified"

    xmlns:xsd="http://www.w3.org/2001/XMLSchema">

      <xsd:element name="InputData">

        <xsd:complexType>

          <xsd:sequence>

            <xsd:element name="x1" type="xsd:string" />

          </xsd:sequence>

        </xsd:complexType>

      </xsd:element>

    </xsd:schema>

  </wsdl:types>

  <wsdl:message name="fRequestMessage">

    <wsdl:part name="parameters" element="ns:InputData" />

  </wsdl:message>

  <wsdl:portType name="dummyPortType">

    <wsdl:operation name="f">

      <wsdl:input message="ns:fRequestMessage" />

    </wsdl:operation>

  </wsdl:portType>

  <wsdl:binding name="dummy" type="ns:dummyPortType">

    <soap:binding style="document"

    transport="http://schemas.xmlsoap.org/soap/http" />

    <wsdl:operation name="f">

      <soap:operation soapAction="f" style="document" />

      <wsdl:input><soap:body use="literal" /></wsdl:input>

      <wsdl:output><soap:body use="literal" /></wsdl:output>

    </wsdl:operation>

  </wsdl:binding>

  <wsdl:service name="dummy">

    <wsdl:port name="dummy" binding="ns:dummy">

      <soap:address location="https://localhost/dummy" />

    </wsdl:port>

  </wsdl:service>

</wsdl:definitions>

"""))

    s = str(client)

    assert " f(xs:string x1)\n" in s





def test_no_trailing_comma_in_function_prototype_description_string__3():

    client = tests.client_from_wsdl(suds.byte_str("""\

<?xml version='1.0' encoding='UTF-8'?>

<wsdl:definitions targetNamespace="my-namespace"

xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

xmlns:ns="my-namespace"

xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">

  <wsdl:types>

    <xsd:schema targetNamespace="my-namespace"

    elementFormDefault="qualified"

    attributeFormDefault="unqualified"

    xmlns:xsd="http://www.w3.org/2001/XMLSchema">

      <xsd:element name="InputData">

        <xsd:complexType>

          <xsd:sequence>

            <xsd:element name="x1" type="xsd:string" />

            <xsd:element name="x2" type="xsd:string" />

            <xsd:element name="x3" type="xsd:string" />

          </xsd:sequence>

        </xsd:complexType>

      </xsd:element>

    </xsd:schema>

  </wsdl:types>

  <wsdl:message name="fRequestMessage">

    <wsdl:part name="parameters" element="ns:InputData" />

  </wsdl:message>

  <wsdl:portType name="dummyPortType">

    <wsdl:operation name="f">

      <wsdl:input message="ns:fRequestMessage" />

    </wsdl:operation>

  </wsdl:portType>

  <wsdl:binding name="dummy" type="ns:dummyPortType">

    <soap:binding style="document"

    transport="http://schemas.xmlsoap.org/soap/http" />

    <wsdl:operation name="f">

      <soap:operation soapAction="f" style="document" />

      <wsdl:input><soap:body use="literal" /></wsdl:input>

      <wsdl:output><soap:body use="literal" /></wsdl:output>

    </wsdl:operation>

  </wsdl:binding>

  <wsdl:service name="dummy">

    <wsdl:port name="dummy" binding="ns:dummy">

      <soap:address location="https://localhost/dummy" />

    </wsdl:port>

  </wsdl:service>

</wsdl:definitions>

"""))

    s = str(client)

    assert " f(xs:string x1, xs:string x2, xs:string x3)\n" in s





def test_no_types():

    client = tests.client_from_wsdl(suds.byte_str("""\

<?xml version='1.0' encoding='UTF-8'?>

<wsdl:definitions targetNamespace="my-namespace"

xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

xmlns:ns="my-namespace"

xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">

  <wsdl:types>

    <xsd:schema targetNamespace="my-namespace"

    elementFormDefault="qualified"

    attributeFormDefault="unqualified"

    xmlns:xsd="http://www.w3.org/2001/XMLSchema" />

  </wsdl:types>

  <wsdl:portType name="dummyPortType">

  </wsdl:portType>

  <wsdl:binding name="dummy" type="ns:dummyPortType">

    <soap:binding style="document"

    transport="http://schemas.xmlsoap.org/soap/http" />

  </wsdl:binding>

  <wsdl:service name="dummy">

    <wsdl:port name="dummy" binding="ns:dummy">

      <soap:address location="https://localhost/dummy" />

    </wsdl:port>

  </wsdl:service>

</wsdl:definitions>

"""))



    assert len(client.sd) == 1

    service = client.sd[0]



    assert not client.wsdl.schema.types

    assert not service.types



    pytest.raises(suds.TypeNotFound, client.factory.create, "NonExistingType")





def test_parameter_referencing_missing_element(monkeypatch):

    wsdl = tests.wsdl_input("", "missingElement")

    monkeypatch.delitem(locals(), "e", False)

    e = pytest.raises(suds.TypeNotFound, tests.client_from_wsdl, wsdl).value

    assert str(e) == "Type not found: '(missingElement, my-namespace, )'"





# TODO: Update the current restriction type input parameter handling so they get

# 'unwrapped' correctly instead of each of their enumeration values getting

# interpreted as a separate input parameter.

@pytest.mark.xfail

def test_restrictions():

    client_unnamed = tests.client_from_wsdl(tests.wsdl_input("""\

      <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>""", "Elemento"))



    client_named = tests.client_from_wsdl(tests.wsdl_input("""\

      <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" />""", "Elemento"))



    client_twice_restricted = tests.client_from_wsdl(tests.wsdl_input("""\

      <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" />""", "Elemento"))



    element_qref = ("Elemento", "my-namespace")

    type_named_qref = ("MyType", "my-namespace")



    element_unnamed = client_unnamed.wsdl.schema.elements[element_qref]

    element_named = client_named.wsdl.schema.elements[element_qref]

    element_twice_restricted = client_twice_restricted.wsdl.schema.elements[

        element_qref]



    type_unnamed = element_unnamed.resolve()

    type_named = element_named.resolve()

    type_twice_restricted = element_twice_restricted.resolve()

    assert type_unnamed is element_unnamed

    assert type_named is client_named.wsdl.schema.types[type_named_qref]

    assert type_twice_restricted is client_twice_restricted.wsdl.schema.types[

        type_named_qref]



    #   Regression test against suds automatically unwrapping input parameter

    # type's enumeration values as separate parameters.

    params_unnamed = client_unnamed.sd[0].params

    params_named = client_named.sd[0].params

    params_twice_restricted = client_twice_restricted.sd[0].params

    assert len(params_unnamed) == 1

    assert len(params_named) == 1

    assert len(params_twice_restricted) == 1

    assert params_unnamed[0][0] is element_unnamed

    assert params_unnamed[0][1] is type_unnamed

    assert params_named[0][0] is element_named

    assert params_named[0][1] is type_named

    assert params_twice_restricted[0][0] is element_twice_restricted

    assert params_twice_restricted[0][1] is type_twice_restricted





def test_schema_node_occurrences():

    client = tests.client_from_wsdl(suds.byte_str("""\

<?xml version='1.0' encoding='UTF-8'?>

<wsdl:definitions targetNamespace="my-namespace"

xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

xmlns:ns="my-namespace"

xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">

  <wsdl:types>

    <xsd:schema targetNamespace="my-namespace"

    elementFormDefault="qualified"

    attributeFormDefault="unqualified"

    xmlns:xsd="http://www.w3.org/2001/XMLSchema">

"""

    + _element_node_xml("AnElement1")

    + _element_node_xml("AnElement2", min=1)

    + _element_node_xml("AnElement3", max=1)



    + _element_node_xml("AnOptionalElement1", min=0)

    + _element_node_xml("AnOptionalElement2", min=0, max=1)



    + _element_node_xml("Array_0_2", min=0, max=2)

    + _element_node_xml("Array_0_999", min=0, max=999)

    + _element_node_xml("Array_0_X", min=0, max="unbounded")



    + _element_node_xml("Array_x_2", max=2)

    + _element_node_xml("Array_x_999", max=999)

    + _element_node_xml("Array_x_X", max="unbounded")



    + _element_node_xml("Array_1_2", min=1, max=2)

    + _element_node_xml("Array_1_999", min=1, max=999)

    + _element_node_xml("Array_1_X", min=1, max="unbounded")



    + _element_node_xml("Array_5_5", min=5, max=5)

    + _element_node_xml("Array_5_999", min=5, max=999)

    + _element_node_xml("Array_5_X", min=5, max="unbounded")

+ """

    </xsd:schema>

  </wsdl:types>

</wsdl:definitions>

"""))

    schema = client.wsdl.schema



    def a(schema, name, min=None, max=None):

        element = schema.elements[name, "my-namespace"]



        if min is None:

            assert element.min is None

            min = 1

        else:

            assert str(min) == element.min

        if max is None:

            assert element.max is None

            max = 1

        else:

            assert str(max) == element.max



        expected_optional = min == 0

        assert expected_optional == element.optional()



        expected_required = not expected_optional

        assert expected_required == element.required()



        expected_multi_occurrence = (max == "unbounded") or (max > 1)

        assert expected_multi_occurrence == element.multi_occurrence()



    a(schema, "AnElement1")

    a(schema, "AnElement2", min=1)

    a(schema, "AnElement3", max=1)



    a(schema, "AnOptionalElement1", min=0)

    a(schema, "AnOptionalElement2", min=0, max=1)



    a(schema, "Array_0_2", min=0, max=2)

    a(schema, "Array_0_999", min=0, max=999)

    a(schema, "Array_0_X", min=0, max="unbounded")



    a(schema, "Array_x_2", max=2)

    a(schema, "Array_x_999", max=999)

    a(schema, "Array_x_X", max="unbounded")



    a(schema, "Array_1_2", min=1, max=2)

    a(schema, "Array_1_999", min=1, max=999)

    a(schema, "Array_1_X", min=1, max="unbounded")



    a(schema, "Array_5_5", min=5, max=5)

    a(schema, "Array_5_999", min=5, max=999)

    a(schema, "Array_5_X", min=5, max="unbounded")





def test_schema_node_resolve():

    client = tests.client_from_wsdl(suds.byte_str("""\

<?xml version='1.0' encoding='UTF-8'?>

<wsdl:definitions targetNamespace="my-namespace"

xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

xmlns:ns="my-namespace"

xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">

  <wsdl:types>

    <xsd:schema targetNamespace="my-namespace"

    elementFormDefault="qualified"

    attributeFormDefault="unqualified"

    xmlns:xsd="http://www.w3.org/2001/XMLSchema">

      <xsd:complexType name="Typo">

        <xsd:sequence>

          <xsd:element name="u1" type="xsd:string" />

          <xsd:element name="u2" type="xsd:string" />

          <xsd:element name="u3" type="xsd:string" />

        </xsd:sequence>

      </xsd:complexType>

      <xsd:element name="Elemento">

        <xsd:complexType>

          <xsd:sequence>

            <xsd:element name="x1" type="xsd:string" />

            <xsd:element name="x2" type="Typo" />

            <xsd:element name="x3">

              <xsd:complexType>

                <xsd:sequence>

                  <xsd:element name="a1" type="xsd:string" />

                  <xsd:element name="a2" type="xsd:string" />

                </xsd:sequence>

              </xsd:complexType>

            </xsd:element>

          </xsd:sequence>

        </xsd:complexType>

      </xsd:element>

      <xsd:element name="ElementoTyped" type="Typo" />

    </xsd:schema>

  </wsdl:types>

</wsdl:definitions>

"""))

    schema = client.wsdl.schema



    # Collect references to the test schema type nodes.

    assert len(schema.types) == 1

    typo = schema.types["Typo", "my-namespace"]

    typo_u1 = typo.children()[0][0]

    assert typo_u1.name == "u1"



    # Collect references to the test schema element nodes.

    assert len(schema.elements) == 2

    elemento = schema.elements["Elemento", "my-namespace"]

    elemento_x2 = elemento.children()[1][0]

    assert elemento_x2.name == "x2"

    elemento_x3 = elemento.children()[2][0]

    assert elemento_x3.name == "x3"

    elementoTyped = schema.elements["ElementoTyped", "my-namespace"]



    # Resolving top-level locally defined non-content nodes.

    assert typo.resolve() is typo



    # Resolving a correctly typed top-level locally typed element.

    assert elemento.resolve() is elemento



    # Resolving top-level globally typed elements.

    assert elementoTyped.resolve() is typo



    # Resolving a subnode referencing a globally defined type.

    assert elemento_x2.resolve() is typo



    # Resolving a locally defined subnode.

    assert elemento_x3.resolve() is elemento_x3



    # Resolving builtin type nodes.

    assert typo_u1.resolve().__class__ is suds.xsd.sxbuiltin.XString

    assert typo_u1.resolve(nobuiltin=False).__class__ is  \

        suds.xsd.sxbuiltin.XString

    assert typo_u1.resolve(nobuiltin=True) is typo_u1

    assert elemento_x2.resolve(nobuiltin=True) is typo

    assert elemento_x3.resolve(nobuiltin=True) is elemento_x3





def test_schema_node_resolve__nobuiltin_caching():

    client = tests.client_from_wsdl(suds.byte_str("""\

<?xml version='1.0' encoding='UTF-8'?>

<wsdl:definitions targetNamespace="my-namespace"

xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

xmlns:ns="my-namespace"

xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">

  <wsdl:types>

    <xsd:schema targetNamespace="my-namespace"

    elementFormDefault="qualified"

    attributeFormDefault="unqualified"

    xmlns:xsd="http://www.w3.org/2001/XMLSchema">

      <xsd:element name="Elemento1" type="xsd:string" />

      <xsd:element name="Elemento2" type="xsd:string" />

      <xsd:element name="Elemento3" type="xsd:string" />

      <xsd:element name="Elemento4" type="xsd:string" />

    </xsd:schema>

  </wsdl:types>

</wsdl:definitions>

"""))

    schema = client.wsdl.schema



    # Collect references to the test schema element nodes.

    assert len(schema.elements) == 4

    e1 = schema.elements["Elemento1", "my-namespace"]

    e2 = schema.elements["Elemento2", "my-namespace"]

    e3 = schema.elements["Elemento3", "my-namespace"]

    e4 = schema.elements["Elemento4", "my-namespace"]



    #   Repeating the same resolve() call twice makes sure that the first call

    # does not cache an incorrect value, thus causing the second call to return

    # an incorrect result.



    assert e1.resolve().__class__ is suds.xsd.sxbuiltin.XString

    assert e1.resolve().__class__ is suds.xsd.sxbuiltin.XString



    assert e2.resolve(nobuiltin=True) is e2

    assert e2.resolve(nobuiltin=True) is e2



    assert e3.resolve().__class__ is suds.xsd.sxbuiltin.XString

    assert e3.resolve(nobuiltin=True) is e3

    assert e3.resolve(nobuiltin=True) is e3



    assert e4.resolve(nobuiltin=True) is e4

    assert e4.resolve().__class__ is suds.xsd.sxbuiltin.XString

    assert e4.resolve().__class__ is suds.xsd.sxbuiltin.XString





def test_schema_node_resolve__invalid_type():

    client = tests.client_from_wsdl(suds.byte_str("""\

<?xml version='1.0' encoding='UTF-8'?>

<wsdl:definitions targetNamespace="my-namespace"

xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

xmlns:ns="my-namespace"

xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">

  <wsdl:types>

    <xsd:schema targetNamespace="my-namespace"

    elementFormDefault="qualified"

    attributeFormDefault="unqualified"

    xmlns:xsd="http://www.w3.org/2001/XMLSchema">

      <xsd:element name="Elemento1" type="Elemento1" />

      <xsd:element name="Elemento2" type="Elemento1" />

      <xsd:element name="Elemento3" type="XXX" />

    </xsd:schema>

  </wsdl:types>

</wsdl:definitions>

"""))

    schema = client.wsdl.schema

    assert len(schema.elements) == 3

    elemento1 = schema.elements["Elemento1", "my-namespace"]

    elemento2 = schema.elements["Elemento2", "my-namespace"]

    elemento3 = schema.elements["Elemento3", "my-namespace"]

    pytest.raises(suds.TypeNotFound, elemento1.resolve)

    pytest.raises(suds.TypeNotFound, elemento2.resolve)

    pytest.raises(suds.TypeNotFound, elemento3.resolve)





def test_schema_node_resolve__references():

    client = tests.client_from_wsdl(suds.byte_str("""\

<?xml version='1.0' encoding='UTF-8'?>

<wsdl:definitions targetNamespace="my-namespace"

xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

xmlns:ns="my-namespace"

xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">

  <wsdl:types>

    <xsd:schema targetNamespace="my-namespace"

    elementFormDefault="qualified"

    attributeFormDefault="unqualified"

    xmlns:xsd="http://www.w3.org/2001/XMLSchema">

      <xsd:complexType name="Typo">

        <xsd:sequence>

          <xsd:element name="u1" type="xsd:string" />

          <xsd:element name="u2" type="xsd:string" />

          <xsd:element name="u3" type="xsd:string" />

        </xsd:sequence>

      </xsd:complexType>

      <xsd:element name="ElementoTyped" type="Typo" />

      <xsd:element name="ElementoTyped11" ref="ElementoTyped" />

      <xsd:element name="ElementoTyped12" ref="ElementoTyped11" />

      <xsd:element name="ElementoTyped13" ref="ElementoTyped12" />

      <xsd:element name="ElementoTyped21" ref="ElementoTyped" />

      <xsd:element name="ElementoTyped22" ref="ElementoTyped21" />

      <xsd:element name="ElementoTyped23" ref="ElementoTyped22" />

      <xsd:element name="ElementoTypedX" ref="ElementoTypedX" />

      <xsd:element name="ElementoTypedX1" ref="ElementoTypedX2" />

      <xsd:element name="ElementoTypedX2" ref="ElementoTypedX1" />

    </xsd:schema>

  </wsdl:types>

</wsdl:definitions>

"""))

    schema = client.wsdl.schema



    # Collect references to the test schema element & type nodes.

    assert len(schema.types) == 1

    typo = schema.types["Typo", "my-namespace"]

    assert len(schema.elements) == 10

    elementoTyped = schema.elements["ElementoTyped", "my-namespace"]

    elementoTyped11 = schema.elements["ElementoTyped11", "my-namespace"]

    elementoTyped12 = schema.elements["ElementoTyped12", "my-namespace"]

    elementoTyped13 = schema.elements["ElementoTyped13", "my-namespace"]

    elementoTyped21 = schema.elements["ElementoTyped21", "my-namespace"]

    elementoTyped22 = schema.elements["ElementoTyped22", "my-namespace"]

    elementoTyped23 = schema.elements["ElementoTyped23", "my-namespace"]

    elementoTypedX = schema.elements["ElementoTypedX", "my-namespace"]

    elementoTypedX1 = schema.elements["ElementoTypedX1", "my-namespace"]

    elementoTypedX2 = schema.elements["ElementoTypedX2", "my-namespace"]



    #   For referenced element node chains try resolving their nodes in both

    # directions and try resolving them twice to try and avoid any internal

    # resolve result caching that might cause some resursive resolution branch

    # to not get taken.

    #   Note that these assertions are actually redundant since inter-element

    # references get processed and referenced type information merged back into

    # the referencee when the schema information is loaded so no recursion is

    # needed here in the first place. The tests should still be left in place

    # and pass to serve as a safeguard in case this reference processing gets

    # changed in the future.

    assert elementoTyped11.resolve() is typo

    assert elementoTyped11.resolve() is typo

    assert elementoTyped13.resolve() is typo

    assert elementoTyped13.resolve() is typo



    assert elementoTyped23.resolve() is typo

    assert elementoTyped23.resolve() is typo

    assert elementoTyped21.resolve() is typo

    assert elementoTyped21.resolve() is typo



    # Recursive element references.

    assert elementoTypedX.resolve() is elementoTypedX

    assert elementoTypedX1.resolve() is elementoTypedX1

    assert elementoTypedX2.resolve() is elementoTypedX2





def test_schema_object_child_access_by_index():

    client = tests.client_from_wsdl(suds.byte_str("""\

<?xml version='1.0' encoding='UTF-8'?>

<wsdl:definitions targetNamespace="my-namespace"

xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

xmlns:ns="my-namespace"

xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">

  <wsdl:types>

    <xsd:schema targetNamespace="my-namespace"

    elementFormDefault="qualified"

    attributeFormDefault="unqualified"

    xmlns:xsd="http://www.w3.org/2001/XMLSchema">

      <xsd:complexType name="Oklahoma">

        <xsd:sequence>

          <xsd:element name="c1" type="xsd:string" />

          <xsd:element name="c2" type="xsd:string" />

          <xsd:element name="c3" type="xsd:string" />

        </xsd:sequence>

      </xsd:complexType>

    </xsd:schema>

  </wsdl:types>

  <wsdl:portType name="dummyPortType">

  </wsdl:portType>

  <wsdl:binding name="dummy" type="ns:dummyPortType">

    <soap:binding style="document"

    transport="http://schemas.xmlsoap.org/soap/http" />

  </wsdl:binding>

  <wsdl:service name="dummy">

    <wsdl:port name="dummy" binding="ns:dummy">

      <soap:address location="https://localhost/dummy" />

    </wsdl:port>

  </wsdl:service>

</wsdl:definitions>

"""))



    service = client.sd[0]

    aType = service.types[0][0]

    sequence = aType.rawchildren[0]

    assert isinstance(sequence, suds.xsd.sxbasic.Sequence)

    children = aType.children()

    assert isinstance(children, list)



    assert sequence[-1] is None



    # TODO: Children are returned as a 2-tuple containing the child element and

    # its ancestry (list of its parent elements). For some reason the ancestry

    # list is returned as a new list on every __getitem__() call and so can not

    # be compared using the 'is' operator. Also the children() function and

    # accesing children by index does not seem to return ancestry lists of the

    # same depth. See whether this can be updated so we always get the same

    # ancestry list object.

    # TODO: Add more detailed tests for the ancestry list structure.

    # TODO: Add more detailed tests for the rawchildren list structure.



    assert isinstance(sequence[0], tuple)

    assert len(sequence[0]) == 2

    assert sequence[0][0] is children[0][0]



    assert isinstance(sequence[1], tuple)

    assert len(sequence[1]) == 2

    assert sequence[1][0] is children[1][0]



    assert isinstance(sequence[2], tuple)

    assert len(sequence[2]) == 2

    assert sequence[2][0] is children[2][0]



    assert sequence[3] is None





def test_simple_wsdl():

    client = tests.client_from_wsdl(suds.byte_str("""\

<?xml version='1.0' encoding='UTF-8'?>

<wsdl:definitions targetNamespace="my-namespace"

xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

xmlns:ns="my-namespace"

xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">

  <wsdl:types>

    <xsd:schema targetNamespace="my-namespace"

    elementFormDefault="qualified"

    attributeFormDefault="unqualified"

    xmlns:xsd="http://www.w3.org/2001/XMLSchema">

      <xsd:element name="f">

        <xsd:complexType>

          <xsd:sequence>

            <xsd:element name="a" type="xsd:string" />

            <xsd:element name="b" type="xsd:string" />

          </xsd:sequence>

        </xsd:complexType>

      </xsd:element>

      <xsd:element name="fResponse">

        <xsd:complexType>

          <xsd:sequence>

            <xsd:element name="c" type="xsd:string" />

          </xsd:sequence>

        </xsd:complexType>

      </xsd:element>

    </xsd:schema>

  </wsdl:types>

  <wsdl:message name="fRequestMessage">

    <wsdl:part name="parameters" element="ns:f" />

  </wsdl:message>

  <wsdl:message name="fResponseMessage">

    <wsdl:part name="parameters" element="ns:fResponse" />

  </wsdl:message>

  <wsdl:portType name="dummyPortType">

    <wsdl:operation name="f">

      <wsdl:input message="ns:fRequestMessage" />

      <wsdl:output message="ns:fResponseMessage" />

    </wsdl:operation>

  </wsdl:portType>

  <wsdl:binding name="dummy" type="ns:dummyPortType">

    <soap:binding style="document"

    transport="http://schemas.xmlsoap.org/soap/http" />

    <wsdl:operation name="f">

      <soap:operation soapAction="f" style="document" />

      <wsdl:input><soap:body use="literal" /></wsdl:input>

      <wsdl:output><soap:body use="literal" /></wsdl:output>

    </wsdl:operation>

  </wsdl:binding>

  <wsdl:service name="dummy">

    <wsdl:port name="dummy" binding="ns:dummy">

      <soap:address location="https://localhost/dummy" />

    </wsdl:port>

  </wsdl:service>

</wsdl:definitions>

"""))



    # Target namespace.

    assert client.wsdl.tns[0] == "ns"

    assert client.wsdl.tns[1] == "my-namespace"



    # Elements.

    assert len(client.wsdl.schema.elements) == 2

    elementIn = client.wsdl.schema.elements["f", "my-namespace"]

    elementOut = client.wsdl.schema.elements["fResponse", "my-namespace"]

    assert isinstance(elementIn, suds.xsd.sxbasic.Element)

    assert isinstance(elementOut, suds.xsd.sxbasic.Element)

    assert elementIn.name == "f"

    assert elementOut.name == "fResponse"

    assert len(elementIn.children()) == 2

    param_in_1 = elementIn.children()[0][0]

    param_in_2 = elementIn.children()[1][0]

    assert param_in_1.name == "a"

    assert param_in_1.type == _string_type

    assert param_in_2.name == "b"

    assert param_in_2.type == _string_type

    assert len(elementOut.children()) == 1

    param_out_1 = elementOut.children()[0][0]

    assert param_out_1.name == "c"

    assert param_out_1.type == _string_type



    # Service definition.

    assert len(client.sd) == 1

    service_definition = client.sd[0]

    assert service_definition.wsdl is client.wsdl



    # Service.

    assert len(client.wsdl.services) == 1

    service = client.wsdl.services[0]

    assert service_definition.service is service



    # Ports.

    assert len(service.ports) == 1

    port = service.ports[0]

    assert len(service_definition.ports) == 1

    assert len(service_definition.ports[0]) == 2

    assert service_definition.ports[0][0] is port



    # Methods (from wsdl).

    assert len(port.methods) == 1

    method = port.methods["f"]

    assert method.name == "f"

    assert method.location == "https://localhost/dummy"



    # Operations (from wsdl).

    assert len(client.wsdl.bindings) == 1

    binding_qname, binding = _first_from_dict(client.wsdl.bindings)

    assert binding_qname == ("dummy", "my-namespace")

    assert binding.__class__ is suds.wsdl.Binding

    assert len(binding.operations) == 1

    operation = list(binding.operations.values())[0]

    input = operation.soap.input.body

    output = operation.soap.output.body

    assert len(input.parts) == 1

    assert len(output.parts) == 1

    input_element_qname = input.parts[0].element

    output_element_qname = output.parts[0].element

    assert input_element_qname == elementIn.qname

    assert output_element_qname == elementOut.qname



    # Methods (from service definition, for format specifications see the

    # suds.serviceDefinition.ServiceDefinition.addports() docstring).

    port, methods = service_definition.ports[0]

    assert len(methods) == 1

    method_name, method_params = methods[0]

    assert method_name == "f"



    param_name, param_element, param_ancestry = method_params[0]

    assert param_name == "a"

    assert param_element is param_in_1

    assert len(param_ancestry) == 3

    assert type(param_ancestry[0]) is suds.xsd.sxbasic.Element

    assert param_ancestry[0].name == "f"

    assert type(param_ancestry[1]) is suds.xsd.sxbasic.Complex

    assert type(param_ancestry[2]) is suds.xsd.sxbasic.Sequence



    param_name, param_element, param_ancestry = method_params[1]

    assert param_name == "b"

    assert param_element is param_in_2

    assert len(param_ancestry) == 3

    assert type(param_ancestry[0]) is suds.xsd.sxbasic.Element

    assert param_ancestry[0].name == "f"

    assert type(param_ancestry[1]) is suds.xsd.sxbasic.Complex

    assert type(param_ancestry[2]) is suds.xsd.sxbasic.Sequence





def test_wsdl_schema_content():

    client = tests.client_from_wsdl(suds.byte_str("""\

<?xml version='1.0' encoding='UTF-8'?>

<wsdl:definitions targetNamespace="my-namespace"

xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

xmlns:ns="my-namespace"

xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">

  <wsdl:types>

    <xsd:schema targetNamespace="my-namespace"

    elementFormDefault="qualified"

    attributeFormDefault="unqualified"

    xmlns:xsd="http://www.w3.org/2001/XMLSchema">

      <xsd:complexType name="UngaBunga">

        <xsd:sequence>

          <xsd:element name="u1" type="xsd:string" />

          <xsd:element name="u2" type="xsd:string" />

          <xsd:element name="u3" type="xsd:string" />

        </xsd:sequence>

      </xsd:complexType>

      <xsd:complexType name="Fifi">

        <xsd:sequence>

          <xsd:element name="x" type="xsd:string" />

        </xsd:sequence>

      </xsd:complexType>

      <xsd:element name="Elemento">

        <xsd:complexType>

          <xsd:sequence>

            <xsd:element name="x1" type="xsd:string" />

            <xsd:element name="x2" type="UngaBunga" />

            <xsd:element name="x3">

              <xsd:complexType>

                <xsd:sequence>

                  <xsd:element name="a1" type="xsd:string" />

                  <xsd:element name="a2" type="xsd:string" />

                </xsd:sequence>

              </xsd:complexType>

            </xsd:element>

          </xsd:sequence>

        </xsd:complexType>

      </xsd:element>

    </xsd:schema>

  </wsdl:types>

</wsdl:definitions>

"""))



    # Elements.

    assert len(client.wsdl.schema.elements) == 1

    elemento = client.wsdl.schema.elements["Elemento", "my-namespace"]

    assert isinstance(elemento, suds.xsd.sxbasic.Element)



    pytest.raises(KeyError, client.wsdl.schema.elements.__getitem__,

        ("DoesNotExist", "OMG"))



    # Types.

    assert len(client.wsdl.schema.types) == 2

    unga_bunga = client.wsdl.schema.types["UngaBunga", "my-namespace"]

    assert isinstance(unga_bunga, suds.xsd.sxbasic.Complex)

    fifi = client.wsdl.schema.types["Fifi", "my-namespace"]

    assert isinstance(unga_bunga, suds.xsd.sxbasic.Complex)



    pytest.raises(KeyError, client.wsdl.schema.types.__getitem__,

        ("DoesNotExist", "OMG"))





def _assert_dynamic_type(anObject, typename):

    assert anObject.__module__ == suds.sudsobject.__name__

    assert anObject.__metadata__.sxtype.name == typename

    #   In order to be compatible with old style classes (py2 only) we need to

    # access the object's class information using its __class__ member and not

    # the type() function. type() function always returns <type 'instance'> for

    # old-style class instances while the __class__ member returns the correct

    # class information for both old and new-style classes.

    assert anObject.__class__.__module__ == suds.sudsobject.__name__

    assert anObject.__class__.__name__ == typename





def _construct_SOAP_request(client, operation_name, *args, **kwargs):

    """

    Returns a SOAP request for a given web service operation invocation.



      To make the test case code calling this function simpler, assumes we want

    to call the operation on the given client's first service & port.



    """

    method = client.wsdl.services[0].ports[0].methods[operation_name]

    return method.binding.input.get_message(method, args, kwargs)





def _element_node_xml(name, min=None, max=None):

    s = []

    s.append('      <xsd:element name="')

    s.append(name)

    s.append('" type="xsd:string" ')

    if min is not None:

        s.append('minOccurs="%s" ' % (min,))

    if max is not None:

        s.append('maxOccurs="%s" ' % (max,))

    s.append('/>\n')

    return ''.join(s)





def _first_from_dict(d):

    """Returns the first name/value pair from a dictionary or None if empty."""

    for x in list(d.items()):

        return x[0], x[1]





_string_type = ("string", "http://www.w3.org/2001/XMLSchema")

