diff --git a/test/integration/test_conferences.py b/test/integration/test_conferences.py index e1a02c0a..f25dbb13 100644 --- a/test/integration/test_conferences.py +++ b/test/integration/test_conferences.py @@ -2,9 +2,10 @@ Integration tests for Bandwidth's Voice Voice Conferences API """ +from cgi import test import json import time -from typing import List, Tuple +from typing import Dict, List, Tuple import unittest from hamcrest import assert_that, has_properties, not_none, instance_of, greater_than @@ -89,6 +90,7 @@ def setUp(self): self.testRecordId = "Recording-Id" self.TEST_SLEEP = 3 self.TEST_SLEEP_LONG = 10 + self.MAX_RETRIES = 40 def tearDown(self): callCleanup(self) @@ -141,24 +143,44 @@ def create_conference(self, answer_url: str) -> Tuple[str, str]: '_from', MANTECA_ACTIVE_NUMBER )) - list_conferences_response = self.conference_api_instance.list_conferences(BW_ACCOUNT_ID, _return_http_data_only=False) - + time.sleep(self.TEST_SLEEP) + list_conferences_response = self.conference_api_instance.list_conferences(BW_ACCOUNT_ID, name=test_id, _return_http_data_only=False) + assert_that(list_conferences_response[1], 200) - conferenceId = (list_conferences_response[0][len(list_conferences_response[0])-1].id) + # TODO: This is not deterministic; our latest conference may not always be the one we just created due to parallelism. + # This new solution should guarantee the right conference id is grabbed. + conference_id = list_conferences_response[0][0].id - get_conference_response = self.conference_api_instance.get_conference(BW_ACCOUNT_ID, conferenceId, _return_http_data_only=False) + get_conference_response = self.conference_api_instance.get_conference(BW_ACCOUNT_ID, conference_id, _return_http_data_only=False) assert_that(get_conference_response[1], 200) self.callIdArray.append(create_call_response.call_id) - return (test_id, create_call_response.call_id) + return (test_id, create_call_response.call_id, conference_id) def validate_recording(self, recording: ConferenceRecordingMetadata, conference_id: str) -> None: assert_that(recording.status,'complete') assert_that(recording.file_format,FileFormatEnum('wav')) + def get_test_status(self, test_id: str) -> Dict: + """ + Get the status of the specified test by its id value from Manteca services. + + Args: + test_id (str): The test id associated with the test to get the status of. + + Returns: + Dict: The status of the test requested. + """ + status_url = MANTECA_STATUS_URL + test_id + response: RESTResponse = self.rest_client.request( + method='GET', + url=status_url + ) + return json.loads(response.data) + def test_conference_and_members(self): """ Tests a successful flow of creating and ending a conference. @@ -171,8 +193,8 @@ def test_conference_and_members(self): - update_conference_bxml """ - answer_url = MANTECA_BASE_URL + "/bxml/joinConferencePause" - (test_id, call_id) = self.create_conference(answer_url) + answer_url = MANTECA_BASE_URL + "bxml/joinConferencePause" + (test_id, call_id, conference_id) = self.create_conference(answer_url) list_conferences_response = self.conference_api_instance.list_conferences(BW_ACCOUNT_ID, _return_http_data_only=False) @@ -180,33 +202,34 @@ def test_conference_and_members(self): assert_that(list_conferences_response[0][0].name, instance_of(str)) assert_that(list_conferences_response[0][0].id, instance_of(str)) - conferenceId = (list_conferences_response[0][len(list_conferences_response[0])-1].id) + # TODO: Also non-deterministic; we could differentiate by conference name instead? The conference name is set to be the test id by Manteca + # conferenceId = (list_conferences_response[0][len(list_conferences_response[0])-1].id) - get_conference_response = self.conference_api_instance.get_conference(BW_ACCOUNT_ID, conferenceId, _return_http_data_only=False) + get_conference_response = self.conference_api_instance.get_conference(BW_ACCOUNT_ID, conference_id, _return_http_data_only=False) assert_that(get_conference_response[1], 200) - assert_that(get_conference_response[0].id, conferenceId) + assert_that(get_conference_response[0].id, conference_id) assert_that(get_conference_response[0].name, instance_of(str)) callId = (get_conference_response[0].active_members[0].call_id) self.callIdArray.append(callId) - get_conference_member_response = self.conference_api_instance.get_conference_member(BW_ACCOUNT_ID, conferenceId, callId, _return_http_data_only=False) + get_conference_member_response = self.conference_api_instance.get_conference_member(BW_ACCOUNT_ID, conference_id, callId, _return_http_data_only=False) assert_that(get_conference_member_response[1], 200) - assert_that(get_conference_member_response[0].conference_id, conferenceId) + assert_that(get_conference_member_response[0].conference_id, conference_id) assert_that(get_conference_member_response[0].call_id, callId) - time.sleep(self.TEST_SLEEP) - update_conference_member_response = self.conference_api_instance.update_conference_member(BW_ACCOUNT_ID, conferenceId, callId, self.testUpdateMember, _return_http_data_only=False) + # time.sleep(self.TEST_SLEEP) + update_conference_member_response = self.conference_api_instance.update_conference_member(BW_ACCOUNT_ID, conference_id, callId, self.testUpdateMember, _return_http_data_only=False) assert_that(update_conference_member_response[1], 204) - time.sleep(self.TEST_SLEEP) - update_conference_response = self.conference_api_instance.update_conference(BW_ACCOUNT_ID, conferenceId, self.testUpdateConf, _return_http_data_only=False) + # time.sleep(self.TEST_SLEEP) + update_conference_response = self.conference_api_instance.update_conference(BW_ACCOUNT_ID, conference_id, self.testUpdateConf, _return_http_data_only=False) assert_that(update_conference_response[1], 204) updateBxmlBody = 'This is a test bxml response' - time.sleep(self.TEST_SLEEP) - update_conference_bxml_response = self.conference_api_instance.update_conference_bxml(BW_ACCOUNT_ID, conferenceId, updateBxmlBody, _return_http_data_only=False) + # time.sleep(self.TEST_SLEEP) + update_conference_bxml_response = self.conference_api_instance.update_conference_bxml(BW_ACCOUNT_ID, conference_id, updateBxmlBody, _return_http_data_only=False) assert_that(update_conference_bxml_response[1], 204) update_call = UpdateCall(state=CallStateEnum('completed')) @@ -221,39 +244,47 @@ def test_conference_recordings(self) -> None: - download_conference_recording """ - answer_url = MANTECA_BASE_URL + "/bxml/joinConferencePause" - (test_id, call_id) = self.create_conference(answer_url) + answer_url = MANTECA_BASE_URL + "bxml/joinConferencePause" + (test_id, call_id, conference_id) = self.create_conference(answer_url) list_conferences_response = self.conference_api_instance.list_conferences(BW_ACCOUNT_ID, _return_http_data_only=False) assert_that(list_conferences_response[1], 200) - conferenceId = (list_conferences_response[0][len(list_conferences_response[0])-1].id) updateBxmlBody = 'This should be a conference recording.' - update_conference_bxml_response = self.conference_api_instance.update_conference_bxml(BW_ACCOUNT_ID, conferenceId, updateBxmlBody, _return_http_data_only=False) + update_conference_bxml_response = self.conference_api_instance.update_conference_bxml(BW_ACCOUNT_ID, conference_id, updateBxmlBody, _return_http_data_only=False) assert_that(update_conference_bxml_response[1], 204) - - time.sleep(self.TEST_SLEEP_LONG) - list_conference_recordings_response: List[ConferenceRecordingMetadata] = self.conference_api_instance.list_conference_recordings(BW_ACCOUNT_ID, conferenceId, _return_http_data_only=False) + # Poll Manteca to ensure our conference is recorded + call_status = self.get_test_status(test_id) + retries = 0 + while call_status['callRecorded'] == False and retries < self.MAX_RETRIES: + time.sleep(self.TEST_SLEEP) + call_status = self.get_test_status(test_id) + retries += 1 + + # If we failed to get a recorded conference, fail due to polling timeout + assert call_status['callRecorded'] == True + + list_conference_recordings_response: List[ConferenceRecordingMetadata] = self.conference_api_instance.list_conference_recordings(BW_ACCOUNT_ID, conference_id, _return_http_data_only=False) assert_that(list_conference_recordings_response[1],200) conference_recordings = list_conference_recordings_response[0] assert_that(len(conference_recordings), greater_than(0)) first_recording: ConferenceRecordingMetadata = conference_recordings[0] - self.validate_recording(first_recording, conferenceId) + self.validate_recording(first_recording, conference_id) recording_id = first_recording.recording_id - recording_response: ConferenceRecordingMetadata = self.conference_api_instance.get_conference_recording(BW_ACCOUNT_ID, conferenceId, recording_id, _return_http_data_only=False) + recording_response: ConferenceRecordingMetadata = self.conference_api_instance.get_conference_recording(BW_ACCOUNT_ID, conference_id, recording_id, _return_http_data_only=False) assert_that(recording_response[1], 200) - assert_that(recording_response[0].conference_id, conferenceId) + assert_that(recording_response[0].conference_id, conference_id) assert_that(recording_response[0].recording_id, recording_id) assert_that(recording_response[0].name, instance_of(str)) - self.validate_recording(recording_response[0], conferenceId) + self.validate_recording(recording_response[0], conference_id) - recording_media_response = self.conference_api_instance.download_conference_recording(BW_ACCOUNT_ID, conferenceId, recording_id, _preload_content=False) + recording_media_response = self.conference_api_instance.download_conference_recording(BW_ACCOUNT_ID, conference_id, recording_id, _preload_content=False) conference_recording_media = recording_media_response.data def test_list_conferences_unauthorized(self) -> None: diff --git a/test/integration/test_recordings.py b/test/integration/test_recordings.py index d1a42596..cfe5ab41 100644 --- a/test/integration/test_recordings.py +++ b/test/integration/test_recordings.py @@ -217,7 +217,6 @@ def get_test_status(self, test_id: str) -> Dict: ) return json.loads(response.data) - @unittest.skip("Manteca currently broken") def test_successful_call_recording(self) -> None: """ Tests a successful flow of creating a call with a recording. @@ -281,7 +280,7 @@ def test_successful_call_recording(self) -> None: call_status = self.get_test_status(test_id) retries += 1 - # If we failed to get a transcribed call, fail due to polling timeout (TEMP COMMENTED) + # If we failed to get a transcribed call, fail due to polling timeout assert call_status['callTranscribed'] == True # Get the transcription @@ -312,7 +311,6 @@ def test_successful_call_recording(self) -> None: call_recordings = self.recordings_api_instance.list_call_recordings(BW_ACCOUNT_ID, call_id) assert len(call_recordings) == 0 - @unittest.skip("Manteca currently broken") def test_successful_update_active_recording(self) -> None: """ Tests updating the recording for a call that is currently active. @@ -349,7 +347,6 @@ def test_successful_update_active_recording(self) -> None: update_call = UpdateCall(state=CallStateEnum('completed')) self.calls_api_instance.update_call(BW_ACCOUNT_ID, call_id, update_call) - @unittest.skip("Manteca currently broken") def test_invalid_list_call_recordings(self) -> None: """ Tests invalid flows for list_call_recordings @@ -370,7 +367,6 @@ def test_invalid_list_call_recordings(self) -> None: # 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") == [] - @unittest.skip("Manteca currently broken") def test_invalid_get_call_recording(self) -> None: """ Tests invalid flows for get_call_recording @@ -395,7 +391,6 @@ def test_invalid_get_call_recording(self) -> None: with self.assertRaises(NotFoundException): self.recordings_api_instance.get_call_recording(BW_ACCOUNT_ID, call_id, "not a recording id") - @unittest.skip("Manteca currently broken") def test_invalid_download_call_recording(self) -> None: """ Tests invalid flows for download_call_recording @@ -420,7 +415,6 @@ def test_invalid_download_call_recording(self) -> None: with self.assertRaises(NotFoundException): self.recordings_api_instance.download_call_recording(BW_ACCOUNT_ID, call_id, "not a recording id") - @unittest.skip("Manteca currently broken") def test_invalid_transcribe_call_recording(self) -> None: """ Tests invalid flows for transcribe_call_recording @@ -451,7 +445,6 @@ def test_invalid_transcribe_call_recording(self) -> None: # self.recordings_api_instance.transcribe_call_recording(BW_ACCOUNT_ID, call_id, "not a recording id", transcribe_recording) - @unittest.skip("Manteca currently broken") def test_invalid_get_call_transcription(self) -> None: """ Tests invalid flows for get_call_transcription @@ -492,7 +485,6 @@ def test_invalid_get_call_transcription(self) -> None: with self.assertRaises(NotFoundException): self.recordings_api_instance.get_call_transcription(BW_ACCOUNT_ID, call_id, "not a recording id") - @unittest.skip("Manteca currently broken") def test_invalid_delete_call_transcription(self) -> None: """ Tests invalid flows for delete_call_transcription @@ -533,7 +525,6 @@ def test_invalid_delete_call_transcription(self) -> None: with self.assertRaises(NotFoundException): self.recordings_api_instance.delete_call_transcription(BW_ACCOUNT_ID, call_id, "not a recording id") - @unittest.skip("Manteca currently broken") def test_invalid_delete_recording_media(self) -> None: """ Tests invalid flows for delete_recording_media @@ -558,7 +549,6 @@ def test_invalid_delete_recording_media(self) -> None: with self.assertRaises(NotFoundException): self.recordings_api_instance.delete_recording_media(BW_ACCOUNT_ID, call_id, "not a recording id") - @unittest.skip("Manteca currently broken") def test_invalid_delete_recording(self) -> None: """ Tests invalid flows for delete_recording @@ -583,7 +573,6 @@ def test_invalid_delete_recording(self) -> None: with self.assertRaises(NotFoundException): self.recordings_api_instance.delete_recording(BW_ACCOUNT_ID, call_id, "not a recording id") - @unittest.skip("Manteca currently broken") def test_invalid_update_call_recording_state(self) -> None: """ Tests invalid flows for update_call_recording_state