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)