🚚(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:
lebaudantoine
2026-07-30 19:46:30 +02:00
parent 8b198726e9
commit e65036fe90
7 changed files with 119 additions and 118 deletions
+1
View File
@@ -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
+4 -4
View File
@@ -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(
+8 -8
View File
@@ -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:
@@ -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()
@@ -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)