8000 finish testing queues · skyl/twilio-python@66a919d · GitHub
[go: up one dir, main page]

Skip to content

Commit 66a919d

Browse files
committed
finish testing queues
1 parent 5805181 commit 66a919d

File tree

10 files changed

+192
-24
lines changed

10 files changed

+192
-24
lines changed

tests/resources/members_instance.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"call_sid": "CAaaf2e9ded94aba3e57c42a3d55be6ff2", "date_enqueued": "Tue, 07 Aug 2012 22:57:41 +0000", "wait_time": 143, "current_position": 1, "uri": "/2010-04-01/Accounts/ACf5af0ea0c9955b67b39c52fb11ee6e69/Queues/QUe675e1913214346f48a9d2296a8d3788/Members/CAaaf2e9ded94aba3e57c42a3d55be6ff2.json"}

tests/resources/members_list.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"first_page_uri": "/2010-04-01/Accounts/ACf5af0ea0c9955b67b39c52fb11ee6e69/Queues/QUe675e1913214346f48a9d2296a8d3788/Members.json?Page=0&PageSize=50", "num_pages": 1, "previous_page_uri": null, "last_page_uri": "/2010-04-01/Accounts/ACf5af0ea0c9955b67b39c52fb11ee6e69/Queues/QUe675e1913214346f48a9d2296a8d3788/Members.json?Page=0&PageSize=50", "uri": "/2010-04-01/Accounts/ACf5af0ea0c9955b67b39c52fb11ee6e69/Queues/QUe675e1913214346f48a9d2296a8d3788/Members.json", "page_size": 50, "start": 0, "next_page_uri": null, "end": 0, "total": 1, "queue_members": [{"call_sid": "CAaaf2e9ded94aba3e57c42a3d55be6ff2", "date_enqueued": "Tue, 07 Aug 2012 22:57:41 +0000", "wait_time": 124, "current_position": 1, "uri": "/2010-04-01/Accounts/ACf5af0ea0c9955b67b39c52fb11ee6e69/Queues/QUe675e1913214346f48a9d2296a8d3788/Members/CAaaf2e9ded94aba3e57c42a3d55be6ff2.json"}], "page": 0}

tests/resources/queues_instance.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"sid": "QU6e2cd5a7c8074edc8b383a3b198b2f8b", "friendly_name": "CutieQueue", "current_size": null, "average_wait_time": null, "max_size": 100, "date_created": "Tue, 07 Aug 2012 21:08:51 +0000", "date_updated": "Tue, 07 Aug 2012 21:08:51 +0000", "uri": "/2010-04-01/Accounts/ACf5af0ea0c9955b67b39c52fb11ee6e69/Queues/QU6e2cd5a7c8074edc8b383a3b198b2f8b.json"}

tests/resources/queues_list.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"first_page_uri": "/2010-04-01/Accounts/ACf5af0ea0c9955b67b39c52fb11ee6e69/Queues.json?Page=0&PageSize=50", "num_pages": 1, "previous_page_uri": null, "queues": [{"sid": "QU1b9faddec3d54ec18488f86c83019bf0", "friendly_name": "Support", "current_size": 0, "average_wait_time": 0, "max_size": 100, "date_created": "Tue, 07 Aug 2012 21:09:04 +0000", "date_updated": "Tue, 07 Aug 2012 21:09:04 +0000", "uri": "/2010-04-01/Accounts/ACf5af0ea0c9955b67b39c52fb11ee6e69/Queues/QU1b9faddec3d54ec18488f86c83019bf0.json"}, {"sid": "QU6e2cd5a7c8074edc8b383a3b198b2f8b", "friendly_name": "CutieQueue", "current_size": 0, "average_wait_time": 0, "max_size": 100, "date_created": "Tue, 07 Aug 2012 21:08:51 +0000", "date_updated": "Tue, 07 Aug 2012 21:08:51 +0000", "uri": "/2010-04-01/Accounts/ACf5af0ea0c9955b67b39c52fb11ee6e69/Queues/QU6e2cd5a7c8074edc8b383a3b198b2f8b.json"}, {"sid": "QUa8ce40f68d3f41958e2519646d55b989", "friendly_name": "Test1", "current_size": 0, "average_wait_time": 0, "max_size": 64, "date_created": "Tue, 07 Aug 2012 19:09:17 +0000", "date_updated": "Tue, 07 Aug 2012 19:09:17 +0000", "uri": "/2010-04-01/Accounts/ACf5af0ea0c9955b67b39c52fb11ee6e69/Queues/QUa8ce40f68d3f41958e2519646d55b989.json"}], "uri": "/2010-04-01/Accounts/ACf5af0ea0c9955b67b39c52fb11ee6e69/Queues.json", "page_size": 50, "start": 0, "next_page_uri": null, "end": 2, "total": 3, "last_page_uri": "/2010-04-01/Accounts/ACf5af0ea0c9955b67b39c52fb11ee6e69/Queues.json?Page=0&PageSize=50", "page": 0}

