Skip to content

Commit a2a19ff

Browse files
DX-2684
1 parent 7da8e35 commit a2a19ff

File tree

3 files changed

+169
-4
lines changed

3 files changed

+169
-4
lines changed

.github/workflows/test.yaml

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ jobs:
1313
strategy:
1414
matrix:
1515
os: [windows-2022, windows-2019, ubuntu-18.04, ubuntu-20.04]
16-
python-version: [3.6, 3.7, 3.8, 3.9]
16+
python-version: [3.6, 3.7, 3.8, 3.9, 3.10]
1717
steps:
1818
- name: Checkout
1919
uses: actions/checkout@v2
@@ -24,17 +24,24 @@ jobs:
2424
python-version: ${{ matrix.python-version }}
2525

2626
- name: Install Packages
27-
run: pip install -r requirements_dev.txt
27+
run: |
28+
pip install -r requirements.txt
29+
pip install -r test-requirements.txt
2830
2931
- name: Test
3032
env:
3133
BW_ACCOUNT_ID: ${{ secrets.BW_ACCOUNT_ID }}
3234
BW_USERNAME: ${{ secrets.BW_USERNAME }}
3335
BW_PASSWORD: ${{ secrets.BW_PASSWORD }}
36+
BW_USERNAME_FORBIDDEN: ${{ secrets.BW_USERNAME_FORBIDDEN }}
37+
BW_PASSWORD_FORBIDDEN: ${{ secrets.BW_PASSWORD_FORBIDDEN }}
3438
BW_VOICE_APPLICATION_ID: ${{ secrets.BW_VOICE_APPLICATION_ID }}
3539
BW_MESSAGING_APPLICATION_ID: ${{ secrets.BW_MESSAGING_APPLICATION_ID }}
3640
BW_NUMBER: ${{ secrets.BW_NUMBER }}
3741
USER_NUMBER: ${{ secrets.USER_NUMBER }}
42+
VZW_NUMBER: ${{ secrets.VZW_NUMBER }}
43+
ATT_NUMBER: ${{ secrets.ATT_NUMBER }}
44+
T_MOBILE_NUMBER: ${{ secrets.T_MOBILE_NUMBER }}
3845
BASE_CALLBACK_URL: ${{ secrets.BASE_CALLBACK_URL }}
3946
run: pytest
4047

