Skip to content

Commit

Permalink
Check messages comply with whatsapp templates
Browse files Browse the repository at this point in the history
  • Loading branch information
jonathansberry committed Dec 17, 2024
1 parent 22674bd commit 13a9f3d
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,26 @@
from ckanext.dataset_subscriptions.tests import factories
from ckanext.dataset_subscriptions.actions import phone_notifications
from unittest import mock
import re


# Whatsapp messages must conform to preapproved templates created in Twilio.
# Copy templates here as a regex replacing placeholders e.g. {{1}} with (.*)
WHATSAPP_MESSAGE_TEMPLATES = [
r"(.*) datasets that you are following have recently been updated in (.*)",
r"(.*) dataset that you are following has recently been updated in (.*)"
]


def _matches_whatsapp_template(message):
for template in WHATSAPP_MESSAGE_TEMPLATES:
if re.compile(template).search(message):
return True
return False


@pytest.mark.ckan_config('ckan.plugins')
@pytest.mark.usefixtures("with_plugins")
@pytest.mark.usefixtures("clean_db")
def create_user_with_resources(with_activity,
sms_notifications_enabled,
whatsapp_notifications_enabled):
def create_user_with_resources(with_activity, sms_notifications_enabled, whatsapp_notifications_enabled):
subscribed_user = factories.User(
name='user1',
activity_streams_sms_notifications=sms_notifications_enabled,
Expand All @@ -36,46 +48,50 @@ def create_user_with_resources(with_activity,
**dataset
)
ckan_factories.Resource(
package_id=dataset['id'],
user=active_user
package_id=dataset['id'],
user=active_user
)
return subscribed_user


@pytest.mark.usefixtures("clean_db")
@pytest.mark.usefixtures("with_plugins")
@pytest.mark.parametrize("notifications_enabled", [(False), (True)])
def test_sms_notifications_disabled_enabled(notifications_enabled):
user = create_user_with_resources(True, notifications_enabled, False)
notifications = phone_notifications._sms_notifications_enabled(user, {})
assert notifications == notifications_enabled

@pytest.mark.usefixtures("with_plugins", "clean_db")
class TestPhoneNotifications():

@pytest.mark.usefixtures("with_request_context")
@pytest.mark.usefixtures("clean_db")
@pytest.mark.usefixtures("with_plugins")
@mock.patch('ckanext.dataset_subscriptions.actions.phone_notifications.client.messages.create')
def test_if_sms_notifications_are_generated(create_message_mock, sysadmin_context):
create_user_with_resources(True, True, False)
expected_sid = 'SM87105da94bff44b999e4e6eb90d8eb6a'
create_message_mock.return_value.sid = expected_sid
sid = helpers.call_action("send_phone_notifications")
assert create_message_mock.called is True
assert sid[0] == expected_sid
@pytest.mark.parametrize("notifications_enabled", [(False), (True)])
def test_sms_notifications_disabled_enabled(self, notifications_enabled):
user = create_user_with_resources(True, notifications_enabled, False)
notifications = phone_notifications._sms_notifications_enabled(user, {})
assert notifications == notifications_enabled

@pytest.mark.usefixtures("with_request_context")
@mock.patch('ckanext.dataset_subscriptions.actions.phone_notifications.client.messages.create')
def test_if_sms_notifications_are_generated(self, create_message_mock, sysadmin_context):
create_user_with_resources(True, True, False)
expected_sid = 'SM87105da94bff44b999e4e6eb90d8eb6a'
create_message_mock.return_value.sid = expected_sid
sid = helpers.call_action("send_phone_notifications")
assert create_message_mock.called is True
assert sid[0] == expected_sid

@pytest.mark.usefixtures("with_request_context")
@pytest.mark.usefixtures("clean_db")
@pytest.mark.usefixtures("with_plugins")
@mock.patch('ckanext.dataset_subscriptions.actions.phone_notifications.client.messages.create')
def test_if_whatsapp_notifications_are_generated(create_message_mock, sysadmin_context):
create_user_with_resources(True, False, True)
expected_sid = 'SM87105da94bff44b999e4e6eb90d8eb6a'
create_message_mock.return_value.sid = expected_sid
sid = helpers.call_action("send_phone_notifications")
assert create_message_mock.called is True
assert sid[0] == expected_sid
call_args = dict(create_message_mock.call_args.kwargs.items())
assert 'whatsapp:+' in call_args['to']
assert 'whatsapp:+' in call_args['from_']
@pytest.mark.usefixtures("with_request_context")
@mock.patch('ckanext.dataset_subscriptions.actions.phone_notifications.client.messages.create')
def test_if_whatsapp_notifications_are_generated(self, create_message_mock, sysadmin_context):
create_user_with_resources(True, False, True)
expected_sid = 'SM87105da94bff44b999e4e6eb90d8eb6a'
create_message_mock.return_value.sid = expected_sid
sid = helpers.call_action("send_phone_notifications")
assert create_message_mock.called is True
assert sid[0] == expected_sid
call_args = dict(create_message_mock.call_args.kwargs.items())
assert 'whatsapp:+' in call_args['to']
assert 'whatsapp:+' in call_args['from_']
assert _matches_whatsapp_template(call_args['body'])

@pytest.mark.parametrize('recent_activities', [[1], [1, 2, 3, 4]])
def test_whatsapp_message_complies_with_templates(self, recent_activities):
"""
Whatsapp messages must comply with a template preapproved through twilio
https://www.twilio.com/docs/whatsapp/tutorial/send-whatsapp-notification-messages-templates
"""
header = phone_notifications._create_message_header(recent_activities)
assert _matches_whatsapp_template(header)
2 changes: 1 addition & 1 deletion ckanext/dataset_subscriptions/tests/actions/test_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def test_user_validate_plugin_extras_valid_phonenumber(self, client_mock, sysadm
helpers.call_action('user_create', context=sysadmin_context, **user_dict)

@pytest.mark.parametrize('phonenumber, enable_sms, enable_whatsapp, expectation', [
("+44712345678", False, False, nullcontext(1)),
("", False, False, nullcontext(1)),
("", False, True, pytest.raises(toolkit.ValidationError)),
("", True, False, pytest.raises(toolkit.ValidationError)),
("", True, True, pytest.raises(toolkit.ValidationError))
Expand Down

0 comments on commit 13a9f3d

Please sign in to comment.