tests/test_calls.py

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,6 @@
1111

1212
list_resource = Calls(BASE_URI, AUTH)
1313

14-
@patch("twilio.rest.resources.make_twilio_request")
15-
def test_paging(mock):
16-
resp = create_mock_json("tests/resources/calls_list.json")
17-
mock.return_value = resp
18-
19-
uri = "%s/Calls" % (BASE_URI)
20-
list_resource.list(started=date(2010,12,5))
21-
exp_params = {'StartTime': '2010-12-05'}
22-
23-
mock.assert_called_with("GET", uri, params=exp_params, auth=AUTH)
24-
2514
@patch("twilio.rest.resources.make_twilio_request")
2615
def test_create_call(mock):
2716
resp = create_mock_json("tests/resources/calls_instance.json")

tests/test_queues.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
from mock import patch, Mock
2+
from datetime import date
3+
from mock import patch, Mock
4+
from nose.tools import raises, assert_equals, assert_true
5+
from tools import create_mock_json
6+
from twilio.rest.resources import Queues, Queue
7+
8+
BASE_URI = "https://api.twilio.com/2010-04-01/Accounts/AC123"
9+
ACCOUNT_SID = "AC123"
10+
AUTH = (ACCOUNT_SID, "token")
11+
QUEUE_SID = "QU1b9faddec3d54ec18488f86c83019bf0"
12+
CALL_SID = "CAaaf2e9ded94aba3e57c42a3d55be6ff2"
13+
14+
list_resource = Queues(BASE_URI, AUTH)
15+
instance_resource = Queue(list_resource, QUEUE_SID)
16+
17+
@patch("twilio.rest.resources.make_twilio_request")
18+
def test_queues_list(mock):
19+
resp = create_mock_json("tests/resources/queues_list.json")
20+
mock.return_value = resp
21+
22+
uri = "%s/Queues" % (BASE_URI)
23+
list_resource.list()
24+
25+
mock.assert_called_with("GET", uri, params={}, auth=AUTH)
26+
27+
@patch("twilio.rest.resources.make_twilio_request")
28+
def test_queues_create(mock):
29+
resp = create_mock_json("tests/resources/queues_instance.json")
30+
resp.status_code = 201
31+
mock.return_value = resp
32+
33+
uri = "%s/Queues" % (BASE_URI)
34+
list_resource.create('test', max_size=9001)
35+
36+
mock.assert_called_with("POST", uri,
37+
data={'FriendlyName': 'test', 'MaxSize': 9001},
38+
auth=AUTH)
39+
40+
@patch("twilio.rest.resources.make_twilio_request")
41+
def test_queues_get(mock):
42+
resp = create_mock_json("tests/resources/queues_instance.json")
43+
mock.return_value = resp
44+
45+
uri = "%s/Queues/%s" % (BASE_URI, QUEUE_SID)
46+
r = list_resource.get(QUEUE_SID)
47+
48+
mock.assert_called_with("GET", uri, auth=AUTH)
49+
50+
51+
@patch("twilio.rest.resources.make_twilio_request")
52+
def test_queue_update(mock):
53+
resp = create_mock_json("tests/resources/queues_instance.json")
54+
mock.return_value = resp
55+
56+
uri = "%s/Queues/%s" % (BASE_URI, QUEUE_SID)
57+
r = instance_resource.update(friendly_name='QQ')
58+
59+
mock.assert_called_with("POST", uri, data={'FriendlyName':'QQ'}, auth=AUTH)
60+
61+
62+
@patch("twilio.rest.resources.make_twilio_request")
63+
def test_queue_delete(mock):
64+
resp = create_mock_json("tests/resources/queues_instance.json")
65+
mock.return_value = resp
66+
67+
uri = "%s/Queues/%s" % (BASE_URI, QUEUE_SID)
68+
r = instance_resource.delete()
69+
70+
mock.assert_called_with("DELETE", uri, auth=AUTH)