test/integration/test_calls.py

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
"""
2+
Integration test for Bandwidth's Voice Voice Calls API
3+
"""
4+
5+
import os
6+
import json
7+
import time
8+
import unittest
9+
10+
import bandwidth
11+
from bandwidth.api import calls_api
12+
from bandwidth.model.create_call import CreateCall
13+
from bandwidth.model.create_call_response import CreateCallResponse
14+
from bandwidth.model.call_callback import CallCallback
15+
from bandwidth.model.call_direction_enum import CallDirectionEnum
16+
from bandwidth.model.call_state_enum import CallStateEnum
17+
from bandwidth.model.call_state import CallState
18+
from bandwidth.model.update_call import UpdateCall
19+
from bandwidth.model.voice_api_error import VoiceApiError
20+
from bandwidth.exceptions import UnauthorizedException, ForbiddenException
21+
22+
try:
23+
BW_USERNAME = os.environ["BW_USERNAME"]
24+
BW_PASSWORD = os.environ["BW_PASSWORD"]
25+
BW_ACCOUNT_ID = os.environ["BW_ACCOUNT_ID"]
26+
BW_VOICE_APPLICATION_ID = os.environ["BW_VOICE_APPLICATION_ID"]
27+
BASE_CALLBACK_URL = os.environ["BASE_CALLBACK_URL"]
28+
BW_NUMBER = os.environ["BW_NUMBER"]
29+
USER_NUMBER = os.environ["USER_NUMBER"]
30+
31+
except KeyError as e:
32+
raise Exception("Environmental variables not found")
33+
34+
class CallsIntegration(unittest.TestCase):
35+
"""Voice Calls API integration test"""
36+
37+
38+
def setUp(self):
39+
configuration = bandwidth.Configuration(
40+
username = os.environ['BW_USERNAME'],
41+
password = os.environ['BW_PASSWORD'],
42+
)
43+
api_client = bandwidth.ApiClient(configuration)
44+
self.api_instance = calls_api.CallsApi(api_client)
45+
self.account_id = os.environ['BW_ACCOUNT_ID']
46+
47+
def tearDown(self):
48+
pass
49+
50+
def testSuccessfulCalls(self):
51+
52+
# Make a CreateCall body and assign the appropriate params
53+
answer_url = BASE_CALLBACK_URL
54+
call_body = CreateCall(to=USER_NUMBER, _from=BW_NUMBER, application_id=BW_VOICE_APPLICATION_ID, answer_url=answer_url)
55+
56+
57+
# Creating the call
58+
create_call_response: CreateCallResponse = self.calls_api_instance.create_call(BW_ACCOUNT_ID, call_body)
59+
60+
# Response Verification
61+
assert len(create_call_response.call_id) == 47 # assert request created and id matches expected length (47)
62+
assert create_call_response.account_id == BW_ACCOUNT_ID
63+
assert create_call_response.application_id == BW_VOICE_APPLICATION_ID
64+
assert create_call_response.to == USER_NUMBER
65+
assert create_call_response._from == BW_NUMBER
66+
assert create_call_response.call_url == "https://voice.bandwidth.com/api/v2/accounts/" + \
67+
BW_ACCOUNT_ID + "/calls/" + create_call_response.call_id
68+
69+
call_id = create_call_response.call_id
70+
71+
time.sleep(30)
72+
73+
#GET call state information
74+
75+
get_call_response: CallState(BW_ACCOUNT_ID, call_id)
76+
77+
#Verification of Call State
78+
assert len(get_call_response.call_id) == 47 # assert request created and id matches expected length (47)
79+
80+
#GET call state information on bad callID to test error
81+
82+
# Update Call with redirect
83+
84+
#Update BXML directly
85+
86+
# Test with wrong BXML
87+
88+
#retry Create Call with using the wrong Voice Application ID
89+
90+
#retry Create Call with the wrong Account ID
91+
92+
def testFailedCall(self):
93+
"""Calls API with bad data to force an error"""
94+
with self.assertRaises(bandwidth.ApiException) as context:
95+
lookup_request = LookupRequest(
96+
tns=[
97+
'not a number',
98+
],
99+
)
100+
self.api_instance.create_lookup(self.account_id, lookup_request)
101+
102+
self.assertIs(type(context.exception.status), int)
103+
self.assertIs(type(context.exception.body), str)
104+
105+
# initialize TnLookupRequestError model
106+
error = TnLookupRequestError(message=(json.loads(context.exception.body))['message'])
107+
self.assertIs(type(error), TnLookupRequestError)
108+
109+
110+
def testUnauthorizedRequest(self):
111+
configuration = bandwidth.Configuration(
112+
username = 'bad_username',
113+
password = 'bad_password'
114+
)
115+
unauthorized_api_client = bandwidth.ApiClient(configuration)
116+
unauthorized_api_instance = phone_number_lookup_api.PhoneNumberLookupApi(unauthorized_api_client)
117+
lookup_request = LookupRequest(
118+
tns=[
119+
os.environ['BW_NUMBER']
120+
],
121+
)
122+
123+
with self.assertRaises(UnauthorizedException) as context:
124+
unauthorized_api_instance.create_lookup(self.account_id, lookup_request)
125+
126+
self.assertIs(type(context.exception), UnauthorizedException)
127+
self.assertIs(type(context.exception.status), int)
128+
self.assertEqual(context.exception.status, 401)
129+
self.assertIs(type(context.exception.body), str)
130+
131+
def testForbiddenRequest(self):
132+
configuration = bandwidth.Configuration(
133+
username = os.environ['BW_USERNAME_FORBIDDEN'],
134+
password = os.environ['BW_PASSWORD_FORBIDDEN']
135+
)
136+
forbidden_api_client = bandwidth.ApiClient(configuration)
137+
forbidden_api_instance = phone_number_lookup_api.PhoneNumberLookupApi(forbidden_api_client)
138+
lookup_request = LookupRequest(
139+
tns=[
140+
os.environ['BW_NUMBER']
141+
],
142+
)
143+
144+
# This API throws a 401 when a user provides valid credentials with the `TN Lookup` role disabled
145+
# with self.assertRaises(ForbiddenException) as context:
146+
with self.assertRaises(UnauthorizedException) as context:
147+
forbidden_api_instance.create_lookup(self.account_id, lookup_request)
148+
149+
# self.assertIs(type(context.exception), ForbiddenException)
150+
# self.assertEqual(context.exception.status, 403)
151+
self.assertIs(type(context.exception), UnauthorizedException)
152+
self.assertIs(type(context.exception.status), int)
153+
self.assertEqual(context.exception.status, 401)
154+
self.assertIs(type(context.exception.body), str)
155+
156+
157+
if __name__ == '__main__':
158+
unittest.main()

test/unit/test_call_callback.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222

2323
class TestCallCallback(unittest.TestCase):
24-
"""CallCallback unit test stubs"""
24+
"""Call Callback unit test stubs"""
2525

2626
def setUp(self):
2727
pass
@@ -30,7 +30,7 @@ def tearDown(self):
3030
pass
3131

3232
def testCallCallback(self):
33-
"""Test CallCallback"""
33+
"""Test Call Callback"""
3434
# FIXME: construct object with mandatory attributes with example values
3535
# model = CallCallback() # noqa: E501
3636
pass

0 commit comments

Comments
 (0)