oncall-engine/engine/apps/base/tests/test_live_settings.py

73 lines
2.6 KiB
Python
Raw Permalink Normal View History

from unittest.mock import patch
import pytest
from apps.base.models import LiveSetting
from apps.base.utils import live_settings
Phone provider refactoring (#1713) # What this PR does This PR moves phone notification logic into separate object PhoneBackend and introduces PhoneProvider interface to hide actual implementation of external phone services provider. It should allow add new phone providers just by implementing one class (See SimplePhoneProvider for example). # Why [Asterisk PR](https://github.com/grafana/oncall/pull/1282) showed that our phone notification system is not flexible. However this is one of the most frequent community questions - how to add "X" phone provider. Also, this refactoring move us one step closer to unifying all notification backends, since with PhoneBackend all phone notification logic is collected in one place and independent from concrete realisation. # Highligts 1. PhoneBackend object - contains all phone notifications business logic. 2. PhoneProvider - interface to external phone services provider. 3. TwilioPhoneProvider and SimplePhoneProvider - two examples of PhoneProvider implementation. 4. PhoneCallRecord and SMSRecord models. I introduced these models to keep phone notification limits logic decoupled from external providers. Existing TwilioPhoneCall and TwilioSMS objects will be migrated to the new table to not to reset limits counter. To be able to receive status callbacks and gather from Twilio TwilioPhoneCall and TwilioSMS still exists, but they are linked to PhoneCallRecord and SMSRecord via fk, to not to leat twilio logic into core code. --------- Co-authored-by: Yulia Shanyrova <yulia.shanyrova@grafana.com>
2023-05-24 14:27:48 +08:00
from apps.twilioapp.phone_provider import TwilioPhoneProvider
@pytest.mark.django_db
def test_fallback_to_settings(settings):
settings.SOME_NEW_FEATURE_ENABLED = True
with patch.object(LiveSetting, "AVAILABLE_NAMES", ("SOME_NEW_FEATURE_ENABLED",)):
assert LiveSetting.get_setting("SOME_NEW_FEATURE_ENABLED") is True
@pytest.mark.django_db
def test_take_from_db(settings):
settings.SOME_NEW_FEATURE_ENABLED = True
with patch.object(LiveSetting, "AVAILABLE_NAMES", ("SOME_NEW_FEATURE_ENABLED",)):
LiveSetting.objects.create(name="SOME_NEW_FEATURE_ENABLED", value=False)
assert LiveSetting.get_setting("SOME_NEW_FEATURE_ENABLED") is False
@pytest.mark.django_db
def test_restrict_foreign_names():
with pytest.raises(ValueError):
LiveSetting.objects.create(name="SOME_NONEXISTENT_FANCY_FEATURE_ENABLED", value=42)
with pytest.raises(ValueError):
LiveSetting.get_setting("SOME_NONEXISTENT_FANCY_FEATURE_ENABLED")
@pytest.mark.parametrize("value", (True, None, 12, "test string", ["hey", "there", 1]))
@pytest.mark.django_db
def test_multi_type_support(value):
with patch.object(LiveSetting, "AVAILABLE_NAMES", ("SOME_NEW_FEATURE_ENABLED",)):
LiveSetting.objects.create(name="SOME_NEW_FEATURE_ENABLED", value=value)
setting_value = LiveSetting.get_setting("SOME_NEW_FEATURE_ENABLED")
assert type(setting_value) is type(value)
assert setting_value == value
@pytest.mark.django_db
def test_live_settings_proxy(settings, monkeypatch):
settings.SOME_SETTING = 12
monkeypatch.setattr(LiveSetting, "AVAILABLE_NAMES", ("SOME_SETTING",))
assert live_settings.SOME_SETTING == 12
live_settings.SOME_SETTING = 42
assert LiveSetting.objects.get(name="SOME_SETTING").value == 42
assert live_settings.SOME_SETTING == 42
@pytest.mark.django_db
def test_twilio_respects_changed_credentials(settings):
settings.TWILIO_ACCOUNT_SID = "twilio_account_sid"
settings.TWILIO_AUTH_TOKEN = "twilio_auth_token"
settings.TWILIO_NUMBER = "twilio_number"
Phone provider refactoring (#1713) # What this PR does This PR moves phone notification logic into separate object PhoneBackend and introduces PhoneProvider interface to hide actual implementation of external phone services provider. It should allow add new phone providers just by implementing one class (See SimplePhoneProvider for example). # Why [Asterisk PR](https://github.com/grafana/oncall/pull/1282) showed that our phone notification system is not flexible. However this is one of the most frequent community questions - how to add "X" phone provider. Also, this refactoring move us one step closer to unifying all notification backends, since with PhoneBackend all phone notification logic is collected in one place and independent from concrete realisation. # Highligts 1. PhoneBackend object - contains all phone notifications business logic. 2. PhoneProvider - interface to external phone services provider. 3. TwilioPhoneProvider and SimplePhoneProvider - two examples of PhoneProvider implementation. 4. PhoneCallRecord and SMSRecord models. I introduced these models to keep phone notification limits logic decoupled from external providers. Existing TwilioPhoneCall and TwilioSMS objects will be migrated to the new table to not to reset limits counter. To be able to receive status callbacks and gather from Twilio TwilioPhoneCall and TwilioSMS still exists, but they are linked to PhoneCallRecord and SMSRecord via fk, to not to leat twilio logic into core code. --------- Co-authored-by: Yulia Shanyrova <yulia.shanyrova@grafana.com>
2023-05-24 14:27:48 +08:00
twilio_client = TwilioPhoneProvider()
live_settings.TWILIO_ACCOUNT_SID = "new_twilio_account_sid"
live_settings.TWILIO_AUTH_TOKEN = "new_twilio_auth_token"
live_settings.TWILIO_NUMBER = "new_twilio_number"
assert twilio_client._default_twilio_api_client.username == "new_twilio_account_sid"
assert twilio_client._default_twilio_api_client.password == "new_twilio_auth_token"
assert twilio_client._default_twilio_number == "new_twilio_number"