def test_stop_sms_notification(self): """ `ParlayXClient.stop_sms_notification` performs a SOAP request to the remote ParlayX notification endpoint indicating that delivery and receipt notifications for a particular service activation number can be deactivated. """ client = self._make_client( MockResponse.build( http.OK, NOTIFICATION_MANAGER_NS.stopSmsNotificationResponse)) client._now = partial(datetime, 2013, 6, 18, 10, 59, 33) self.successResultOf(client.stop_sms_notification()) self.assertEqual(1, len(self.requests)) self.assertEqual('notification', self.requests[0][0]) body, header = unwrap_soap_envelope(fromstring(self.requests[0][1])) self.assertEqual( { str(NOTIFICATION_MANAGER_NS.stopSmsNotification): { 'correlator': client._service_correlator } }, element_to_dict( elemfind(body, NOTIFICATION_MANAGER_NS.stopSmsNotification))) self.assertEqual( { str(PARLAYX_HEAD_NS.RequestSOAPHeader): { str(PARLAYX_HEAD_NS.serviceId): 'service_id', str(PARLAYX_HEAD_NS.spId): 'user', str(PARLAYX_HEAD_NS.spPassword): '1f2e67e642b16f6623459fa76dc3894f', str(PARLAYX_HEAD_NS.timeStamp): '20130618105933' } }, element_to_dict(elemfind(header, PARLAYX_HEAD_NS.RequestSOAPHeader)))
def test_render_exceptions(self): """ `SmsNotificationService.render_POST` logs any exceptions that occur during processing and writes a SOAP fault back to the request. """ def process(*a, **kw): raise ValueError('What is this') service = SmsNotificationService(None, None) service.process = process request = DummyRequest([]) request.content = StringIO(tostring(soap_envelope('hello'))) d = request.notifyFinish() service.render_POST(request) self.successResultOf(d) self.assertEqual(http.INTERNAL_SERVER_ERROR, request.responseCode) failures = self.flushLoggedErrors(ValueError) self.assertEqual(1, len(failures)) self.assertEqual( {str(SOAP_ENV.Envelope): { str(SOAP_ENV.Body): { str(SOAP_ENV.Fault): { 'faultcode': 'soapenv:Server', 'faultstring': 'What is this'}}}}, element_to_dict(fromstring(''.join(request.written))))
def test_namespaced_attributes(self): """ XML attributes that are `QualifiedName` instances or use Clark notation produce namespaced XML element attributes. """ ns = Namespace('http://example.com', 'ex') attrib = {ns.key: 'value'} self.assertEqual( {'{http://example.com}tag': { '@{http://example.com}key': 'value'}}, element_to_dict(ns.tag(attrib))) attrib = {'{http://example.com}key': 'value'} self.assertEqual( {'{http://example.com}tag': { '@{http://example.com}key': 'value'}}, element_to_dict(ns.tag(attrib)))
def test_render_soap_fault(self): """ `SmsNotificationService.render_POST` logs any exceptions that occur during processing and writes a SOAP fault back to the request. If the logged exception is a `SoapFault` its ``to_element`` method is invoked to serialize the fault. """ service = SmsNotificationService(None, None) service.process = lambda *a, **kw: L.done() request = DummyRequest([]) request.content = StringIO(tostring(L.hello())) d = request.notifyFinish() service.render_POST(request) self.successResultOf(d) self.assertEqual(http.INTERNAL_SERVER_ERROR, request.responseCode) failures = self.flushLoggedErrors(SoapFault) self.assertEqual(1, len(failures)) self.assertEqual( {str(SOAP_ENV.Envelope): { str(SOAP_ENV.Body): { str(SOAP_ENV.Fault): { 'faultcode': 'soapenv:Client', 'faultstring': 'Malformed SOAP request'}}}}, element_to_dict(fromstring(''.join(request.written))))
def test_render_exceptions(self): """ `SmsNotificationService.render_POST` logs any exceptions that occur during processing and writes a SOAP fault back to the request. """ def process(*a, **kw): raise ValueError('What is this') service = SmsNotificationService(None, None) service.process = process request = DummyRequest([]) request.content = StringIO(tostring(soap_envelope('hello'))) d = request.notifyFinish() service.render_POST(request) self.successResultOf(d) self.assertEqual(http.INTERNAL_SERVER_ERROR, request.responseCode) failures = self.flushLoggedErrors(ValueError) self.assertEqual(1, len(failures)) self.assertEqual( { str(SOAP_ENV.Envelope): { str(SOAP_ENV.Body): { str(SOAP_ENV.Fault): { 'faultcode': 'soapenv:Server', 'faultstring': 'What is this' } } } }, element_to_dict(fromstring(''.join(request.written))))
def test_render_soap_fault(self): """ `SmsNotificationService.render_POST` logs any exceptions that occur during processing and writes a SOAP fault back to the request. If the logged exception is a `SoapFault` its ``to_element`` method is invoked to serialize the fault. """ service = SmsNotificationService(None, None) service.process = lambda *a, **kw: L.done() request = DummyRequest([]) request.content = StringIO(tostring(L.hello())) d = request.notifyFinish() service.render_POST(request) self.successResultOf(d) self.assertEqual(http.INTERNAL_SERVER_ERROR, request.responseCode) failures = self.flushLoggedErrors(SoapFault) self.assertEqual(1, len(failures)) self.assertEqual( { str(SOAP_ENV.Envelope): { str(SOAP_ENV.Body): { str(SOAP_ENV.Fault): { 'faultcode': 'soapenv:Client', 'faultstring': 'Malformed SOAP request' } } } }, element_to_dict(fromstring(''.join(request.written))))
def test_namespaced_attributes(self): """ XML attributes that are `QualifiedName` instances or use Clark notation produce namespaced XML element attributes. """ ns = Namespace('http://example.com', 'ex') attrib = {ns.key: 'value'} self.assertEqual( {'{http://example.com}tag': { '@{http://example.com}key': 'value' }}, element_to_dict(ns.tag(attrib))) attrib = {'{http://example.com}key': 'value'} self.assertEqual( {'{http://example.com}tag': { '@{http://example.com}key': 'value' }}, element_to_dict(ns.tag(attrib)))
def test_empty(self): """ An empty element produces a ``None`` value keyed against its tag name. """ self.assertEqual( {'root': None}, element_to_dict(L.root()))
def test_empty_attributes(self): """ An element containing only attributes, and no content, has its attributes, prefixed with an ``@`` keyed against its tag name. """ self.assertEqual({'root': { '@attr': 'value' }}, element_to_dict(L.root(attr='value')))
def test_empty_attributes(self): """ An element containing only attributes, and no content, has its attributes, prefixed with an ``@`` keyed against its tag name. """ self.assertEqual( {'root': {'@attr': 'value'}}, element_to_dict(L.root(attr='value')))
def test_text(self): """ An element containing only text content, has its text keyed against its tag name. """ self.assertEqual( {'root': 'hello'}, element_to_dict(L.root('hello')))
def test_text_attributes(self): """ An element containing attributes and text content, has its attributes, prefixed with an ``@`` keyed against its tag name and its text keyed against ``#text``. """ self.assertEqual( {'root': {'#text': 'hello', '@attr': 'value'}}, element_to_dict(L.root('hello', attr='value')))
def test_children_multiple(self): """ Multiple child elements with the same tag name are coalesced into a ``list``. """ self.assertEqual( {'root': {'child': [{'@attr': 'value'}, 'hello']}}, element_to_dict( L.root(L.child(attr='value'), L.child('hello'))))
def test_children_text(self): """ Child elements are recursively nested. An element containing only text content, has its text keyed against its tag name. """ self.assertEqual({'root': { 'child': 'hello' }}, element_to_dict(L.root(L.child('hello'))))
def test_children_multiple(self): """ Multiple child elements with the same tag name are coalesced into a ``list``. """ self.assertEqual({'root': { 'child': [{ '@attr': 'value' }, 'hello'] }}, element_to_dict(L.root(L.child(attr='value'), L.child('hello'))))
def test_text_attributes(self): """ An element containing attributes and text content, has its attributes, prefixed with an ``@`` keyed against its tag name and its text keyed against ``#text``. """ self.assertEqual({'root': { '#text': 'hello', '@attr': 'value' }}, element_to_dict(L.root('hello', attr='value')))
def test_send_sms(self): """ `ParlayXClient.send_sms` performs a SOAP request to the remote ParlayX send endpoint to deliver a message via SMS. """ client = self._make_client( MockResponse.build( http.OK, SEND_NS.sendSmsResponse(SEND_NS.result('reference')))) client._now = partial(datetime, 2013, 6, 18, 10, 59, 33) response = self.successResultOf( client.send_sms('+27117654321', 'content', 'message_id', 'linkid')) self.assertEqual('reference', response) self.assertEqual(1, len(self.requests)) self.assertEqual('send', self.requests[0][0]) body, header = unwrap_soap_envelope(fromstring(self.requests[0][1])) self.assertEqual( { str(SEND_NS.sendSms): { str(SEND_NS.addresses): 'tel:27117654321', str(SEND_NS.message): 'content', str(SEND_NS.receiptRequest): { 'correlator': 'message_id', 'endpoint': 'endpoint', 'interfaceName': 'SmsNotification' } } }, element_to_dict(elemfind(body, SEND_NS.sendSms))) self.assertEqual( { str(PARLAYX_HEAD_NS.RequestSOAPHeader): { str(PARLAYX_HEAD_NS.serviceId): 'service_id', str(PARLAYX_HEAD_NS.spId): 'user', str(PARLAYX_HEAD_NS.spPassword): '1f2e67e642b16f6623459fa76dc3894f', str(PARLAYX_HEAD_NS.timeStamp): '20130618105933', str(PARLAYX_HEAD_NS.linkid): 'linkid', str(PARLAYX_HEAD_NS.OA): 'tel:27117654321' } }, element_to_dict(elemfind(header, PARLAYX_HEAD_NS.RequestSOAPHeader)))
def test_children_text(self): """ Child elements are recursively nested. An element containing only text content, has its text keyed against its tag name. """ self.assertEqual( {'root': {'child': 'hello'}}, element_to_dict( L.root(L.child('hello'))))
def test_children_attributes(self): """ Child elements are recursively nested. An element containing only attributes, and no content, has its attributes, prefixed with an ``@`` keyed against its tag name. """ self.assertEqual( {'root': {'child': {'@attr': 'value'}}}, element_to_dict( L.root(L.child(attr='value'))))
def test_children_attributes(self): """ Child elements are recursively nested. An element containing only attributes, and no content, has its attributes, prefixed with an ``@`` keyed against its tag name. """ self.assertEqual({'root': { 'child': { '@attr': 'value' } }}, element_to_dict(L.root(L.child(attr='value'))))
def test_to_element_no_detail(self): """ `SoapFault.to_element` serializes the fault to a SOAP ``Fault`` ElementTree element, omitting the ``detail`` element if `SoapFault.detail` is None. """ fault = SoapFault.from_element(_make_fault( 'soapenv:Client', 'message', 'actor')) self.assertEqual( {str(SOAP_ENV.Fault): { 'faultcode': fault.code, 'faultstring': fault.string, 'faultactor': fault.actor}}, element_to_dict(fault.to_element()))
def test_to_element_no_detail(self): """ `SoapFault.to_element` serializes the fault to a SOAP ``Fault`` ElementTree element, omitting the ``detail`` element if `SoapFault.detail` is None. """ fault = SoapFault.from_element( _make_fault('soapenv:Client', 'message', 'actor')) self.assertEqual( { str(SOAP_ENV.Fault): { 'faultcode': fault.code, 'faultstring': fault.string, 'faultactor': fault.actor } }, element_to_dict(fault.to_element()))
def test_to_element(self): """ `SoapFault.to_element` serializes the fault to a SOAP ``Fault`` ElementTree element. """ detail = L.ToyFaultDetail(L.foo('a'), L.bar('b')) fault = SoapFault.from_element(_make_fault( 'soapenv:Client', 'message', 'actor', detail=detail)) self.assertEqual( {str(SOAP_ENV.Fault): { 'faultcode': fault.code, 'faultstring': fault.string, 'faultactor': fault.actor, 'detail': { 'ToyFaultDetail': {'foo': 'a', 'bar': 'b'}}}}, element_to_dict(fault.to_element()))
def test_namespaced(self): """ `element_to_dict` supports namespaced element names and namespaced attributes. """ ns = Namespace('http://example.com', 'ex') self.assertEqual( {str(ns.root): { 'child': [ {'@' + str(ns.attr): 'value'}, {'@attr2': 'value2', '#text': 'hello'}, 'world']}}, element_to_dict( ns.root( L.child({ns.attr: 'value'}), L.child('hello', attr2='value2'), L.child('world'))))
def test_render(self): """ `SmsNotificationService.render_POST` parses a SOAP request and dispatches it to `SmsNotificationService.process` for processing. """ service = SmsNotificationService(None, None) service.process = lambda *a, **kw: L.done() request = DummyRequest([]) request.content = StringIO(tostring(soap_envelope('hello'))) d = request.notifyFinish() service.render_POST(request) self.successResultOf(d) self.assertEqual(http.OK, request.responseCode) self.assertEqual( {str(SOAP_ENV.Envelope): { str(SOAP_ENV.Body): { 'done': None}}}, element_to_dict(fromstring(''.join(request.written))))
def test_render(self): """ `SmsNotificationService.render_POST` parses a SOAP request and dispatches it to `SmsNotificationService.process` for processing. """ service = SmsNotificationService(None, None) service.process = lambda *a, **kw: L.done() request = DummyRequest([]) request.content = StringIO(tostring(soap_envelope('hello'))) d = request.notifyFinish() service.render_POST(request) self.successResultOf(d) self.assertEqual(http.OK, request.responseCode) self.assertEqual( {str(SOAP_ENV.Envelope): { str(SOAP_ENV.Body): { 'done': None } }}, element_to_dict(fromstring(''.join(request.written))))
def test_namespaced(self): """ `element_to_dict` supports namespaced element names and namespaced attributes. """ ns = Namespace('http://example.com', 'ex') self.assertEqual( { str(ns.root): { 'child': [{ '@' + str(ns.attr): 'value' }, { '@attr2': 'value2', '#text': 'hello' }, 'world'] } }, element_to_dict( ns.root(L.child({ns.attr: 'value'}), L.child('hello', attr2='value2'), L.child('world'))))
def test_to_element(self): """ `SoapFault.to_element` serializes the fault to a SOAP ``Fault`` ElementTree element. """ detail = L.ToyFaultDetail(L.foo('a'), L.bar('b')) fault = SoapFault.from_element( _make_fault('soapenv:Client', 'message', 'actor', detail=detail)) self.assertEqual( { str(SOAP_ENV.Fault): { 'faultcode': fault.code, 'faultstring': fault.string, 'faultactor': fault.actor, 'detail': { 'ToyFaultDetail': { 'foo': 'a', 'bar': 'b' } } } }, element_to_dict(fault.to_element()))
def test_empty(self): """ An empty element produces a ``None`` value keyed against its tag name. """ self.assertEqual({'root': None}, element_to_dict(L.root()))
def test_text(self): """ An element containing only text content, has its text keyed against its tag name. """ self.assertEqual({'root': 'hello'}, element_to_dict(L.root('hello')))