diff --git a/suds/wsdl.py b/suds/wsdl.py index 041ca4a..1e62aae 100644 --- a/suds/wsdl.py +++ b/suds/wsdl.py @@ -720,7 +720,7 @@ class Binding(NamedObject): # Later on we will require access to the message data referenced by # this port_type instance, and in order for those data references to be # available, port_type first needs to dereference its message - # identification string. The only scenario where the port_type could + # identification string. The only scenario where the port_type might # possibly not have already resolved its references, and where this # explicit resolve() call is required, is if we are dealing with a # recursive WSDL import chain. @@ -951,6 +951,13 @@ class Service(NamedObject): log.debug("binding '%s' - not a SOAP binding, discarded", binding.name) continue + # After we have been resolved, our caller will expect that the + # binding we are referencing has been fully constructed, i.e. + # resolved, as well. The only scenario where the operations binding + # might possibly not have already resolved its references, and + # where this explicit resolve() call is required, is if we are + # dealing with a recursive WSDL import chain. + binding.resolve(definitions) p.binding = binding filtered.append(p) self.ports = filtered diff --git a/tests/test_client.py b/tests/test_client.py index 1f660f3..966f07a 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -821,21 +821,19 @@ def test_resolving_references_to_later_entities_in_XML(): assert input_element == ('Lollypop', 'xsd-ns') -def test_recursive_WSDL_import(): +class TestRecursiveWSDLImport: """ - Recursive WSDL imports should be supported. + Test different recursive WSDL import variations. As WSDL imports are nothing but forward declarations, and not component inclusions, recursive WSDL imports are well defined and should be supported. """ - url_main = "suds://wsdl_main" - tns_main = "main-wsdl" - url_binding = "suds://wsdl_binding" - tns_binding = "binding-wsdl" - wsdl_binding = b("""\ + @staticmethod + def __wsdl_binding(tns_binding, tns_main, url_main): + return b("""\ """ % dict(tns=tns_binding, tns_imported=tns_main, - url_imported=url_main)) + url_imported=url_main)) - wsdl_main = b("""\ + @staticmethod + def __wsdl_main(tns_main, tns_binding, url_binding): + return b("""\ """ % dict(tns=tns_main, tns_imported=tns_binding, - url_imported=url_binding)) + url_imported=url_binding)) - store = MockDocumentStore(wsdl_main=wsdl_main, - wsdl_binding=wsdl_binding) - suds.client.Client("suds://wsdl_main", cache=None, documentStore=store) + def test_recursive_WSDL_import_with_single_URL_per_WSDL(self): + url_main = "suds://wsdl_main" + tns_main = "main-wsdl" + url_binding = "suds://wsdl_binding" + tns_binding = "binding-wsdl" + + wsdl_binding = self.__wsdl_binding(tns_binding, tns_main, url_main) + wsdl_main = self.__wsdl_main(tns_main, tns_binding, url_binding) + + store = MockDocumentStore(wsdl_main=wsdl_main, + wsdl_binding=wsdl_binding) + suds.client.Client(url_main, cache=None, documentStore=store) + + def test_recursive_WSDL_import_with_multiple_URLs_per_WSDL(self): + url_main1 = "suds://wsdl_main_1" + url_main2 = "suds://wsdl_main_2" + tns_main = "main-wsdl" + url_binding = "suds://wsdl_binding" + tns_binding = "binding-wsdl" + + wsdl_binding = self.__wsdl_binding(tns_binding, tns_main, url_main2) + wsdl_main = self.__wsdl_main(tns_main, tns_binding, url_binding) + + store = MockDocumentStore(wsdl_main_1=wsdl_main, wsdl_main_2=wsdl_main, + wsdl_binding=wsdl_binding) + suds.client.Client(url_main1, cache=None, documentStore=store)