tests/test_twiml.py

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,11 @@ def improperAppend(self, verb):
2626
self.assertRaises(TwimlException, verb.append, twiml.Reject())
2727
self.assertRaises(TwimlException, verb.append, twiml.Redirect())
2828
self.assertRaises(TwimlException, verb.append, twiml.Dial())
29+
self.assertRaises(TwimlException, verb.append, twiml.Enqueue(""))
30+
self.assertRaises(TwimlException, verb.append, twiml.Queue(""))
31+
self.assertRaises(TwimlException, verb.append, twiml.Leave())
2932
self.assertRaises(TwimlException, verb.append, twiml.Conference(""))
33+
self.assertRaises(TwimlException, verb.append, twiml.Client(""))
3034
self.assertRaises(TwimlException, verb.append, twiml.Sms(""))
3135
self.assertRaises(TwimlException, verb.append, twiml.Pause())
3236

@@ -240,6 +244,20 @@ def testBadAppend(self):
240244
self.improperAppend(twiml.Hangup())
241245

242246

247+
class TestLeave(TwilioTest):
248+
249+
def testLeave(self):
250+
"""convenience: should Hangup to a url via POST"""
251+
r = Response()
252+
r.append(twiml.Leave())
253+
r = self.strip(r)
254+
self.assertEquals(r, '<?xml version="1.0" encoding="UTF-8"?><Response><Leave /></Response>')
255+
256+
def testBadAppend(self):
257+
""" should raise exceptions for wrong appending"""
258+
self.improperAppend(twiml.Leave())
259+
260+
243261
class TestReject(TwilioTest):
244262

245263
def testReject(self):
@@ -338,22 +356,51 @@ def setUp(self):
338356
r = Response()
339357
with r.dial() as dial:
340358
dial.queue("TestQueueAttribute", url="", method='GET')
359+
xml = r.toxml()
360+
361+
#parse twiml XML string with Element Tree and inspect
362+
#structure
363+
tree = ET.fromstring(xml)
364+
self.conf = tree.find(".//Dial/Queue")
365+
366+
def test_conf_text(self):
367+
self.assertEqual(self.conf.text.strip(), "TestQueueAttribute")
368+
369+
def test_conf_waiturl(self):
370+
self.assertEqual(self.conf.get('url'), "")
371+
372+
def test_conf_method(self):
373+
self.assertEqual(self.conf.get('method'), "GET")
374+
375+
376+
class TestEnqueue(TwilioTest):
377+
378+
def setUp(self):
379+
r = Response()
380+
r.enqueue("TestEnqueueAttribute", action="act", method='GET',
381+
wait_url='wait', wait_url_method='POST')
341382
xml = r.toxml()
342383

