Skip to content

Commit b05d043

Browse files
authored
DX-2751 Refactor Integration Tests to Use Hamcrest (#105)
* DX-2751 Refactor Integration Tests to Use Hamcrest * fix messages tests * fix recordings tests * media tests * empty array * update tests to use env var helper * _ :upside_down_face
1 parent fc60e67 commit b05d043

File tree

6 files changed

+231
-240
lines changed

6 files changed

+231
-240
lines changed

test/integration/test_media_api.py

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import logging
99

1010
import bandwidth
11+
from hamcrest import *
1112
from bandwidth.api import media_api
1213
from bandwidth.model.media import Media
1314
from bandwidth.exceptions import ApiException, NotFoundException
@@ -43,13 +44,13 @@ def uploadMedia(self) -> None:
4344
account_id=self.account_id,
4445
media_id=media_id,
4546
body=self.original_file,
46-
content_type=content_type,
47+
_content_type=content_type,
4748
cache_control=cache_control,
4849
_return_http_data_only=False
4950
)
5051

5152
logging.debug(api_response_with_http_info)
52-
self.assertEqual(api_response_with_http_info[1], 204)
53+
assert_that(api_response_with_http_info[1], equal_to(204))
5354

5455
# reopen the media file
5556
# the client automatically closes any files passed into request bodies
@@ -60,7 +61,7 @@ def uploadMedia(self) -> None:
6061
account_id=self.account_id,
6162
media_id=media_id,
6263
body=reopened_file,
63-
content_type=content_type,
64+
_content_type=content_type,
6465
cache_control=cache_control,
6566
_return_http_data_only=False
6667
)
@@ -71,12 +72,12 @@ def listMedia(self) -> None:
7172
api_response_with_http_info = self.api_instance.list_media(
7273
self.account_id, _return_http_data_only=False)
7374

74-
self.assertEqual(api_response_with_http_info[1], 200)
75+
assert_that(api_response_with_http_info[1], equal_to(200))
7576

7677
api_response = self.api_instance.list_media(self.account_id)
7778
logging.debug("List Media" + str(api_response))
7879

79-
self.assertIs(type(api_response[0]), Media)
80+
assert_that(api_response[0], instance_of(Media))
8081
pass
8182

8283
def getMedia(self) -> None:
@@ -86,16 +87,16 @@ def getMedia(self) -> None:
8687
self.account_id, self.media_id, _return_http_data_only=False)
8788

8889
logging.debug(api_response_with_http_info)
89-
self.assertEqual(api_response_with_http_info[1], 200)
90+
assert_that(api_response_with_http_info[1], equal_to(200))
9091

9192
api_response = self.api_instance.get_media(
9293
self.account_id, self.media_id, _preload_content=False)
9394

9495
with open(self.media_path + self.download_file_path, "wb") as download_file:
9596
download_file.write(api_response.data)
9697

97-
self.assertTrue(filecmp.cmp(self.media_path + self.media_file,
98-
self.media_path + self.download_file_path))
98+
assert_that(filecmp.cmp(self.media_path + self.media_file,
99+
self.media_path + self.download_file_path), equal_to(True))
99100
download_file.close()
100101

101102
def deleteMedia(self) -> None:
@@ -105,7 +106,7 @@ def deleteMedia(self) -> None:
105106
self.account_id, self.media_id, _return_http_data_only=False)
106107

107108
logging.debug(api_response_with_http_info)
108-
self.assertEqual(api_response_with_http_info[1], 204)
109+
assert_that(api_response_with_http_info[1], equal_to(204))
109110

110111
# returns void
111112
self.api_instance.delete_media(self.account_id, self.media_id)
@@ -127,11 +128,5 @@ def testGetMediaWithBandwidthId(self) -> None:
127128
# use a nonexistent mediaId - results in a 404
128129
media_id = "abcd1234-e5f6-1111-2222-3456ghi7890/image123456.jpg"
129130

130-
with self.assertRaises(NotFoundException) as context:
131-
api_response = self.api_instance.get_media(
132-
self.account_id,
133-
media_id,
134-
_preload_content=False
135-
)
136-
137-
self.assertEqual(context.exception.status, 404)
131+
assert_that(calling(self.api_instance.get_media).with_args(
132+
self.account_id, media_id, _preload_content=False)), raises(NotFoundException)

