def test_find_binding(self): res = Binding(name="foo") obj = Definitions(bindings=[res]) self.assertEqual(res, obj.find_binding("foo")) with self.assertRaises(DefinitionsValueError) as cm: obj.find_binding("nope") self.assertEqual("Unknown Binding name: nope", str(cm.exception))
def test_find_port_type(self): res = PortType(name="foo") obj = Definitions(port_types=[res]) self.assertEqual(res, obj.find_port_type("foo")) with self.assertRaises(DefinitionsValueError) as cm: obj.find_port_type("nope") self.assertEqual("Unknown PortType name: nope", str(cm.exception))
def test_find_message(self): res = Message(name="foo") obj = Definitions(messages=[res]) self.assertEqual(res, obj.find_message("foo")) with self.assertRaises(DefinitionsValueError) as cm: obj.find_message("nope") self.assertEqual("Unknown Message name: nope", str(cm.exception))
def map_port(cls, definitions: Definitions, port: ServicePort) -> Iterator[Class]: """Step 2: Match a ServicePort to a Binding and PortType object and delegate the process to the next entry point.""" binding = definitions.find_binding(text.suffix(port.binding)) port_type = definitions.find_port_type(text.suffix(binding.type)) elements = collections.concat(binding.extended_elements, port.extended_elements) config = cls.attributes(elements) yield from cls.map_binding(definitions, binding, port_type, config)
def test_property_module(self): obj = Definitions() with self.assertRaises(SchemaValueError) as cm: obj.module self.assertEqual("Definitions empty location.", str(cm.exception)) obj.location = "a/b/c/d/foo.services" self.assertEqual("foo.services", obj.module) obj.location = "a/b/c/d/foo.services.wsdl" self.assertEqual("foo.services", obj.module)
def test_property_schemas(self): obj = Definitions() self.assertIsInstance(obj.schemas, Generator) self.assertEqual([], list(obj.schemas)) obj.types = Types() self.assertEqual([], list(obj.schemas)) schemas = [Schema(), Schema] obj.types.schemas.extend(schemas) self.assertEqual(schemas, list(obj.schemas))
def test_map_binding_operation_messages_with_style_rpc( self, mock_build_envelope_class, mock_build_message_class): definitions = Definitions() operation = BindingOperation() port_operation = PortTypeOperation() name = "Add" namespace = "someNS" target = ClassFactory.create() message = ClassFactory.create() style = "rpc" mock_build_message_class.return_value = message mock_build_envelope_class.return_value = target operation.input = BindingMessage() port_operation.input = PortTypeMessage() result = DefinitionsMapper.map_binding_operation_messages( definitions, operation, port_operation, name, style, namespace) self.maxDiff = None self.assertEqual([message, target], list(result)) mock_build_message_class.assert_called_once_with( definitions, port_operation.input) mock_build_envelope_class.assert_called_once_with( definitions, operation.input, port_operation.input, f"{name}_input", style, namespace, )
def test_convert_definitions(self, mock_definitions_map): classes = ClassFactory.list(2) mock_definitions_map.return_value = classes definitions = Definitions(location="foo") self.transformer.convert_definitions(definitions) self.assertEqual(classes, self.transformer.class_map[definitions.location])
def test_map_port( self, mock_find_binding, mock_find_port_type, mock_attributes, mock_map_binding ): definitions = Definitions() service_port = ServicePort(binding="zaa:port", extended=[AnyElement()]) port_type = PortType(name="Calc") binding = Binding( type="zaa:zoo", extended=[AnyElement()], operations=[BindingOperation(name="ADD"), BindingOperation(name="SUB")], ) classes = ClassFactory.list(2) cfg = { "style": "document", "location": "http://endpoint.stub/action", "transport": "public", } mock_find_binding.return_value = binding mock_find_port_type.return_value = port_type mock_map_binding.return_value = classes mock_attributes.return_value = cfg result = DefinitionsMapper.map_port(definitions, service_port) self.assertIsInstance(result, Generator) self.assertEqual(classes, list(result)) mock_find_binding.assert_called_once_with("port") mock_find_port_type.assert_called_once_with("zoo") self.assertEqual(2, len(list(mock_attributes.call_args[0][0]))) self.assertEqual(1, mock_attributes.call_count) mock_map_binding.assert_called_once_with(definitions, binding, port_type, cfg)
def build_envelope_fault( cls, definitions: Definitions, port_type_operation: PortTypeOperation, target: Class, ): """Build inner fault class with default fields.""" ns_map: Dict = {} body = next(inner for inner in target.inner if inner.name == "Body") fault_class = cls.build_inner_class(body, "Fault", target.namespace) detail_attrs: List[Attr] = [] for fault in port_type_operation.faults: message = definitions.find_message(text.suffix(fault.message)) detail_attrs.extend( cls.build_parts_attributes(message.parts, ns_map)) default_fields = ["faultcode", "faultstring", "faultactor"] if detail_attrs: detail = cls.build_inner_class(fault_class, "detail", namespace="") detail.attrs.extend(detail_attrs) else: default_fields.append("detail") collections.prepend( fault_class.attrs, *[ cls.build_attr(f, str(DataType.STRING), native=True, namespace="") for f in default_fields ], )
def test_map_binding_message_parts_with_all_parts( self, mock_find_message, mock_create_message_attributes): definitions = Definitions() message_name = "session" ns_map = {} message = Message( name="session", parts=[ Part(name="token", element="foo:token"), Part(name="messageId", type="id"), Part(name="another", type="id"), ], ) extended = AnyElement(attributes={"message": "{bar}session"}) mock_create_message_attributes.return_value = AttrFactory.list(2) mock_find_message.return_value = message actual = DefinitionsMapper.map_binding_message_parts( definitions, message_name, extended, ns_map) self.assertIsInstance(actual, Generator) self.assertEqual(2, len(list(actual))) mock_find_message.assert_called_once_with("session") mock_create_message_attributes.assert_called_once_with( message.parts, ns_map)
def test_build_envelope_fault_raises_error_if_missing_inner_body(self): target = ClassFactory.create() operation = PortTypeOperation() definitions = Definitions() with self.assertRaises(StopIteration): DefinitionsMapper.build_envelope_fault(definitions, operation, target)
def map_binding_message_parts(cls, definitions: Definitions, message: str, extended: AnyElement, ns_map: Dict) -> Iterator[Attr]: """Find a Message instance and map its parts to attributes according to the the extensible element..""" parts = [] if "part" in extended.attributes: parts.append(extended.attributes["part"]) elif "parts" in extended.attributes: parts.extend(extended.attributes["parts"].split()) if "message" in extended.attributes: message_name = local_name(extended.attributes["message"]) else: message_name = text.suffix(message) definition_message = definitions.find_message(message_name) message_parts = definition_message.parts if parts: message_parts = [ part for part in message_parts if part.name in parts ] yield from cls.build_parts_attributes(message_parts, ns_map)
def test_build_envelope_fault(self): body = ClassFactory.create(qname="Body") target = ClassFactory.create() target.inner.append(body) port_type_operation = PortTypeOperation() definitions = Definitions() DefinitionsMapper.build_envelope_fault(definitions, port_type_operation, target) expected_fault_attr = DefinitionsMapper.build_attr( "Fault", body.inner[0].qname, forward=True, namespace=target.namespace) str_qname = str(DataType.STRING) expected_fault_attrs = [ DefinitionsMapper.build_attr(name, str_qname, native=True, namespace="") for name in ["faultcode", "faultstring", "faultactor", "detail"] ] self.assertEqual(1, len(body.attrs)) self.assertEqual(expected_fault_attr, body.attrs[0]) self.assertEqual(expected_fault_attrs, body.inner[0].attrs)
def test_map_binding(self, mock_attributes, mock_find_operation, mock_map_binding_operation): definitions = Definitions() port_type = PortType(name="Calc") binding = Binding( type="zaa:zoo", operations=[ BindingOperation(name="ADD"), BindingOperation(name="SUB") ], ) port_type_add = PortTypeOperation(name="PortAdd") port_type_sub = PortTypeOperation(name="PortSub") classes = [ ClassFactory.list(2), ClassFactory.list(2), ] mock_map_binding_operation.side_effect = classes mock_find_operation.side_effect = [port_type_add, port_type_sub] mock_attributes.side_effect = [ { "soapAction": "add" }, { "soapAction": "sub" }, ] config = {"foo": "bar"} result = DefinitionsMapper.map_binding(definitions, binding, port_type, config) self.assertIsInstance(result, Generator) self.assertEqual(classes[0] + classes[1], list(result)) mock_find_operation.assert_has_calls( [mock.call("ADD"), mock.call("SUB")]) self.assertEqual(2, mock_attributes.call_count) config_add = {"soapAction": "add", **config} config_sub = {"soapAction": "sub", **config} mock_map_binding_operation.assert_has_calls([ mock.call( definitions, binding.operations[0], port_type_add, config_add, "Calc", ), mock.call( definitions, binding.operations[1], port_type_sub, config_sub, "Calc", ), ])
def test_map_binding_operation(self, mock_operation_namespace, mock_map_binding_operation_messages): definitions = Definitions(location="foo.wsdl", target_namespace="xsdata") operation = BindingOperation(name="Add") operation.ns_map["foo"] = "bar" port_operation = PortTypeOperation() config = {"a": "one", "b": "two", "style": "rpc"} name = "Calc" namespace = "SomeNS" first = ClassFactory.create(qname="some_name_first", meta_name="Envelope") second = ClassFactory.create(qname="some_name_second", meta_name="Envelope") other = ClassFactory.create() service = ClassFactory.create( qname=build_qname("xsdata", "Calc_Add"), status=Status.PROCESSED, tag=Tag.BINDING_OPERATION, module="foo", package=None, ns_map={"foo": "bar"}, attrs=[ DefinitionsMapper.build_attr("a", str(DataType.STRING), native=True, default="one"), DefinitionsMapper.build_attr("b", str(DataType.STRING), native=True, default="two"), DefinitionsMapper.build_attr("style", str(DataType.STRING), native=True, default="rpc"), DefinitionsMapper.build_attr("first", first.qname), DefinitionsMapper.build_attr("second", second.qname), ], ) mock_operation_namespace.return_value = namespace mock_map_binding_operation_messages.return_value = [ first, second, other ] result = DefinitionsMapper.map_binding_operation( definitions, operation, port_operation, config, name) expected = [first, second, other, service] self.assertIsInstance(result, Generator) self.assertEqual(expected, list(result)) mock_operation_namespace.assert_called_once_with(config) mock_map_binding_operation_messages.assert_called_once_with( definitions, operation, port_operation, service.name, "rpc", namespace)
def test_parse_definitions( self, mock_load_resource, mock_definitions_parser, mock_definitions_merge, mock_process_schema, ): def_one = Definitions(imports=[ Import(), Import(location="file://sub.wsdl"), Import(location="file://sub.wsdl"), Import(location="file://types.xsd"), ]) def_two = Definitions() mock_load_resource.side_effect = ["a", "b", None] mock_definitions_parser.side_effect = [def_one, def_two] actual = self.transformer.parse_definitions("main.wsdl", "fooNS") self.assertEqual(def_one, actual) mock_definitions_merge.assert_called_once_with(def_two) mock_process_schema.assert_called_once_with("file://types.xsd")
def test_process_definitions( self, mock_parse_definitions, mock_convert_definitions, mock_convert_schema, ): uris = [ "http://xsdata/services.wsdl", "http://xsdata/abstractServices.wsdl", "http://xsdata/notfound.wsdl", ] fist_def = Definitions(types=Types(schemas=[Schema(), Schema()])) second_def = Definitions(bindings=[Binding()]) mock_parse_definitions.side_effect = [fist_def, second_def, None] self.transformer.process_definitions(uris) mock_convert_schema.assert_has_calls( [mock.call(x) for x in fist_def.schemas]) mock_parse_definitions.assert_has_calls([ mock.call(uris[0], namespace=None), mock.call(uris[1], namespace=None) ]) mock_convert_definitions.assert_called_once_with(fist_def)
def test_build_envelope_fault_with_detail_messages(self): body = ClassFactory.create(qname="Body") target = ClassFactory.create() target.inner.append(body) port_type_operation = PortTypeOperation() port_type_operation.faults.append(PortTypeMessage(message="x:foo")) port_type_operation.faults.append(PortTypeMessage(message="x:bar")) definitions = Definitions() definitions.messages.append( Message(name="foo", parts=[Part(element="fooEl")])) definitions.messages.append( Message(name="bar", parts=[Part(element="barEl")])) DefinitionsMapper.build_envelope_fault(definitions, port_type_operation, target) expected_fault_attr = DefinitionsMapper.build_attr( "Fault", body.inner[0].qname, forward=True, namespace=target.namespace) str_qname = str(DataType.STRING) expected_fault_attrs = [ DefinitionsMapper.build_attr(name, str_qname, native=True, namespace="") for name in ["faultcode", "faultstring", "faultactor"] ] expected_fault_attrs.append( DefinitionsMapper.build_attr("detail", body.inner[0].inner[0].qname, forward=True, namespace="")) expected_fault_detail_attrs = [ DefinitionsMapper.build_attr(name, qname=name, namespace=target.namespace, native=False) for name in ["fooEl", "barEl"] ] self.assertEqual(1, len(body.attrs)) self.assertEqual(expected_fault_attr, body.attrs[0]) self.assertEqual(expected_fault_attrs, body.inner[0].attrs) self.assertEqual(expected_fault_detail_attrs, body.inner[0].inner[0].attrs)
def test_map(self, mock_map_port): classes = [ ClassFactory.list(2), ClassFactory.list(3), ] mock_map_port.side_effect = classes definitions = Definitions() service = Service(ports=[ServicePort() for _ in range(2)]) definitions.services.append(service) result = DefinitionsMapper.map(definitions) self.assertEqual(classes[0] + classes[1], result) mock_map_port.assert_has_calls( [mock.call(definitions, port) for port in service.ports])
def build_message_class(cls, definitions: Definitions, port_type_message: PortTypeMessage) -> Class: """Step 6.2: Build the input/output message class of an rpc style operation.""" message_name = text.suffix(port_type_message.message) definition_message = definitions.find_message(message_name) ns_map = definition_message.ns_map.copy() return Class( qname=build_qname(definitions.target_namespace, message_name), status=Status.PROCESSED, tag=Tag.ELEMENT, module=definitions.module, ns_map=ns_map, attrs=list( cls.build_parts_attributes(definition_message.parts, ns_map)), )
def test_end_definitions(self): parser = DefinitionsParser() definitions = Definitions(imports=[ Import(location="../foo.xsd"), Import(location="bar.xsd") ]) parser.end_definitions(definitions) self.assertEqual("bar.xsd", definitions.imports[1].location) parser.location = "file://a/b/services/parent.wsdl" parser.end_definitions(definitions) self.assertEqual("file://a/b/foo.xsd", definitions.imports[0].location) self.assertEqual("file://a/b/services/bar.xsd", definitions.imports[1].location) # Update only Definitions instances parser.end_definitions("foo")
def test_build_message_class(self, mock_create_message_attributes): message = Message(name="bar", parts=[Part()]) message.ns_map["foo"] = "bar" definitions = Definitions( messages=[message], target_namespace="xsdata", location="foo.wsdl" ) port_type_message = PortTypeMessage(message="foo:bar") attrs = AttrFactory.list(2) mock_create_message_attributes.return_value = attrs actual = DefinitionsMapper.build_message_class(definitions, port_type_message) expected = Class( qname=build_qname("xsdata", "bar"), status=Status.PROCESSED, type=Element, module="foo", ns_map=message.ns_map, attrs=attrs, ) self.assertEqual(expected, actual)
def test_process_definitions( self, mock_parse_definitions, mock_convert_definitions, mock_convert_schema, mock_process_classes, ): uri = "http://xsdata/services.xsd" definitions = Definitions(types=Types(schemas=[Schema(), Schema()])) mock_parse_definitions.return_value = definitions self.transformer.process_definitions(uri) mock_convert_schema.assert_has_calls( [mock.call(x) for x in definitions.schemas] ) mock_parse_definitions.assert_called_once_with(uri, namespace=None) mock_convert_definitions.assert_called_once_with(definitions) mock_process_classes.assert_called_once_with()
def test_build_envelope_class( self, mock_get_or_create_inner_class, mock_map_binding_message_parts, mock_map_port_type_message, ): mock_get_or_create_inner_class.side_effect = mock_create_inner mock_map_binding_message_parts.side_effect = mock_create_attr name = "some_operation_bindings" style = "document" namespace = "xsdata" definitions = Definitions(location="foo.wsdl", target_namespace="bar") port_type_message = PortTypeMessage(message="some_operation") binding_message = BindingMessage( extended=[ AnyElement(qname="body"), AnyElement(qname="header"), AnyElement(qname="header"), ] ) binding_message.ns_map["foo"] = "bar" result = DefinitionsMapper.build_envelope_class( definitions, binding_message, port_type_message, name, style, namespace ) expected = Class( qname=build_qname("bar", name), meta_name="Envelope", type=BindingMessage, module="foo", ns_map={"foo": "bar"}, namespace="xsdata", ) self.assertEqual(2, len(result.inner)) self.assertEqual(1, len(result.inner[0].attrs)) self.assertEqual(2, len(result.inner[1].attrs)) self.assertEqual(0, mock_map_port_type_message.call_count) mock_map_binding_message_parts.assert_has_calls( [ mock.call( definitions, port_type_message.message, binding_message.extended[0], result.inner[0].ns_map, ), mock.call( definitions, port_type_message.message, binding_message.extended[1], result.inner[1].ns_map, ), mock.call( definitions, port_type_message.message, binding_message.extended[2], result.inner[1].ns_map, ), ] ) mock_get_or_create_inner_class.assert_has_calls( [ mock.call(mock.ANY, "Body"), mock.call(mock.ANY, "Header"), mock.call(mock.ANY, "Header"), ] ) result.inner.clear() self.assertEqual(expected, result)
def test_build_envelope_class_with_style_rpc( self, mock_get_or_create_inner_class, mock_map_binding_message_parts, mock_map_port_type_message, ): mock_get_or_create_inner_class.side_effect = mock_create_inner mock_map_binding_message_parts.side_effect = mock_create_attr mock_map_port_type_message.side_effect = mock_create_attr name = "some_operation_bindings" style = "rpc" namespace = "xsdata" definitions = Definitions(location="foo.wsdl", target_namespace="bar") port_type_message = PortTypeMessage(message="some_operation") binding_message = BindingMessage(extended=[ AnyElement(qname="body", attributes={"namespace": "bodyns"}), AnyElement(qname="header"), AnyElement(qname="header"), ]) binding_message.ns_map["foo"] = "bar" result = DefinitionsMapper.build_envelope_class( definitions, binding_message, port_type_message, name, style, namespace) expected = Class( qname=build_qname("bar", name), meta_name="Envelope", tag=Tag.BINDING_MESSAGE, module="foo", ns_map={"foo": "bar"}, namespace="xsdata", ) self.assertEqual(2, len(result.inner)) self.assertEqual(1, len(result.inner[0].attrs)) self.assertEqual(2, len(result.inner[1].attrs)) self.maxDiff = None mock_map_port_type_message.assert_called_once_with( port_type_message, "bodyns") mock_map_binding_message_parts.assert_has_calls([ mock.call( definitions, port_type_message.message, binding_message.extended[1], result.inner[1].ns_map, ), mock.call( definitions, port_type_message.message, binding_message.extended[2], result.inner[1].ns_map, ), ]) mock_get_or_create_inner_class.assert_has_calls([ mock.call(mock.ANY, "Body"), mock.call(mock.ANY, "Header"), mock.call(mock.ANY, "Header"), ]) result.inner.clear() self.assertEqual(expected, result)
def test_map_binding_operation_messages(self, mock_build_envelope_class, mock_build_envelope_fault): definitions = Definitions() operation = BindingOperation() port_operation = PortTypeOperation() name = "Add" namespace = "someNS" target = ClassFactory.create() style = "document" mock_build_envelope_class.return_value = target result = DefinitionsMapper.map_binding_operation_messages( definitions, operation, port_operation, name, style, namespace) self.assertIsInstance(result, Generator) self.assertEqual(0, len(list(result))) operation.input = BindingMessage() port_operation.input = PortTypeMessage() result = DefinitionsMapper.map_binding_operation_messages( definitions, operation, port_operation, name, style, namespace) self.maxDiff = None self.assertEqual([target], list(result)) operation.output = BindingMessage() port_operation.output = PortTypeMessage() result = DefinitionsMapper.map_binding_operation_messages( definitions, operation, port_operation, name, style, namespace) self.assertEqual([target, target], list(result)) mock_build_envelope_class.assert_has_calls([ mock.call( definitions, operation.input, port_operation.input, f"{name}_input", style, namespace, ), mock.call( definitions, operation.input, port_operation.input, f"{name}_input", style, namespace, ), mock.call( definitions, operation.output, port_operation.output, f"{name}_output", style, namespace, ), ]) mock_build_envelope_fault.assert_called_once_with( definitions, port_operation, target)
def test_merge(self): target = Definitions() source = Definitions() source.types = Types() source.messages.append(Message()) source.port_types.append(PortType()) source.bindings.append(Binding()) source.services.append(Service()) source.extended.append(AnyElement()) source_two = copy.deepcopy(source) source_two.types.schemas.append(Schema()) target.merge(source) self.assertEqual(source.types, target.types) self.assertEqual(0, len(target.types.schemas)) self.assertEqual(1, len(target.messages)) self.assertEqual(1, len(target.port_types)) self.assertEqual(1, len(target.bindings)) self.assertEqual(1, len(target.services)) self.assertEqual(1, len(target.extended)) target.merge(source_two) target.merge(Definitions()) self.assertEqual(1, len(target.types.schemas)) self.assertEqual(2, len(target.messages)) self.assertEqual(2, len(target.port_types)) self.assertEqual(2, len(target.bindings)) self.assertEqual(2, len(target.services)) self.assertEqual(2, len(target.extended))