From 9e122a74d97fb23a17dde37164cfe2948704a6b3 Mon Sep 17 00:00:00 2001 From: Cameron Koegel Date: Fri, 26 Aug 2022 14:26:08 -0400 Subject: [PATCH 1/7] DX-2751 Refactor Integration Tests to Use Hamcrest --- test/integration/test_media_api.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/test/integration/test_media_api.py b/test/integration/test_media_api.py index 97d950ab..51e6e746 100644 --- a/test/integration/test_media_api.py +++ b/test/integration/test_media_api.py @@ -8,6 +8,7 @@ import logging import bandwidth +from hamcrest import * from bandwidth.api import media_api from bandwidth.model.media import Media from bandwidth.exceptions import ApiException, NotFoundException @@ -49,7 +50,7 @@ def uploadMedia(self) -> None: ) logging.debug(api_response_with_http_info) - self.assertEqual(api_response_with_http_info[1], 204) + assert_that(api_response_with_http_info[1], equal_to(204)) # reopen the media file # the client automatically closes any files passed into request bodies @@ -71,12 +72,12 @@ def listMedia(self) -> None: api_response_with_http_info = self.api_instance.list_media( self.account_id, _return_http_data_only=False) - self.assertEqual(api_response_with_http_info[1], 200) + assert_that(api_response_with_http_info[1], equal_to(200)) api_response = self.api_instance.list_media(self.account_id) logging.debug("List Media" + str(api_response)) - self.assertIs(type(api_response[0]), Media) + assert_that(api_response[0], instance_of(Media)) pass def getMedia(self) -> None: @@ -86,7 +87,7 @@ def getMedia(self) -> None: self.account_id, self.media_id, _return_http_data_only=False) logging.debug(api_response_with_http_info) - self.assertEqual(api_response_with_http_info[1], 200) + assert_that(api_response_with_http_info[1], equal_to(200)) api_response = self.api_instance.get_media( self.account_id, self.media_id, _preload_content=False) @@ -94,8 +95,8 @@ def getMedia(self) -> None: with open(self.media_path + self.download_file_path, "wb") as download_file: download_file.write(api_response.data) - self.assertTrue(filecmp.cmp(self.media_path + self.media_file, - self.media_path + self.download_file_path)) + assert_that(filecmp.cmp(self.media_path + self.media_file, + self.media_path + self.download_file_path), equal_to(True)) download_file.close() def deleteMedia(self) -> None: @@ -105,7 +106,7 @@ def deleteMedia(self) -> None: self.account_id, self.media_id, _return_http_data_only=False) logging.debug(api_response_with_http_info) - self.assertEqual(api_response_with_http_info[1], 204) + assert_that(api_response_with_http_info[1], equal_to(204)) # returns void self.api_instance.delete_media(self.account_id, self.media_id) From 2fb7fc280e0a7983ddff6cf4b21cae3a16eaf238 Mon Sep 17 00:00:00 2001 From: Cameron Koegel Date: Fri, 26 Aug 2022 15:20:10 -0400 Subject: [PATCH 2/7] fix messages tests --- test/integration/test_messages_api.py | 123 +++++++++++--------------- 1 file changed, 51 insertions(+), 72 deletions(-) diff --git a/test/integration/test_messages_api.py b/test/integration/test_messages_api.py index ae92be49..0d7cf0ed 100644 --- a/test/integration/test_messages_api.py +++ b/test/integration/test_messages_api.py @@ -16,6 +16,7 @@ from datetime import datetime import bandwidth +from hamcrest import * from bandwidth.api import messages_api from bandwidth.model.list_message_direction_enum import ListMessageDirectionEnum from bandwidth.model.list_message_item import ListMessageItem @@ -77,56 +78,42 @@ def setUp(self): def test_create_message(self): response = self.api_instance.create_message(self.account_id, self.message_request, _return_http_data_only=False) - self.assertEqual(response[1], 202) + assert_that(response[1], equal_to(202)) api_response = response[0] - self.assertIsInstance(api_response, Message) - self.assertEqual(api_response.application_id,self.application_id) - self.assertEqual(api_response.to, self.to_number) - self.assertEqual(api_response._from, self.from_number) - self.assertEqual(api_response.owner, self.from_number) - self.assertEqual(api_response.text, self.text) - self.assertEqual(api_response.media, self.media) - self.assertEqual(api_response.tag, self.tag) - self.assertIsInstance(api_response.priority, PriorityEnum) - self.assertEqual(api_response.priority, self.priority) - self.assertEqual(api_response.segment_count, 1) - self.assertTrue(datetime.fromisoformat(api_response.time[:-1])) - - - def test_create_message_bad_request(self): - with self.assertRaises(ApiException) as context: - self.api_instance.create_message(self.account_id, self.invalid_message_request) - - self.assertEqual(context.exception.status, 400) - - e = json.loads(context.exception.body) - self.assertEqual(e['type'], 'request-validation') - self.assertIsInstance(e['description'], str) - self.assertIsInstance(e['fieldErrors'], list) - - field_error = e['fieldErrors'][0] - self.assertEqual(field_error['fieldName'], 'to') - self.assertEqual(field_error['description'], "'+invalid' must be replaced with a valid E164 formatted telephone number") - + assert_that(api_response, instance_of(Message)) + assert_that(api_response, has_properties( + 'application_id', self.application_id, + 'to', self.to_number, + '_from', self.from_number, + 'owner', self.from_number, + 'text', self.text, + 'media', self.media, + 'tag', self.tag, + 'priority', instance_of(PriorityEnum), + 'priority', self.priority, + 'segment_count', 1, + ) + ) + assert_that(datetime.fromisoformat(api_response.time[:-1]), instance_of(datetime)) - def test_create_message_unauthorized(self): - with self.assertRaises(UnauthorizedException) as context: - self.unauthorized_api_instance.create_message(self.account_id, self.invalid_message_request) - - self.assertEqual(context.exception.status, 401) - e = json.loads(context.exception.body) - self.assertEqual(e['type'], 'unauthorized') - self.assertEqual(e['description'], 'Authentication Failed') + def test_create_message_bad_request(self): + assert_that(calling(self.api_instance.create_message).with_args( + self.account_id, self.invalid_message_request)), raises(ApiException) + + + def test_create_message_unauthorized(self): + assert_that(calling(self.unauthorized_api_instance.create_message).with_args( + self.account_id, self.invalid_message_request)), raises(UnauthorizedException) @unittest.skip('The SDK catches incorrect content-type before making the request and attempts to create an ApiException,\ but the creation of the exception fails since there is no response body. This should probably create some\ kind of Client Exception instead, since this is not an actual API Exception.') def test_create_message_invalid_media(self): - with self.assertRaises(ApiException) as context: - self.api_instance.create_message(self.account_id, self.message_request, _content_type='application/xml') + assert_that(calling(self.api_instance.create_message).with_args( + self.account_id, self.message_request, _content_type='application/xml')), raises(ApiException) def test_list_messages(self): @@ -134,47 +121,39 @@ def test_list_messages(self): response = self.api_instance.list_messages(self.account_id, message_direction=message_direction, _return_http_data_only=False) - self.assertEqual(response[1], 200) + assert_that(response[1], equal_to(200)) api_response = response[0] - self.assertIsInstance(api_response, MessagesList) - self.assertGreater(api_response.total_count, 0) - self.assertTrue(api_response.messages[0], ListMessageItem) + assert_that(api_response, instance_of(MessagesList)) + assert_that(api_response, has_properties( + 'total_count', greater_than(0), + 'messages', instance_of(list) + )) + + assert_that(api_response.messages[0], instance_of(ListMessageItem)) message = api_response.messages[0] - self.assertEqual(message.account_id, self.account_id) - self.assertRegex(message.destination_tn, '^\\+[1-9]\\d{1,14}$') - self.assertEqual(message.message_direction, ListMessageDirectionEnum("OUTBOUND")) - self.assertTrue(message.message_id) - self.assertIsInstance(message.message_status, MessageStatusEnum) - self.assertIsInstance(message.message_type, MessageTypeEnum) - self.assertTrue(datetime.fromisoformat(message.receive_time[:-1])) - self.assertTrue(message.segment_count) - self.assertRegex(message.source_tn, '^\\+[1-9]\\d{1,14}$') + assert_that(message, has_properties( + 'account_id', self.account_id, + 'destination_tn', matches_regexp('^\\+[1-9]\\d{1,14}$'), + 'message_direction', ListMessageDirectionEnum("OUTBOUND"), + 'message_id', matches_regexp('^.+$'), + 'message_status', instance_of(MessageStatusEnum), + 'message_type', instance_of(MessageTypeEnum), + 'segment_count', greater_than(0), + 'source_tn', matches_regexp('^\\+[1-9]\\d{1,14}$') + )) + assert_that(datetime.fromisoformat(message.receive_time[:-1]), instance_of(datetime)) - - def test_list_messages_bad_request(self): - - with self.assertRaises(ApiException) as context: - self.api_instance.list_messages(self.account_id) - - self.assertEqual(context.exception.status, 400) - e = json.loads(context.exception.body) - self.assertEqual(e['type'], 'bad-request') - self.assertIsInstance(e['description'], str) + def test_list_messages_bad_request(self): + assert_that(calling(self.api_instance.list_messages).with_args( + self.account_id), raises(ApiException)) def test_list_messages_unauthorized(self): - - with self.assertRaises(UnauthorizedException) as context: - self.unauthorized_api_instance.list_messages(self.account_id) - - self.assertEqual(context.exception.status, 401) - - e = json.loads(context.exception.body) - self.assertEqual(e['type'], 'unauthorized') - self.assertEqual(e['description'], 'Your request could not be authenticated') + assert_that(calling(self.unauthorized_api_instance.list_messages).with_args( + self.account_id), raises(UnauthorizedException)) if __name__ == '__main__': From f9b515236d2571ea1a59732e5be34ea311446795 Mon Sep 17 00:00:00 2001 From: Cameron Koegel Date: Fri, 26 Aug 2022 15:55:52 -0400 Subject: [PATCH 3/7] fix recordings tests --- test/integration/test_recordings.py | 185 +++++++++++++++------------- 1 file changed, 97 insertions(+), 88 deletions(-) diff --git a/test/integration/test_recordings.py b/test/integration/test_recordings.py index cfe5ab41..0b37f5aa 100644 --- a/test/integration/test_recordings.py +++ b/test/integration/test_recordings.py @@ -16,6 +16,7 @@ import json import bandwidth +from hamcrest import * from bandwidth.api.recordings_api import RecordingsApi from bandwidth.configuration import Configuration from bandwidth.exceptions import ForbiddenException, NotFoundException, UnauthorizedException @@ -144,13 +145,15 @@ def create_and_validate_call(self, answer_url: str) -> Tuple[str, str]: create_call_response: CreateCallResponse = self.calls_api_instance.create_call(BW_ACCOUNT_ID, call_body) # Verify info about the call - assert len(create_call_response.call_id) == 47 # assert request created and id matches expected length (47) - assert create_call_response.account_id == BW_ACCOUNT_ID - assert create_call_response.application_id == MANTECA_APPLICATION_ID - assert create_call_response.to == MANTECA_IDLE_NUMBER - assert create_call_response._from == MANTECA_ACTIVE_NUMBER - assert create_call_response.call_url == "https://voice.bandwidth.com/api/v2/accounts/" + \ - BW_ACCOUNT_ID + "/calls/" + create_call_response.call_id + assert_that(create_call_response, has_properties( + 'call_id', has_length(47), # assert request created and id matches expected length (47) + 'account_id', BW_ACCOUNT_ID, + 'application_id', MANTECA_APPLICATION_ID, + 'to', MANTECA_IDLE_NUMBER, + '_from', MANTECA_ACTIVE_NUMBER, + 'call_url', "https://voice.bandwidth.com/api/v2/accounts/" + \ + BW_ACCOUNT_ID + "/calls/" + create_call_response.call_id + )) # Adding the call to the callIdArray callIdArray.append(create_call_response.call_id) @@ -181,7 +184,7 @@ def complete_recorded_call(self) -> Tuple[str, str]: retries += 1 # If we failed to get a recorded call, fail due to polling timeout - assert call_status['callRecorded'] == True + assert_that(call_status['callRecorded'], equal_to(True)) # Return our test_id and call_id return (test_id, call_id) @@ -194,11 +197,13 @@ def validate_recording(self, recording: CallRecordingMetadata, call_id: str) -> recording (CallRecordingMetadata): The recording metadata to validate. call_id (str): The call id associated with the given recording. """ - assert recording.account_id == BW_ACCOUNT_ID - assert recording.call_id == call_id - assert recording.application_id == MANTECA_APPLICATION_ID - assert recording.status == 'complete' - assert recording.file_format == FileFormatEnum('wav') + assert_that(recording, has_properties( + 'account_id', BW_ACCOUNT_ID, + 'call_id', call_id, + 'application_id', MANTECA_APPLICATION_ID, + 'status', 'complete', + 'file_format', FileFormatEnum('wav') + )) def get_test_status(self, test_id: str) -> Dict: """ @@ -236,11 +241,11 @@ def test_successful_call_recording(self) -> None: # List Call Recordings Endpoint response: List[CallRecordingMetadata] = self.recordings_api_instance.list_call_recordings(BW_ACCOUNT_ID, call_id, _return_http_data_only=False) - assert response[1] == 200 # Check response code + assert_that(response[1], equal_to(200)) # Check response code # We should get back 1 recording call_recordings = response[0] - assert len(call_recordings) == 1 + assert_that(call_recordings, has_length(1)) # Checks on the first recording first_recording: CallRecordingMetadata = call_recordings[0] @@ -249,10 +254,10 @@ def test_successful_call_recording(self) -> None: # Get Single Recording Endpoint recording_response: CallRecordingMetadata = self.recordings_api_instance.get_call_recording(BW_ACCOUNT_ID, call_id, recording_id, _return_http_data_only=False) - assert recording_response[1] == 200 + assert_that(recording_response[1], equal_to(200)) # Check response code recording = recording_response[0] - assert recording.recording_id == recording_id + assert_that(recording.recording_id, equal_to(recording_id)) self.validate_recording(recording, call_id) # Download recording media @@ -270,7 +275,7 @@ def test_successful_call_recording(self) -> None: transcription_url = MANTECA_BASE_URL + "/transcriptions" transcribe_recording_request = TranscribeRecording(callback_url=transcription_url,tag=test_id) transcription_response = self.recordings_api_instance.transcribe_call_recording(BW_ACCOUNT_ID, call_id, recording_id, transcribe_recording_request, _return_http_data_only=False) - assert transcription_response[1] == 204 + assert_that(transcription_response[1], equal_to(204)) # Check response code # Poll Manteca to make sure our call is transcribed call_status = self.get_test_status(test_id) @@ -281,35 +286,38 @@ def test_successful_call_recording(self) -> None: retries += 1 # If we failed to get a transcribed call, fail due to polling timeout - assert call_status['callTranscribed'] == True + assert_that(call_status['callTranscribed'], equal_to(True)) # Get the transcription transcription_response = self.recordings_api_instance.get_call_transcription(BW_ACCOUNT_ID, call_id, recording_id, _return_http_data_only=False) - assert transcription_response[1] == 200 + assert_that(transcription_response[1], equal_to(200)) # Check response code transcription_list = transcription_response[0] - assert len(transcription_list.transcripts) == 1 + assert_that(transcription_list.transcripts, has_length(1)) transcription = transcription_list.transcripts[0] - assert isinstance(transcription, Transcription) - assert isinstance(transcription.text, str) - assert isinstance(transcription.confidence, float) + assert_that(transcription, instance_of(Transcription)) + assert_that(transcription, has_properties( + 'text', instance_of(str), + 'confidence', instance_of(float) + )) # Delete the transcription delete_transcription_response = self.recordings_api_instance.delete_call_transcription(BW_ACCOUNT_ID, call_id, recording_id, _return_http_data_only=False) - assert delete_transcription_response[1] == 204 - with self.assertRaises(NotFoundException): - self.recordings_api_instance.get_call_transcription(BW_ACCOUNT_ID, call_id, recording_id) + assert_that(delete_transcription_response[1], equal_to(204)) # Check response code + + assert_that(calling(self.recordings_api_instance.get_call_transcription).with_args( + BW_ACCOUNT_ID, call_id, recording_id), raises(NotFoundException)) # Delete Recording media delete_recording_media_response = self.recordings_api_instance.delete_recording_media(BW_ACCOUNT_ID, call_id, recording_id, _return_http_data_only=False) # Validate the 204 response - assert delete_recording_media_response[1] == 204 + assert_that(delete_recording_media_response[1], equal_to(204)) # Delete Recording delete_recording_response = self.recordings_api_instance.delete_recording(BW_ACCOUNT_ID, call_id, recording_id, _return_http_data_only=False) - assert delete_recording_response[1] == 204 + assert_that(delete_recording_response[1], equal_to(204)) call_recordings = self.recordings_api_instance.list_call_recordings(BW_ACCOUNT_ID, call_id) - assert len(call_recordings) == 0 + assert_that(call_recordings, has_length(0)) def test_successful_update_active_recording(self) -> None: """ @@ -331,17 +339,17 @@ def test_successful_update_active_recording(self) -> None: retries += 1 # Make sure the call is alive - assert call_status['status'] == 'ALIVE' + assert_that(call_status['status'], equal_to('ALIVE')) # Update the call to pause the recording update_call_recording = UpdateCallRecording(RecordingStateEnum('paused')) update_response = self.recordings_api_instance.update_call_recording_state(BW_ACCOUNT_ID, call_id, update_call_recording, _return_http_data_only=False) - assert update_response[1] == 200 + assert_that(update_response[1], equal_to(200)) # Update the call to resume the recording update_call_recording = UpdateCallRecording(RecordingStateEnum('recording')) update_response = self.recordings_api_instance.update_call_recording_state(BW_ACCOUNT_ID, call_id, update_call_recording, _return_http_data_only=False) - assert update_response[1] == 200 + assert_that(update_response[1], equal_to(200)) # Kill the call update_call = UpdateCall(state=CallStateEnum('completed')) @@ -356,16 +364,17 @@ def test_invalid_list_call_recordings(self) -> None: (test_id, call_id) = self.complete_recorded_call() # Use the unauthorized client to try to list recordings (401) - with self.assertRaises(UnauthorizedException): - self.unauthorized_recordings_api_instance.list_call_recordings(BW_ACCOUNT_ID, call_id) + assert_that(calling(self.unauthorized_recordings_api_instance.list_call_recordings).with_args( + BW_ACCOUNT_ID, call_id), raises(UnauthorizedException)) # Invalid account id (403) - with self.assertRaises(ForbiddenException): - self.recordings_api_instance.list_call_recordings("not an account id", call_id) + assert_that(calling(self.recordings_api_instance.list_call_recordings).with_args( + "not an account id", call_id), raises(ForbiddenException)) # Non-existent call id # This should probably be a 404, but actually returns an empty list - assert self.recordings_api_instance.list_call_recordings(BW_ACCOUNT_ID, "not a call id") == [] + not_found_call_recordings = self.recordings_api_instance.list_call_recordings(BW_ACCOUNT_ID, "not a call id") + assert_that(not_found_call_recordings, empty) def test_invalid_get_call_recording(self) -> None: """ @@ -380,16 +389,16 @@ def test_invalid_get_call_recording(self) -> None: recording_id = recordings[0].recording_id # Use the unauthorized client to try to get a recording (401) - with self.assertRaises(UnauthorizedException): - self.unauthorized_recordings_api_instance.get_call_recording(BW_ACCOUNT_ID, call_id, recording_id) - + assert_that(calling(self.unauthorized_recordings_api_instance.get_call_recording).with_args( + BW_ACCOUNT_ID, call_id, recording_id), raises(UnauthorizedException)) + # Non-existent account id (403) - with self.assertRaises(ForbiddenException): - self.recordings_api_instance.get_call_recording("not an account id", call_id, recording_id) + assert_that(calling(self.recordings_api_instance.get_call_recording).with_args( + "not an account id", call_id, recording_id), raises(ForbiddenException)) # Non-existent recording id (404) - with self.assertRaises(NotFoundException): - self.recordings_api_instance.get_call_recording(BW_ACCOUNT_ID, call_id, "not a recording id") + assert_that(calling(self.recordings_api_instance.get_call_recording).with_args( + BW_ACCOUNT_ID, call_id, "not a recording id"), raises(NotFoundException)) def test_invalid_download_call_recording(self) -> None: """ @@ -404,16 +413,16 @@ def test_invalid_download_call_recording(self) -> None: recording_id = recordings[0].recording_id # Use the unauthorized client to try to download a recording (401) - with self.assertRaises(UnauthorizedException): - self.unauthorized_recordings_api_instance.download_call_recording(BW_ACCOUNT_ID, call_id, recording_id) + assert_that(calling(self.unauthorized_recordings_api_instance.download_call_recording).with_args( + BW_ACCOUNT_ID, call_id, recording_id), raises(UnauthorizedException)) # Non-existent account id (403) - with self.assertRaises(ForbiddenException): - self.recordings_api_instance.download_call_recording("not an account id", call_id, recording_id) + assert_that(calling(self.recordings_api_instance.download_call_recording).with_args( + "not an account id", call_id, recording_id), raises(ForbiddenException)) # Non-existent recording id (404) - with self.assertRaises(NotFoundException): - self.recordings_api_instance.download_call_recording(BW_ACCOUNT_ID, call_id, "not a recording id") + assert_that(calling(self.recordings_api_instance.download_call_recording).with_args( + BW_ACCOUNT_ID, call_id, "not a recording id"), raises(NotFoundException)) def test_invalid_transcribe_call_recording(self) -> None: """ @@ -432,12 +441,12 @@ def test_invalid_transcribe_call_recording(self) -> None: transcribe_recording = TranscribeRecording(callback_url=transcription_url, tag=test_id) # Use the unauthorized client to request a transcription (401) - with self.assertRaises(UnauthorizedException): - self.unauthorized_recordings_api_instance.transcribe_call_recording(BW_ACCOUNT_ID, call_id, recording_id, transcribe_recording) + assert_that(calling(self.unauthorized_recordings_api_instance.transcribe_call_recording).with_args( + BW_ACCOUNT_ID, call_id, recording_id, transcribe_recording), raises(UnauthorizedException)) # Non existent account id (403) - with self.assertRaises(ForbiddenException): - self.recordings_api_instance.transcribe_call_recording("not an account id", call_id, recording_id, transcribe_recording) + assert_that(calling(self.recordings_api_instance.transcribe_call_recording).with_args( + "not an account id", call_id, recording_id, transcribe_recording), raises(ForbiddenException)) # Non-existent recording id (404) # TODO: This does not work right now as the API is unexpectedly returning a 502 Bad Gateway for this request. @@ -471,19 +480,19 @@ def test_invalid_get_call_transcription(self) -> None: retries += 1 # If we failed to get a transcribed call, fail due to polling timeout (TEMP COMMENTED) - assert call_status['callTranscribed'] == True + assert_that(call_status['callTranscribed'], equal_to(True)) # Use the unauthorized client to get transcripion (401) - with self.assertRaises(UnauthorizedException): - self.unauthorized_recordings_api_instance.get_call_transcription(BW_ACCOUNT_ID, call_id, recording_id) + assert_that(calling(self.unauthorized_recordings_api_instance.get_call_transcription).with_args( + BW_ACCOUNT_ID, call_id, recording_id), raises(UnauthorizedException)) # Non-existent account id (403) - with self.assertRaises(ForbiddenException): - self.recordings_api_instance.get_call_transcription("not an account id", call_id, recording_id) + assert_that(calling(self.recordings_api_instance.get_call_transcription).with_args( + "not an account id", call_id, recording_id), raises(ForbiddenException)) # Non-existent recording id (404) - with self.assertRaises(NotFoundException): - self.recordings_api_instance.get_call_transcription(BW_ACCOUNT_ID, call_id, "not a recording id") + assert_that(calling(self.recordings_api_instance.get_call_transcription).with_args( + BW_ACCOUNT_ID, call_id, "not a recording id"), raises(NotFoundException)) def test_invalid_delete_call_transcription(self) -> None: """ @@ -511,19 +520,19 @@ def test_invalid_delete_call_transcription(self) -> None: retries += 1 # If we failed to get a transcribed call, fail due to polling timeout (TEMP COMMENTED) - assert call_status['callTranscribed'] == True + assert_that(call_status['callTranscribed'], equal_to(True)) # Use the unauthorized client to delete transcripion (401) - with self.assertRaises(UnauthorizedException): - self.unauthorized_recordings_api_instance.delete_call_transcription(BW_ACCOUNT_ID, call_id, recording_id) + assert_that(calling(self.unauthorized_recordings_api_instance.delete_call_transcription).with_args( + BW_ACCOUNT_ID, call_id, recording_id), raises(UnauthorizedException)) # Non-existent account id (403) - with self.assertRaises(ForbiddenException): - self.recordings_api_instance.delete_call_transcription("not an account id", call_id, recording_id) + assert_that(calling(self.recordings_api_instance.delete_call_transcription).with_args( + "not an account id", call_id, recording_id), raises(ForbiddenException)) # Non-existent recording id (404) - with self.assertRaises(NotFoundException): - self.recordings_api_instance.delete_call_transcription(BW_ACCOUNT_ID, call_id, "not a recording id") + assert_that(calling(self.recordings_api_instance.delete_call_transcription).with_args( + BW_ACCOUNT_ID, call_id, "not a recording id"), raises(NotFoundException)) def test_invalid_delete_recording_media(self) -> None: """ @@ -538,16 +547,16 @@ def test_invalid_delete_recording_media(self) -> None: recording_id = recordings[0].recording_id # Use the unauthorized client to try to delete a recording (401) - with self.assertRaises(UnauthorizedException): - self.unauthorized_recordings_api_instance.delete_recording_media(BW_ACCOUNT_ID, call_id, recording_id) + assert_that(calling(self.unauthorized_recordings_api_instance.delete_recording_media).with_args( + BW_ACCOUNT_ID, call_id, recording_id), raises(UnauthorizedException)) # Non-existent account id (403) - with self.assertRaises(ForbiddenException): - self.recordings_api_instance.delete_recording_media("not an account id", call_id, recording_id) + assert_that(calling(self.recordings_api_instance.delete_recording_media).with_args( + "not an account id", call_id, recording_id), raises(ForbiddenException)) # Non-existent recording id (404) - with self.assertRaises(NotFoundException): - self.recordings_api_instance.delete_recording_media(BW_ACCOUNT_ID, call_id, "not a recording id") + assert_that(calling(self.recordings_api_instance.delete_recording_media).with_args( + BW_ACCOUNT_ID, call_id, "not a recording id"), raises(NotFoundException)) def test_invalid_delete_recording(self) -> None: """ @@ -562,16 +571,16 @@ def test_invalid_delete_recording(self) -> None: recording_id = recordings[0].recording_id # Use the unauthorized client to try to delete a recording (401) - with self.assertRaises(UnauthorizedException): - self.unauthorized_recordings_api_instance.delete_recording(BW_ACCOUNT_ID, call_id, recording_id) + assert_that(calling(self.unauthorized_recordings_api_instance.delete_recording).with_args( + BW_ACCOUNT_ID, call_id, recording_id), raises(UnauthorizedException)) # Non-existent account id (403) - with self.assertRaises(ForbiddenException): - self.recordings_api_instance.delete_recording("not an account id", call_id, recording_id) + assert_that(calling(self.recordings_api_instance.delete_recording).with_args( + "not an account id", call_id, recording_id), raises(ForbiddenException)) # Non-existent recording id (404) - with self.assertRaises(NotFoundException): - self.recordings_api_instance.delete_recording(BW_ACCOUNT_ID, call_id, "not a recording id") + assert_that(calling(self.recordings_api_instance.delete_recording).with_args( + BW_ACCOUNT_ID, call_id, "not a recording id"), raises(NotFoundException)) def test_invalid_update_call_recording_state(self) -> None: """ @@ -591,23 +600,23 @@ def test_invalid_update_call_recording_state(self) -> None: retries += 1 # Make sure the call is alive - assert call_status['status'] == 'ALIVE' + assert_that(call_status['status'], equal_to('ALIVE')) # Common models pause_recording = UpdateCallRecording(RecordingStateEnum('paused')) resume_recording = UpdateCallRecording(RecordingStateEnum('recording')) # Use the unauthorized client to try to update (401) - with self.assertRaises(UnauthorizedException): - self.unauthorized_recordings_api_instance.update_call_recording_state(BW_ACCOUNT_ID, call_id, pause_recording) + assert_that(calling(self.unauthorized_recordings_api_instance.update_call_recording_state).with_args( + BW_ACCOUNT_ID, call_id, pause_recording), raises(UnauthorizedException)) # Non-existent account id (403) - with self.assertRaises(ForbiddenException): - self.recordings_api_instance.update_call_recording_state("not an account id", call_id, pause_recording) + assert_that(calling(self.recordings_api_instance.update_call_recording_state).with_args( + "not an account id", call_id, pause_recording), raises(ForbiddenException)) # Non-existent call id (404) - with self.assertRaises(NotFoundException): - self.recordings_api_instance.update_call_recording_state(BW_ACCOUNT_ID, "not a call id", pause_recording) + assert_that(calling(self.recordings_api_instance.update_call_recording_state).with_args( + BW_ACCOUNT_ID, "not a call id", pause_recording), raises(NotFoundException)) # Kill the call update_call = UpdateCall(state=CallStateEnum('completed')) From 5b33440d62d5a973dec0f682a15375e312512376 Mon Sep 17 00:00:00 2001 From: Cameron Koegel Date: Fri, 26 Aug 2022 15:55:59 -0400 Subject: [PATCH 4/7] media tests --- test/integration/test_media_api.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/test/integration/test_media_api.py b/test/integration/test_media_api.py index 51e6e746..86ca3e06 100644 --- a/test/integration/test_media_api.py +++ b/test/integration/test_media_api.py @@ -128,11 +128,5 @@ def testGetMediaWithBandwidthId(self) -> None: # use a nonexistent mediaId - results in a 404 media_id = "abcd1234-e5f6-1111-2222-3456ghi7890/image123456.jpg" - with self.assertRaises(NotFoundException) as context: - api_response = self.api_instance.get_media( - self.account_id, - media_id, - _preload_content=False - ) - - self.assertEqual(context.exception.status, 404) + assert_that(calling(self.api_instance.get_media).with_args( + self.account_id, media_id, _preload_content=False)), raises(NotFoundException) From a4ba56c06ae1038e32ee7de1e2af49101370aeaa Mon Sep 17 00:00:00 2001 From: Cameron Koegel Date: Fri, 26 Aug 2022 16:25:59 -0400 Subject: [PATCH 5/7] empty array --- test/integration/test_recordings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/test_recordings.py b/test/integration/test_recordings.py index 0b37f5aa..d0f34ec9 100644 --- a/test/integration/test_recordings.py +++ b/test/integration/test_recordings.py @@ -374,7 +374,7 @@ def test_invalid_list_call_recordings(self) -> None: # Non-existent call id # This should probably be a 404, but actually returns an empty list not_found_call_recordings = self.recordings_api_instance.list_call_recordings(BW_ACCOUNT_ID, "not a call id") - assert_that(not_found_call_recordings, empty) + assert_that(not_found_call_recordings, equal_to([])) def test_invalid_get_call_recording(self) -> None: """ From 3cbd274eaea4ac037e9af6adfc82416036936bed Mon Sep 17 00:00:00 2001 From: Cameron Koegel Date: Mon, 29 Aug 2022 11:26:00 -0400 Subject: [PATCH 6/7] update tests to use env var helper --- test/integration/test_messages_api.py | 13 ++++--- .../test_multi_factor_authentication.py | 28 ++++++------- test/integration/test_phone_number_lookup.py | 39 ++++++++++--------- test/integration/test_recordings.py | 19 ++++----- test/utils/env_variables.py | 35 ++++++++++------- 5 files changed, 71 insertions(+), 63 deletions(-) diff --git a/test/integration/test_messages_api.py b/test/integration/test_messages_api.py index 0d7cf0ed..f3d4c6a7 100644 --- a/test/integration/test_messages_api.py +++ b/test/integration/test_messages_api.py @@ -27,6 +27,7 @@ from bandwidth.model.priority_enum import PriorityEnum from bandwidth.model.message import Message from bandwidth.exceptions import ApiException, UnauthorizedException +from test.utils.env_variables import * class TestMessagesApi(unittest.TestCase): @@ -35,21 +36,21 @@ class TestMessagesApi(unittest.TestCase): def setUp(self): # API Client configuration = bandwidth.Configuration( - username = os.environ.get('BW_USERNAME'), - password = os.environ.get('BW_PASSWORD') + username = BW_USERNAME, + password = BW_PASSWORD ) api_client = bandwidth.ApiClient(configuration) self.api_instance = messages_api.MessagesApi(api_client) - self.account_id = os.environ.get('BW_ACCOUNT_ID') + self.account_id = BW_ACCOUNT_ID # Unauthorized API Client self.unauthorized_api_client = bandwidth.ApiClient() self.unauthorized_api_instance = messages_api.MessagesApi(self.unauthorized_api_client) # Message Properties - self.application_id = os.environ.get('BW_MESSAGING_APPLICATION_ID') - self.to_number = [os.environ.get('USER_NUMBER')] - self.from_number = os.environ.get('BW_NUMBER') + self.application_id = BW_MESSAGING_APPLICATION_ID + self.to_number = [USER_NUMBER] + self.from_number = BW_NUMBER self.text = 'python integration' self.media = ['https://cdn2.thecatapi.com/images/MTY3ODIyMQ.jpg'] self.tag = 'python integration tag' diff --git a/test/integration/test_multi_factor_authentication.py b/test/integration/test_multi_factor_authentication.py index 087762c5..a0e1103b 100644 --- a/test/integration/test_multi_factor_authentication.py +++ b/test/integration/test_multi_factor_authentication.py @@ -16,8 +16,8 @@ from bandwidth.model.verify_code_response import VerifyCodeResponse from bandwidth.model.voice_code_response import VoiceCodeResponse from bandwidth.exceptions import ApiException, UnauthorizedException, ForbiddenException +from test.utils.env_variables import * -import hamcrest from hamcrest.core import * from hamcrest.library import * @@ -27,31 +27,31 @@ class TestMultiFactorAuthentication(unittest.TestCase): def setUp(self) -> None: configuration = bandwidth.Configuration( - username=os.environ['BW_USERNAME'], - password=os.environ['BW_PASSWORD'] + username=BW_USERNAME, + password=BW_PASSWORD ) api_client = bandwidth.ApiClient(configuration) self.api_instance = mfa_api.MFAApi(api_client) - self.account_id = os.environ['BW_ACCOUNT_ID'] + self.account_id = BW_ACCOUNT_ID self.messaging_code_request = CodeRequest( - to=os.environ['USER_NUMBER'], - _from=os.environ['BW_NUMBER'], - application_id=os.environ['BW_MESSAGING_APPLICATION_ID'], + to=USER_NUMBER, + _from=BW_NUMBER, + application_id=BW_MESSAGING_APPLICATION_ID, scope="scope", message="Your temporary {NAME} {SCOPE} code is {CODE}", digits=6, ) self.voice_code_request = CodeRequest( - to=os.environ['USER_NUMBER'], - _from=os.environ['BW_NUMBER'], - application_id=os.environ['BW_VOICE_APPLICATION_ID'], + to=USER_NUMBER, + _from=BW_NUMBER, + application_id=BW_VOICE_APPLICATION_ID, scope="scope", message="Your temporary {NAME} {SCOPE} code is {CODE}", digits=6, ) self.bad_code_request = CodeRequest( - to=os.environ['USER_NUMBER'], - _from=os.environ['BW_NUMBER'], + to=USER_NUMBER, + _from=BW_NUMBER, application_id='not_an_application_id', scope="scope", message="Your temporary {NAME} {SCOPE} code is {CODE}", @@ -154,8 +154,8 @@ def testForbiddenRequest(self) -> None: """Validate a forbidden (403) request """ configuration = bandwidth.Configuration( - username=os.environ['BW_USERNAME_FORBIDDEN'], - # password=os.environ['BW_PASSWORD_FORBIDDEN'], + username=FORBIDDEN_USERNAME, + # password=FORBIDDEN_PASSWORD, password='bad_password' ) forbidden_api_client = bandwidth.ApiClient(configuration) diff --git a/test/integration/test_phone_number_lookup.py b/test/integration/test_phone_number_lookup.py index 711d1627..3a473fe5 100644 --- a/test/integration/test_phone_number_lookup.py +++ b/test/integration/test_phone_number_lookup.py @@ -16,6 +16,7 @@ from bandwidth.model.lookup_status_enum import LookupStatusEnum from bandwidth.model.tn_lookup_request_error import TnLookupRequestError from bandwidth.exceptions import ApiException, UnauthorizedException, ForbiddenException +from test.utils.env_variables import * from hamcrest.core import * from hamcrest.library import * @@ -29,12 +30,12 @@ class TestPhoneNumberLookupIntegration(unittest.TestCase): def setUp(self) -> None: configuration = bandwidth.Configuration( - username=os.environ['BW_USERNAME'], - password=os.environ['BW_PASSWORD'] + username=BW_USERNAME, + password=BW_PASSWORD ) api_client = bandwidth.ApiClient(configuration) self.api_instance = phone_number_lookup_api.PhoneNumberLookupApi(api_client) - self.account_id = os.environ['BW_ACCOUNT_ID'] + self.account_id = BW_ACCOUNT_ID def validateResult(self, result: LookupResult, e_164_format: str, line_provider: str) -> None: """Verify a successful phone number lookup LookupResult object @@ -105,11 +106,11 @@ def testSuccessfulPhoneNumberLookup(self) -> None: """ lookup_request = LookupRequest( tns=[ - os.environ['BW_NUMBER'], - os.environ['VZW_NUMBER'], - os.environ['ATT_NUMBER'], - os.environ['T_MOBILE_NUMBER'], - # os.environ['BW_INVALID_TN_LOOKUP_NUMBER'] + BW_NUMBER, + VZW_NUMBER, + ATT_NUMBER, + T_MOBILE_NUMBER, + # BW_INVALID_TN_LOOKUP_NUMBER ], ) @@ -143,24 +144,24 @@ def testSuccessfulPhoneNumberLookup(self) -> None: # Check the information for a Bandwidth TN bw_lookup_result: LookupResult = get_lookup_status_response.result[0] - self.validateResult(bw_lookup_result, os.environ['BW_NUMBER'], os.environ['BW_NUMBER_PROVIDER']) + self.validateResult(bw_lookup_result, BW_NUMBER, BW_NUMBER_PROVIDER) # Check the information for a Verizon TN vzw_lookup_result = get_lookup_status_response.result[1] - self.validateResult(vzw_lookup_result, os.environ['VZW_NUMBER'], "Verizon") + self.validateResult(vzw_lookup_result, VZW_NUMBER, "Verizon") # Check the information for an AT&T TN att_lookup_result = get_lookup_status_response.result[2] - self.validateResult(att_lookup_result, os.environ['ATT_NUMBER'], "AT&T") + self.validateResult(att_lookup_result, ATT_NUMBER, "AT&T") # Check the information for a T-Mobile TN t_mobile_lookup_result = get_lookup_status_response.result[3] - self.validateResult(t_mobile_lookup_result, os.environ['T_MOBILE_NUMBER'], "T-Mobile") + self.validateResult(t_mobile_lookup_result, T_MOBILE_NUMBER, "T-Mobile") # The only way to get a failed number is if the api call to the downstream service fails - so there is no way to force this in our testing currently # check the failed_telephone_number list # self.assertIs(type(get_lookup_status_response.failed_telephone_numbers), list) - # self.assertIn(os.environ['BW_INVALID_TN_LOOKUP_NUMBER'], get_lookup_status_response.failed_telephone_numbers) + # self.assertIn(BW_INVALID_TN_LOOKUP_NUMBER, get_lookup_status_response.failed_telephone_numbers) def testFailedPhoneNumberLookup(self) -> None: """Test Phone Number Lookup API with bad data to force an error @@ -186,8 +187,8 @@ def testDuplicatePhoneNumberLookup(self) -> None: with self.assertRaises(ApiException) as context: lookup_request = LookupRequest( tns=[ - os.environ['BW_NUMBER'], - os.environ['BW_NUMBER'] + BW_NUMBER, + BW_NUMBER ], ) self.api_instance.create_lookup(self.account_id, lookup_request) @@ -208,7 +209,7 @@ def testUnauthorizedRequest(self) -> None: unauthorized_api_client) lookup_request = LookupRequest( tns=[ - os.environ['BW_NUMBER'] + BW_NUMBER ], ) @@ -221,14 +222,14 @@ def testForbiddenRequest(self) -> None: """Validate a forbidden (403) request """ configuration = bandwidth.Configuration( - username=os.environ['BW_USERNAME_FORBIDDEN'], - password=os.environ['BW_PASSWORD_FORBIDDEN'] + username=FORBIDDEN_USERNAME, + password=FORBIDDEN_PASSWORD ) forbidden_api_client = bandwidth.ApiClient(configuration) forbidden_api_instance = phone_number_lookup_api.PhoneNumberLookupApi(forbidden_api_client) lookup_request = LookupRequest( tns=[ - os.environ['BW_NUMBER'] + BW_NUMBER ], ) diff --git a/test/integration/test_recordings.py b/test/integration/test_recordings.py index d0f34ec9..dd0fd5c6 100644 --- a/test/integration/test_recordings.py +++ b/test/integration/test_recordings.py @@ -33,26 +33,27 @@ from bandwidth.model.update_call import UpdateCall from bandwidth.model.update_call_recording import UpdateCallRecording from bandwidth.rest import RESTClientObject, RESTResponse +from test.utils.env_variables import * try: # BW Credentials - BW_USERNAME = os.environ["BW_USERNAME"] - BW_PASSWORD = os.environ["BW_PASSWORD"] - BW_ACCOUNT_ID = os.environ["BW_ACCOUNT_ID"] + BW_USERNAME = BW_USERNAME + BW_PASSWORD = BW_PASSWORD + BW_ACCOUNT_ID = BW_ACCOUNT_ID # Manteca Numbers - MANTECA_ACTIVE_NUMBER = os.environ["MANTECA_ACTIVE_NUMBER"] - MANTECA_IDLE_NUMBER = os.environ["MANTECA_IDLE_NUMBER"] + MANTECA_ACTIVE_NUMBER = MANTECA_ACTIVE_NUMBER + MANTECA_IDLE_NUMBER = MANTECA_IDLE_NUMBER # Manteca - MANTECA_BASE_URL = os.environ["MANTECA_BASE_URL"] + MANTECA_BASE_URL = MANTECA_BASE_URL MANTECA_STATUS_URL = MANTECA_BASE_URL + "tests/" - MANTECA_APPLICATION_ID = os.environ["MANTECA_APPLICATION_ID"] + MANTECA_APPLICATION_ID = MANTECA_APPLICATION_ID # Test Environment - PYTHON_VERSION = os.environ["PYTHON_VERSION"] - OPERATING_SYSTEM = os.environ["OPERATING_SYSTEM"] + PYTHON_VERSION = PYTHON_VERSION + OPERATING_SYSTEM = OPERATING_SYSTEM except KeyError as e: raise Exception("Environmental variables not found") diff --git a/test/utils/env_variables.py b/test/utils/env_variables.py index 7e25b7f3..efff46fb 100644 --- a/test/utils/env_variables.py +++ b/test/utils/env_variables.py @@ -1,23 +1,28 @@ import os try: - BW_USERNAME = os.environ["BW_USERNAME"] - BW_PASSWORD = os.environ["BW_PASSWORD"] - BW_ACCOUNT_ID = os.environ["BW_ACCOUNT_ID"] - BW_VOICE_APPLICATION_ID = os.environ["BW_VOICE_APPLICATION_ID"] - BASE_CALLBACK_URL = os.environ["BASE_CALLBACK_URL"] - BW_NUMBER = os.environ["BW_NUMBER"] - USER_NUMBER = os.environ["USER_NUMBER"] + BW_USERNAME = os.environ['BW_USERNAME'] + BW_PASSWORD = os.environ['BW_PASSWORD'] + BW_ACCOUNT_ID = os.environ['BW_ACCOUNT_ID'] + BW_MESSAGING_APPLICATION_ID = os.environ['BW_MESSAGING_APPLICATION_ID'] + BW_VOICE_APPLICATION_ID = os.environ['BW_VOICE_APPLICATION_ID'] + BASE_CALLBACK_URL = os.environ['BASE_CALLBACK_URL'] + BW_NUMBER_PROVIDER = os.environ['BW_NUMBER_PROVIDER'] + BW_NUMBER = os.environ['BW_NUMBER'] + VZW_NUMBER = os.environ['VZW_NUMBER'] + ATT_NUMBER = os.environ['ATT_NUMBER'] + T_MOBILE_NUMBER = os.environ['T_MOBILE_NUMBER'] + USER_NUMBER = os.environ['USER_NUMBER'] FORBIDDEN_USERNAME = os.environ['BW_USERNAME_FORBIDDEN'] FORBIDDEN_PASSWORD = os.environ['BW_PASSWORD_FORBIDDEN'] - MANTECA_ACTIVE_NUMBER = os.environ["MANTECA_ACTIVE_NUMBER"] - MANTECA_IDLE_NUMBER = os.environ["MANTECA_IDLE_NUMBER"] - MANTECA_BASE_URL = os.environ["MANTECA_BASE_URL"] - MANTECA_STATUS_URL = MANTECA_BASE_URL + "tests/" - MANTECA_APPLICATION_ID = os.environ["MANTECA_APPLICATION_ID"] - PYTHON_VERSION = os.environ["PYTHON_VERSION"] - OPERATING_SYSTEM = os.environ["OPERATING_SYSTEM"] + MANTECA_ACTIVE_NUMBER = os.environ['MANTECA_ACTIVE_NUMBER'] + MANTECA_IDLE_NUMBER = os.environ['MANTECA_IDLE_NUMBER'] + MANTECA_BASE_URL = os.environ['MANTECA_BASE_URL'] + MANTECA_STATUS_URL = MANTECA_BASE_URL + 'tests/' + MANTECA_APPLICATION_ID = os.environ['MANTECA_APPLICATION_ID'] + PYTHON_VERSION = os.environ['PYTHON_VERSION'] + OPERATING_SYSTEM = os.environ['OPERATING_SYSTEM'] RUNNER_OS = os.environ['RUNNER_OS'] except KeyError as e: - raise Exception("Environmental variables not found") \ No newline at end of file + raise Exception('Environmental variables not found') \ No newline at end of file From e7962c3314b59191120a8586c6fd1ff1cc1dfa5b Mon Sep 17 00:00:00 2001 From: Cameron Koegel Date: Mon, 29 Aug 2022 11:40:55 -0400 Subject: [PATCH 7/7] _ :upside_down_face --- test/integration/test_media_api.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/integration/test_media_api.py b/test/integration/test_media_api.py index 86ca3e06..5a970c60 100644 --- a/test/integration/test_media_api.py +++ b/test/integration/test_media_api.py @@ -44,7 +44,7 @@ def uploadMedia(self) -> None: account_id=self.account_id, media_id=media_id, body=self.original_file, - content_type=content_type, + _content_type=content_type, cache_control=cache_control, _return_http_data_only=False ) @@ -61,7 +61,7 @@ def uploadMedia(self) -> None: account_id=self.account_id, media_id=media_id, body=reopened_file, - content_type=content_type, + _content_type=content_type, cache_control=cache_control, _return_http_data_only=False )