diff --git a/bandwidth/models/bxml/verbs/__init__.py b/bandwidth/models/bxml/verbs/__init__.py index 57902f63..63bf867d 100644 --- a/bandwidth/models/bxml/verbs/__init__.py +++ b/bandwidth/models/bxml/verbs/__init__.py @@ -11,6 +11,7 @@ from .phone_number import PhoneNumber from .play_audio import PlayAudio from .record import Record +from .refer import Refer from .redirect import Redirect from .resume_recording import ResumeRecording from .ring import Ring diff --git a/bandwidth/models/bxml/verbs/refer.py b/bandwidth/models/bxml/verbs/refer.py new file mode 100644 index 00000000..91ba6c2d --- /dev/null +++ b/bandwidth/models/bxml/verbs/refer.py @@ -0,0 +1,59 @@ +""" +refer.py + +Bandwidth's Refer BXML verb + +@copyright Bandwidth INC +""" +from ..nestable_verb import NestableVerb +from .sip_uri import SipUri + + +class Refer(NestableVerb): + + def __init__( + self, sip_uri: SipUri, + refer_complete_url: str=None, refer_complete_method: str=None, + tag: str=None + ): + """Initialize a verb + + The verb sends a SIP REFER to the remote endpoint, asking it + to redirect the call to a new SIP URI. Unlike , a successful + REFER terminates the call on Bandwidth's side: the remote endpoint + redirects away from Bandwidth entirely. This is a SIP protocol + property, not a Bandwidth design choice. As a result, BXML returned in + response to the referComplete callback is only meaningful for failure + handling - there is no live call to act on after success. + + Args: + sip_uri (SipUri): The SIP URI to refer the call to. Required. + Exactly one child element is allowed. This is the + same SipUri model used by . + refer_complete_url (str, optional): URL to send the Refer Complete + event to when the REFER flow finishes (success or failure). + May be a relative URL. Defaults to None. + refer_complete_method (str, optional): The HTTP method to use for + the request to referCompleteUrl. GET or POST. Default value + is POST. Defaults to None. + tag (str, optional): A custom string that will be sent with this + and all future callbacks unless overwritten by a future tag + attribute or cleared. May be cleared by setting tag="". Max + length 256 characters. Defaults to None. + """ + self.sip_uri = sip_uri + self.refer_complete_url = refer_complete_url + self.refer_complete_method = refer_complete_method + self.tag = tag + super().__init__( + tag="Refer", + nested_verbs=[self.sip_uri] + ) + + @property + def _attributes(self): + return { + "referCompleteUrl": self.refer_complete_url, + "referCompleteMethod": self.refer_complete_method, + "tag": self.tag + } diff --git a/bandwidth/models/bxml/verbs/sip_uri.py b/bandwidth/models/bxml/verbs/sip_uri.py index e52dbcc5..fbadf02e 100644 --- a/bandwidth/models/bxml/verbs/sip_uri.py +++ b/bandwidth/models/bxml/verbs/sip_uri.py @@ -18,6 +18,8 @@ def __init__( ): """Initialize a verb + This SipUri is shared between the and verbs. + Args: uri (str): A SIP URI to transfer the call to (e.g. sip:user@server.com) uui (str, optional): he value of the User-To-User header to send within the initial INVITE. Must include the encoding parameter as specified in RFC 7433. Only base64 and jwt encoding are currently allowed. This value, including the encoding specifier, may not exceed 256 characters. Defaults to None. diff --git a/test/unit/models/bxml/test_refer.py b/test/unit/models/bxml/test_refer.py new file mode 100644 index 00000000..e49a7c88 --- /dev/null +++ b/test/unit/models/bxml/test_refer.py @@ -0,0 +1,44 @@ +""" +test_refer.py + +Unit tests for the BXML verb + +@copyright Bandwidth Inc. +""" +import unittest + +from bandwidth.models.bxml import Refer, SipUri, Verb, NestableVerb + + +class TestRefer(unittest.TestCase): + + def setUp(self): + self.sip_uri = SipUri(uri="sip:alice@atlanta.example.com") + self.refer = Refer( + sip_uri=self.sip_uri, + refer_complete_url="https://example.com/handleRefer", + refer_complete_method="POST", + tag="test" + ) + + def test_instance(self): + assert isinstance(self.refer, Refer) + assert isinstance(self.refer, NestableVerb) + assert isinstance(self.refer, Verb) + + def test_to_bxml(self): + expected = 'sip:alice@atlanta.example.com' + assert expected == self.refer.to_bxml() + + def test_minimal(self): + minimal_refer = Refer(sip_uri=SipUri(uri="sip:bob@example.com")) + expected = 'sip:bob@example.com' + assert expected == minimal_refer.to_bxml() + + def test_shares_sip_uri_with_transfer(self): + """Refer uses the same SipUri model as Transfer, including its + transfer-flavored attributes if the caller sets them.""" + sip_uri = SipUri(uri="sip:alice@atlanta.example.com", uui="test") + refer = Refer(sip_uri=sip_uri) + expected = 'sip:alice@atlanta.example.com' + assert expected == refer.to_bxml()