def test_can_dispatch_good_soap_message(self): handler, handler_state = _echo_handler() dispatcher = SOAPDispatcher(_echo_service(handler)) soap_message = ('<ns1:echoRequest xmlns:ns1="http://soap.example/echo/types">' '<value>foobar</value>' '</ns1:echoRequest>') request_message = self._wrap_with_soap_envelope(soap_message) request = SoapboxRequest(dict(SOAPACTION='echo', REQUEST_METHOD='POST'), request_message) response = dispatcher.dispatch(request) self.assert_is_successful_response(response, handler_state) assert_equals('foobar', handler_state.input_.value) response_document = etree.fromstring(response.http_content) response_xml = etree.tostring(response_document, pretty_print=True) expected_xml = ( b'<ns0:Envelope xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/">\n' b' <ns0:Body>\n' b' <ns0:echoResponse xmlns:ns0="http://soap.example/echo/types">\n' b' <value>foobar</value>\n' b' </ns0:echoResponse>\n' b' </ns0:Body>\n' b'</ns0:Envelope>\n' ) assert_equals(expected_xml, response_xml)
def test_can_dispatch_good_soap_message(self): handler, handler_state = _echo_handler() dispatcher = SOAPDispatcher(_echo_service(handler)) soap_message = ( '<ns1:echoRequest xmlns:ns1="http://soap.example/echo/types">' '<value>foobar</value>' '</ns1:echoRequest>') request_message = self._wrap_with_soap_envelope(soap_message) request = SoapboxRequest( dict(SOAPACTION='echo', REQUEST_METHOD='POST'), request_message) response = dispatcher.dispatch(request) self.assert_is_successful_response(response, handler_state) assert_equals('foobar', handler_state.input_.value) response_document = etree.fromstring(response.http_content) response_xml = etree.tostring(response_document, pretty_print=True) expected_xml = ( b'<ns0:Envelope xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/">\n' b' <ns0:Body>\n' b' <ns0:echoResponse xmlns:ns0="http://soap.example/echo/types">\n' b' <value>foobar</value>\n' b' </ns0:echoResponse>\n' b' </ns0:Body>\n' b'</ns0:Envelope>\n') assert_equals(expected_xml, response_xml)
def test_can_validate_wsa_header(self): service = _echo_service() dispatcher = SOAPDispatcher(service) header = wsa.Header.parsexml( '<Header><Action xmlns="http://www.w3.org/2005/08/addressing">/Action</Action></Header>' ) dispatcher._validate_header(header)
def test_can_reject_malformed_xml_soap_message(self): request = SoapboxRequest(dict(SOAPACTION='echo', REQUEST_METHOD='POST'), 'garbage') dispatcher = SOAPDispatcher(_echo_service()) response = dispatcher.dispatch(request) assert_equals(500, response.http_status_code) assert_equals('text/xml', response.http_headers['Content-Type']) self.assert_is_soap_fault(response, partial_fault_string=u"Start tag expected, '<' not found")
def test_can_reject_invalid_root_tag(self): soap_message = ('<ns0:invalid xmlns:ns0="invalid"/>') request_message = self._wrap_with_soap_envelope(soap_message) request = SoapboxRequest(dict(REQUEST_METHOD='POST'), request_message) dispatcher = SOAPDispatcher(_echo_service()) response = dispatcher.dispatch(request) self.assert_is_soap_fault(response, partial_fault_string="DocumentInvalid")
def test_can_reject_invalid_root_tag(self): soap_message = ('<ns0:invalid xmlns:ns0="invalid"/>') request_message = self._wrap_with_soap_envelope(soap_message) request = SoapboxRequest(dict(REQUEST_METHOD='POST'), request_message) dispatcher = SOAPDispatcher(_echo_service()) response = dispatcher.dispatch(request) self.assert_is_soap_fault(response, partial_fault_string="DocumentInvalid")
def test_can_reject_non_soap_xml_body(self): request = SoapboxRequest(dict(SOAPACTION='echo', REQUEST_METHOD='POST'), '<some>xml</some>') dispatcher = SOAPDispatcher(_echo_service()) # previously this raised an AttributeError due to an unhandled exception response = dispatcher.dispatch(request) assert_equals(500, response.http_status_code) assert_equals('text/xml', response.http_headers['Content-Type']) self.assert_is_soap_fault(response, partial_fault_string=u'Missing SOAP body')
def test_can_reject_invalid_action(self): soap_message = ('<ns1:echoRequest xmlns:ns1="http://soap.example/echo/types">' '<value>foobar</value>' '</ns1:echoRequest>') request_message = self._wrap_with_soap_envelope(soap_message) request = SoapboxRequest(dict(SOAPACTION='invalid', REQUEST_METHOD='POST'), request_message) dispatcher = SOAPDispatcher(_echo_service()) response = dispatcher.dispatch(request) self.assert_is_soap_fault(response, partial_fault_string=u"Invalid soap action 'invalid'")
def test_can_dispatch_requests_based_on_soap_body(self): handler, handler_state = _echo_handler() dispatcher = SOAPDispatcher(_echo_service(handler)) soap_message = ('<ns1:echoRequest xmlns:ns1="http://soap.example/echo/types">' '<value>foobar</value>' '</ns1:echoRequest>') request_message = self._wrap_with_soap_envelope(soap_message) request = SoapboxRequest(dict(SOAPACTION='""', REQUEST_METHOD='POST'), request_message) response = dispatcher.dispatch(request) self.assert_is_successful_response(response, handler_state)
def test_can_handle_empty_output_header(self): handler, handler_state = _echo_handler() dispatcher = SOAPDispatcher(_echo_service(handler, output_header=OutputHeader)) soap_message = ('<tns:echoRequest xmlns:tns="http://soap.example/echo/types">' '<value>foobar</value>' '</tns:echoRequest>') request_message = self._wrap_with_soap_envelope(soap_message) request = SoapboxRequest(dict(SOAPACTION='echo', REQUEST_METHOD='POST'), request_message) response = dispatcher.dispatch(request) self.assert_is_successful_response(response, handler_state)
def test_can_reject_malformed_xml_soap_message(self): request = SoapboxRequest( dict(SOAPACTION='echo', REQUEST_METHOD='POST'), 'garbage') dispatcher = SOAPDispatcher(_echo_service()) response = dispatcher.dispatch(request) assert_equals(500, response.http_status_code) assert_equals('text/xml', response.http_headers['Content-Type']) self.assert_is_soap_fault( response, partial_fault_string=u"Start tag expected, '<' not found")
def test_can_validate_soap_header(self): handler, handler_state = _echo_handler() dispatcher = SOAPDispatcher(_echo_service(handler, input_header=InputHeader)) soap_header = ('<tns:invalid>42</tns:invalid>') soap_message = ('<tns:echoRequest>' '<value>foobar</value>' '</tns:echoRequest>') request_message = self._wrap_with_soap_envelope(soap_message, header=soap_header) request = SoapboxRequest(dict(SOAPACTION='echo', REQUEST_METHOD='POST'), request_message) response = dispatcher.dispatch(request) self.assert_is_soap_fault(response, partial_fault_string="DocumentInvalid")
def test_can_reject_non_soap_xml_body(self): request = SoapboxRequest( dict(SOAPACTION='echo', REQUEST_METHOD='POST'), '<some>xml</some>') dispatcher = SOAPDispatcher(_echo_service()) # previously this raised an AttributeError due to an unhandled exception response = dispatcher.dispatch(request) assert_equals(500, response.http_status_code) assert_equals('text/xml', response.http_headers['Content-Type']) self.assert_is_soap_fault(response, partial_fault_string=u'Missing SOAP body')
def test_can_dispatch_requests_based_on_soap_body(self): handler, handler_state = _echo_handler() dispatcher = SOAPDispatcher(_echo_service(handler)) soap_message = ( '<ns1:echoRequest xmlns:ns1="http://soap.example/echo/types">' '<value>foobar</value>' '</ns1:echoRequest>') request_message = self._wrap_with_soap_envelope(soap_message) request = SoapboxRequest(dict(SOAPACTION='""', REQUEST_METHOD='POST'), request_message) response = dispatcher.dispatch(request) self.assert_is_successful_response(response, handler_state)
def test_can_reject_invalid_action(self): soap_message = ( '<ns1:echoRequest xmlns:ns1="http://soap.example/echo/types">' '<value>foobar</value>' '</ns1:echoRequest>') request_message = self._wrap_with_soap_envelope(soap_message) request = SoapboxRequest( dict(SOAPACTION='invalid', REQUEST_METHOD='POST'), request_message) dispatcher = SOAPDispatcher(_echo_service()) response = dispatcher.dispatch(request) self.assert_is_soap_fault( response, partial_fault_string=u"Invalid soap action 'invalid'")
def test_can_validate_soap_message(self): handler, handler_state = _echo_handler() dispatcher = SOAPDispatcher(_echo_service(handler)) soap_message = ('<ns1:echoRequest xmlns:ns1="http://soap.example/echo/types">' '<invalid>foobar</invalid>' '</ns1:echoRequest>') request_message = self._wrap_with_soap_envelope(soap_message) request = SoapboxRequest(dict(SOAPACTION='echo', REQUEST_METHOD='POST'), request_message) response = dispatcher.dispatch(request) assert_false(handler_state.was_called) self.assert_is_soap_fault(response, partial_fault_string=u"Element 'invalid': This element is not expected. Expected is ( value ).")
def test_can_propagete_custom_input_header(self): handler, handler_state = _echo_handler() dispatcher = SOAPDispatcher(_echo_service(handler, input_header=InputHeader)) soap_header = ('<tns:InputVersion>42</tns:InputVersion>') soap_message = ('<tns:echoRequest>' '<value>foobar</value>' '</tns:echoRequest>') request_message = self._wrap_with_soap_envelope(soap_message, header=soap_header) request = SoapboxRequest(dict(SOAPACTION='echo', REQUEST_METHOD='POST'), request_message) response = dispatcher.dispatch(request) self.assert_is_successful_response(response, handler_state) assert_not_none(handler_state.input_header) self.assertEqual('42', handler_state.input_header.InputVersion)
def test_can_handle_empty_output_header(self): handler, handler_state = _echo_handler() dispatcher = SOAPDispatcher( _echo_service(handler, output_header=OutputHeader)) soap_message = ( '<tns:echoRequest xmlns:tns="http://soap.example/echo/types">' '<value>foobar</value>' '</tns:echoRequest>') request_message = self._wrap_with_soap_envelope(soap_message) request = SoapboxRequest( dict(SOAPACTION='echo', REQUEST_METHOD='POST'), request_message) response = dispatcher.dispatch(request) self.assert_is_successful_response(response, handler_state)
def test_can_validate_soap_header(self): handler, handler_state = _echo_handler() dispatcher = SOAPDispatcher( _echo_service(handler, input_header=InputHeader)) soap_header = ('<tns:invalid>42</tns:invalid>') soap_message = ('<tns:echoRequest>' '<value>foobar</value>' '</tns:echoRequest>') request_message = self._wrap_with_soap_envelope(soap_message, header=soap_header) request = SoapboxRequest( dict(SOAPACTION='echo', REQUEST_METHOD='POST'), request_message) response = dispatcher.dispatch(request) self.assert_is_soap_fault(response, partial_fault_string="DocumentInvalid")
def test_can_use_soap_error_from_handler(self): faulty_handler = _faulty_handler() dispatcher = SOAPDispatcher(_echo_service(handler=faulty_handler)) soap_message = ( '<ns1:echoRequest xmlns:ns1="http://soap.example/echo/types">' '<value>foobar</value>' '</ns1:echoRequest>') request_message = self._wrap_with_soap_envelope(soap_message) request = SoapboxRequest(dict(REQUEST_METHOD='POST'), request_message) response = dispatcher.dispatch(request) assert_equals('text/xml', response.http_headers['Content-Type']) assert_equals(500, response.http_status_code) self.assert_is_soap_fault(response, fault_code='code', partial_fault_string=u'internal data error')
def test_can_propagete_custom_output_header(self): handler, handler_state = _echo_handler() def _handler(request, _input): resp = handler(request, _input) resp.soap_header = OutputHeader(OutputVersion = '42') return resp dispatcher = SOAPDispatcher(_echo_service(_handler, output_header=OutputHeader)) soap_header = ('<tns:InputVersion>42</tns:InputVersion>') soap_message = ('<tns:echoRequest xmlns:tns="http://soap.example/echo/types">' '<value>foobar</value>' '</tns:echoRequest>') request_message = self._wrap_with_soap_envelope(soap_message, header=soap_header) request = SoapboxRequest(dict(SOAPACTION='echo', REQUEST_METHOD='POST'), request_message) response = dispatcher.dispatch(request) self.assert_is_successful_response(response, handler_state) assert_contains(b'<ns0:OutputVersion>42</ns0:OutputVersion>', response.http_content)
def test_can_propagete_custom_input_header(self): handler, handler_state = _echo_handler() dispatcher = SOAPDispatcher( _echo_service(handler, input_header=InputHeader)) soap_header = ('<tns:InputVersion>42</tns:InputVersion>') soap_message = ('<tns:echoRequest>' '<value>foobar</value>' '</tns:echoRequest>') request_message = self._wrap_with_soap_envelope(soap_message, header=soap_header) request = SoapboxRequest( dict(SOAPACTION='echo', REQUEST_METHOD='POST'), request_message) response = dispatcher.dispatch(request) self.assert_is_successful_response(response, handler_state) assert_not_none(handler_state.input_header) self.assertEqual('42', handler_state.input_header.InputVersion)
def test_can_use_soap_error_from_handler(self): faulty_handler = _faulty_handler() dispatcher = SOAPDispatcher(_echo_service(handler=faulty_handler)) soap_message = ('<ns1:echoRequest xmlns:ns1="http://soap.example/echo/types">' '<value>foobar</value>' '</ns1:echoRequest>') request_message = self._wrap_with_soap_envelope(soap_message) request = SoapboxRequest(dict(REQUEST_METHOD='POST'), request_message) response = dispatcher.dispatch(request) assert_equals('text/xml', response.http_headers['Content-Type']) assert_equals(500, response.http_status_code) self.assert_is_soap_fault(response, fault_code='code', partial_fault_string=u'internal data error' )
def test_return_soap_fault_on_exception(self): def handler(request, _input): raise Exception('unexpected exception') service = _echo_service(handler) dispatcher = SOAPDispatcher(service, [ExceptionToSoapFault()]) soap_message = ('<tns:echoRequest xmlns:tns="http://soap.example/echo/types">' '<value>foobar</value>' '</tns:echoRequest>') request_message = self._wrap_with_soap_envelope(soap_message) request = SoapboxRequest(dict(SOAPACTION='echo', REQUEST_METHOD='POST'), request_message) response = dispatcher.dispatch(request) self.assert_is_soap_fault(response, fault_code=service.version.Code.SERVER, partial_fault_string=u'Internal Error', ) assert_equals('text/xml', response.http_headers['Content-Type']) assert_equals(500, response.http_status_code)
def test_can_invalidate_wsa_header(self): service = _echo_service() dispatcher = SOAPDispatcher(service) header = wsa.Header.parsexml( '<Header><Invalid xmlns="http://www.w3.org/2005/08/addressing">/Action</Invalid></Header>' ) self.assertRaises(etree.DocumentInvalid, dispatcher._validate_header, header)
def test_can_validate_soap_message(self): handler, handler_state = _echo_handler() dispatcher = SOAPDispatcher(_echo_service(handler)) soap_message = ( '<ns1:echoRequest xmlns:ns1="http://soap.example/echo/types">' '<invalid>foobar</invalid>' '</ns1:echoRequest>') request_message = self._wrap_with_soap_envelope(soap_message) request = SoapboxRequest( dict(SOAPACTION='echo', REQUEST_METHOD='POST'), request_message) response = dispatcher.dispatch(request) assert_false(handler_state.was_called) self.assert_is_soap_fault( response, partial_fault_string= u"Element 'invalid': This element is not expected. Expected is ( value )." )
def test_return_soap_fault_on_exception(self): def handler(request, _input): raise Exception('unexpected exception') service = _echo_service(handler) dispatcher = SOAPDispatcher(service, [ExceptionToSoapFault()]) soap_message = ( '<tns:echoRequest xmlns:tns="http://soap.example/echo/types">' '<value>foobar</value>' '</tns:echoRequest>') request_message = self._wrap_with_soap_envelope(soap_message) request = SoapboxRequest( dict(SOAPACTION='echo', REQUEST_METHOD='POST'), request_message) response = dispatcher.dispatch(request) self.assert_is_soap_fault( response, fault_code=service.version.Code.SERVER, partial_fault_string=u'Internal Error', ) assert_equals('text/xml', response.http_headers['Content-Type']) assert_equals(500, response.http_status_code)
def test_can_propagete_custom_output_header(self): handler, handler_state = _echo_handler() def _handler(request, _input): resp = handler(request, _input) resp.soap_header = OutputHeader(OutputVersion='42') return resp dispatcher = SOAPDispatcher( _echo_service(_handler, output_header=OutputHeader)) soap_header = ('<tns:InputVersion>42</tns:InputVersion>') soap_message = ( '<tns:echoRequest xmlns:tns="http://soap.example/echo/types">' '<value>foobar</value>' '</tns:echoRequest>') request_message = self._wrap_with_soap_envelope(soap_message, header=soap_header) request = SoapboxRequest( dict(SOAPACTION='echo', REQUEST_METHOD='POST'), request_message) response = dispatcher.dispatch(request) self.assert_is_successful_response(response, handler_state) assert_contains(b'<ns0:OutputVersion>42</ns0:OutputVersion>', response.http_content)
def test_wsgi(self): service = _echo_service() dispatcher = SOAPDispatcher(service) app = WsgiSoapApplication(dispatcher) class StartResponse(): self.code = None self.headers = None def __call__(self, code, headers): self.code = code self.headers = headers start_response = StartResponse() soap_message = ( b'<?xml version="1.0" encoding="UTF-8"?>' b'<senv:Envelope xmlns:senv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tns="http://soap.example/echo/types">' b'<senv:Body>' b'<ns1:echoRequest xmlns:ns1="http://soap.example/echo/types">' b'<value>foobar</value>' b'</ns1:echoRequest>' b'</senv:Body>' b'</senv:Envelope>') response_xml = b''.join( app( { 'SOAPACTION': 'echo', 'PATH_INFO': '/service', 'CONTENT_LENGTH': len(soap_message), 'QUERY_STRING': '', 'SERVER_NAME': 'localhost', 'SERVER_PORT': '7000', 'REQUEST_METHOD': 'POST', 'wsgi.url_scheme': 'http', 'wsgi.input': io.BytesIO(soap_message), }, start_response)) dict_headers = dict(start_response.headers) expected_xml = ( b'<ns0:Envelope xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/">\n' b' <ns0:Body>\n' b' <ns0:echoResponse xmlns:ns0="http://soap.example/echo/types">\n' b' <value>foobar</value>\n' b' </ns0:echoResponse>\n' b' </ns0:Body>\n' b'</ns0:Envelope>\n') self.assertEqual(expected_xml, response_xml) self.assertEqual(WsgiSoapApplication.HTTP_200, start_response.code) self.assertEqual('text/xml', dict_headers['Content-Type'])
def test_can_validate_wsa_header(self): service = _echo_service() dispatcher = SOAPDispatcher(service) header = wsa.Header.parsexml('<Header><Action xmlns="http://www.w3.org/2005/08/addressing">/Action</Action></Header>') dispatcher._validate_header(header)