test/integration/test_messages_api.py

Lines changed: 58 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from datetime import datetime
1717

1818
import bandwidth
19+
from hamcrest import *
1920
from bandwidth.api import messages_api
2021
from bandwidth.model.list_message_direction_enum import ListMessageDirectionEnum
2122
from bandwidth.model.list_message_item import ListMessageItem
@@ -26,6 +27,7 @@
2627
from bandwidth.model.priority_enum import PriorityEnum
2728
from bandwidth.model.message import Message
2829
from bandwidth.exceptions import ApiException, UnauthorizedException
30+
from test.utils.env_variables import *
2931

3032

3133
class TestMessagesApi(unittest.TestCase):
@@ -34,21 +36,21 @@ class TestMessagesApi(unittest.TestCase):
3436
def setUp(self):
3537
# API Client
3638
configuration = bandwidth.Configuration(
37-
username = os.environ.get('BW_USERNAME'),
38-
password = os.environ.get('BW_PASSWORD')
39+
username = BW_USERNAME,
40+
password = BW_PASSWORD
3941
)
4042
api_client = bandwidth.ApiClient(configuration)
4143
self.api_instance = messages_api.MessagesApi(api_client)
42-
self.account_id = os.environ.get('BW_ACCOUNT_ID')
44+
self.account_id = BW_ACCOUNT_ID
4345

4446
# Unauthorized API Client
4547
self.unauthorized_api_client = bandwidth.ApiClient()
4648
self.unauthorized_api_instance = messages_api.MessagesApi(self.unauthorized_api_client)
4749

4850
# Message Properties
49-
self.application_id = os.environ.get('BW_MESSAGING_APPLICATION_ID')
50-
self.to_number = [os.environ.get('USER_NUMBER')]
51-
self.from_number = os.environ.get('BW_NUMBER')
51+
self.application_id = BW_MESSAGING_APPLICATION_ID
52+
self.to_number = [USER_NUMBER]
53+
self.from_number = BW_NUMBER
5254
self.text = 'python integration'
5355
self.media = ['https://cdn2.thecatapi.com/images/MTY3ODIyMQ.jpg']
5456
self.tag = 'python integration tag'
@@ -77,104 +79,82 @@ def setUp(self):
7779
def test_create_message(self):
7880
response = self.api_instance.create_message(self.account_id, self.message_request, _return_http_data_only=False)
7981

80-
self.assertEqual(response[1], 202)
82+
assert_that(response[1], equal_to(202))
8183

8284
api_response = response[0]
83-
self.assertIsInstance(api_response, Message)
84-
self.assertEqual(api_response.application_id,self.application_id)
85-
self.assertEqual(api_response.to, self.to_number)
86-
self.assertEqual(api_response._from, self.from_number)
87-
self.assertEqual(api_response.owner, self.from_number)
88-
self.assertEqual(api_response.text, self.text)
89-
self.assertEqual(api_response.media, self.media)
90-
self.assertEqual(api_response.tag, self.tag)
91-
self.assertIsInstance(api_response.priority, PriorityEnum)
92-
self.assertEqual(api_response.priority, self.priority)
93-
self.assertEqual(api_response.segment_count, 1)
94-
self.assertTrue(datetime.fromisoformat(api_response.time[:-1]))
95-
96-
97-
def test_create_message_bad_request(self):
98-
with self.assertRaises(ApiException) as context:
99-
self.api_instance.create_message(self.account_id, self.invalid_message_request)
100-
101-
self.assertEqual(context.exception.status, 400)
102-
103-
e = json.loads(context.exception.body)
104-
self.assertEqual(e['type'], 'request-validation')
105-
self.assertIsInstance(e['description'], str)
106-
self.assertIsInstance(e['fieldErrors'], list)
107-
108-
field_error = e['fieldErrors'][0]
109-
self.assertEqual(field_error['fieldName'], 'to')
110-
self.assertEqual(field_error['description'], "'+invalid' must be replaced with a valid E164 formatted telephone number")
111-
85+
assert_that(api_response, instance_of(Message))
86+
assert_that(api_response, has_properties(
87+
'application_id', self.application_id,
88+
'to', self.to_number,
89+
'_from', self.from_number,
90+
'owner', self.from_number,
91+
'text', self.text,
92+
'media', self.media,
93+
'tag', self.tag,
94+
'priority', instance_of(PriorityEnum),
95+
'priority', self.priority,
96+
'segment_count', 1,
97+
)
98+
)
99+
assert_that(datetime.fromisoformat(api_response.time[:-1]), instance_of(datetime))
112100

