From cf4a633ded8322f648acdf07afc79c21cceadd24 Mon Sep 17 00:00:00 2001
From: Cameron Koegel <53310569+ckoegel@users.noreply.github.com>
Date: Tue, 18 Jun 2024 15:59:27 -0400
Subject: [PATCH] SWI-5462 Add Real Time Transcriptions Tests (#207)
* add privacy field to calls api test
* remove unused env var
* update recordings smoke tests to use new method names
* add files for stats and transcriptions apis
* update smoke test header blocks
* add statistics smoke tests
* fill in skeleton of transcriptions test
* transcriptions
* 403 from manteca :(
* finalize transcriptions tests
* update smoke test wf
* only main
---
.../{test-nightly.yml => test-smoke.yml} | 9 +-
test/smoke/test_calls_api.py | 3 +-
test/smoke/test_conferences_api.py | 2 +-
test/smoke/test_media_api.py | 2 +-
test/smoke/test_messages_api.py | 10 +-
test/smoke/test_recordings_api.py | 32 ++--
test/smoke/test_statistics_api.py | 41 +++++
test/smoke/test_transcriptions_api.py | 154 ++++++++++++++++++
test/utils/env_variables.py | 1 -
9 files changed, 219 insertions(+), 35 deletions(-)
rename .github/workflows/{test-nightly.yml => test-smoke.yml} (95%)
create mode 100644 test/smoke/test_statistics_api.py
create mode 100644 test/smoke/test_transcriptions_api.py
diff --git a/.github/workflows/test-nightly.yml b/.github/workflows/test-smoke.yml
similarity index 95%
rename from .github/workflows/test-nightly.yml
rename to .github/workflows/test-smoke.yml
index 15325927..e3cd470d 100644
--- a/.github/workflows/test-nightly.yml
+++ b/.github/workflows/test-smoke.yml
@@ -1,4 +1,4 @@
-name: Nightly Smoke Tests
+name: Smoke Tests
on:
schedule:
@@ -13,6 +13,11 @@ on:
options:
- WARNING
- DEBUG
+ pull_request:
+ branches:
+ - main
+ paths:
+ - 'test/smoke/**'
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref }}
@@ -39,7 +44,7 @@ env:
jobs:
test:
- name: Nightly Smoke Test
+ name: Smoke Test
runs-on: ubuntu-latest
env:
PYTHON_VERSION: '3.12'
diff --git a/test/smoke/test_calls_api.py b/test/smoke/test_calls_api.py
index 0dea554e..03b90049 100644
--- a/test/smoke/test_calls_api.py
+++ b/test/smoke/test_calls_api.py
@@ -1,5 +1,5 @@
"""
-Integration test for Bandwidth's Voice Voice Calls API
+Integration test for Bandwidth's Voice Calls API
"""
from bandwidth import ApiResponse
from test.utils.env_variables import *
@@ -57,6 +57,7 @@ def setUp(self):
self.createCallBody = CreateCall(
to=USER_NUMBER,
var_from=BW_NUMBER,
+ privacy=True,
application_id=BW_VOICE_APPLICATION_ID,
answer_url=BASE_CALLBACK_URL,
answer_method=CallbackMethodEnum("POST"),
diff --git a/test/smoke/test_conferences_api.py b/test/smoke/test_conferences_api.py
index e222c7b4..4af01266 100644
--- a/test/smoke/test_conferences_api.py
+++ b/test/smoke/test_conferences_api.py
@@ -1,5 +1,5 @@
"""
-Integration tests for Bandwidth's Voice Voice Conferences API
+Integration tests for Bandwidth's Voice Conferences API
"""
from cgi import test
diff --git a/test/smoke/test_media_api.py b/test/smoke/test_media_api.py
index 3c7dd6c4..23147811 100644
--- a/test/smoke/test_media_api.py
+++ b/test/smoke/test_media_api.py
@@ -1,5 +1,5 @@
"""
-Integration test for Bandwidth's Media API
+Integration test for Bandwidth's Messaging Media API
"""
import uuid
diff --git a/test/smoke/test_messages_api.py b/test/smoke/test_messages_api.py
index 8e5bcb27..074350a0 100644
--- a/test/smoke/test_messages_api.py
+++ b/test/smoke/test_messages_api.py
@@ -1,13 +1,5 @@
"""
- Bandwidth
-
-
- Bandwidth's Communication APIs # noqa: E501
-
-
- The version of the OpenAPI document: 1.0.0
- Contact: letstalk@bandwidth.com
- Generated by: https://openapi-generator.tech
+Integration test for Bandwidth's Messaging API
"""
import os
diff --git a/test/smoke/test_recordings_api.py b/test/smoke/test_recordings_api.py
index 17c9c4bf..e631a7a0 100644
--- a/test/smoke/test_recordings_api.py
+++ b/test/smoke/test_recordings_api.py
@@ -1,14 +1,6 @@
"""
- Bandwidth
-
- Bandwidth's Communication APIs # noqa: E501
-
- The version of the OpenAPI document: 1.0.0
- Contact: letstalk@bandwidth.com
- Generated by: https://openapi-generator.tech
+Integration test for Bandwidth's Voice Recordings API
"""
-
-
import os
from typing import Dict, List, Tuple
import unittest
@@ -219,8 +211,8 @@ def test_successful_call_recording(self) -> None:
- get_call_recording
- download_call_recording
- transcribe_call_recording
- - get_call_transcription
- - delete_call_transcription
+ - get_recording_transcription
+ - delete_recording_transcription
- delete_recording_media
- delete_recording
"""
@@ -288,7 +280,7 @@ def test_successful_call_recording(self) -> None:
assert_that(call_status['callTranscribed'], equal_to(True))
# Get the transcription
- transcription_response = self.recordings_api_instance.get_call_transcription_with_http_info(
+ transcription_response = self.recordings_api_instance.get_recording_transcription_with_http_info(
BW_ACCOUNT_ID, call_id, recording_id)
assert_that(transcription_response.status_code, equal_to(200)) # Check response code
@@ -302,11 +294,11 @@ def test_successful_call_recording(self) -> None:
))
# Delete the transcription
- delete_transcription_response = self.recordings_api_instance.delete_call_transcription_with_http_info(
+ delete_transcription_response = self.recordings_api_instance.get_recording_transcription_with_http_info(
BW_ACCOUNT_ID, call_id, recording_id)
assert_that(delete_transcription_response.status_code, equal_to(204)) # Check response code
- assert_that(calling(self.recordings_api_instance.get_call_transcription).with_args(
+ assert_that(calling(self.recordings_api_instance.get_recording_transcription).with_args(
BW_ACCOUNT_ID, call_id, recording_id), raises(NotFoundException))
# Delete Recording media
@@ -454,28 +446,28 @@ def test_4xx_errors(self) -> None:
assert_that(call_status['callTranscribed'], equal_to(True))
# Use the unauthorized client to get transcripion (401)
- assert_that(calling(self.unauthorized_recordings_api_instance.get_call_transcription).with_args(
+ assert_that(calling(self.unauthorized_recordings_api_instance.get_recording_transcription).with_args(
BW_ACCOUNT_ID, call_id, recording_id), raises(UnauthorizedException))
# Non-existent account id (403)
- assert_that(calling(self.recordings_api_instance.get_call_transcription).with_args(
+ assert_that(calling(self.recordings_api_instance.get_recording_transcription).with_args(
"not an account id", call_id, recording_id), raises(ForbiddenException))
# Non-existent recording id (404)
- assert_that(calling(self.recordings_api_instance.get_call_transcription).with_args(
+ assert_that(calling(self.recordings_api_instance.get_recording_transcription).with_args(
BW_ACCOUNT_ID, call_id, "not a recording id"), raises(NotFoundException))
# Delete Transcription
# Use the unauthorized client to delete transcripion (401)
- assert_that(calling(self.unauthorized_recordings_api_instance.delete_call_transcription).with_args(
+ assert_that(calling(self.unauthorized_recordings_api_instance.delete_recording_transcription).with_args(
BW_ACCOUNT_ID, call_id, recording_id), raises(UnauthorizedException))
# Non-existent account id (403)
- assert_that(calling(self.recordings_api_instance.delete_call_transcription).with_args(
+ assert_that(calling(self.recordings_api_instance.delete_recording_transcription).with_args(
"not an account id", call_id, recording_id), raises(ForbiddenException))
# Non-existent recording id (404)
- assert_that(calling(self.recordings_api_instance.delete_call_transcription).with_args(
+ assert_that(calling(self.recordings_api_instance.delete_recording_transcription).with_args(
BW_ACCOUNT_ID, call_id, "not a recording id"), raises(NotFoundException))
# Delete Recording Media
diff --git a/test/smoke/test_statistics_api.py b/test/smoke/test_statistics_api.py
new file mode 100644
index 00000000..2e99f0e7
--- /dev/null
+++ b/test/smoke/test_statistics_api.py
@@ -0,0 +1,41 @@
+"""
+Integration test for Bandwidth's Statistics API
+"""
+import unittest
+import logging
+
+from hamcrest import *
+from bandwidth import ApiClient, Configuration
+from bandwidth.api.statistics_api import StatisticsApi
+from bandwidth.models import AccountStatistics
+from test.utils.env_variables import *
+
+
+class TestStatisticsApi(unittest.TestCase):
+ """StatisticsApi integration Test
+ """
+
+ def setUp(self):
+ configuration = Configuration(
+ username=BW_USERNAME,
+ password=BW_PASSWORD
+ )
+ self.api_client = ApiClient(configuration)
+ self.api_instance = StatisticsApi(self.api_client)
+ self.account_id = BW_ACCOUNT_ID
+
+ def test_get_statistics(self):
+ api_response_with_http_info = self.api_instance.get_statistics_with_http_info(self.account_id)
+
+ logging.debug(api_response_with_http_info)
+ assert_that(api_response_with_http_info.status_code, equal_to(200))
+
+ api_response = self.api_instance.get_statistics(self.account_id)
+ assert_that(api_response, instance_of(AccountStatistics))
+ assert_that(api_response, has_properties(
+ 'current_call_queue_size', instance_of(int),
+ 'max_call_queue_size', instance_of(int)
+ ))
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/test/smoke/test_transcriptions_api.py b/test/smoke/test_transcriptions_api.py
new file mode 100644
index 00000000..dda936ef
--- /dev/null
+++ b/test/smoke/test_transcriptions_api.py
@@ -0,0 +1,154 @@
+"""
+Integration test for Bandwidth's Voice Transcriptions API
+"""
+import unittest
+import time
+
+from hamcrest import *
+from bandwidth import ApiClient, Configuration
+from bandwidth.rest import RESTClientObject, RESTResponse
+from bandwidth.api.transcriptions_api import TranscriptionsApi
+from bandwidth.api.calls_api import CallsApi
+from bandwidth.models import CreateCall, CallTranscriptionMetadata, CallTranscriptionResponse, CallTranscription
+from test.utils.env_variables import *
+
+
+class TestTranscriptionsApi(unittest.TestCase):
+ """TranscriptionsApi integration Test"""
+
+ def setUp(self) -> None:
+ configuration = Configuration(
+ username=BW_USERNAME,
+ password=BW_PASSWORD
+ )
+ api_client = ApiClient(configuration)
+
+ self.calls_api_instance = CallsApi(api_client)
+ self.transcriptions_api_instance = TranscriptionsApi(api_client)
+
+ # Rest client for interacting with Manteca
+ self.rest_client = RESTClientObject(Configuration.get_default_copy())
+
+ # Call ID Array
+ self.callIdArray = []
+ self.SLEEP_TIME_SEC = 3
+
+ # Transcription ID
+ self.transcription_id: str
+
+ def create_call_transcription(self) -> None:
+
+ # Initialize the call with Manteca
+ response = self.rest_client.request(
+ method='POST',
+ url=MANTECA_BASE_URL + '/tests',
+ body={
+ 'os': OPERATING_SYSTEM,
+ 'language': 'python' + PYTHON_VERSION,
+ 'type': 'CALL'
+ },
+ headers={
+ 'Content-Type': 'application/json'
+ }
+ )
+
+ # Get the test id from the response
+ test_id = response.response.data.decode("utf-8")
+ answer_url = MANTECA_BASE_URL + '/bxml/idle'
+
+ # Make a CreateCall body and assign the appropriate params
+ call_body = CreateCall(to=MANTECA_IDLE_NUMBER, var_from=MANTECA_ACTIVE_NUMBER,
+ application_id=MANTECA_APPLICATION_ID, answer_url=answer_url, tag=test_id)
+
+ # Make the call
+ create_call_response: CreateCallResponse = self.calls_api_instance.create_call(
+ BW_ACCOUNT_ID, call_body)
+ # assert_that(create_call_response.status_code, equal_to(201))
+
+ # Get the call id from the response
+ self.call_id = create_call_response.call_id
+
+ # Adding the call to the callIdArray
+ self.callIdArray.append(create_call_response.call_id)
+
+
+ time.sleep(self.SLEEP_TIME_SEC)
+ start_transcription_bxml = ""
+ start_response = self.calls_api_instance.update_call_bxml_with_http_info(
+ BW_ACCOUNT_ID, self.call_id, start_transcription_bxml)
+ assert_that(start_response.status_code, equal_to(204))
+
+ stop_transcription_bxml = ""
+ stop_response = self.calls_api_instance.update_call_bxml_with_http_info(
+ BW_ACCOUNT_ID, self.call_id, stop_transcription_bxml)
+ assert_that(stop_response.status_code, equal_to(204))
+ time.sleep(self.SLEEP_TIME_SEC)
+
+ end_response = self.calls_api_instance.update_call_with_http_info(
+ BW_ACCOUNT_ID, self.call_id, {"state": "completed"})
+ assert_that(end_response.status_code, equal_to(200))
+
+ def list_real_time_transcriptions(self) -> None:
+ """Test case for list_real_time_transcriptions
+
+ Enumerate transcriptions made with StartTranscription
+ """
+ time.sleep(self.SLEEP_TIME_SEC * 20)
+ response = self.transcriptions_api_instance.list_real_time_transcriptions_with_http_info(
+ BW_ACCOUNT_ID, self.call_id)
+
+ assert_that(response.status_code, equal_to(200))
+ assert_that(response.data, instance_of(list))
+ assert_that(response.data[0], instance_of(CallTranscriptionMetadata))
+ assert_that(response.data[0].transcription_id, instance_of(str))
+ assert_that(response.data[0].transcription_url, instance_of(str))
+
+ self.transcription_id = response.data[0].transcription_id
+
+ def get_real_time_transcription(self) -> None:
+ """Test case for get_real_time_transcription
+
+ Retrieve a specific transcription
+ """
+ response = self.transcriptions_api_instance.get_real_time_transcription_with_http_info(
+ BW_ACCOUNT_ID, self.call_id, self.transcription_id)
+
+ assert_that(response.status_code, equal_to(200))
+ assert_that(response.data, instance_of(CallTranscriptionResponse))
+ assert_that(response.data.account_id, equal_to(BW_ACCOUNT_ID))
+ assert_that(response.data.call_id, equal_to(self.call_id))
+ assert_that(response.data.transcription_id, equal_to(self.transcription_id))
+ assert_that(response.data.tracks, instance_of(list))
+ assert_that(response.data.tracks[0], instance_of(CallTranscription))
+ assert_that(response.data.tracks[0].track, equal_to('inbound'))
+ assert_that(response.data.tracks[0].confidence, instance_of(float))
+
+ def delete_real_time_transcription(self) -> None:
+ """Test case for delete_real_time_transcription
+
+ Delete a specific transcription
+ """
+ response = self.transcriptions_api_instance.delete_real_time_transcription_with_http_info(
+ BW_ACCOUNT_ID, self.call_id, self.transcription_id)
+
+ assert_that(response.status_code, equal_to(200))
+
+ def _steps(self):
+ call_order = [
+ 'create_call_transcription',
+ 'list_real_time_transcriptions',
+ 'get_real_time_transcription',
+ 'delete_real_time_transcription'
+ ]
+ for name in call_order:
+ yield name, getattr(self, name)
+
+ def test_steps(self) -> None:
+ """Test each function from _steps.call_order in specified order
+ """
+
+ for name, step in self._steps():
+ step()
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/test/utils/env_variables.py b/test/utils/env_variables.py
index a6d11ef8..d9a89c73 100644
--- a/test/utils/env_variables.py
+++ b/test/utils/env_variables.py
@@ -7,7 +7,6 @@
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']