343384
#parse twiml XML string with Element Tree and inspect
344385
#structure
345386
tree = ET.fromstring(xml)
346-
self.conf = tree.find(".//Dial/Queue")
387+
self.conf = tree.find(".//Enqueue")
347388

348389
def test_conf_text(self):
349-
self.assertEqual(self.conf.text.strip(), "TestQueueAttribute")
390+
self.assertEqual(self.conf.text.strip(), "TestEnqueueAttribute")
350391

351392
def test_conf_waiturl(self):
352-
self.assertEqual(self.conf.get('url'), "")
393+
self.assertEqual(self.conf.get('wait_url'), "wait")
353394

354395
def test_conf_method(self):
355396
self.assertEqual(self.conf.get('method'), "GET")
356397

398+
def test_conf_action(self):
399+
self.assertEqual(self.conf.get('action'), "act")
400+
401+
def test_conf_waitmethod(self):
402+
self.assertEqual(self.conf.get('wait_url_method'), "POST")
403+
357404

358405
class TestDial(TwilioTest):
359406

twilio/rest/__init__.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from twilio.rest.resources import AuthorizedConnectApps
88
from twilio.rest.resources import Calls
99
from twilio.rest.resources import CallerIds
10+
from twilio.rest.resources import Queues
1011
from twilio.rest.resources import ConnectApps
1112
from twilio.rest.resources import Notifications
1213
from twilio.rest.resources import Recordings
@@ -108,7 +109,7 @@ def __init__(self, account=None, token=None, base="https://api.twilio.com",
108109
and be sure to replace the values for the Account SID and auth token with the
109110
values from your Twilio Account at https://www.twilio.com/user/account.
110111
""")
111-
112+
112113
self.base = base
113114
auth = (account, token)
114115
version_uri = "%s/%s" % (base, version)
@@ -126,6 +127,7 @@ def __init__(self, account=None, token=None, base="https://api.twilio.com",
126127
self.sms = Sms(account_uri, auth)
127128
self.phone_numbers = PhoneNumbers(account_uri, auth)
128129
self.conferences = Conferences(account_uri, auth)
130+
self.queues = Queues(account_uri, auth)
129131
self.sandboxes = Sandboxes(account_uri, auth)
130132

131133
self.auth = auth
@@ -138,4 +140,3 @@ def participants(self, conference_sid):
138140
"""
139141
base_uri = "%s/Conferences/%s" % (self.account_uri, conference_sid)
140142
return Participants(base_uri, self.auth)
141-

twilio/rest/resources.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ def update_instance(self, sid, body):
340340< 10000 /code>
Update an InstanceResource via a POST
341341
342342
sid: string -- String identifier for the list resource
343-
body: string -- Dict of items to POST
343+
body: dictionary -- Dict of items to POST
344344
"""
345345
uri = "%s/%s" % (self.uri, sid)
346346
resp, entry = self.request("POST", uri, data=transform_params(body))
@@ -1183,13 +1183,13 @@ def update(self, **kwargs):
11831183
current size results in the queue rejecting incoming
11841184
requests until it shrinks below the new max size
11851185
"""
1186-
return self.parent.update(self.sid, kwargs)
1186+
return self.parent.update_instance(self.name, kwargs)
11871187

11881188
def delete(self):
11891189
"""
11901190
Delete this queue. Can only be run on empty queues.
11911191
"""
1192-
return self.parent.delete(self.sid)
1192+
return self.parent.delete_instance(self.name)
11931193

11941194

11951195
class Queues(ListResource):
@@ -1199,12 +1199,13 @@ class Queues(ListResource):
11991199
def list(self, **kwargs):
12001200
return self.get_instances(kwargs)
12011201

1202-
def create(self, **kwargs):
1202+
def create(self, name, **kwargs):
12031203
""" Create an :class:`Queue` with any of these optional parameters.
1204-
:param friendly_name: A human readable description of the application,
1204+
:param name: A human readable description of the application,
12051205
with maximum length 64 characters.
1206-
:param max_size: The upper limit of calls allowed into the queue
1206+
:param max_size: The limit on calls allowed into the queue (optional)
12071207
"""
1208+
kwargs['friendly_name'] = name
12081209
return self.create_instance(kwargs)
12091210

12101211

@@ -1317,6 +1318,7 @@ class Account(InstanceResource):
13171318
PhoneNumbers,
13181319
Conferences,
13191320
ConnectApps,
1321+
Queues,
13201322
AuthorizedConnectApps,
13211323
]
13221324

