Skip to content

Commit

Permalink
Merge branch 'DEVEXP-710_Available_Numbers' into DEVEXP-729_E2E-Tests…
Browse files Browse the repository at this point in the history
…-available-numbers
  • Loading branch information
asein-sinch committed Feb 5, 2025
2 parents 514896c + 57bcc50 commit 4832865
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 44 deletions.
21 changes: 2 additions & 19 deletions sinch/domains/numbers/models/available/activate_number_request.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
from typing import Optional, Dict
from pydantic import Field, StrictStr
from sinch.domains.numbers.validators import validate_sms_voice_configuration
from sinch.domains.numbers.models.base_model_numbers import BaseModelConfigRequest
from sinch.domains.numbers.models.numbers import (SmsConfigurationRequest, VoiceConfigurationFAX,
VoiceConfigurationEST, VoiceConfigurationRTC,
VoiceConfigurationCustom)


class ActivateNumberRequest(BaseModelConfigRequest):
Expand All @@ -17,20 +15,5 @@ def __init__(self, **data):
"""
Custom initializer to validate nested dictionaries.
"""
for key in ("smsConfiguration", "sms_configuration"):
if key in data and data[key] is not None:
SmsConfigurationRequest(**data[key])

voice_config_map = {
"RTC": VoiceConfigurationRTC,
"EST": VoiceConfigurationEST,
"FAX": VoiceConfigurationFAX,
}

for key in ("voiceConfiguration", "voice_configuration"):
if key in data and data[key] is not None:
voice_type = data[key].get('type') or 'RTC'
voice_config_class = voice_config_map.get(voice_type, VoiceConfigurationCustom)
voice_config_class(**data[key])

validate_sms_voice_configuration(data)
super().__init__(**data)
18 changes: 12 additions & 6 deletions sinch/domains/numbers/models/available/rent_any_number_request.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from typing import Optional, Union, Dict, Any
from typing import Optional, Dict
from pydantic import Field, StrictStr
from sinch.domains.numbers.validators import validate_sms_voice_configuration
from sinch.domains.numbers.models.base_model_numbers import BaseModelConfigRequest
from sinch.domains.numbers.models.numbers import (NumberSearchPatternType, CapabilityType,
SmsConfigurationRequest, VoiceConfigurationType)
from sinch.domains.numbers.models.numbers import NumberSearchPatternType, CapabilityType


class NumberPattern(BaseModelConfigRequest):
Expand All @@ -15,7 +15,13 @@ class RentAnyNumberRequest(BaseModelConfigRequest):
type_: StrictStr = Field(default=None, alias="type")
number_pattern: Optional[NumberPattern] = Field(default=None, alias="numberPattern")
capabilities: Optional[CapabilityType] = Field(default=None)
sms_configuration: Optional[SmsConfigurationRequest] = Field(default=None, alias="smsConfiguration")
voice_configuration: Union[VoiceConfigurationType, Dict[str, Any], None] = (
Field(default=None, alias="voiceConfiguration"))
sms_configuration: Optional[Dict] = Field(default=None, alias="smsConfiguration")
voice_configuration: Optional[Dict] = Field(default=None, alias="voiceConfiguration")
callback_url: Optional[StrictStr] = Field(default=None, alias="callbackUrl")

def __init__(self, **data):
"""
Custom initializer to validate nested dictionaries.
"""
validate_sms_voice_configuration(data)
super().__init__(**data)
36 changes: 36 additions & 0 deletions sinch/domains/numbers/validators.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from typing import Dict, Any
from sinch.domains.numbers.models.numbers import (
SmsConfigurationRequest, VoiceConfigurationRTC,
VoiceConfigurationEST, VoiceConfigurationFAX,
VoiceConfigurationCustom
)


def validate_sms_voice_configuration(data: Dict[str, Any]) -> None:
"""
Validates `sms_configuration` and `voice_configuration` fields in request data.
Args:
data (dict): The request payload.
Raises:
ValidationError: If validation fails for the configurations.
"""
# Validate SMS Configuration
for key in ("smsConfiguration", "sms_configuration"):
if key in data and data[key] is not None:
SmsConfigurationRequest(**data[key])

# Validate Voice Configuration
voice_config_map = {
"RTC": VoiceConfigurationRTC,
"EST": VoiceConfigurationEST,
"FAX": VoiceConfigurationFAX,
}

for key in ("voiceConfiguration", "voice_configuration"):
if key in data and data[key] is not None:
# Handle legacy requests
voice_type = data[key].get("type") or "RTC"
voice_config_class = voice_config_map.get(voice_type, VoiceConfigurationCustom)
voice_config_class(**data[key])
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,14 @@ def test_rent_any_number_request_expects_valid_data():
assert request.region_code == "string"
assert request.type_ == "MOBILE"
assert request.capabilities == ["SMS"]
assert request.sms_configuration.service_plan_id == "string"
assert request.sms_configuration.campaign_id == "string"
assert request.voice_configuration.app_id == "string"
assert request.sms_configuration == {
"servicePlanId": "string",
"campaignId": "string"
}
assert request.voice_configuration == {
"type": "RTC",
"appId": "string"
}
assert request.callback_url == "https://www.your-callback-server.com/callback"


Expand All @@ -57,19 +62,3 @@ def test_rent_any_number_request_expects_missing_optional_fields():
assert request.voice_configuration is None
assert request.callback_url is None


def test_rent_any_number_request_expects_extra_fields():
"""
Test that RentAnyNumberRequest accepts extra fields.
"""
data = {
"regionCode": "string",
"type": "MOBILE",
"extraField": "Extra field"
}

request = RentAnyNumberRequest(**data)

assert request.region_code == "string"
assert request.type_ == "MOBILE"
assert request.extraField == "Extra field"

0 comments on commit 4832865

Please sign in to comment.