Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions bandwidth/models/bxml/verbs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
59 changes: 59 additions & 0 deletions bandwidth/models/bxml/verbs/refer.py
Original file line number Diff line number Diff line change
@@ -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 <Refer> verb

The <Refer> verb sends a SIP REFER to the remote endpoint, asking it
to redirect the call to a new SIP URI. Unlike <Transfer>, 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 <SipUri> child element is allowed. This is the
same SipUri model used by <Transfer>.
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
}
2 changes: 2 additions & 0 deletions bandwidth/models/bxml/verbs/sip_uri.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ def __init__(
):
"""Initialize a <SipUri> verb

This SipUri is shared between the <Transfer> and <Refer> 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.
Expand Down
44 changes: 44 additions & 0 deletions test/unit/models/bxml/test_refer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"""
test_refer.py

Unit tests for the <Refer> 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 = '<Refer referCompleteUrl="https://example.com/handleRefer" referCompleteMethod="POST" tag="test"><SipUri>sip:alice@atlanta.example.com</SipUri></Refer>'
assert expected == self.refer.to_bxml()

def test_minimal(self):
minimal_refer = Refer(sip_uri=SipUri(uri="sip:bob@example.com"))
expected = '<Refer><SipUri>sip:bob@example.com</SipUri></Refer>'
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 = '<Refer><SipUri uui="test">sip:alice@atlanta.example.com</SipUri></Refer>'
assert expected == refer.to_bxml()