twilio/twiml.py

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ def xml(self):
8282

8383
def append(self, verb):
8484
if not self.nestables or verb.name not in self.nestables:
85-
raise TwimlException("%s is not nestable inside %s" % \
85+
raise TwimlException("%s is not nestable inside %s" %
8686
(verb.name, self.name))
8787
self.verbs.append(verb)
8888
return verb
@@ -101,6 +101,8 @@ class Response(Verb):
101101
'Hangup',
102102
'Reject',
103103
'Sms',
104+
'Enqueue',
105+
'Leave'
104106
]
105107

106108
def __init__(self, **kwargs):
@@ -147,6 +149,16 @@ def dial(self, number=None, **kwargs):
147149
:class:`Response` """
148150
return self.append(Dial(number, **kwargs))
149151

152+
def enqueue(self, name, **kwargs):
153+
"""Return a newly created :class:`Enqueue` verb, nested inside this
154+
:class:`Response` """
155+
return self.append(Enqueue(name, **kwargs))
156+
157+
def leave(self, **kwargs):
158+
"""Return a newly created :class:`Leave` verb, nested inside this
159+
:class:`Response` """
160+
return self.append(Leave(**kwargs))
161+
150162
def record(self, **kwargs):
151163
"""Return a newly created :class:`Record` verb, nested inside this
152164
:class:`Response` """
@@ -411,7 +423,23 @@ class Queue(Verb):
411423
412424
:param name: friendly name for the queue
413425
:param url: url to a twiml document that executes after a call is dequeued
414-
and before the call is connected
426+
and before the call is connected
427+
:param method: HTTP method for url GET/POST
428+
"""
429+
GET = 'GET'
430+
POST = 'POST'
431+
432+
def __init__(self, name, **kwargs):
433+
super(Queue, self).__init__(**kwargs)
434+
self.body = name
435+
436+
437+
class Queue(Verb):
438+
"""Specify queue in a nested Dial element.
439+
440+
:param name: friendly name for the queue
441+
:param url: url to a twiml document that executes after a call is dequeued
442+
and before the call is connected
415443
:param method: HTTP method for url GET/POST
416444
"""
417445
GET = 'GET'
@@ -422,6 +450,33 @@ def __init__(self, name, **kwargs):
422450
self.body = name
423451

424452

453+
class Enqueue(Verb):
454+
"""Enqueue the call into a specific queue.
455+
456+
:param name: friendly name for the queue
457+
:param action: url to a twiml document that executes when the call
458+
leaves the queue. When dequeued vial a <Dial> verb,
459+
this url is executed after the bridged parties disconnect
460+
:param method: HTTP method for action GET/POST
461+
:param wait_url: url to a twiml document that executes
462+
while the call is on the queue
463+
:param wait_url_methid: HTTP method for wait_url GET/POST
464+
"""
465+
GET = 'GET'
466+
POST = 'POST'
467+
468+
def __init__(self, name, **kwargs):
469+
super(Enqueue, self).__init__(**kwargs)
470+
self.body = name
471+
472+
473+
class Leave(Verb):
474+
"""Signals the call to leave it's queue
475+
"""
476+
GET = 'GET'
477+
POST = 'POST'
478+
479+
425480
class Record(Verb):
426481
"""Record audio from caller
427482

0 commit comments

Comments
 (0)
0