Skip to content

Commit

Permalink
Test extras validation
Browse files Browse the repository at this point in the history
  • Loading branch information
jonathansberry committed Dec 17, 2024
1 parent 9f29a8b commit 3b9ba02
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 39 deletions.
6 changes: 4 additions & 2 deletions ckanext/dataset_subscriptions/actions/twilio_notifications.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,15 @@ def send_twilio_notifications(context, data_dict):


def _sms_notifications_enabled(user_dict):
if user_dict.get("activity_streams_sms_notifications") and user_dict.get("phonenumber"):
enable_sms = toolkit.asbool(user_dict.get("activity_streams_sms_notifications"))
if enable_sms and user_dict.get("phonenumber"):
return True
return False


def _whatsapp_notifications_enabled(user_dict):
if user_dict.get("activity_streams_whatsapp_notifications") and user_dict.get("phonenumber"):
enable_whatsapp = toolkit.asbool(user_dict.get("activity_streams_whatsapp_notifications"))
if enable_whatsapp and user_dict.get("phonenumber"):
return True
return False

Expand Down
19 changes: 15 additions & 4 deletions ckanext/dataset_subscriptions/actions/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,14 +128,25 @@ def _validate_plugin_extras(extras):
if extras.get('phonenumber'):
try:
client.lookups.phone_numbers(extras['phonenumber']).fetch(type=['carrier'])
except TwilioRestException:
errors['phonenumber'] = [toolkit._(f'Invalid phonenumber: {extras["phonenumber"]}')]
if extras.get('activity_streams_sms_notifications'):
except TwilioRestException as e:
if e.status == 404:
errors['phonenumber'] = [toolkit._(f'Invalid phonenumber: {extras["phonenumber"]}')]
else:
logger.exception(
f"Failed to reach Twilio API to verify phonenumber {extras['phonenumber']}",
exc_info=True
)
except Exception:
logger.exception(
f"Failed to reach Twilio API to verify phonenumber {extras['phonenumber']}",
exc_info=True
)
if toolkit.asbool(extras.get('activity_streams_sms_notifications')):
if not extras.get('phonenumber'):
errors['activity_streams_sms_notifications'] = [
toolkit._('No phone number given')
]
if extras.get('activity_streams_whatsapp_notifications'):
if toolkit.asbool(extras.get('activity_streams_whatsapp_notifications')):
if not extras.get('phonenumber'):
errors['activity_streams_whatsapp_notifications'] = [
toolkit._('No phone number given')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
{{ form.input('phonenumber', label=_('Phone number'), id='field-phonenumber', type='tel', value=data.phonenumber, error=errors.phonenumber, placeholder=_('eg. +44 123123123'), classes=['control-medium'], is_required=false) }}
<div class="alert phonenumber alert-error" style="display: none"></div>
{% call form.checkbox('activity_streams_sms_notifications', label=_('Subscribe to recieve SMS notifications'), id='field-activity-streams-sms-notifications', value=True, checked=data.activity_streams_sms_notifications) %}
{% set helper_text = _("You will receive SMS notifications from {site_title} when you have new activities on your dashboard."|string) %}
{% set helper_text = _("You will receive SMS notifications from {site_title} when datasets you are following have been updated."|string) %}
{{ form.info(helper_text.format(site_title=g.site_title), classes=['info-help-tight']) }}
{% endcall %}
{% call form.checkbox('activity_streams_whatsapp_notifications', label=_('Subscribe to recieve Whatsapp notifications'), id='field-activity-streams-whatsapp-notifications', value=True, checked=data.activity_streams_whatsapp_notifications) %}
{% set helper_text = _("You will receive Whatsapp notifications from {site_title} when you have new activities on your dashboard."|string) %}
{% set helper_text = _("You will receive Whatsapp notifications from {site_title} when datasets you are following have been updated."|string) %}
{{ form.info(helper_text.format(site_title=g.site_title), classes=['info-help-tight']) }}
{% endcall %}
{% asset "ckanext-dataset-subscriptions/phone-number-js" %}
Expand Down
100 changes: 69 additions & 31 deletions ckanext/dataset_subscriptions/tests/actions/test_user.py
Original file line number Diff line number Diff line change
@@ -1,38 +1,76 @@
import pytest
from ckan.plugins import toolkit
from ckan.tests import helpers
from ckan.tests import factories
from unittest import mock
from twilio.base.exceptions import TwilioRestException
from contextlib import nullcontext


@pytest.mark.usefixtures("clean_db")
@pytest.mark.usefixtures("with_plugins")
def test_user_create_supports_plugin_extras(sysadmin_context):
user_dict = {
"name": "test_user_001",
"fullname": "Mr. Test User",
"password": "fjelltopp",
"display_name": "Mr. Test User",
"email": "[email protected]",
"phonenumber": 123,
"activity_streams_sms_notifications": True
}

created_user = helpers.call_action('user_create', context=sysadmin_context, **user_dict)

for key in ["phonenumber", "activity_streams_sms_notifications"]:
assert created_user[key] == user_dict[key]


@pytest.mark.usefixtures("clean_db")
@pytest.mark.usefixtures("with_plugins")
def test_user_update_supports_plugin_extras(sysadmin_context):
user = factories.User()
user_dict = {**user, **{
"phonenumber": 123,
"activity_streams_sms_notifications": True
@pytest.mark.usefixtures("with_plugins", "clean_db")
class TestUserActions():

def test_user_create_supports_plugin_extras(self, sysadmin_context):
user_dict = {
"name": "test_user_001",
"fullname": "Mr. Test User",
"password": "fjelltopp",
"display_name": "Mr. Test User",
"email": "[email protected]",
"phonenumber": "+447855474558",
"activity_streams_sms_notifications": True
}

created_user = helpers.call_action('user_create', context=sysadmin_context, **user_dict)

for key in ["phonenumber", "activity_streams_sms_notifications"]:
assert created_user[key] == user_dict[key]

def test_user_update_supports_plugin_extras(self, sysadmin_context):
user = factories.User()
user_dict = {**user, **{
"phonenumber": 123,
"activity_streams_sms_notifications": True
}
}
}
helpers.call_action('user_update', **user_dict)
updated_user = helpers.call_action('user_show', context=sysadmin_context, include_plugin_extras=True, **user_dict)
helpers.call_action('user_update', **user_dict)
updated_user = helpers.call_action('user_show', context=sysadmin_context, include_plugin_extras=True, **user_dict)

for key in ["phonenumber", "activity_streams_sms_notifications"]:
assert updated_user[key] == user_dict[key]
for key in ["phonenumber", "activity_streams_sms_notifications"]:
assert updated_user[key] == user_dict[key]

@mock.patch('ckanext.dataset_subscriptions.actions.user.client')
def test_user_validate_plugin_extras_valid_phonenumber(self, client_mock, sysadmin_context):
phonenumber = 123
client_mock.lookups.phone_numbers(phonenumber).fetch.side_effect = TwilioRestException(404, "not found")
user_dict = {
"name": "test_user_001",
"fullname": "Mr. Test User",
"password": "fjelltopp",
"display_name": "Mr. Test User",
"email": "[email protected]",
"phonenumber": phonenumber,
"activity_streams_sms_notifications": True
}
with pytest.raises(toolkit.ValidationError, match="Invalid phonenumber"):
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, True, pytest.raises(toolkit.ValidationError)),
("", True, False, pytest.raises(toolkit.ValidationError)),
("", True, True, pytest.raises(toolkit.ValidationError))
])
def test_user_validate_plugin_extras_requires_phonenumber(self, phonenumber, enable_sms, enable_whatsapp, expectation, sysadmin_context):
user_dict = {
"name": "test_user_001",
"fullname": "Mr. Test User",
"password": "fjelltopp",
"display_name": "Mr. Test User",
"email": "[email protected]",
"phonenumber": phonenumber,
"activity_streams_sms_notifications": enable_sms,
"activity_streams_whatsapp_notifications": enable_whatsapp
}
with expectation:
helpers.call_action('user_create', context=sysadmin_context, **user_dict)

0 comments on commit 3b9ba02

Please sign in to comment.