mirror of
https://github.com/suitenumerique/meet.git
synced 2026-08-28 11:16:58 +00:00
🚚(backend) rename TelephonyService to SIPManagement
Rename the telephony service to a more descriptive name, SIPManagementService, which clearly states what the service is used for. It is no longer used only by the telephony feature; the roomkit feature also relies on it now.
This commit is contained in:
@@ -27,6 +27,7 @@ and this project adheres to
|
|||||||
- 📝(legal) update terms of service
|
- 📝(legal) update terms of service
|
||||||
- 💄(frontend) render Avatar initials in uppercase
|
- 💄(frontend) render Avatar initials in uppercase
|
||||||
- 💄(frontend) improve participant name rendering in the list
|
- 💄(frontend) improve participant name rendering in the list
|
||||||
|
- 🚚(backend) rename TelephonyService to SIPManagement
|
||||||
|
|
||||||
## Fixed
|
## Fixed
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ from rest_framework import (
|
|||||||
from core import analytics, models
|
from core import analytics, models
|
||||||
from core.api import permissions, throttling
|
from core.api import permissions, throttling
|
||||||
from core.api.feature_flag import FeatureFlag
|
from core.api.feature_flag import FeatureFlag
|
||||||
from core.services.telephony import TelephonyException, TelephonyService
|
from core.services.sip_management import SIPException, SIPManagement
|
||||||
|
|
||||||
from . import authentication, serializers
|
from . import authentication, serializers
|
||||||
|
|
||||||
@@ -50,7 +50,7 @@ class RoomKitViewSet(viewsets.ViewSet):
|
|||||||
without waiting for a WebRTC user.
|
without waiting for a WebRTC user.
|
||||||
|
|
||||||
The webhook-based creation path is kept: both converge on the same rule
|
The webhook-based creation path is kept: both converge on the same rule
|
||||||
through the shared TelephonyService.
|
through the shared SIPManagement.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
serializer = serializers.RoomKitJoinSerializer(data=request.data)
|
serializer = serializers.RoomKitJoinSerializer(data=request.data)
|
||||||
@@ -64,8 +64,8 @@ class RoomKitViewSet(viewsets.ViewSet):
|
|||||||
raise drf_exceptions.NotFound("No room found for this PIN code.") from e
|
raise drf_exceptions.NotFound("No room found for this PIN code.") from e
|
||||||
|
|
||||||
try:
|
try:
|
||||||
created = TelephonyService().ensure_dispatch_rule(room)
|
created = SIPManagement().ensure_dispatch_rule(room)
|
||||||
except TelephonyException as e:
|
except SIPException as e:
|
||||||
raise drf_exceptions.APIException("Could not create dispatch rule.") from e
|
raise drf_exceptions.APIException("Could not create dispatch rule.") from e
|
||||||
|
|
||||||
analytics.capture(
|
analytics.capture(
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ from .room_management import (
|
|||||||
RoomManagementException,
|
RoomManagementException,
|
||||||
RoomNotFoundException,
|
RoomNotFoundException,
|
||||||
)
|
)
|
||||||
from .telephony import TelephonyException, TelephonyService
|
from .sip_management import SIPException, SIPManagement
|
||||||
|
|
||||||
logger = getLogger(__name__)
|
logger = getLogger(__name__)
|
||||||
|
|
||||||
@@ -107,7 +107,7 @@ class LiveKitEventsService:
|
|||||||
)
|
)
|
||||||
self.webhook_receiver = api.WebhookReceiver(token_verifier)
|
self.webhook_receiver = api.WebhookReceiver(token_verifier)
|
||||||
self.lobby_service = LobbyService()
|
self.lobby_service = LobbyService()
|
||||||
self.telephony_service = TelephonyService()
|
self.sip_management = SIPManagement()
|
||||||
self.recording_events = RecordingEventsService()
|
self.recording_events = RecordingEventsService()
|
||||||
|
|
||||||
self._filter_regex = None
|
self._filter_regex = None
|
||||||
@@ -247,10 +247,10 @@ class LiveKitEventsService:
|
|||||||
|
|
||||||
if settings.ROOM_TELEPHONY_ENABLED or settings.ROOMKIT_ENABLED:
|
if settings.ROOM_TELEPHONY_ENABLED or settings.ROOMKIT_ENABLED:
|
||||||
try:
|
try:
|
||||||
self.telephony_service.create_dispatch_rule(room)
|
self.sip_management.create_dispatch_rule(room)
|
||||||
except TelephonyException as e:
|
except SIPException as e:
|
||||||
raise ActionFailedError(
|
raise ActionFailedError(
|
||||||
f"Failed to create telephony dispatch rule for room {room_id}"
|
f"Failed to create sip dispatch rule for room {room_id}"
|
||||||
) from e
|
) from e
|
||||||
|
|
||||||
def _handle_room_finished(self, data):
|
def _handle_room_finished(self, data):
|
||||||
@@ -267,10 +267,10 @@ class LiveKitEventsService:
|
|||||||
|
|
||||||
if settings.ROOM_TELEPHONY_ENABLED or settings.ROOMKIT_ENABLED:
|
if settings.ROOM_TELEPHONY_ENABLED or settings.ROOMKIT_ENABLED:
|
||||||
try:
|
try:
|
||||||
self.telephony_service.delete_dispatch_rule(room_id)
|
self.sip_management.delete_dispatch_rule(room_id)
|
||||||
except TelephonyException as e:
|
except SIPException as e:
|
||||||
raise ActionFailedError(
|
raise ActionFailedError(
|
||||||
f"Failed to delete telephony dispatch rule for room {room_id}"
|
f"Failed to delete sip dispatch rule for room {room_id}"
|
||||||
) from e
|
) from e
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|||||||
+10
-10
@@ -1,4 +1,4 @@
|
|||||||
"""Telephony service for managing SIP dispatch rules for room access."""
|
"""SIP management service for managing SIP dispatch rules for room access."""
|
||||||
|
|
||||||
from logging import getLogger
|
from logging import getLogger
|
||||||
|
|
||||||
@@ -17,16 +17,16 @@ from core import utils
|
|||||||
logger = getLogger(__name__)
|
logger = getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class TelephonyException(Exception):
|
class SIPException(Exception):
|
||||||
"""Exception raised when telephony operations fail."""
|
"""Exception raised when SIP operations fail."""
|
||||||
|
|
||||||
|
|
||||||
class DispatchRuleConflictError(TelephonyException):
|
class DispatchRuleConflictError(SIPException):
|
||||||
"""Raised when a dispatch rule already exists for the same routing criteria."""
|
"""Raised when a dispatch rule already exists for the same routing criteria."""
|
||||||
|
|
||||||
|
|
||||||
class TelephonyService:
|
class SIPManagement:
|
||||||
"""Service for managing participant access through the telephony system (SIP)."""
|
"""Service for managing SIP access through the telephony or roomkit system (SIP)."""
|
||||||
|
|
||||||
def _rule_name(self, room_id):
|
def _rule_name(self, room_id):
|
||||||
"""Generate the rule name for a room based on its ID."""
|
"""Generate the rule name for a room based on its ID."""
|
||||||
@@ -36,7 +36,7 @@ class TelephonyService:
|
|||||||
async def create_dispatch_rule(self, room):
|
async def create_dispatch_rule(self, room):
|
||||||
"""Create a SIP inbound dispatch rule for direct room routing.
|
"""Create a SIP inbound dispatch rule for direct room routing.
|
||||||
|
|
||||||
Configures telephony to route incoming SIP calls directly to the specified room
|
Configures livekit-sip to route incoming SIP calls directly to the specified room
|
||||||
using the room's ID and PIN code for authentication.
|
using the room's ID and PIN code for authentication.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@@ -60,7 +60,7 @@ class TelephonyService:
|
|||||||
logger.exception(
|
logger.exception(
|
||||||
"Unexpected error creating dispatch rule for room %s", room.id
|
"Unexpected error creating dispatch rule for room %s", room.id
|
||||||
)
|
)
|
||||||
raise TelephonyException("Could not create dispatch rule") from e
|
raise SIPException("Could not create dispatch rule") from e
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
await lkapi.aclose()
|
await lkapi.aclose()
|
||||||
@@ -85,7 +85,7 @@ class TelephonyService:
|
|||||||
)
|
)
|
||||||
except TwirpError as e:
|
except TwirpError as e:
|
||||||
logger.exception("Failed to list dispatch rules for room %s", room_id)
|
logger.exception("Failed to list dispatch rules for room %s", room_id)
|
||||||
raise TelephonyException("Could not list dispatch rules") from e
|
raise SIPException("Could not list dispatch rules") from e
|
||||||
finally:
|
finally:
|
||||||
await lkapi.aclose()
|
await lkapi.aclose()
|
||||||
|
|
||||||
@@ -146,7 +146,7 @@ class TelephonyService:
|
|||||||
|
|
||||||
except TwirpError as e:
|
except TwirpError as e:
|
||||||
logger.exception("Failed to delete dispatch rules for room %s", room_id)
|
logger.exception("Failed to delete dispatch rules for room %s", room_id)
|
||||||
raise TelephonyException("Could not delete dispatch rules") from e
|
raise SIPException("Could not delete dispatch rules") from e
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
await lkapi.aclose()
|
await lkapi.aclose()
|
||||||
@@ -9,19 +9,19 @@ from unittest import mock
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from ...factories import RoomFactory
|
from ...factories import RoomFactory
|
||||||
from ...services.telephony import TelephonyException
|
from ...services.sip_management import SIPException
|
||||||
|
|
||||||
pytestmark = pytest.mark.django_db
|
pytestmark = pytest.mark.django_db
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def mock_telephony_service():
|
def mock_sip_management():
|
||||||
"""Mock the TelephonyService used by the roomkit viewset."""
|
"""Mock the SIPManagement used by the roomkit viewset."""
|
||||||
with mock.patch("core.roomkit.viewsets.TelephonyService") as mock_service_class:
|
with mock.patch("core.roomkit.viewsets.SIPManagement") as mock_service_class:
|
||||||
yield mock_service_class.return_value
|
yield mock_service_class.return_value
|
||||||
|
|
||||||
|
|
||||||
def test_join_anonymous(settings, mock_telephony_service, client):
|
def test_join_anonymous(settings, mock_sip_management, client):
|
||||||
"""Requests without an Authorization header should be rejected."""
|
"""Requests without an Authorization header should be rejected."""
|
||||||
settings.ROOMKIT_ENABLED = True
|
settings.ROOMKIT_ENABLED = True
|
||||||
settings.ROOMKIT_SERVER_TO_SERVER_API_TOKEN = "testAuthToken"
|
settings.ROOMKIT_SERVER_TO_SERVER_API_TOKEN = "testAuthToken"
|
||||||
@@ -32,10 +32,10 @@ def test_join_anonymous(settings, mock_telephony_service, client):
|
|||||||
|
|
||||||
assert response.status_code == 401
|
assert response.status_code == 401
|
||||||
assert response.json() == {"detail": "Authorization header is missing."}
|
assert response.json() == {"detail": "Authorization header is missing."}
|
||||||
mock_telephony_service.ensure_dispatch_rule.assert_not_called()
|
mock_sip_management.ensure_dispatch_rule.assert_not_called()
|
||||||
|
|
||||||
|
|
||||||
def test_join_malformed_authorization_header(settings, mock_telephony_service, client):
|
def test_join_malformed_authorization_header(settings, mock_sip_management, client):
|
||||||
"""Requests with a malformed Authorization header should be rejected."""
|
"""Requests with a malformed Authorization header should be rejected."""
|
||||||
settings.ROOMKIT_ENABLED = True
|
settings.ROOMKIT_ENABLED = True
|
||||||
settings.ROOMKIT_SERVER_TO_SERVER_API_TOKEN = "testAuthToken"
|
settings.ROOMKIT_SERVER_TO_SERVER_API_TOKEN = "testAuthToken"
|
||||||
@@ -50,10 +50,10 @@ def test_join_malformed_authorization_header(settings, mock_telephony_service, c
|
|||||||
|
|
||||||
assert response.status_code == 401
|
assert response.status_code == 401
|
||||||
assert response.json() == {"detail": "Invalid authorization header."}
|
assert response.json() == {"detail": "Invalid authorization header."}
|
||||||
mock_telephony_service.ensure_dispatch_rule.assert_not_called()
|
mock_sip_management.ensure_dispatch_rule.assert_not_called()
|
||||||
|
|
||||||
|
|
||||||
def test_join_wrong_bearer(settings, mock_telephony_service, client):
|
def test_join_wrong_bearer(settings, mock_sip_management, client):
|
||||||
"""Requests with an incorrect bearer token should be rejected."""
|
"""Requests with an incorrect bearer token should be rejected."""
|
||||||
settings.ROOMKIT_ENABLED = True
|
settings.ROOMKIT_ENABLED = True
|
||||||
settings.ROOMKIT_SERVER_TO_SERVER_API_TOKEN = "testAuthToken"
|
settings.ROOMKIT_SERVER_TO_SERVER_API_TOKEN = "testAuthToken"
|
||||||
@@ -68,10 +68,10 @@ def test_join_wrong_bearer(settings, mock_telephony_service, client):
|
|||||||
|
|
||||||
assert response.status_code == 401
|
assert response.status_code == 401
|
||||||
assert response.json() == {"detail": "Invalid server-to-server token."}
|
assert response.json() == {"detail": "Invalid server-to-server token."}
|
||||||
mock_telephony_service.ensure_dispatch_rule.assert_not_called()
|
mock_sip_management.ensure_dispatch_rule.assert_not_called()
|
||||||
|
|
||||||
|
|
||||||
def test_join_token_not_configured(settings, mock_telephony_service, client):
|
def test_join_token_not_configured(settings, mock_sip_management, client):
|
||||||
"""Requests should be rejected when no server-to-server token is configured."""
|
"""Requests should be rejected when no server-to-server token is configured."""
|
||||||
|
|
||||||
settings.ROOMKIT_ENABLED = True
|
settings.ROOMKIT_ENABLED = True
|
||||||
@@ -86,10 +86,10 @@ def test_join_token_not_configured(settings, mock_telephony_service, client):
|
|||||||
)
|
)
|
||||||
|
|
||||||
assert response.status_code == 401
|
assert response.status_code == 401
|
||||||
mock_telephony_service.ensure_dispatch_rule.assert_not_called()
|
mock_sip_management.ensure_dispatch_rule.assert_not_called()
|
||||||
|
|
||||||
|
|
||||||
def test_join_roomkit_disabled(settings, mock_telephony_service, client):
|
def test_join_roomkit_disabled(settings, mock_sip_management, client):
|
||||||
"""The endpoint should not be exposed when the roomkit integration is disabled."""
|
"""The endpoint should not be exposed when the roomkit integration is disabled."""
|
||||||
|
|
||||||
settings.ROOMKIT_ENABLED = False
|
settings.ROOMKIT_ENABLED = False
|
||||||
@@ -104,10 +104,10 @@ def test_join_roomkit_disabled(settings, mock_telephony_service, client):
|
|||||||
)
|
)
|
||||||
|
|
||||||
assert response.status_code == 404
|
assert response.status_code == 404
|
||||||
mock_telephony_service.ensure_dispatch_rule.assert_not_called()
|
mock_sip_management.ensure_dispatch_rule.assert_not_called()
|
||||||
|
|
||||||
|
|
||||||
def test_join_missing_pin(settings, mock_telephony_service, client):
|
def test_join_missing_pin(settings, mock_sip_management, client):
|
||||||
"""Requests without a PIN code should be rejected."""
|
"""Requests without a PIN code should be rejected."""
|
||||||
|
|
||||||
settings.ROOMKIT_ENABLED = True
|
settings.ROOMKIT_ENABLED = True
|
||||||
@@ -121,10 +121,10 @@ def test_join_missing_pin(settings, mock_telephony_service, client):
|
|||||||
|
|
||||||
assert response.status_code == 400
|
assert response.status_code == 400
|
||||||
assert response.json() == {"pin_code": ["This field is required."]}
|
assert response.json() == {"pin_code": ["This field is required."]}
|
||||||
mock_telephony_service.ensure_dispatch_rule.assert_not_called()
|
mock_sip_management.ensure_dispatch_rule.assert_not_called()
|
||||||
|
|
||||||
|
|
||||||
def test_join_blank_pin(settings, mock_telephony_service, client):
|
def test_join_blank_pin(settings, mock_sip_management, client):
|
||||||
"""Requests with a blank PIN code should be rejected."""
|
"""Requests with a blank PIN code should be rejected."""
|
||||||
|
|
||||||
settings.ROOMKIT_ENABLED = True
|
settings.ROOMKIT_ENABLED = True
|
||||||
@@ -138,10 +138,10 @@ def test_join_blank_pin(settings, mock_telephony_service, client):
|
|||||||
|
|
||||||
assert response.status_code == 400
|
assert response.status_code == 400
|
||||||
assert response.json() == {"pin_code": ["This field may not be blank."]}
|
assert response.json() == {"pin_code": ["This field may not be blank."]}
|
||||||
mock_telephony_service.ensure_dispatch_rule.assert_not_called()
|
mock_sip_management.ensure_dispatch_rule.assert_not_called()
|
||||||
|
|
||||||
|
|
||||||
def test_join_wrong_pin_length(settings, mock_telephony_service, client):
|
def test_join_wrong_pin_length(settings, mock_sip_management, client):
|
||||||
"""Requests with a PIN code of unexpected length should be rejected."""
|
"""Requests with a PIN code of unexpected length should be rejected."""
|
||||||
|
|
||||||
settings.ROOMKIT_ENABLED = True
|
settings.ROOMKIT_ENABLED = True
|
||||||
@@ -156,10 +156,10 @@ def test_join_wrong_pin_length(settings, mock_telephony_service, client):
|
|||||||
|
|
||||||
assert response.status_code == 400
|
assert response.status_code == 400
|
||||||
assert response.json() == {"pin_code": ["PIN code length is invalid."]}
|
assert response.json() == {"pin_code": ["PIN code length is invalid."]}
|
||||||
mock_telephony_service.ensure_dispatch_rule.assert_not_called()
|
mock_sip_management.ensure_dispatch_rule.assert_not_called()
|
||||||
|
|
||||||
|
|
||||||
def test_join_unknown_pin(settings, mock_telephony_service, client):
|
def test_join_unknown_pin(settings, mock_sip_management, client):
|
||||||
"""Requests with a PIN matching no room should return 404 and create no rule."""
|
"""Requests with a PIN matching no room should return 404 and create no rule."""
|
||||||
settings.ROOMKIT_ENABLED = True
|
settings.ROOMKIT_ENABLED = True
|
||||||
settings.ROOMKIT_SERVER_TO_SERVER_API_TOKEN = "testAuthToken"
|
settings.ROOMKIT_SERVER_TO_SERVER_API_TOKEN = "testAuthToken"
|
||||||
@@ -174,16 +174,16 @@ def test_join_unknown_pin(settings, mock_telephony_service, client):
|
|||||||
|
|
||||||
assert response.status_code == 404
|
assert response.status_code == 404
|
||||||
assert response.json() == {"detail": "No room found for this PIN code."}
|
assert response.json() == {"detail": "No room found for this PIN code."}
|
||||||
mock_telephony_service.ensure_dispatch_rule.assert_not_called()
|
mock_sip_management.ensure_dispatch_rule.assert_not_called()
|
||||||
|
|
||||||
|
|
||||||
def test_join_success(settings, mock_telephony_service, client):
|
def test_join_success(settings, mock_sip_management, client):
|
||||||
"""Requests with a valid PIN should create the dispatch rule."""
|
"""Requests with a valid PIN should create the dispatch rule."""
|
||||||
settings.ROOMKIT_ENABLED = True
|
settings.ROOMKIT_ENABLED = True
|
||||||
settings.ROOMKIT_SERVER_TO_SERVER_API_TOKEN = "testAuthToken"
|
settings.ROOMKIT_SERVER_TO_SERVER_API_TOKEN = "testAuthToken"
|
||||||
|
|
||||||
room = RoomFactory(pin_code="1234567890")
|
room = RoomFactory(pin_code="1234567890")
|
||||||
mock_telephony_service.ensure_dispatch_rule.return_value = True
|
mock_sip_management.ensure_dispatch_rule.return_value = True
|
||||||
|
|
||||||
response = client.post(
|
response = client.post(
|
||||||
"/api/v1.0/roomkit/join/",
|
"/api/v1.0/roomkit/join/",
|
||||||
@@ -193,17 +193,17 @@ def test_join_success(settings, mock_telephony_service, client):
|
|||||||
|
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
assert response.json() == {"status": "success"}
|
assert response.json() == {"status": "success"}
|
||||||
mock_telephony_service.ensure_dispatch_rule.assert_called_once_with(room)
|
mock_sip_management.ensure_dispatch_rule.assert_called_once_with(room)
|
||||||
|
|
||||||
|
|
||||||
def test_join_dispatch_rule_already_exists(settings, mock_telephony_service, client):
|
def test_join_dispatch_rule_already_exists(settings, mock_sip_management, client):
|
||||||
"""Requests should succeed when the dispatch rule already exists (idempotency)."""
|
"""Requests should succeed when the dispatch rule already exists (idempotency)."""
|
||||||
|
|
||||||
settings.ROOMKIT_ENABLED = True
|
settings.ROOMKIT_ENABLED = True
|
||||||
settings.ROOMKIT_SERVER_TO_SERVER_API_TOKEN = "testAuthToken"
|
settings.ROOMKIT_SERVER_TO_SERVER_API_TOKEN = "testAuthToken"
|
||||||
|
|
||||||
room = RoomFactory(pin_code="1234567890")
|
room = RoomFactory(pin_code="1234567890")
|
||||||
mock_telephony_service.ensure_dispatch_rule.return_value = False
|
mock_sip_management.ensure_dispatch_rule.return_value = False
|
||||||
|
|
||||||
response = client.post(
|
response = client.post(
|
||||||
"/api/v1.0/roomkit/join/",
|
"/api/v1.0/roomkit/join/",
|
||||||
@@ -213,17 +213,17 @@ def test_join_dispatch_rule_already_exists(settings, mock_telephony_service, cli
|
|||||||
|
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
assert response.json() == {"status": "success"}
|
assert response.json() == {"status": "success"}
|
||||||
mock_telephony_service.ensure_dispatch_rule.assert_called_once_with(room)
|
mock_sip_management.ensure_dispatch_rule.assert_called_once_with(room)
|
||||||
|
|
||||||
|
|
||||||
def test_join_tracks_analytics_event(settings, mock_telephony_service, client):
|
def test_join_tracks_analytics_event(settings, mock_sip_management, client):
|
||||||
"""Successful joins should be tracked with an analytics event."""
|
"""Successful joins should be tracked with an analytics event."""
|
||||||
|
|
||||||
settings.ROOMKIT_ENABLED = True
|
settings.ROOMKIT_ENABLED = True
|
||||||
settings.ROOMKIT_SERVER_TO_SERVER_API_TOKEN = "testAuthToken"
|
settings.ROOMKIT_SERVER_TO_SERVER_API_TOKEN = "testAuthToken"
|
||||||
|
|
||||||
room = RoomFactory(pin_code="1234567890")
|
room = RoomFactory(pin_code="1234567890")
|
||||||
mock_telephony_service.ensure_dispatch_rule.return_value = True
|
mock_sip_management.ensure_dispatch_rule.return_value = True
|
||||||
|
|
||||||
with mock.patch("core.roomkit.viewsets.analytics.capture") as mock_capture:
|
with mock.patch("core.roomkit.viewsets.analytics.capture") as mock_capture:
|
||||||
response = client.post(
|
response = client.post(
|
||||||
@@ -242,14 +242,14 @@ def test_join_tracks_analytics_event(settings, mock_telephony_service, client):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def test_join_telephony_failure(settings, mock_telephony_service, client):
|
def test_join_sip_failure(settings, mock_sip_management, client):
|
||||||
"""Requests should fail with a server error when the telephony service fails."""
|
"""Requests should fail with a server error when the sip management service fails."""
|
||||||
|
|
||||||
settings.ROOMKIT_ENABLED = True
|
settings.ROOMKIT_ENABLED = True
|
||||||
settings.ROOMKIT_SERVER_TO_SERVER_API_TOKEN = "testAuthToken"
|
settings.ROOMKIT_SERVER_TO_SERVER_API_TOKEN = "testAuthToken"
|
||||||
|
|
||||||
room = RoomFactory(pin_code="1234567890")
|
room = RoomFactory(pin_code="1234567890")
|
||||||
mock_telephony_service.ensure_dispatch_rule.side_effect = TelephonyException(
|
mock_sip_management.ensure_dispatch_rule.side_effect = SIPException(
|
||||||
"Could not create dispatch rule"
|
"Could not create dispatch rule"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -262,5 +262,5 @@ def test_join_telephony_failure(settings, mock_telephony_service, client):
|
|||||||
)
|
)
|
||||||
|
|
||||||
assert response.status_code == 500
|
assert response.status_code == 500
|
||||||
mock_telephony_service.ensure_dispatch_rule.assert_called_once_with(room)
|
mock_sip_management.ensure_dispatch_rule.assert_called_once_with(room)
|
||||||
mock_capture.assert_not_called()
|
mock_capture.assert_not_called()
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ from core.services.livekit_events import (
|
|||||||
)
|
)
|
||||||
from core.services.lobby import LobbyService
|
from core.services.lobby import LobbyService
|
||||||
from core.services.room_management import RoomManagementException
|
from core.services.room_management import RoomManagementException
|
||||||
from core.services.telephony import TelephonyException, TelephonyService
|
from core.services.sip_management import SIPException, SIPManagement
|
||||||
from core.utils import NotificationError
|
from core.utils import NotificationError
|
||||||
|
|
||||||
pytestmark = pytest.mark.django_db
|
pytestmark = pytest.mark.django_db
|
||||||
@@ -59,7 +59,7 @@ def test_initialization(
|
|||||||
mock_token_verifier.assert_called_once_with(api_key, api_secret)
|
mock_token_verifier.assert_called_once_with(api_key, api_secret)
|
||||||
mock_webhook_receiver.assert_called_once_with(mock_token_verifier.return_value)
|
mock_webhook_receiver.assert_called_once_with(mock_token_verifier.return_value)
|
||||||
assert isinstance(service.lobby_service, LobbyService)
|
assert isinstance(service.lobby_service, LobbyService)
|
||||||
assert isinstance(service.telephony_service, TelephonyService)
|
assert isinstance(service.sip_management, SIPManagement)
|
||||||
assert isinstance(service.recording_events, RecordingEventsService)
|
assert isinstance(service.recording_events, RecordingEventsService)
|
||||||
|
|
||||||
|
|
||||||
@@ -471,11 +471,11 @@ def test_handle_egress_ended_ignores_non_savable_recording(
|
|||||||
|
|
||||||
|
|
||||||
@mock.patch.object(LobbyService, "clear_room_cache")
|
@mock.patch.object(LobbyService, "clear_room_cache")
|
||||||
@mock.patch.object(TelephonyService, "delete_dispatch_rule")
|
@mock.patch.object(SIPManagement, "delete_dispatch_rule")
|
||||||
def test_handle_room_finished_clears_cache_and_deletes_dispatch_rule(
|
def test_handle_room_finished_clears_cache_and_deletes_dispatch_rule(
|
||||||
mock_delete_dispatch_rule, mock_clear_cache, service, settings
|
mock_delete_dispatch_rule, mock_clear_cache, service, settings
|
||||||
):
|
):
|
||||||
"""Should clear lobby cache and delete telephony dispatch rule when room finishes."""
|
"""Should clear lobby cache and delete SIP dispatch rule when room finishes."""
|
||||||
settings.ROOM_TELEPHONY_ENABLED = True
|
settings.ROOM_TELEPHONY_ENABLED = True
|
||||||
mock_room_name = uuid.uuid4()
|
mock_room_name = uuid.uuid4()
|
||||||
mock_data = mock.MagicMock()
|
mock_data = mock.MagicMock()
|
||||||
@@ -488,7 +488,7 @@ def test_handle_room_finished_clears_cache_and_deletes_dispatch_rule(
|
|||||||
|
|
||||||
|
|
||||||
@mock.patch.object(LobbyService, "clear_room_cache")
|
@mock.patch.object(LobbyService, "clear_room_cache")
|
||||||
@mock.patch.object(TelephonyService, "delete_dispatch_rule")
|
@mock.patch.object(SIPManagement, "delete_dispatch_rule")
|
||||||
def test_handle_room_finished_deletes_dispatch_rule_when_only_roomkit_enabled(
|
def test_handle_room_finished_deletes_dispatch_rule_when_only_roomkit_enabled(
|
||||||
mock_delete_dispatch_rule, mock_clear_cache, service, settings
|
mock_delete_dispatch_rule, mock_clear_cache, service, settings
|
||||||
):
|
):
|
||||||
@@ -506,7 +506,7 @@ def test_handle_room_finished_deletes_dispatch_rule_when_only_roomkit_enabled(
|
|||||||
|
|
||||||
|
|
||||||
@mock.patch.object(LobbyService, "clear_room_cache")
|
@mock.patch.object(LobbyService, "clear_room_cache")
|
||||||
@mock.patch.object(TelephonyService, "delete_dispatch_rule")
|
@mock.patch.object(SIPManagement, "delete_dispatch_rule")
|
||||||
def test_handle_room_finished_skips_telephony_when_disabled(
|
def test_handle_room_finished_skips_telephony_when_disabled(
|
||||||
mock_delete_dispatch_rule, mock_clear_cache, service, settings
|
mock_delete_dispatch_rule, mock_clear_cache, service, settings
|
||||||
):
|
):
|
||||||
@@ -526,7 +526,7 @@ def test_handle_room_finished_skips_telephony_when_disabled(
|
|||||||
@mock.patch.object(
|
@mock.patch.object(
|
||||||
LobbyService, "clear_room_cache", side_effect=Exception("Test error")
|
LobbyService, "clear_room_cache", side_effect=Exception("Test error")
|
||||||
)
|
)
|
||||||
@mock.patch.object(TelephonyService, "delete_dispatch_rule")
|
@mock.patch.object(SIPManagement, "delete_dispatch_rule")
|
||||||
def test_handle_room_finished_raises_error_when_cache_clearing_fails(
|
def test_handle_room_finished_raises_error_when_cache_clearing_fails(
|
||||||
mock_delete_dispatch_rule, mock_clear_cache, service, settings
|
mock_delete_dispatch_rule, mock_clear_cache, service, settings
|
||||||
):
|
):
|
||||||
@@ -549,9 +549,9 @@ def test_handle_room_finished_raises_error_when_cache_clearing_fails(
|
|||||||
|
|
||||||
@mock.patch.object(LobbyService, "clear_room_cache")
|
@mock.patch.object(LobbyService, "clear_room_cache")
|
||||||
@mock.patch.object(
|
@mock.patch.object(
|
||||||
TelephonyService,
|
SIPManagement,
|
||||||
"delete_dispatch_rule",
|
"delete_dispatch_rule",
|
||||||
side_effect=TelephonyException("Test error"),
|
side_effect=SIPException("Test error"),
|
||||||
)
|
)
|
||||||
def test_handle_room_finished_raises_error_when_telephony_deletion_fails(
|
def test_handle_room_finished_raises_error_when_telephony_deletion_fails(
|
||||||
mock_delete_dispatch_rule, mock_clear_cache, service, settings
|
mock_delete_dispatch_rule, mock_clear_cache, service, settings
|
||||||
@@ -583,11 +583,11 @@ def test_handle_room_finished_raises_error_for_invalid_room_name(service):
|
|||||||
service._handle_room_finished(mock_data)
|
service._handle_room_finished(mock_data)
|
||||||
|
|
||||||
|
|
||||||
@mock.patch.object(TelephonyService, "create_dispatch_rule")
|
@mock.patch.object(SIPManagement, "create_dispatch_rule")
|
||||||
def test_handle_room_started_creates_dispatch_rule_successfully(
|
def test_handle_room_started_creates_dispatch_rule_successfully(
|
||||||
mock_create_dispatch_rule, service, settings
|
mock_create_dispatch_rule, service, settings
|
||||||
):
|
):
|
||||||
"""Should create telephony dispatch rule when room starts successfully."""
|
"""Should create SIP dispatch rule when room starts successfully."""
|
||||||
settings.ROOM_TELEPHONY_ENABLED = True
|
settings.ROOM_TELEPHONY_ENABLED = True
|
||||||
room = RoomFactory()
|
room = RoomFactory()
|
||||||
mock_data = mock.MagicMock()
|
mock_data = mock.MagicMock()
|
||||||
@@ -598,7 +598,7 @@ def test_handle_room_started_creates_dispatch_rule_successfully(
|
|||||||
mock_create_dispatch_rule.assert_called_once_with(room)
|
mock_create_dispatch_rule.assert_called_once_with(room)
|
||||||
|
|
||||||
|
|
||||||
@mock.patch.object(TelephonyService, "create_dispatch_rule")
|
@mock.patch.object(SIPManagement, "create_dispatch_rule")
|
||||||
def test_handle_room_started_creates_dispatch_rule_when_only_roomkit_enabled(
|
def test_handle_room_started_creates_dispatch_rule_when_only_roomkit_enabled(
|
||||||
mock_create_dispatch_rule, service, settings
|
mock_create_dispatch_rule, service, settings
|
||||||
):
|
):
|
||||||
@@ -614,11 +614,11 @@ def test_handle_room_started_creates_dispatch_rule_when_only_roomkit_enabled(
|
|||||||
mock_create_dispatch_rule.assert_called_once_with(room)
|
mock_create_dispatch_rule.assert_called_once_with(room)
|
||||||
|
|
||||||
|
|
||||||
@mock.patch.object(TelephonyService, "create_dispatch_rule")
|
@mock.patch.object(SIPManagement, "create_dispatch_rule")
|
||||||
def test_handle_room_started_skips_dispatch_rule_when_telephony_disabled(
|
def test_handle_room_started_skips_dispatch_rule_when_telephony_disabled(
|
||||||
mock_create_dispatch_rule, service, settings
|
mock_create_dispatch_rule, service, settings
|
||||||
):
|
):
|
||||||
"""Should skip creating telephony dispatch rule when telephony is disabled during room start."""
|
"""Should skip creating SIP dispatch rule when telephony is disabled during room start."""
|
||||||
settings.ROOM_TELEPHONY_ENABLED = False
|
settings.ROOM_TELEPHONY_ENABLED = False
|
||||||
settings.ROOMKIT_ENABLED = False
|
settings.ROOMKIT_ENABLED = False
|
||||||
room = RoomFactory()
|
room = RoomFactory()
|
||||||
|
|||||||
+48
-48
@@ -1,5 +1,5 @@
|
|||||||
"""
|
"""
|
||||||
Test telephony service.
|
Test SIP mamagement service.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# pylint: disable=W0212
|
# pylint: disable=W0212
|
||||||
@@ -20,10 +20,10 @@ from livekit.protocol.sip import (
|
|||||||
|
|
||||||
from core.factories import RoomFactory
|
from core.factories import RoomFactory
|
||||||
from core.models import RoomAccessLevel
|
from core.models import RoomAccessLevel
|
||||||
from core.services.telephony import (
|
from core.services.sip_management import (
|
||||||
DispatchRuleConflictError,
|
DispatchRuleConflictError,
|
||||||
TelephonyException,
|
SIPException,
|
||||||
TelephonyService,
|
SIPManagement,
|
||||||
)
|
)
|
||||||
|
|
||||||
pytestmark = pytest.mark.django_db
|
pytestmark = pytest.mark.django_db
|
||||||
@@ -39,9 +39,9 @@ def create_mock_livekit_client():
|
|||||||
|
|
||||||
def test_rule_name():
|
def test_rule_name():
|
||||||
"""Test rule name generation."""
|
"""Test rule name generation."""
|
||||||
telephony_service = TelephonyService()
|
sip_management = SIPManagement()
|
||||||
room = RoomFactory(access_level=RoomAccessLevel.RESTRICTED, pin_code="1234")
|
room = RoomFactory(access_level=RoomAccessLevel.RESTRICTED, pin_code="1234")
|
||||||
rule_name = telephony_service._rule_name(room.id)
|
rule_name = sip_management._rule_name(room.id)
|
||||||
|
|
||||||
assert rule_name == f"SIP_{str(room.id)}"
|
assert rule_name == f"SIP_{str(room.id)}"
|
||||||
|
|
||||||
@@ -49,14 +49,14 @@ def test_rule_name():
|
|||||||
@mock.patch("core.utils.create_livekit_client")
|
@mock.patch("core.utils.create_livekit_client")
|
||||||
def test_create_dispatch_rule_success(mock_client_factory):
|
def test_create_dispatch_rule_success(mock_client_factory):
|
||||||
"""Test successful dispatch rule creation."""
|
"""Test successful dispatch rule creation."""
|
||||||
telephony_service = TelephonyService()
|
sip_management = SIPManagement()
|
||||||
room = RoomFactory(access_level=RoomAccessLevel.RESTRICTED, pin_code="1234")
|
room = RoomFactory(access_level=RoomAccessLevel.RESTRICTED, pin_code="1234")
|
||||||
|
|
||||||
mock_api = create_mock_livekit_client()
|
mock_api = create_mock_livekit_client()
|
||||||
mock_api.sip.create_sip_dispatch_rule = mock.AsyncMock()
|
mock_api.sip.create_sip_dispatch_rule = mock.AsyncMock()
|
||||||
mock_client_factory.return_value = mock_api
|
mock_client_factory.return_value = mock_api
|
||||||
|
|
||||||
telephony_service.create_dispatch_rule(room)
|
sip_management.create_dispatch_rule(room)
|
||||||
|
|
||||||
mock_api.sip.create_sip_dispatch_rule.assert_called_once()
|
mock_api.sip.create_sip_dispatch_rule.assert_called_once()
|
||||||
create_request = mock_api.sip.create_sip_dispatch_rule.call_args[1]["create"]
|
create_request = mock_api.sip.create_sip_dispatch_rule.call_args[1]["create"]
|
||||||
@@ -71,7 +71,7 @@ def test_create_dispatch_rule_success(mock_client_factory):
|
|||||||
@mock.patch("core.utils.create_livekit_client")
|
@mock.patch("core.utils.create_livekit_client")
|
||||||
def test_create_dispatch_rule_api_failure(mock_client_factory):
|
def test_create_dispatch_rule_api_failure(mock_client_factory):
|
||||||
"""Test dispatch rule creation when API fails."""
|
"""Test dispatch rule creation when API fails."""
|
||||||
telephony_service = TelephonyService()
|
sip_management = SIPManagement()
|
||||||
room = RoomFactory(access_level=RoomAccessLevel.RESTRICTED, pin_code="1234")
|
room = RoomFactory(access_level=RoomAccessLevel.RESTRICTED, pin_code="1234")
|
||||||
|
|
||||||
mock_api = create_mock_livekit_client()
|
mock_api = create_mock_livekit_client()
|
||||||
@@ -80,8 +80,8 @@ def test_create_dispatch_rule_api_failure(mock_client_factory):
|
|||||||
)
|
)
|
||||||
mock_client_factory.return_value = mock_api
|
mock_client_factory.return_value = mock_api
|
||||||
|
|
||||||
with pytest.raises(TelephonyException, match="Could not create dispatch rule"):
|
with pytest.raises(SIPException, match="Could not create dispatch rule"):
|
||||||
telephony_service.create_dispatch_rule(room)
|
sip_management.create_dispatch_rule(room)
|
||||||
|
|
||||||
mock_api.sip.create_sip_dispatch_rule.assert_called_once()
|
mock_api.sip.create_sip_dispatch_rule.assert_called_once()
|
||||||
mock_api.aclose.assert_called_once()
|
mock_api.aclose.assert_called_once()
|
||||||
@@ -90,7 +90,7 @@ def test_create_dispatch_rule_api_failure(mock_client_factory):
|
|||||||
@mock.patch("core.utils.create_livekit_client")
|
@mock.patch("core.utils.create_livekit_client")
|
||||||
def test_list_dispatch_rules_ids_success(mock_client_factory):
|
def test_list_dispatch_rules_ids_success(mock_client_factory):
|
||||||
"""Test successful listing of dispatch rule IDs."""
|
"""Test successful listing of dispatch rule IDs."""
|
||||||
telephony_service = TelephonyService()
|
sip_management = SIPManagement()
|
||||||
room = RoomFactory(access_level=RoomAccessLevel.RESTRICTED, pin_code="1234")
|
room = RoomFactory(access_level=RoomAccessLevel.RESTRICTED, pin_code="1234")
|
||||||
|
|
||||||
mock_rules = [
|
mock_rules = [
|
||||||
@@ -115,7 +115,7 @@ def test_list_dispatch_rules_ids_success(mock_client_factory):
|
|||||||
)
|
)
|
||||||
mock_client_factory.return_value = mock_api
|
mock_client_factory.return_value = mock_api
|
||||||
|
|
||||||
result = async_to_sync(telephony_service._list_dispatch_rules_ids)(room.id)
|
result = async_to_sync(sip_management._list_dispatch_rules_ids)(room.id)
|
||||||
|
|
||||||
assert len(result) == 2
|
assert len(result) == 2
|
||||||
assert "rule-1" in result
|
assert "rule-1" in result
|
||||||
@@ -131,7 +131,7 @@ def test_list_dispatch_rules_ids_success(mock_client_factory):
|
|||||||
@mock.patch("core.utils.create_livekit_client")
|
@mock.patch("core.utils.create_livekit_client")
|
||||||
def test_list_dispatch_rules_ids_empty_response(mock_client_factory):
|
def test_list_dispatch_rules_ids_empty_response(mock_client_factory):
|
||||||
"""Test listing dispatch rule IDs when no rules exist."""
|
"""Test listing dispatch rule IDs when no rules exist."""
|
||||||
telephony_service = TelephonyService()
|
sip_management = SIPManagement()
|
||||||
room = RoomFactory(access_level=RoomAccessLevel.RESTRICTED, pin_code="1234")
|
room = RoomFactory(access_level=RoomAccessLevel.RESTRICTED, pin_code="1234")
|
||||||
|
|
||||||
mock_api = create_mock_livekit_client()
|
mock_api = create_mock_livekit_client()
|
||||||
@@ -140,7 +140,7 @@ def test_list_dispatch_rules_ids_empty_response(mock_client_factory):
|
|||||||
)
|
)
|
||||||
mock_client_factory.return_value = mock_api
|
mock_client_factory.return_value = mock_api
|
||||||
|
|
||||||
result = async_to_sync(telephony_service._list_dispatch_rules_ids)(room.id)
|
result = async_to_sync(sip_management._list_dispatch_rules_ids)(room.id)
|
||||||
|
|
||||||
assert result == []
|
assert result == []
|
||||||
mock_api.aclose.assert_called_once()
|
mock_api.aclose.assert_called_once()
|
||||||
@@ -149,7 +149,7 @@ def test_list_dispatch_rules_ids_empty_response(mock_client_factory):
|
|||||||
@mock.patch("core.utils.create_livekit_client")
|
@mock.patch("core.utils.create_livekit_client")
|
||||||
def test_list_dispatch_rules_ids_no_matching_rules(mock_client_factory):
|
def test_list_dispatch_rules_ids_no_matching_rules(mock_client_factory):
|
||||||
"""Test listing dispatch rule IDs when no rules match the room."""
|
"""Test listing dispatch rule IDs when no rules match the room."""
|
||||||
telephony_service = TelephonyService()
|
sip_management = SIPManagement()
|
||||||
room = RoomFactory(access_level=RoomAccessLevel.RESTRICTED, pin_code="1234")
|
room = RoomFactory(access_level=RoomAccessLevel.RESTRICTED, pin_code="1234")
|
||||||
|
|
||||||
mock_rules = [
|
mock_rules = [
|
||||||
@@ -167,7 +167,7 @@ def test_list_dispatch_rules_ids_no_matching_rules(mock_client_factory):
|
|||||||
)
|
)
|
||||||
mock_client_factory.return_value = mock_api
|
mock_client_factory.return_value = mock_api
|
||||||
|
|
||||||
result = async_to_sync(telephony_service._list_dispatch_rules_ids)(room.id)
|
result = async_to_sync(sip_management._list_dispatch_rules_ids)(room.id)
|
||||||
|
|
||||||
assert result == []
|
assert result == []
|
||||||
mock_api.aclose.assert_called_once()
|
mock_api.aclose.assert_called_once()
|
||||||
@@ -176,7 +176,7 @@ def test_list_dispatch_rules_ids_no_matching_rules(mock_client_factory):
|
|||||||
@mock.patch("core.utils.create_livekit_client")
|
@mock.patch("core.utils.create_livekit_client")
|
||||||
def test_list_dispatch_rules_ids_api_failure(mock_client_factory):
|
def test_list_dispatch_rules_ids_api_failure(mock_client_factory):
|
||||||
"""Test listing dispatch rule IDs when API fails."""
|
"""Test listing dispatch rule IDs when API fails."""
|
||||||
telephony_service = TelephonyService()
|
sip_management = SIPManagement()
|
||||||
room = RoomFactory(access_level=RoomAccessLevel.RESTRICTED, pin_code="1234")
|
room = RoomFactory(access_level=RoomAccessLevel.RESTRICTED, pin_code="1234")
|
||||||
|
|
||||||
mock_api = create_mock_livekit_client()
|
mock_api = create_mock_livekit_client()
|
||||||
@@ -185,34 +185,34 @@ def test_list_dispatch_rules_ids_api_failure(mock_client_factory):
|
|||||||
)
|
)
|
||||||
mock_client_factory.return_value = mock_api
|
mock_client_factory.return_value = mock_api
|
||||||
|
|
||||||
with pytest.raises(TelephonyException, match="Could not list dispatch rules"):
|
with pytest.raises(SIPException, match="Could not list dispatch rules"):
|
||||||
async_to_sync(telephony_service._list_dispatch_rules_ids)(room.id)
|
async_to_sync(sip_management._list_dispatch_rules_ids)(room.id)
|
||||||
|
|
||||||
mock_api.sip.list_sip_dispatch_rule.assert_called_once()
|
mock_api.sip.list_sip_dispatch_rule.assert_called_once()
|
||||||
mock_api.aclose.assert_called_once()
|
mock_api.aclose.assert_called_once()
|
||||||
|
|
||||||
|
|
||||||
@mock.patch("core.services.telephony.TelephonyService._list_dispatch_rules_ids")
|
@mock.patch("core.services.sip_management.SIPManagement._list_dispatch_rules_ids")
|
||||||
@mock.patch("core.utils.create_livekit_client")
|
@mock.patch("core.utils.create_livekit_client")
|
||||||
def test_delete_dispatch_rule_no_rules(mock_client_factory, mock_list_rules):
|
def test_delete_dispatch_rule_no_rules(mock_client_factory, mock_list_rules):
|
||||||
"""Test deleting dispatch rules when no rules exist."""
|
"""Test deleting dispatch rules when no rules exist."""
|
||||||
telephony_service = TelephonyService()
|
sip_management = SIPManagement()
|
||||||
room = RoomFactory(access_level=RoomAccessLevel.RESTRICTED, pin_code="1234")
|
room = RoomFactory(access_level=RoomAccessLevel.RESTRICTED, pin_code="1234")
|
||||||
|
|
||||||
mock_list_rules.return_value = []
|
mock_list_rules.return_value = []
|
||||||
|
|
||||||
result = telephony_service.delete_dispatch_rule(room.id)
|
result = sip_management.delete_dispatch_rule(room.id)
|
||||||
|
|
||||||
assert result is False
|
assert result is False
|
||||||
mock_list_rules.assert_called_once_with(room.id)
|
mock_list_rules.assert_called_once_with(room.id)
|
||||||
mock_client_factory.assert_not_called()
|
mock_client_factory.assert_not_called()
|
||||||
|
|
||||||
|
|
||||||
@mock.patch("core.services.telephony.TelephonyService._list_dispatch_rules_ids")
|
@mock.patch("core.services.sip_management.SIPManagement._list_dispatch_rules_ids")
|
||||||
@mock.patch("core.utils.create_livekit_client")
|
@mock.patch("core.utils.create_livekit_client")
|
||||||
def test_delete_dispatch_rule_single_rule(mock_client_factory, mock_list_rules):
|
def test_delete_dispatch_rule_single_rule(mock_client_factory, mock_list_rules):
|
||||||
"""Test deleting a single dispatch rule."""
|
"""Test deleting a single dispatch rule."""
|
||||||
telephony_service = TelephonyService()
|
sip_management = SIPManagement()
|
||||||
room = RoomFactory(access_level=RoomAccessLevel.RESTRICTED, pin_code="1234")
|
room = RoomFactory(access_level=RoomAccessLevel.RESTRICTED, pin_code="1234")
|
||||||
|
|
||||||
mock_list_rules.return_value = ["rule-1"]
|
mock_list_rules.return_value = ["rule-1"]
|
||||||
@@ -220,7 +220,7 @@ def test_delete_dispatch_rule_single_rule(mock_client_factory, mock_list_rules):
|
|||||||
mock_api.sip.delete_sip_dispatch_rule = mock.AsyncMock()
|
mock_api.sip.delete_sip_dispatch_rule = mock.AsyncMock()
|
||||||
mock_client_factory.return_value = mock_api
|
mock_client_factory.return_value = mock_api
|
||||||
|
|
||||||
result = telephony_service.delete_dispatch_rule(room.id)
|
result = sip_management.delete_dispatch_rule(room.id)
|
||||||
|
|
||||||
assert result is True
|
assert result is True
|
||||||
mock_api.sip.delete_sip_dispatch_rule.assert_called_once()
|
mock_api.sip.delete_sip_dispatch_rule.assert_called_once()
|
||||||
@@ -230,11 +230,11 @@ def test_delete_dispatch_rule_single_rule(mock_client_factory, mock_list_rules):
|
|||||||
mock_api.aclose.assert_called_once()
|
mock_api.aclose.assert_called_once()
|
||||||
|
|
||||||
|
|
||||||
@mock.patch("core.services.telephony.TelephonyService._list_dispatch_rules_ids")
|
@mock.patch("core.services.sip_management.SIPManagement._list_dispatch_rules_ids")
|
||||||
@mock.patch("core.utils.create_livekit_client")
|
@mock.patch("core.utils.create_livekit_client")
|
||||||
def test_delete_dispatch_rule_multiple_rules(mock_client_factory, mock_list_rules):
|
def test_delete_dispatch_rule_multiple_rules(mock_client_factory, mock_list_rules):
|
||||||
"""Test deleting multiple dispatch rules."""
|
"""Test deleting multiple dispatch rules."""
|
||||||
telephony_service = TelephonyService()
|
sip_management = SIPManagement()
|
||||||
room = RoomFactory(access_level=RoomAccessLevel.RESTRICTED, pin_code="1234")
|
room = RoomFactory(access_level=RoomAccessLevel.RESTRICTED, pin_code="1234")
|
||||||
|
|
||||||
mock_list_rules.return_value = ["rule-1", "rule-2", "rule-3"]
|
mock_list_rules.return_value = ["rule-1", "rule-2", "rule-3"]
|
||||||
@@ -242,7 +242,7 @@ def test_delete_dispatch_rule_multiple_rules(mock_client_factory, mock_list_rule
|
|||||||
mock_api.sip.delete_sip_dispatch_rule = mock.AsyncMock()
|
mock_api.sip.delete_sip_dispatch_rule = mock.AsyncMock()
|
||||||
mock_client_factory.return_value = mock_api
|
mock_client_factory.return_value = mock_api
|
||||||
|
|
||||||
result = telephony_service.delete_dispatch_rule(room.id)
|
result = sip_management.delete_dispatch_rule(room.id)
|
||||||
|
|
||||||
assert result is True
|
assert result is True
|
||||||
assert mock_api.sip.delete_sip_dispatch_rule.call_count == 3
|
assert mock_api.sip.delete_sip_dispatch_rule.call_count == 3
|
||||||
@@ -257,11 +257,11 @@ def test_delete_dispatch_rule_multiple_rules(mock_client_factory, mock_list_rule
|
|||||||
mock_api.aclose.assert_called_once()
|
mock_api.aclose.assert_called_once()
|
||||||
|
|
||||||
|
|
||||||
@mock.patch("core.services.telephony.TelephonyService._list_dispatch_rules_ids")
|
@mock.patch("core.services.sip_management.SIPManagement._list_dispatch_rules_ids")
|
||||||
@mock.patch("core.utils.create_livekit_client")
|
@mock.patch("core.utils.create_livekit_client")
|
||||||
def test_delete_dispatch_rule_partial_failure(mock_client_factory, mock_list_rules):
|
def test_delete_dispatch_rule_partial_failure(mock_client_factory, mock_list_rules):
|
||||||
"""Test deleting multiple dispatch rules when one deletion fails."""
|
"""Test deleting multiple dispatch rules when one deletion fails."""
|
||||||
telephony_service = TelephonyService()
|
sip_management = SIPManagement()
|
||||||
room = RoomFactory(access_level=RoomAccessLevel.RESTRICTED, pin_code="1234")
|
room = RoomFactory(access_level=RoomAccessLevel.RESTRICTED, pin_code="1234")
|
||||||
|
|
||||||
mock_list_rules.return_value = ["rule-1", "rule-2", "rule-3"]
|
mock_list_rules.return_value = ["rule-1", "rule-2", "rule-3"]
|
||||||
@@ -281,18 +281,18 @@ def test_delete_dispatch_rule_partial_failure(mock_client_factory, mock_list_rul
|
|||||||
)
|
)
|
||||||
mock_client_factory.return_value = mock_api
|
mock_client_factory.return_value = mock_api
|
||||||
|
|
||||||
with pytest.raises(TelephonyException, match="Could not delete dispatch rules"):
|
with pytest.raises(SIPException, match="Could not delete dispatch rules"):
|
||||||
telephony_service.delete_dispatch_rule(room.id)
|
sip_management.delete_dispatch_rule(room.id)
|
||||||
|
|
||||||
assert mock_api.sip.delete_sip_dispatch_rule.call_count == 2
|
assert mock_api.sip.delete_sip_dispatch_rule.call_count == 2
|
||||||
mock_api.aclose.assert_called_once()
|
mock_api.aclose.assert_called_once()
|
||||||
|
|
||||||
|
|
||||||
@mock.patch("core.services.telephony.TelephonyService._list_dispatch_rules_ids")
|
@mock.patch("core.services.sip_management.SIPManagement._list_dispatch_rules_ids")
|
||||||
@mock.patch("core.utils.create_livekit_client")
|
@mock.patch("core.utils.create_livekit_client")
|
||||||
def test_delete_dispatch_rule_api_failure(mock_client_factory, mock_list_rules):
|
def test_delete_dispatch_rule_api_failure(mock_client_factory, mock_list_rules):
|
||||||
"""Test deleting dispatch rules when API fails immediately."""
|
"""Test deleting dispatch rules when API fails immediately."""
|
||||||
telephony_service = TelephonyService()
|
sip_management = SIPManagement()
|
||||||
room = RoomFactory(access_level=RoomAccessLevel.RESTRICTED, pin_code="1234")
|
room = RoomFactory(access_level=RoomAccessLevel.RESTRICTED, pin_code="1234")
|
||||||
|
|
||||||
mock_list_rules.return_value = ["rule-1"]
|
mock_list_rules.return_value = ["rule-1"]
|
||||||
@@ -302,8 +302,8 @@ def test_delete_dispatch_rule_api_failure(mock_client_factory, mock_list_rules):
|
|||||||
)
|
)
|
||||||
mock_client_factory.return_value = mock_api
|
mock_client_factory.return_value = mock_api
|
||||||
|
|
||||||
with pytest.raises(TelephonyException, match="Could not delete dispatch rules"):
|
with pytest.raises(SIPException, match="Could not delete dispatch rules"):
|
||||||
telephony_service.delete_dispatch_rule(room.id)
|
sip_management.delete_dispatch_rule(room.id)
|
||||||
|
|
||||||
mock_api.sip.delete_sip_dispatch_rule.assert_called_once()
|
mock_api.sip.delete_sip_dispatch_rule.assert_called_once()
|
||||||
mock_api.aclose.assert_called_once()
|
mock_api.aclose.assert_called_once()
|
||||||
@@ -312,7 +312,7 @@ def test_delete_dispatch_rule_api_failure(mock_client_factory, mock_list_rules):
|
|||||||
@mock.patch("core.utils.create_livekit_client")
|
@mock.patch("core.utils.create_livekit_client")
|
||||||
def test_create_dispatch_rule_conflict_raises_dedicated_error(mock_client_factory):
|
def test_create_dispatch_rule_conflict_raises_dedicated_error(mock_client_factory):
|
||||||
"""Test that a LiveKit conflict error raises DispatchRuleConflictError."""
|
"""Test that a LiveKit conflict error raises DispatchRuleConflictError."""
|
||||||
telephony_service = TelephonyService()
|
sip_management = SIPManagement()
|
||||||
room = RoomFactory(access_level=RoomAccessLevel.RESTRICTED, pin_code="1234")
|
room = RoomFactory(access_level=RoomAccessLevel.RESTRICTED, pin_code="1234")
|
||||||
|
|
||||||
mock_api = create_mock_livekit_client()
|
mock_api = create_mock_livekit_client()
|
||||||
@@ -329,7 +329,7 @@ def test_create_dispatch_rule_conflict_raises_dedicated_error(mock_client_factor
|
|||||||
mock_client_factory.return_value = mock_api
|
mock_client_factory.return_value = mock_api
|
||||||
|
|
||||||
with pytest.raises(DispatchRuleConflictError):
|
with pytest.raises(DispatchRuleConflictError):
|
||||||
telephony_service.create_dispatch_rule(room)
|
sip_management.create_dispatch_rule(room)
|
||||||
|
|
||||||
mock_api.aclose.assert_called_once()
|
mock_api.aclose.assert_called_once()
|
||||||
|
|
||||||
@@ -337,7 +337,7 @@ def test_create_dispatch_rule_conflict_raises_dedicated_error(mock_client_factor
|
|||||||
@mock.patch("core.utils.create_livekit_client")
|
@mock.patch("core.utils.create_livekit_client")
|
||||||
def test_ensure_dispatch_rule_creates_when_missing(mock_client_factory):
|
def test_ensure_dispatch_rule_creates_when_missing(mock_client_factory):
|
||||||
"""Test that ensure_dispatch_rule creates the rule when none exists."""
|
"""Test that ensure_dispatch_rule creates the rule when none exists."""
|
||||||
telephony_service = TelephonyService()
|
sip_management = SIPManagement()
|
||||||
room = RoomFactory(access_level=RoomAccessLevel.RESTRICTED, pin_code="1234")
|
room = RoomFactory(access_level=RoomAccessLevel.RESTRICTED, pin_code="1234")
|
||||||
|
|
||||||
mock_api = create_mock_livekit_client()
|
mock_api = create_mock_livekit_client()
|
||||||
@@ -347,7 +347,7 @@ def test_ensure_dispatch_rule_creates_when_missing(mock_client_factory):
|
|||||||
mock_api.sip.create_sip_dispatch_rule = mock.AsyncMock()
|
mock_api.sip.create_sip_dispatch_rule = mock.AsyncMock()
|
||||||
mock_client_factory.return_value = mock_api
|
mock_client_factory.return_value = mock_api
|
||||||
|
|
||||||
created = telephony_service.ensure_dispatch_rule(room)
|
created = sip_management.ensure_dispatch_rule(room)
|
||||||
|
|
||||||
assert created is True
|
assert created is True
|
||||||
mock_api.sip.create_sip_dispatch_rule.assert_called_once()
|
mock_api.sip.create_sip_dispatch_rule.assert_called_once()
|
||||||
@@ -362,7 +362,7 @@ def test_ensure_dispatch_rule_creates_when_missing(mock_client_factory):
|
|||||||
@mock.patch("core.utils.create_livekit_client")
|
@mock.patch("core.utils.create_livekit_client")
|
||||||
def test_ensure_dispatch_rule_skips_when_existing(mock_client_factory):
|
def test_ensure_dispatch_rule_skips_when_existing(mock_client_factory):
|
||||||
"""Test that ensure_dispatch_rule is idempotent when the rule already exists."""
|
"""Test that ensure_dispatch_rule is idempotent when the rule already exists."""
|
||||||
telephony_service = TelephonyService()
|
sip_management = SIPManagement()
|
||||||
room = RoomFactory(access_level=RoomAccessLevel.RESTRICTED, pin_code="1234")
|
room = RoomFactory(access_level=RoomAccessLevel.RESTRICTED, pin_code="1234")
|
||||||
|
|
||||||
existing_rule = SIPDispatchRuleInfo(
|
existing_rule = SIPDispatchRuleInfo(
|
||||||
@@ -375,7 +375,7 @@ def test_ensure_dispatch_rule_skips_when_existing(mock_client_factory):
|
|||||||
mock_api.sip.create_sip_dispatch_rule = mock.AsyncMock()
|
mock_api.sip.create_sip_dispatch_rule = mock.AsyncMock()
|
||||||
mock_client_factory.return_value = mock_api
|
mock_client_factory.return_value = mock_api
|
||||||
|
|
||||||
created = telephony_service.ensure_dispatch_rule(room)
|
created = sip_management.ensure_dispatch_rule(room)
|
||||||
|
|
||||||
assert created is False
|
assert created is False
|
||||||
mock_api.sip.create_sip_dispatch_rule.assert_not_called()
|
mock_api.sip.create_sip_dispatch_rule.assert_not_called()
|
||||||
@@ -389,7 +389,7 @@ def test_ensure_dispatch_rule_returns_false_on_conflict(mock_client_factory):
|
|||||||
between the existence check and the creation, LiveKit rejects the
|
between the existence check and the creation, LiveKit rejects the
|
||||||
duplicate and ensure_dispatch_rule reports the rule as already existing.
|
duplicate and ensure_dispatch_rule reports the rule as already existing.
|
||||||
"""
|
"""
|
||||||
telephony_service = TelephonyService()
|
sip_management = SIPManagement()
|
||||||
room = RoomFactory(access_level=RoomAccessLevel.RESTRICTED, pin_code="1234")
|
room = RoomFactory(access_level=RoomAccessLevel.RESTRICTED, pin_code="1234")
|
||||||
|
|
||||||
mock_api = create_mock_livekit_client()
|
mock_api = create_mock_livekit_client()
|
||||||
@@ -408,7 +408,7 @@ def test_ensure_dispatch_rule_returns_false_on_conflict(mock_client_factory):
|
|||||||
)
|
)
|
||||||
mock_client_factory.return_value = mock_api
|
mock_client_factory.return_value = mock_api
|
||||||
|
|
||||||
created = telephony_service.ensure_dispatch_rule(room)
|
created = sip_management.ensure_dispatch_rule(room)
|
||||||
|
|
||||||
assert created is False
|
assert created is False
|
||||||
|
|
||||||
@@ -416,7 +416,7 @@ def test_ensure_dispatch_rule_returns_false_on_conflict(mock_client_factory):
|
|||||||
@mock.patch("core.utils.create_livekit_client")
|
@mock.patch("core.utils.create_livekit_client")
|
||||||
def test_ensure_dispatch_rule_raises_on_other_failures(mock_client_factory):
|
def test_ensure_dispatch_rule_raises_on_other_failures(mock_client_factory):
|
||||||
"""Test that ensure_dispatch_rule propagates unexpected LiveKit failures."""
|
"""Test that ensure_dispatch_rule propagates unexpected LiveKit failures."""
|
||||||
telephony_service = TelephonyService()
|
sip_management = SIPManagement()
|
||||||
room = RoomFactory(access_level=RoomAccessLevel.RESTRICTED, pin_code="1234")
|
room = RoomFactory(access_level=RoomAccessLevel.RESTRICTED, pin_code="1234")
|
||||||
|
|
||||||
mock_api = create_mock_livekit_client()
|
mock_api = create_mock_livekit_client()
|
||||||
@@ -428,5 +428,5 @@ def test_ensure_dispatch_rule_raises_on_other_failures(mock_client_factory):
|
|||||||
)
|
)
|
||||||
mock_client_factory.return_value = mock_api
|
mock_client_factory.return_value = mock_api
|
||||||
|
|
||||||
with pytest.raises(TelephonyException, match="Could not create dispatch rule"):
|
with pytest.raises(SIPException, match="Could not create dispatch rule"):
|
||||||
telephony_service.ensure_dispatch_rule(room)
|
sip_management.ensure_dispatch_rule(room)
|
||||||
Reference in New Issue
Block a user