Skip to content

Commit

Permalink
Add tests for Twilio update credentials
Browse files Browse the repository at this point in the history
  • Loading branch information
norkans7 committed Jan 19, 2023
1 parent 12121e1 commit 1778cca
Show file tree
Hide file tree
Showing 6 changed files with 192 additions and 12 deletions.
9 changes: 5 additions & 4 deletions temba/channels/types/twilio/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from temba.channels.models import Channel
from temba.contacts.models import URN
from temba.orgs.models import Org
from temba.tests import TembaTest, CRUDLTestMixin
from temba.tests import CRUDLTestMixin, TembaTest
from temba.tests.twilio import MockRequestValidator, MockTwilioClient

from .type import TwilioType
Expand Down Expand Up @@ -243,12 +243,13 @@ def test_claim(self):
self.assertContentMenu(
reverse("channels.channel_read", args=[channel.uuid]),
self.admin,
["Twilio Credentials", "Edit", "Delete"],
True,
["Twilio Credentials", "Channel Log", "Edit", "Delete"],
)

update_credentials_url = reverse("channels.types.twilio.update_credentials", args=[channel.uuid])

self.assertUpdateFetch(
reverse("channels.types.twilio.update_credentials", args=[channel.uuid]),
update_credentials_url,
allow_viewers=False,
allow_editors=True,
form_fields=("account_sid", "account_token"),
Expand Down
5 changes: 2 additions & 3 deletions temba/channels/types/twilio_messaging_service/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from django.urls import reverse

from temba.orgs.models import Org
from temba.tests import TembaTest, CRUDLTestMixin
from temba.tests import CRUDLTestMixin, TembaTest
from temba.tests.twilio import MockRequestValidator, MockTwilioClient

from .type import TwilioMessagingServiceType
Expand Down Expand Up @@ -89,8 +89,7 @@ def test_claim(self):
self.assertContentMenu(
reverse("channels.channel_read", args=[channel.uuid]),
self.admin,
["Twilio Credentials", "Settings", "Edit", "Delete"],
True,
["Twilio Credentials", "Settings", "Channel Log", "Edit", "Delete"],
)

self.assertUpdateFetch(
Expand Down
5 changes: 2 additions & 3 deletions temba/channels/types/twilio_whatsapp/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from temba.channels.models import Channel
from temba.orgs.models import Org
from temba.tests import TembaTest, CRUDLTestMixin
from temba.tests import CRUDLTestMixin, TembaTest
from temba.tests.twilio import MockRequestValidator, MockTwilioClient

from .type import TwilioWhatsappType
Expand Down Expand Up @@ -130,8 +130,7 @@ def test_claim(self):
self.assertContentMenu(
reverse("channels.channel_read", args=[channel.uuid]),
self.admin,
["Twilio Credentials", "Settings", "Edit", "Delete"],
True,
["Twilio Credentials", "Settings", "Channel Log", "Edit", "Delete"],
)

self.assertUpdateFetch(
Expand Down
15 changes: 15 additions & 0 deletions temba/tests/twilio.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,19 @@ def __init__(self, short_code):
self.short_code = short_code
self.sid = "ShortSid"

def update(self, *args, **kwargs):
print("Updating short code with sid %s, short code %s" % (self.sid, self.short_code))

class MockShortCodes(MockInstanceResource):
def __init__(self, *args):
pass

def list(self, short_code=None):
return [MockTwilioClient.MockShortCode(short_code)]

def get(self, sid):
return MockTwilioClient.MockShortCode("1122")

def stream(self, *args, **kwargs):
return iter([MockTwilioClient.MockShortCode("1122")])

Expand Down Expand Up @@ -128,6 +134,9 @@ class MockAccounts(MockInstanceResource):
def __init__(self, *args):
pass

def fetch(self, account_type):
return MockTwilioClient.MockAccount(account_type)

def get(self, account_type):
return MockTwilioClient.MockAccount(account_type)

Expand Down Expand Up @@ -159,6 +168,12 @@ def create(self, *args, **kwargs):
phone_number = kwargs["phone_number"]
return MockTwilioClient.MockPhoneNumber(phone_number)

def get(self, *args, **kwargs):
return MockTwilioClient.MockPhoneNumber("+12062345678")

def update(self, *args, **kwargs):
print("Updating phone number with sid %s, number %s" % (self.sid, self.phone_number))

class MockApplications(MockInstanceResource):
def __init__(self, *args):
pass
Expand Down
162 changes: 162 additions & 0 deletions temba/utils/twilio/tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
from unittest.mock import patch

from django.urls import reverse

from temba.channels.models import Channel
from temba.tests import CRUDLTestMixin, TembaTest
from temba.tests.twilio import MockRequestValidator, MockTwilioClient


class TwilioUtilsTest(TembaTest, CRUDLTestMixin):
@patch("temba.utils.twilio.views.TwilioClient", MockTwilioClient)
@patch("twilio.request_validator.RequestValidator", MockRequestValidator)
def test_twilio_update_credentials(self):
self.login(self.admin)

config = {
Channel.CONFIG_APPLICATION_SID: "app-sid",
Channel.CONFIG_NUMBER_SID: "number-sid",
Channel.CONFIG_ACCOUNT_SID: "account-sid",
Channel.CONFIG_AUTH_TOKEN: "account-token",
Channel.CONFIG_CALLBACK_DOMAIN: "rapidpro.io",
}

channel = self.create_channel("T", "channel", "1234", config=config)

update_credentials_url = reverse("channels.types.twilio.update_credentials", args=[channel.uuid])

self.assertUpdateFetch(
update_credentials_url,
allow_viewers=False,
allow_editors=True,
form_fields={"account_sid": "account-sid", "account_token": "account-token"},
)

with patch("temba.tests.twilio.MockTwilioClient.MockPhoneNumbers.stream") as mock_numbers:
mock_numbers.return_value = iter([])

with patch("temba.tests.twilio.MockTwilioClient.MockShortCodes.stream") as mock_short_codes:
mock_short_codes.return_value = iter([MockTwilioClient.MockShortCode("8080")])

self.assertUpdateSubmit(
update_credentials_url,
{"account_sid": "AccountSid", "account_token": "AccountToken"},
)
channel.refresh_from_db()
channel_config = channel.config
self.assertEqual(channel_config[Channel.CONFIG_ACCOUNT_SID], "AccountSid")
self.assertEqual(channel_config[Channel.CONFIG_AUTH_TOKEN], "AccountToken")
self.assertEqual(channel_config[Channel.CONFIG_APPLICATION_SID], "TwilioTestSid")
self.assertEqual(channel_config[Channel.CONFIG_NUMBER_SID], "ShortSid")

channel = self.create_channel("T", "channel", "12062345678", config=config)

update_credentials_url = reverse("channels.types.twilio.update_credentials", args=[channel.uuid])

self.assertUpdateFetch(
update_credentials_url,
allow_viewers=False,
allow_editors=True,
form_fields={"account_sid": "account-sid", "account_token": "account-token"},
)

channel.refresh_from_db()
channel_config = channel.config
self.assertEqual(channel_config[Channel.CONFIG_ACCOUNT_SID], "account-sid")
self.assertEqual(channel_config[Channel.CONFIG_AUTH_TOKEN], "account-token")
self.assertEqual(channel_config[Channel.CONFIG_APPLICATION_SID], "app-sid")
self.assertEqual(channel_config[Channel.CONFIG_NUMBER_SID], "number-sid")

with patch("temba.tests.twilio.MockTwilioClient.MockPhoneNumbers.stream") as mock_numbers:
mock_numbers.return_value = iter([MockTwilioClient.MockPhoneNumber("+12062345678")])

with patch("temba.tests.twilio.MockTwilioClient.MockShortCodes.stream") as mock_short_codes:
mock_short_codes.return_value = iter([])

self.assertUpdateSubmit(
update_credentials_url,
{"account_sid": "AccountSid", "account_token": "AccountToken"},
)
channel.refresh_from_db()
channel_config = channel.config
self.assertEqual(channel_config[Channel.CONFIG_ACCOUNT_SID], "AccountSid")
self.assertEqual(channel_config[Channel.CONFIG_AUTH_TOKEN], "AccountToken")
self.assertEqual(channel_config[Channel.CONFIG_APPLICATION_SID], "TwilioTestSid")
self.assertEqual(channel_config[Channel.CONFIG_NUMBER_SID], "PhoneNumberSid")

@patch("temba.utils.twilio.views.TwilioClient", MockTwilioClient)
@patch("twilio.request_validator.RequestValidator", MockRequestValidator)
def test_twilio_whatsapp_update_credentials(self):
self.login(self.admin)

config = {
Channel.CONFIG_NUMBER_SID: "number-sid",
Channel.CONFIG_ACCOUNT_SID: "account-sid",
Channel.CONFIG_AUTH_TOKEN: "account-token",
Channel.CONFIG_CALLBACK_DOMAIN: "rapidpro.io",
}

channel = self.create_channel("TWA", "channel", "1234", config=config)

update_credentials_url = reverse("channels.types.twilio_whatsapp.update_credentials", args=[channel.uuid])

self.assertUpdateFetch(
update_credentials_url,
allow_viewers=False,
allow_editors=True,
form_fields={"account_sid": "account-sid", "account_token": "account-token"},
)

with patch("temba.tests.twilio.MockTwilioClient.MockPhoneNumbers.stream") as mock_numbers:
mock_numbers.return_value = iter([MockTwilioClient.MockPhoneNumber("+12062345678")])

self.assertUpdateSubmit(
update_credentials_url,
{"account_sid": "AccountSid", "account_token": "AccountToken"},
)
channel.refresh_from_db()
channel_config = channel.config
self.assertEqual(channel_config[Channel.CONFIG_ACCOUNT_SID], "AccountSid")
self.assertEqual(channel_config[Channel.CONFIG_AUTH_TOKEN], "AccountToken")
# TWA number SID should have not changedon the same Twilio account, no support for number moved on Twilio
self.assertEqual(channel_config[Channel.CONFIG_NUMBER_SID], "number-sid")
self.assertFalse(Channel.CONFIG_APPLICATION_SID in channel_config)

@patch("temba.utils.twilio.views.TwilioClient", MockTwilioClient)
@patch("twilio.request_validator.RequestValidator", MockRequestValidator)
def test_twilio_messaging_service_update_credentials(self):
self.login(self.admin)

config = {
Channel.CONFIG_MESSAGING_SERVICE_SID: "messaging-sid",
Channel.CONFIG_ACCOUNT_SID: "account-sid",
Channel.CONFIG_AUTH_TOKEN: "account-token",
Channel.CONFIG_CALLBACK_DOMAIN: "rapidpro.io",
}

channel = self.create_channel("TMS", "channel", "1234", config=config)

update_credentials_url = reverse(
"channels.types.twilio_messaging_service.update_credentials", args=[channel.uuid]
)

self.assertUpdateFetch(
update_credentials_url,
allow_viewers=False,
allow_editors=True,
form_fields={"account_sid": "account-sid", "account_token": "account-token"},
)

self.assertUpdateSubmit(
update_credentials_url,
{"account_sid": "AccountSid", "account_token": "AccountToken"},
)
channel.refresh_from_db()
channel_config = channel.config
self.assertEqual(channel_config[Channel.CONFIG_ACCOUNT_SID], "AccountSid")
self.assertEqual(channel_config[Channel.CONFIG_AUTH_TOKEN], "AccountToken")
self.assertEqual(
channel_config[Channel.CONFIG_MESSAGING_SERVICE_SID], "messaging-sid"
) # we do not change that
self.assertFalse(Channel.CONFIG_APPLICATION_SID in channel_config)
self.assertFalse(Channel.CONFIG_NUMBER_SID in channel_config)
8 changes: 6 additions & 2 deletions temba/utils/twilio/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from django.utils.translation import gettext_lazy as _

from temba.channels.models import Channel
from temba.orgs.views import ModalMixin, OrgPermsMixin
from temba.orgs.views import OrgPermsMixin
from temba.utils.fields import InputWidget


Expand Down Expand Up @@ -100,7 +100,7 @@ def form_valid(self, form):
if config_app_id:
try:
twilio_app = client.api.applications.get(sid=config_app_id).fetch()
except Exception:
except Exception: # pragma: no cover
twilio_app = client.api.applications.create(
friendly_name="%s/%s" % (callback_domain.lower(), channel_uuid),
sms_method="POST",
Expand Down Expand Up @@ -132,7 +132,10 @@ def form_valid(self, form):
)
)
else:
twilio_phones = client.api.incoming_phone_numbers.stream(phone_number=phone_number)
twilio_phone = next(twilio_phones, None)
if twilio_phone:
number_sid = twilio_phone.sid

client.api.incoming_phone_numbers.get(twilio_phone.sid).update(
voice_application_sid=twilio_app.sid, sms_application_sid=twilio_app.sid
Expand All @@ -146,6 +149,7 @@ def form_valid(self, form):
)

self.object.config[Channel.CONFIG_APPLICATION_SID] = twilio_app.sid
self.object.config[Channel.CONFIG_NUMBER_SID] = number_sid

self.object.config[Channel.CONFIG_ACCOUNT_SID] = data["account_sid"]
self.object.config[Channel.CONFIG_AUTH_TOKEN] = data["account_token"]
Expand Down

0 comments on commit 1778cca

Please sign in to comment.