113-
def test_create_message_unauthorized(self):
114-
with self.assertRaises(UnauthorizedException) as context:
115-
self.unauthorized_api_instance.create_message(self.account_id, self.invalid_message_request)
116-
117-
self.assertEqual(context.exception.status, 401)
118101

119-
e = json.loads(context.exception.body)
120-
self.assertEqual(e['type'], 'unauthorized')
121-
self.assertEqual(e['description'], 'Authentication Failed')
102+
def test_create_message_bad_request(self):
103+
assert_that(calling(self.api_instance.create_message).with_args(
104+
self.account_id, self.invalid_message_request)), raises(ApiException)
105+
106+
107+
def test_create_message_unauthorized(self):
108+
assert_that(calling(self.unauthorized_api_instance.create_message).with_args(
109+
self.account_id, self.invalid_message_request)), raises(UnauthorizedException)
122110

123111

124112
@unittest.skip('The SDK catches incorrect content-type before making the request and attempts to create an ApiException,\
125113
but the creation of the exception fails since there is no response body. This should probably create some\
126114
kind of Client Exception instead, since this is not an actual API Exception.')
127115
def test_create_message_invalid_media(self):
128-
with self.assertRaises(ApiException) as context:
129-
self.api_instance.create_message(self.account_id, self.message_request, _content_type='application/xml')
116+
assert_that(calling(self.api_instance.create_message).with_args(
117+
self.account_id, self.message_request, _content_type='application/xml')), raises(ApiException)
130118

131119

132120
def test_list_messages(self):
133121
message_direction = ListMessageDirectionEnum("OUTBOUND")
134122

135123
response = self.api_instance.list_messages(self.account_id, message_direction=message_direction, _return_http_data_only=False)
136124

137-
self.assertEqual(response[1], 200)
125+
assert_that(response[1], equal_to(200))
138126

139127
api_response = response[0]
140-
self.assertIsInstance(api_response, MessagesList)
141-
self.assertGreater(api_response.total_count, 0)
142-
self.assertTrue(api_response.messages[0], ListMessageItem)
128+
assert_that(api_response, instance_of(MessagesList))
129+
assert_that(api_response, has_properties(
130+
'total_count', greater_than(0),
131+
'messages', instance_of(list)
132+
))
133+
134+
assert_that(api_response.messages[0], instance_of(ListMessageItem))
143135

144136
message = api_response.messages[0]
145-
self.assertEqual(message.account_id, self.account_id)
146-
self.assertRegex(message.destination_tn, '^\\+[1-9]\\d{1,14}$')
147-
self.assertEqual(message.message_direction, ListMessageDirectionEnum("OUTBOUND"))
148-
self.assertTrue(message.message_id)
149-
self.assertIsInstance(message.message_status, MessageStatusEnum)
150-
self.assertIsInstance(message.message_type, MessageTypeEnum)
151-
self.assertTrue(datetime.fromisoformat(message.receive_time[:-1]))
152-
self.assertTrue(message.segment_count)
153-
self.assertRegex(message.source_tn, '^\\+[1-9]\\d{1,14}$')
137+
assert_that(message, has_properties(
138+
'account_id', self.account_id,
139+
'destination_tn', matches_regexp('^\\+[1-9]\\d{1,14}$'),
140+
'message_direction', ListMessageDirectionEnum("OUTBOUND"),
141+
'message_id', matches_regexp('^.+$'),
142+
'message_status', instance_of(MessageStatusEnum),
143+
'message_type', instance_of(MessageTypeEnum),
144+
'segment_count', greater_than(0),
145+
'source_tn', matches_regexp('^\\+[1-9]\\d{1,14}$')
146+
))
147+
assert_that(datetime.fromisoformat(message.receive_time[:-1]), instance_of(datetime))
154148

155-
156-
def test_list_messages_bad_request(self):
157-
158-
with self.assertRaises(ApiException) as context:
159-
self.api_instance.list_messages(self.account_id)
160-
161-
self.assertEqual(context.exception.status, 400)
162149

163-
e = json.loads(context.exception.body)
164-
self.assertEqual(e['type'], 'bad-request')
165-
self.assertIsInstance(e['description'], str)
150+
def test_list_messages_bad_request(self):
151+
assert_that(calling(self.api_instance.list_messages).with_args(
152+
self.account_id), raises(ApiException))
166153

167154

168155
def test_list_messages_unauthorized(self):
169-
170-
with self.assertRaises(UnauthorizedException) as context:
171-
self.unauthorized_api_instance.list_messages(self.account_id)
172-
173-
self.assertEqual(context.exception.status, 401)
174-
175-
e = json.loads(context.exception.body)
176-
self.assertEqual(e['type'], 'unauthorized')
177-
self.assertEqual(e['description'], 'Your request could not be authenticated')
156+
assert_that(calling(self.unauthorized_api_instance.list_messages).with_args(
157+
self.account_id), raises(UnauthorizedException))
178158

179159

180160
if __name__ == '__main__':

test/integration/test_multi_factor_authentication.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616
from bandwidth.model.verify_code_response import VerifyCodeResponse
1717
from bandwidth.model.voice_code_response import VoiceCodeResponse
1818
from bandwidth.exceptions import ApiException, UnauthorizedException, ForbiddenException
19+
from test.utils.env_variables import *
1920

20-
import hamcrest
2121
from hamcrest.core import *
2222
from hamcrest.library import *
2323

@@ -27,31 +27,31 @@ class TestMultiFactorAuthentication(unittest.TestCase):
2727

2828
def setUp(self) -> None:
2929
configuration = bandwidth.Configuration(
30-
username=os.environ['BW_USERNAME'],
31-
password=os.environ['BW_PASSWORD']
30+
username=BW_USERNAME,
31+
password=BW_PASSWORD
3232
)
3333
api_client = bandwidth.ApiClient(configuration)
3434
self.api_instance = mfa_api.MFAApi(api_client)
35-
self.account_id = os.environ['BW_ACCOUNT_ID']
35+
self.account_id = BW_ACCOUNT_ID
3636
self.messaging_code_request = CodeRequest(
37-
to=os.environ['USER_NUMBER'],
38-
_from=os.environ['BW_NUMBER'],
39-
application_id=os.environ['BW_MESSAGING_APPLICATION_ID'],
37+
to=USER_NUMBER,
38+
_from=BW_NUMBER,
39+
application_id=BW_MESSAGING_APPLICATION_ID,
4040
scope="scope",
4141
message="Your temporary {NAME} {SCOPE} code is {CODE}",
4242
digits=6,
4343
)
4444
self.voice_code_request = CodeRequest(
45-
to=os.environ['USER_NUMBER'],
46-
_from=os.environ['BW_NUMBER'],
47-
application_id=os.environ['BW_VOICE_APPLICATION_ID'],
45+
to=USER_NUMBER,
46+
_from=BW_NUMBER,
47+
application_id=BW_VOICE_APPLICATION_ID,
4848
scope="scope",
4949
message="Your temporary {NAME} {SCOPE} code is {CODE}",
5050
digits=6,
5151
)
5252
self.bad_code_request = CodeRequest(
53-
to=os.environ['USER_NUMBER'],
54-
_from=os.environ['BW_NUMBER'],
53+
to=USER_NUMBER,
54+
_from=BW_NUMBER,
5555
application_id='not_an_application_id',
5656
scope="scope",
5757
message="Your temporary {NAME} {SCOPE} code is {CODE}",
@@ -154,8 +154,8 @@ def testForbiddenRequest(self) -> None:
154154
"""Validate a forbidden (403) request
155155
"""
156156
configuration = bandwidth.Configuration(
157-
username=os.environ['BW_USERNAME_FORBIDDEN'],
158-
# password=os.environ['BW_PASSWORD_FORBIDDEN'],
157+
username=FORBIDDEN_USERNAME,
158+
# password=FORBIDDEN_PASSWORD,
159159
password='bad_password'
160160
)
161161
forbidden_api_client = bandwidth.ApiClient(configuration)

0 commit comments

Comments
 (0)