From 3f54f92bd8bedb1e634f51c0d1d4b565a4d68fb4 Mon Sep 17 00:00:00 2001 From: Zihan Zhang Date: Fri, 10 Sep 2021 12:23:52 -0700 Subject: [PATCH] Fix SDK bug. Add UT for Call Connection apis. --- .../callingserver/_call_connection.py | 59 +-- .../callingserver/_callingserver_client.py | 2 +- .../callingserver/_converters/__init__.py | 5 +- .../callingserver/_converters/_converter.py | 52 ++- .../communication/callingserver/_models.py | 14 +- .../aio/_call_connection_async.py | 59 +-- .../aio/_callingserver_client_async.py | 2 +- .../tests/_test_constants.py | 54 ++- .../tests/_test_utils.py | 6 +- .../tests/test_call_connection.py | 382 ++++++++++++++++++ .../tests/test_call_connection_async.py | 380 +++++++++++++++++ .../tests/test_callingserver_client.py | 22 +- .../tests/test_callingserver_client_async.py | 22 +- 13 files changed, 917 insertions(+), 142 deletions(-) diff --git a/sdk/communication/azure-communication-callingserver/azure/communication/callingserver/_call_connection.py b/sdk/communication/azure-communication-callingserver/azure/communication/callingserver/_call_connection.py index be9461a4f1e..cc3848698e9 100644 --- a/sdk/communication/azure-communication-callingserver/azure/communication/callingserver/_call_connection.py +++ b/sdk/communication/azure-communication-callingserver/azure/communication/callingserver/_call_connection.py @@ -10,7 +10,7 @@ from ._generated.operations import CallConnectionsOperations from ._generated.models import CancelAllMediaOperationsRequest, PlayAudioRequest, PhoneNumberIdentifierModel -from ._converters import PlayAudioRequestConverter +from ._converters import PlayAudioRequestConverter, AddParticipantRequestConverter from ._models import PlayAudioOptions, PlayAudioResult, CancelAllMediaOperationsResult, AddParticipantResult from ._communication_identifier_serializer import (deserialize_identifier, serialize_identifier) @@ -60,53 +60,17 @@ def cancel_all_media_operations( def play_audio( self, audio_file_uri, # type: str - loop, # type: bool - audio_file_id, # type: str - callback_uri, # type: str - operation_context = None, # type: Optional[str] - **kwargs, # type: str: Any - ): # type: (...) -> PlayAudioResult - - try: - if not audio_file_uri.lower().startswith('http'): - audio_file_uri = "https://" + audio_file_uri - except AttributeError: - raise ValueError("URL must be a string.") - - if not audio_file_id: - raise ValueError("audio_file_id can not be None") - - try: - if not callback_uri.lower().startswith('http'): - callback_uri = "https://" + callback_uri - except AttributeError: - raise ValueError("URL must be a string.") - - play_audio_options = PlayAudioOptions( - audio_file_uri=audio_file_uri, - loop = loop, - audio_file_id=audio_file_id, - callback_uri=callback_uri, - operation_context=operation_context, - ) - - return self.play_audio( - playaudio_options=play_audio_options, - **kwargs - ) - - @distributed_trace() - @overload - def play_audio( - self, play_audio_options, # type: PlayAudioOptions **kwargs, # type: str: Any ): # type: (...) -> PlayAudioResult + if not audio_file_uri: + raise ValueError("audio_file_uri can not be None") + if not play_audio_options: raise ValueError("options can not be None") - play_audio_request = PlayAudioRequestConverter.convert(play_audio_options) + play_audio_request = PlayAudioRequestConverter.convert(audio_file_uri, play_audio_options) play_audio_result = self.call_connection_client.play_audio( call_connection_id=self.call_connection_id, @@ -128,12 +92,17 @@ def add_participant( if not participant: raise ValueError("participant can not be None") + alternate_caller_id = None if alternate_caller_id == None else PhoneNumberIdentifierModel(value=alternate_caller_id) + + add_participant_request = AddParticipantRequestConverter.convert( + serialize_identifier(participant), + alternate_caller_id, + operation_context + ) + add_participant_result = self.call_connection_client.add_participant( call_connection_id=self.call_connection_id, - participant=serialize_identifier(participant), - alternate_caller_id=None if alternate_caller_id == None else PhoneNumberIdentifierModel(value=alternate_caller_id.properties['value']), - operation_context=operation_context, - callback_uri=None, + add_participant_request=add_participant_request, **kwargs ) diff --git a/sdk/communication/azure-communication-callingserver/azure/communication/callingserver/_callingserver_client.py b/sdk/communication/azure-communication-callingserver/azure/communication/callingserver/_callingserver_client.py index af1d0864000..9531c7f2b7f 100644 --- a/sdk/communication/azure-communication-callingserver/azure/communication/callingserver/_callingserver_client.py +++ b/sdk/communication/azure-communication-callingserver/azure/communication/callingserver/_callingserver_client.py @@ -162,7 +162,7 @@ def create_call_connection( callback_uri=options.callback_uri, requested_media_types=options.requested_media_types, requested_call_events=options.requested_call_events, - alternate_caller_id=None if options.alternate_Caller_Id == None else PhoneNumberIdentifierModel(value=options.alternate_Caller_Id), + alternate_caller_id=None if options.alternate_Caller_Id == None else PhoneNumberIdentifierModel(value=options.alternate_Caller_Id.properties['value']), subject=options.subject, **kwargs ) diff --git a/sdk/communication/azure-communication-callingserver/azure/communication/callingserver/_converters/__init__.py b/sdk/communication/azure-communication-callingserver/azure/communication/callingserver/_converters/__init__.py index 4082d80f453..d9429823a46 100644 --- a/sdk/communication/azure-communication-callingserver/azure/communication/callingserver/_converters/__init__.py +++ b/sdk/communication/azure-communication-callingserver/azure/communication/callingserver/_converters/__init__.py @@ -1,6 +1,7 @@ -from ._converter import JoinCallRequestConverter, PlayAudioRequestConverter +from ._converter import JoinCallRequestConverter, PlayAudioRequestConverter, AddParticipantRequestConverter __all__ = [ 'JoinCallRequestConverter', - 'PlayAudioRequestConverter' + 'PlayAudioRequestConverter', + "AddParticipantRequestConverter" ] \ No newline at end of file diff --git a/sdk/communication/azure-communication-callingserver/azure/communication/callingserver/_converters/_converter.py b/sdk/communication/azure-communication-callingserver/azure/communication/callingserver/_converters/_converter.py index 961f0ad7533..873a456e165 100644 --- a/sdk/communication/azure-communication-callingserver/azure/communication/callingserver/_converters/_converter.py +++ b/sdk/communication/azure-communication-callingserver/azure/communication/callingserver/_converters/_converter.py @@ -5,12 +5,23 @@ # -------------------------------------------------------------------------- from .._models import JoinCallOptions, PlayAudioOptions -from .._shared.models import CommunicationIdentifier -from .._generated.models import JoinCallRequest, PlayAudioRequest, CommunicationIdentifierModel +from .._shared.models import CommunicationIdentifier, PhoneNumberIdentifier +from .._generated.models import ( + JoinCallRequest, + PlayAudioRequest, + CommunicationIdentifierModel, + AddParticipantRequest, + PhoneNumberIdentifierModel + ) class JoinCallRequestConverter(object): @classmethod - def convert(self, source: CommunicationIdentifierModel, join_call_options: JoinCallOptions): + def convert( + self, + source: CommunicationIdentifierModel, + join_call_options: JoinCallOptions + ): # type: (...) -> JoinCallRequest + if not source: raise ValueError("source can not be None") if not join_call_options: @@ -21,19 +32,46 @@ def convert(self, source: CommunicationIdentifierModel, join_call_options: JoinC callback_uri=join_call_options.callback_uri, requested_media_types=join_call_options.requested_media_types, requested_call_events=join_call_options.requested_call_events, - subject= join_call_options.subject) + subject= join_call_options.subject + ) class PlayAudioRequestConverter(object): @classmethod - def convert(self, play_audio_options: PlayAudioOptions): + def convert( + self, + audio_file_uri: str, + play_audio_options: PlayAudioOptions + ): # type: (...) -> PlayAudioRequest + if not audio_file_uri: + raise ValueError("audio_file_uri can not be None") if not play_audio_options: raise ValueError("playaudio_options can not be None") return PlayAudioRequest( - audio_file_uri=play_audio_options.audio_file_uri, + audio_file_uri=audio_file_uri, loop = play_audio_options.loop, operation_context=play_audio_options, audio_file_id=play_audio_options.audio_file_id, - callback_uri=play_audio_options.callback_uri) + callback_uri=play_audio_options.callback_uri + ) + +class AddParticipantRequestConverter(object): + @classmethod + def convert( + self, + participant: CommunicationIdentifierModel, + alternate_caller_id: PhoneNumberIdentifierModel = None, + operation_context: str = None + ): # type: (...) -> AddParticipantRequest + + if not participant: + raise ValueError("participant can not be None") + + return AddParticipantRequest( + alternate_caller_id = alternate_caller_id, + participant = participant, + operation_context=operation_context, + callback_uri=None + ) diff --git a/sdk/communication/azure-communication-callingserver/azure/communication/callingserver/_models.py b/sdk/communication/azure-communication-callingserver/azure/communication/callingserver/_models.py index f80d0dc43d7..e2e2ae39acd 100644 --- a/sdk/communication/azure-communication-callingserver/azure/communication/callingserver/_models.py +++ b/sdk/communication/azure-communication-callingserver/azure/communication/callingserver/_models.py @@ -125,13 +125,11 @@ class PlayAudioOptions(object): def __init__( self, *, - audio_file_uri: str, loop: bool, operation_context: str, audio_file_id: str, callback_uri: str, ): - self.audio_file_uri = audio_file_uri self.loop = loop self.operation_context = operation_context self.audio_file_id = audio_file_id @@ -179,15 +177,15 @@ def __init__( self.result_info = kwargs['result_info'] @classmethod - def _from_generated(cls, play_audio_result): - if play_audio_result is None: + def _from_generated(cls, cancel_all_media_operations_result): + if cancel_all_media_operations_result is None: return None return cls( - operation_id=play_audio_result.operation_id, - status=play_audio_result.status, - operation_context=play_audio_result.operation_context, - result_info=ResultInfo._from_generated(play_audio_result.result_info) + operation_id=cancel_all_media_operations_result.operation_id, + status=cancel_all_media_operations_result.status, + operation_context=cancel_all_media_operations_result.operation_context, + result_info=ResultInfo._from_generated(cancel_all_media_operations_result.result_info) ) class AddParticipantResult(object): diff --git a/sdk/communication/azure-communication-callingserver/azure/communication/callingserver/aio/_call_connection_async.py b/sdk/communication/azure-communication-callingserver/azure/communication/callingserver/aio/_call_connection_async.py index f2865ecaab5..1c928dde05a 100644 --- a/sdk/communication/azure-communication-callingserver/azure/communication/callingserver/aio/_call_connection_async.py +++ b/sdk/communication/azure-communication-callingserver/azure/communication/callingserver/aio/_call_connection_async.py @@ -10,7 +10,7 @@ from .._generated.aio.operations import CallConnectionsOperations from .._generated.models import CancelAllMediaOperationsRequest, PlayAudioRequest, PhoneNumberIdentifierModel -from .._converters import PlayAudioRequestConverter +from .._converters import PlayAudioRequestConverter, AddParticipantRequestConverter from .._models import PlayAudioOptions, PlayAudioResult, CancelAllMediaOperationsResult, AddParticipantResult from .._communication_identifier_serializer import (deserialize_identifier, serialize_identifier) @@ -60,53 +60,17 @@ async def cancel_all_media_operations( async def play_audio( self, audio_file_uri, # type: str - loop, # type: bool - audio_file_id, # type: str - callback_uri, # type: str - operation_context = None, # type: Optional[str] - **kwargs, # type: str: Any - ): # type: (...) -> PlayAudioResult - - try: - if not audio_file_uri.lower().startswith('http'): - audio_file_uri = "https://" + audio_file_uri - except AttributeError: - raise ValueError("URL must be a string.") - - if not audio_file_id: - raise ValueError("audio_file_id can not be None") - - try: - if not callback_uri.lower().startswith('http'): - callback_uri = "https://" + callback_uri - except AttributeError: - raise ValueError("URL must be a string.") - - play_audio_options = PlayAudioOptions( - audio_file_uri=audio_file_uri, - loop = loop, - audio_file_id=audio_file_id, - callback_uri=callback_uri, - operation_context=operation_context, - ) - - return await self.play_audio( - playaudio_options=play_audio_options, - **kwargs - ) - - @distributed_trace_async() - @overload - async def play_audio( - self, play_audio_options, # type: PlayAudioOptions **kwargs, # type: str: Any ): # type: (...) -> PlayAudioResult + if not audio_file_uri: + raise ValueError("audio_file_uri can not be None") + if not play_audio_options: raise ValueError("options can not be None") - play_audio_request = PlayAudioRequestConverter.convert(play_audio_options) + play_audio_request = PlayAudioRequestConverter.convert(audio_file_uri, play_audio_options) play_audio_result = await self.call_connection_client.play_audio( call_connection_id=self.call_connection_id, @@ -129,12 +93,17 @@ async def add_participant( if not participant: raise ValueError("participant can not be None") + alternate_caller_id = None if alternate_caller_id == None else PhoneNumberIdentifierModel(value=alternate_caller_id) + + add_participant_request = AddParticipantRequestConverter.convert( + serialize_identifier(participant), + alternate_caller_id, + operation_context + ) + add_participant_result = await self.call_connection_client.add_participant( call_connection_id=self.call_connection_id, - participant=serialize_identifier(participant), - alternate_caller_id=None if alternate_caller_id == None else PhoneNumberIdentifierModel(value=alternate_caller_id.properties['value']), - operation_context=operation_context, - callback_uri=None, + add_participant_request=add_participant_request, **kwargs ) diff --git a/sdk/communication/azure-communication-callingserver/azure/communication/callingserver/aio/_callingserver_client_async.py b/sdk/communication/azure-communication-callingserver/azure/communication/callingserver/aio/_callingserver_client_async.py index e51254f532a..8c41fbf4b6c 100644 --- a/sdk/communication/azure-communication-callingserver/azure/communication/callingserver/aio/_callingserver_client_async.py +++ b/sdk/communication/azure-communication-callingserver/azure/communication/callingserver/aio/_callingserver_client_async.py @@ -161,7 +161,7 @@ async def create_call_connection( callback_uri=options.callback_uri, requested_media_types=options.requested_media_types, requested_call_events=options.requested_call_events, - alternate_caller_id=None if options.alternate_Caller_Id == None else PhoneNumberIdentifierModel(value=options.alternate_Caller_Id), + alternate_caller_id=None if options.alternate_Caller_Id == None else PhoneNumberIdentifierModel(value=options.alternate_Caller_Id.properties['value']), subject=options.subject, **kwargs ) diff --git a/sdk/communication/azure-communication-callingserver/tests/_test_constants.py b/sdk/communication/azure-communication-callingserver/tests/_test_constants.py index f7d14186d81..cd3686635a6 100644 --- a/sdk/communication/azure-communication-callingserver/tests/_test_constants.py +++ b/sdk/communication/azure-communication-callingserver/tests/_test_constants.py @@ -6,20 +6,58 @@ RESOURCE_SOURCE = "8:acs:resource_source" RESOURCE_TARGET = "8:acs:resource_target" -Phone_Number = "+14255550123" CALL_ID = "cad9df7b-f3ac-4c53-96f7-c76e7437b3c1" -CALLBACK_URI = "callBackUri" -CONNECTION_STRING = "endpoint=https://REDACTED.communication.azure.com/;accesskey=eyJhbG==" FAKE_ENDPOINT = "https://endpoint" FAKE_TOKEN = "Fake Token" CALL_SUBJECT = "testsubject" + +# CreateOrJoinCall CreateOrJoinCallPayload={ - "callLegId": CALL_ID, - "callConnectionId": CALL_ID, - } -ErrorPayload={"msg": "some error"} + "callLegId": CALL_ID, + "callConnectionId": CALL_ID, + } +# Common +Phone_Number = "+14255550123" +OPERATION_CONTEXT = "dummyOperationContext" +ErrorPayload={"msg": "some error"} ClientType_ConnectionString = "use connectionString" ClientType_ManagedIdentity = "use managedIdentity" +CALLBACK_URI = "https://bot.contoso.io/callback" +CONNECTION_STRING = "endpoint=https://REDACTED.communication.azure.com/;accesskey=eyJhbG==" + +# CancelAllMediaOperaions +CancelAllMediaOperaionsResponsePayload = { + "operationId": "dummyId", + "status": "completed", + "operationContext": OPERATION_CONTEXT, + "resultInfo": { + "code": 200, + "subcode": 200, + "message": "dummyMessage" + } + } + +SEVERCALL_ID = "b3ba87f4-9daf-4d0b-b95a-53d955a40577" + +# PlayAudio +AUDIO_FILE_URI = "https://bot.contoso.io/audio/sample-message.wav" +AUDIO_FILE_ID = "sampleAudioFileId" +PlayAudioResponsePayload = { + "operationId": "dummyId", + "status": "running", + "operationContext": OPERATION_CONTEXT, + "resultInfo": { + "code": 200, + "subcode": 200, + "message": "dummyMessage" + } + } + +# AddParticipant +AddParticipantResultPayload = { + "participantId": "dummyparticipantid" + } -SEVERCALL_ID = "b3ba87f4-9daf-4d0b-b95a-53d955a40577" \ No newline at end of file +# RemoveParticipant +ParticipantId = "dummyParticipantId" diff --git a/sdk/communication/azure-communication-callingserver/tests/_test_utils.py b/sdk/communication/azure-communication-callingserver/tests/_test_utils.py index 8ad974dc9da..45cf8b83460 100644 --- a/sdk/communication/azure-communication-callingserver/tests/_test_utils.py +++ b/sdk/communication/azure-communication-callingserver/tests/_test_utils.py @@ -28,9 +28,9 @@ def __init__(self): async def get_token(self, *args): return self.token -def create_mock_call_connection(status_code, payload, is_async=False): - calling_server_client = create_mock_calling_server_client(status_code, payload, is_async) - return calling_server_client.get_call_connection(_test_constants.CALL_ID) +def create_mock_call_connection(call_connection_id, status_code, payload, is_async=False, use_managed_identity=False): + calling_server_client = create_mock_calling_server_client(status_code, payload, is_async, use_managed_identity) + return calling_server_client.get_call_connection(call_connection_id) def create_mock_calling_server_client(status_code, payload, is_async=False, use_managed_identity=False): async def async_mock_send(*_, **__): diff --git a/sdk/communication/azure-communication-callingserver/tests/test_call_connection.py b/sdk/communication/azure-communication-callingserver/tests/test_call_connection.py index e69de29bb2d..54574dd9a92 100644 --- a/sdk/communication/azure-communication-callingserver/tests/test_call_connection.py +++ b/sdk/communication/azure-communication-callingserver/tests/test_call_connection.py @@ -0,0 +1,382 @@ +# ------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +import unittest +import pytest +import _test_utils +import _test_constants + +from typing import List +from parameterized import parameterized +from azure.communication.callingserver._shared.models import CommunicationIdentifier, CommunicationUserIdentifier, PhoneNumberIdentifier +from azure.communication.callingserver._models import ( + CreateCallOptions, + MediaType, + EventSubscriptionType, + JoinCallOptions, + CancelAllMediaOperationsResult, + PlayAudioOptions, + AddParticipantResult + ) + +try: + from unittest.mock import Mock, patch +except ImportError: # python < 3.3 + from mock import Mock, patch # type: ignore + + +def test_data_source_hang_up(): + parameters = [] + parameters.append(( + _test_constants.ClientType_ConnectionString, + _test_constants.CALL_ID, + )) + + parameters.append(( + _test_constants.ClientType_ManagedIdentity, + _test_constants.CALL_ID, + True, + )) + + return parameters + +def test_data_source_cancel_all_media_operations(): + parameters = [] + parameters.append(( + _test_constants.ClientType_ConnectionString, + _test_constants.CALL_ID, + _test_constants.OPERATION_CONTEXT, + )) + + parameters.append(( + _test_constants.ClientType_ManagedIdentity, + _test_constants.CALL_ID, + _test_constants.OPERATION_CONTEXT, + True, + )) + + return parameters + +def test_data_source_play_audio(): + options = PlayAudioOptions( + loop = True, + audio_file_id = _test_constants.AUDIO_FILE_ID, + callback_uri = _test_constants.CALLBACK_URI, + operation_context = _test_constants.OPERATION_CONTEXT + ) + parameters = [] + parameters.append(( + _test_constants.ClientType_ConnectionString, + _test_constants.CALL_ID, + _test_constants.AUDIO_FILE_URI, + options, + )) + + parameters.append(( + _test_constants.ClientType_ManagedIdentity, + _test_constants.CALL_ID, + _test_constants.AUDIO_FILE_URI, + options, + True, + )) + + return parameters + +def test_data_source_add_participant(): + + parameters = [] + parameters.append(( + _test_constants.ClientType_ConnectionString, + _test_constants.CALL_ID, + CommunicationUserIdentifier(_test_constants.RESOURCE_SOURCE), + _test_constants.Phone_Number, + _test_constants.OPERATION_CONTEXT, + )) + + parameters.append(( + _test_constants.ClientType_ManagedIdentity, + _test_constants.CALL_ID, + CommunicationUserIdentifier(_test_constants.RESOURCE_SOURCE), + _test_constants.Phone_Number, + _test_constants.OPERATION_CONTEXT, + True, + )) + + return parameters + +def test_data_source_remove_participant(): + + parameters = [] + parameters.append(( + _test_constants.ClientType_ConnectionString, + _test_constants.CALL_ID, + _test_constants.ParticipantId, + )) + + parameters.append(( + _test_constants.ClientType_ManagedIdentity, + _test_constants.CALL_ID, + _test_constants.ParticipantId, + True, + )) + + return parameters + +def verify_cancel_all_media_operations_result(result: CancelAllMediaOperationsResult): + assert "dummyId" == result.operation_id + assert "completed" == result.status + assert _test_constants.OPERATION_CONTEXT == result.operation_context + assert 200 == result.result_info.code + assert "dummyMessage" == result.result_info.message + +def verify_play_audio_result(result: CancelAllMediaOperationsResult): + assert "dummyId" == result.operation_id + assert "running" == result.status + assert _test_constants.OPERATION_CONTEXT == result.operation_context + assert 200 == result.result_info.code + assert "dummyMessage" == result.result_info.message + +def verify_add_participant_result(result: AddParticipantResult): + assert "dummyparticipantid" == result.participant_id + +class TestCallConnection(unittest.TestCase): + + @parameterized.expand(test_data_source_hang_up()) + def test_hang_up_succeed( + self, + test_name: str, + call_connection_id: str, + use_managed_identity = False + ): + + call_connection = _test_utils.create_mock_call_connection( + call_connection_id, + status_code=202, + payload=None, + is_async=False, + use_managed_identity=use_managed_identity + ) + + call_connection.hang_up() + assert call_connection.call_connection_id == _test_constants.CALL_ID + assert call_connection.call_connection_client + + @parameterized.expand(test_data_source_hang_up()) + def test_hang_up_failed( + self, + test_name: str, + call_connection_id: str, + use_managed_identity = False + ): + + call_connection = _test_utils.create_mock_call_connection( + call_connection_id, + status_code=404, + payload=_test_constants.ErrorPayload, + is_async=False, + use_managed_identity = use_managed_identity + ) + + raised = False + try: + call_connection.hang_up() + except: + raised = True + assert raised == True + + @parameterized.expand(test_data_source_cancel_all_media_operations()) + def test_cancel_all_media_operations_succeed( + self, + test_name: str, + call_connection_id: str, + operation_context: str = None, + use_managed_identity = False + ): + + call_connection = _test_utils.create_mock_call_connection( + call_connection_id, + status_code=200, + payload=_test_constants.CancelAllMediaOperaionsResponsePayload, + is_async=False, + use_managed_identity=use_managed_identity + ) + + result = call_connection.cancel_all_media_operations(operation_context) + verify_cancel_all_media_operations_result(result) + + @parameterized.expand(test_data_source_cancel_all_media_operations()) + def test_cancel_all_media_operations_failed( + self, + test_name: str, + call_connection_id: str, + operation_context: str = None, + use_managed_identity = False + ): + + call_connection = _test_utils.create_mock_call_connection( + call_connection_id, + status_code=404, + payload=_test_constants.ErrorPayload, + is_async=False, + use_managed_identity = use_managed_identity + ) + + raised = False + try: + call_connection.cancel_all_media_operations(operation_context) + except: + raised = True + assert raised == True + + @parameterized.expand(test_data_source_play_audio()) + def test_play_audio_succeed( + self, + test_name: str, + call_connection_id: str, + audio_file_uri: str, + options: PlayAudioOptions, + use_managed_identity = False + ): + + call_connection = _test_utils.create_mock_call_connection( + call_connection_id, + status_code=202, + payload=_test_constants.PlayAudioResponsePayload, + is_async=False, + use_managed_identity=use_managed_identity + ) + + result = call_connection.play_audio(audio_file_uri, options) + verify_play_audio_result(result) + + @parameterized.expand(test_data_source_play_audio()) + def test_play_audio_failed( + self, + test_name: str, + call_connection_id: str, + audio_file_uri: str, + options: PlayAudioOptions, + use_managed_identity = False + ): + + call_connection = _test_utils.create_mock_call_connection( + call_connection_id, + status_code=404, + payload=_test_constants.ErrorPayload, + is_async=False, + use_managed_identity = use_managed_identity + ) + + raised = False + try: + call_connection.play_audio(audio_file_uri, options) + except: + raised = True + assert raised == True + + @parameterized.expand(test_data_source_add_participant()) + def test_add_participant_succeed( + self, + test_name: str, + call_connection_id: str, + participant: CommunicationIdentifier, + alternate_caller_id: str, + operation_context: str, + use_managed_identity = False + ): + + call_connection = _test_utils.create_mock_call_connection( + call_connection_id, + status_code=202, + payload=_test_constants.AddParticipantResultPayload, + is_async=False, + use_managed_identity=use_managed_identity + ) + + result = call_connection.add_participant( + participant = participant, + alternate_caller_id = alternate_caller_id, + operation_context = operation_context + ) + verify_add_participant_result(result) + + @parameterized.expand(test_data_source_add_participant()) + def test_add_participant_failed( + self, + test_name: str, + call_connection_id: str, + participant: CommunicationIdentifier, + alternate_caller_id: str, + operation_context: str, + use_managed_identity = False + ): + + call_connection = _test_utils.create_mock_call_connection( + call_connection_id, + status_code=404, + payload=_test_constants.ErrorPayload, + is_async=False, + use_managed_identity = use_managed_identity + ) + + raised = False + try: + call_connection.add_participant( + participant = participant, + alternate_caller_id = alternate_caller_id, + operation_context = operation_context + ) + except: + raised = True + assert raised == True + + @parameterized.expand(test_data_source_remove_participant()) + def test_remove_participant_succeed( + self, + test_name: str, + call_connection_id: str, + participant_id: str, + use_managed_identity = False + ): + + call_connection = _test_utils.create_mock_call_connection( + call_connection_id, + status_code=202, + payload=_test_constants.AddParticipantResultPayload, + is_async=False, + use_managed_identity=use_managed_identity + ) + + call_connection.remove_participant( + participant_id = participant_id + ) + assert call_connection.call_connection_id == _test_constants.CALL_ID + assert call_connection.call_connection_client + + @parameterized.expand(test_data_source_remove_participant()) + def test_remove_participant_failed( + self, + test_name: str, + call_connection_id: str, + participant_id: str, + use_managed_identity = False + ): + + call_connection = _test_utils.create_mock_call_connection( + call_connection_id, + status_code=404, + payload=_test_constants.ErrorPayload, + is_async=False, + use_managed_identity = use_managed_identity + ) + + raised = False + try: + call_connection.remove_participant( + participant_id = participant_id + ) + except: + raised = True + assert raised == True \ No newline at end of file diff --git a/sdk/communication/azure-communication-callingserver/tests/test_call_connection_async.py b/sdk/communication/azure-communication-callingserver/tests/test_call_connection_async.py index e69de29bb2d..2208c78fbfa 100644 --- a/sdk/communication/azure-communication-callingserver/tests/test_call_connection_async.py +++ b/sdk/communication/azure-communication-callingserver/tests/test_call_connection_async.py @@ -0,0 +1,380 @@ +# ------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +import aiounittest +import pytest +import _test_utils +import _test_constants + +from typing import List +from parameterized import parameterized +from azure.communication.callingserver._shared.models import CommunicationIdentifier, CommunicationUserIdentifier, PhoneNumberIdentifier +from azure.communication.callingserver._models import ( + CreateCallOptions, + MediaType, + EventSubscriptionType, + JoinCallOptions, + CancelAllMediaOperationsResult, + PlayAudioOptions, + AddParticipantResult + ) + +try: + from unittest.mock import Mock, patch +except ImportError: # python < 3.3 + from mock import Mock, patch # type: ignore + + +def test_data_source_hang_up(): + parameters = [] + parameters.append(( + _test_constants.ClientType_ConnectionString, + _test_constants.CALL_ID, + )) + + parameters.append(( + _test_constants.ClientType_ManagedIdentity, + _test_constants.CALL_ID, + True, + )) + + return parameters + +def test_data_source_cancel_all_media_operations(): + parameters = [] + parameters.append(( + _test_constants.ClientType_ConnectionString, + _test_constants.CALL_ID, + _test_constants.OPERATION_CONTEXT, + )) + + parameters.append(( + _test_constants.ClientType_ManagedIdentity, + _test_constants.CALL_ID, + _test_constants.OPERATION_CONTEXT, + True, + )) + + return parameters + +def test_data_source_play_audio(): + options = PlayAudioOptions( + loop = True, + audio_file_id = _test_constants.AUDIO_FILE_ID, + callback_uri = _test_constants.CALLBACK_URI, + operation_context = _test_constants.OPERATION_CONTEXT + ) + parameters = [] + parameters.append(( + _test_constants.ClientType_ConnectionString, + _test_constants.CALL_ID, + _test_constants.AUDIO_FILE_URI, + options, + )) + + parameters.append(( + _test_constants.ClientType_ManagedIdentity, + _test_constants.CALL_ID, + _test_constants.AUDIO_FILE_URI, + options, + True, + )) + + return parameters + +def test_data_source_add_participant(): + + parameters = [] + parameters.append(( + _test_constants.ClientType_ConnectionString, + _test_constants.CALL_ID, + CommunicationUserIdentifier(_test_constants.RESOURCE_SOURCE), + _test_constants.Phone_Number, + _test_constants.OPERATION_CONTEXT, + )) + + parameters.append(( + _test_constants.ClientType_ManagedIdentity, + _test_constants.CALL_ID, + CommunicationUserIdentifier(_test_constants.RESOURCE_SOURCE), + _test_constants.Phone_Number, + _test_constants.OPERATION_CONTEXT, + True, + )) + + return parameters + +def test_data_source_remove_participant(): + + parameters = [] + parameters.append(( + _test_constants.ClientType_ConnectionString, + _test_constants.CALL_ID, + _test_constants.ParticipantId, + )) + + parameters.append(( + _test_constants.ClientType_ManagedIdentity, + _test_constants.CALL_ID, + _test_constants.ParticipantId, + True, + )) + + return parameters + +def verify_cancel_all_media_operations_result(result: CancelAllMediaOperationsResult): + assert "dummyId" == result.operation_id + assert "completed" == result.status + assert _test_constants.OPERATION_CONTEXT == result.operation_context + assert 200 == result.result_info.code + assert "dummyMessage" == result.result_info.message + +def verify_play_audio_result(result: CancelAllMediaOperationsResult): + assert "dummyId" == result.operation_id + assert "running" == result.status + assert _test_constants.OPERATION_CONTEXT == result.operation_context + assert 200 == result.result_info.code + assert "dummyMessage" == result.result_info.message + +def verify_add_participant_result(result: AddParticipantResult): + assert "dummyparticipantid" == result.participant_id + +@parameterized.expand(test_data_source_hang_up()) +@pytest.mark.asyncio +async def test_hang_up_succeed( + test_name: str, + call_connection_id: str, + use_managed_identity = False + ): + + call_connection = _test_utils.create_mock_call_connection( + call_connection_id, + status_code=202, + payload=None, + is_async=True, + use_managed_identity=use_managed_identity + ) + + await call_connection.hang_up() + assert call_connection.call_connection_id == _test_constants.CALL_ID + assert call_connection.call_connection_client + +@parameterized.expand(test_data_source_hang_up()) +@pytest.mark.asyncio +async def test_hang_up_failed( + test_name: str, + call_connection_id: str, + use_managed_identity = False + ): + + call_connection = _test_utils.create_mock_call_connection( + call_connection_id, + status_code=404, + payload=_test_constants.ErrorPayload, + is_async=True, + use_managed_identity = use_managed_identity + ) + + raised = False + try: + await call_connection.hang_up() + except: + raised = True + assert raised == True + +@parameterized.expand(test_data_source_cancel_all_media_operations()) +@pytest.mark.asyncio +async def test_cancel_all_media_operations_succeed( + test_name: str, + call_connection_id: str, + operation_context: str = None, + use_managed_identity = False + ): + + call_connection = _test_utils.create_mock_call_connection( + call_connection_id, + status_code=200, + payload=_test_constants.CancelAllMediaOperaionsResponsePayload, + is_async=True, + use_managed_identity=use_managed_identity + ) + + result = await call_connection.cancel_all_media_operations(operation_context) + verify_cancel_all_media_operations_result(result) + +@parameterized.expand(test_data_source_cancel_all_media_operations()) +@pytest.mark.asyncio +async def test_cancel_all_media_operations_failed( + test_name: str, + call_connection_id: str, + operation_context: str = None, + use_managed_identity = False + ): + + call_connection = _test_utils.create_mock_call_connection( + call_connection_id, + status_code=404, + payload=_test_constants.ErrorPayload, + is_async=True, + use_managed_identity = use_managed_identity + ) + + raised = False + try: + await call_connection.cancel_all_media_operations(operation_context) + except: + raised = True + assert raised == True + +@parameterized.expand(test_data_source_play_audio()) +@pytest.mark.asyncio +async def test_play_audio_succeed( + test_name: str, + call_connection_id: str, + audio_file_uri: str, + options: PlayAudioOptions, + use_managed_identity = False + ): + + call_connection = _test_utils.create_mock_call_connection( + call_connection_id, + status_code=202, + payload=_test_constants.PlayAudioResponsePayload, + is_async=True, + use_managed_identity=use_managed_identity + ) + + result = await call_connection.play_audio(audio_file_uri, options) + verify_play_audio_result(result) + +@parameterized.expand(test_data_source_play_audio()) +@pytest.mark.asyncio +async def test_play_audio_failed( + test_name: str, + call_connection_id: str, + audio_file_uri: str, + options: PlayAudioOptions, + use_managed_identity = False + ): + + call_connection = _test_utils.create_mock_call_connection( + call_connection_id, + status_code=404, + payload=_test_constants.ErrorPayload, + is_async=True, + use_managed_identity = use_managed_identity + ) + + raised = False + try: + await call_connection.play_audio(audio_file_uri, options) + except: + raised = True + assert raised == True + +@parameterized.expand(test_data_source_add_participant()) +@pytest.mark.asyncio +async def test_add_participant_succeed( + test_name: str, + call_connection_id: str, + participant: CommunicationIdentifier, + alternate_caller_id: str, + operation_context: str, + use_managed_identity = False + ): + + call_connection = _test_utils.create_mock_call_connection( + call_connection_id, + status_code=202, + payload=_test_constants.AddParticipantResultPayload, + is_async=True, + use_managed_identity=use_managed_identity + ) + + result = await call_connection.add_participant( + participant = participant, + alternate_caller_id = alternate_caller_id, + operation_context = operation_context + ) + verify_add_participant_result(result) + +@parameterized.expand(test_data_source_add_participant()) +@pytest.mark.asyncio +async def test_add_participant_failed( + test_name: str, + call_connection_id: str, + participant: CommunicationIdentifier, + alternate_caller_id: str, + operation_context: str, + use_managed_identity = False + ): + + call_connection = _test_utils.create_mock_call_connection( + call_connection_id, + status_code=404, + payload=_test_constants.ErrorPayload, + is_async=True, + use_managed_identity = use_managed_identity + ) + + raised = False + try: + await call_connection.add_participant( + participant = participant, + alternate_caller_id = alternate_caller_id, + operation_context = operation_context + ) + except: + raised = True + assert raised == True + +@parameterized.expand(test_data_source_remove_participant()) +@pytest.mark.asyncio +async def test_remove_participant_succeed( + test_name: str, + call_connection_id: str, + participant_id: str, + use_managed_identity = False + ): + + call_connection = _test_utils.create_mock_call_connection( + call_connection_id, + status_code=202, + payload=_test_constants.AddParticipantResultPayload, + is_async=True, + use_managed_identity=use_managed_identity + ) + + await call_connection.remove_participant( + participant_id = participant_id + ) + assert call_connection.call_connection_id == _test_constants.CALL_ID + assert call_connection.call_connection_client + +@parameterized.expand(test_data_source_remove_participant()) +@pytest.mark.asyncio +async def test_remove_participant_failed( + test_name: str, + call_connection_id: str, + participant_id: str, + use_managed_identity = False + ): + + call_connection = _test_utils.create_mock_call_connection( + call_connection_id, + status_code=404, + payload=_test_constants.ErrorPayload, + is_async=True, + use_managed_identity = use_managed_identity + ) + + raised = False + try: + await call_connection.remove_participant( + participant_id = participant_id + ) + except: + raised = True + assert raised == True \ No newline at end of file diff --git a/sdk/communication/azure-communication-callingserver/tests/test_callingserver_client.py b/sdk/communication/azure-communication-callingserver/tests/test_callingserver_client.py index 9610a5adc13..c47f81e56ce 100644 --- a/sdk/communication/azure-communication-callingserver/tests/test_callingserver_client.py +++ b/sdk/communication/azure-communication-callingserver/tests/test_callingserver_client.py @@ -22,51 +22,51 @@ def test_data_source_create_connection(): - option = CreateCallOptions( + options = CreateCallOptions( callback_uri=_test_constants.CALLBACK_URI, requested_media_types=[MediaType.AUDIO], requested_call_events=[EventSubscriptionType.PARTICIPANTS_UPDATED]) - option.subject=_test_constants.CALL_SUBJECT - option.alternate_Caller_Id = PhoneNumberIdentifier(_test_constants.Phone_Number), + options.subject=_test_constants.CALL_SUBJECT + options.alternate_Caller_Id = PhoneNumberIdentifier(_test_constants.Phone_Number) parameters = [] parameters.append(( _test_constants.ClientType_ConnectionString, CommunicationUserIdentifier(_test_constants.RESOURCE_SOURCE), [CommunicationUserIdentifier(_test_constants.RESOURCE_TARGET), PhoneNumberIdentifier(_test_constants.Phone_Number)], - option, + options, )) parameters.append(( _test_constants.ClientType_ManagedIdentity, CommunicationUserIdentifier(_test_constants.RESOURCE_SOURCE), [CommunicationUserIdentifier(_test_constants.RESOURCE_TARGET), PhoneNumberIdentifier(_test_constants.Phone_Number)], - option, + options, True, )) return parameters def test_data_source_join_call(): - option = JoinCallOptions( + options = JoinCallOptions( callback_uri=_test_constants.CALLBACK_URI, requested_media_types=[MediaType.AUDIO], requested_call_events=[EventSubscriptionType.PARTICIPANTS_UPDATED]) - option.subject=_test_constants.CALL_SUBJECT + options.subject=_test_constants.CALL_SUBJECT parameters = [] parameters.append(( _test_constants.ClientType_ConnectionString, _test_constants.SEVERCALL_ID, CommunicationUserIdentifier(_test_constants.RESOURCE_SOURCE), - option, + options, )) parameters.append(( _test_constants.ClientType_ManagedIdentity, _test_constants.SEVERCALL_ID, CommunicationUserIdentifier(_test_constants.RESOURCE_SOURCE), - option, + options, True, )) @@ -106,7 +106,7 @@ def test_create_connection_failed( use_managed_identity = False ): - calling_server_client = _test_utils.create_mock_calling_server_client(status_code=400, payload=_test_constants.ErrorPayload, is_async=False, use_managed_identity = use_managed_identity) + calling_server_client = _test_utils.create_mock_calling_server_client(status_code=404, payload=_test_constants.ErrorPayload, is_async=False, use_managed_identity = use_managed_identity) raised = False try: calling_server_client.create_call_connection(source_user, target_users, options) @@ -151,7 +151,7 @@ def test_join_call_failed( ): calling_server_client = _test_utils.create_mock_calling_server_client( - status_code=400, + status_code=404, payload=_test_constants.ErrorPayload, is_async=False, use_managed_identity = use_managed_identity diff --git a/sdk/communication/azure-communication-callingserver/tests/test_callingserver_client_async.py b/sdk/communication/azure-communication-callingserver/tests/test_callingserver_client_async.py index aa97eb15de5..1806d604e5e 100644 --- a/sdk/communication/azure-communication-callingserver/tests/test_callingserver_client_async.py +++ b/sdk/communication/azure-communication-callingserver/tests/test_callingserver_client_async.py @@ -20,51 +20,51 @@ def test_data_source_create_connection(): - option = CreateCallOptions( + options = CreateCallOptions( callback_uri=_test_constants.CALLBACK_URI, requested_media_types=[MediaType.AUDIO], requested_call_events=[EventSubscriptionType.PARTICIPANTS_UPDATED]) - option.subject=_test_constants.CALL_SUBJECT - option.alternate_Caller_Id = PhoneNumberIdentifier(_test_constants.Phone_Number), + options.subject=_test_constants.CALL_SUBJECT + options.alternate_Caller_Id = PhoneNumberIdentifier(_test_constants.Phone_Number) parameters = [] parameters.append(( _test_constants.ClientType_ConnectionString, CommunicationUserIdentifier(_test_constants.RESOURCE_SOURCE), [CommunicationUserIdentifier(_test_constants.RESOURCE_TARGET), PhoneNumberIdentifier(_test_constants.Phone_Number)], - option, + options, )) parameters.append(( _test_constants.ClientType_ManagedIdentity, CommunicationUserIdentifier(_test_constants.RESOURCE_SOURCE), [CommunicationUserIdentifier(_test_constants.RESOURCE_TARGET), PhoneNumberIdentifier(_test_constants.Phone_Number)], - option, + options, True, )) return parameters def test_data_source_join_call(): - option = JoinCallOptions( + options = JoinCallOptions( callback_uri=_test_constants.CALLBACK_URI, requested_media_types=[MediaType.AUDIO], requested_call_events=[EventSubscriptionType.PARTICIPANTS_UPDATED]) - option.subject=_test_constants.CALL_SUBJECT + options.subject=_test_constants.CALL_SUBJECT parameters = [] parameters.append(( _test_constants.ClientType_ConnectionString, _test_constants.SEVERCALL_ID, CommunicationUserIdentifier(_test_constants.RESOURCE_SOURCE), - option, + options, )) parameters.append(( _test_constants.ClientType_ManagedIdentity, _test_constants.SEVERCALL_ID, CommunicationUserIdentifier(_test_constants.RESOURCE_SOURCE), - option, + options, True, )) @@ -97,7 +97,7 @@ async def test_create_connection_failed( use_managed_identity = False ): - calling_server_client = _test_utils.create_mock_calling_server_client(status_code=400, payload=_test_constants.ErrorPayload, is_async=True, use_managed_identity = use_managed_identity) + calling_server_client = _test_utils.create_mock_calling_server_client(status_code=404, payload=_test_constants.ErrorPayload, is_async=True, use_managed_identity = use_managed_identity) raised = False try: await calling_server_client.create_call_connection(source_user, target_users, options) @@ -142,7 +142,7 @@ async def test_join_call_failed( ): calling_server_client = _test_utils.create_mock_calling_server_client( - status_code=400, + status_code=404, payload=_test_constants.ErrorPayload, is_async=True, use_managed_identity = use_managed_identity