diff --git a/app/main/forms.py b/app/main/forms.py
index c99eeef22..016534ed4 100644
--- a/app/main/forms.py
+++ b/app/main/forms.py
@@ -40,7 +40,7 @@ from app.main.validators import (
DoesNotStartWithDoubleZero,
LettersNumbersAndFullStopsOnly,
NoCommasInPlaceHolders,
- OnlyGSMCharacters,
+ OnlySMSCharacters,
ValidEmail,
ValidGovEmail,
)
@@ -639,7 +639,7 @@ class BaseTemplateForm(StripWhitespaceForm):
class SMSTemplateForm(BaseTemplateForm):
def validate_template_content(self, field):
- OnlyGSMCharacters()(None, field)
+ OnlySMSCharacters()(None, field)
class EmailTemplateForm(BaseTemplateForm):
diff --git a/app/main/validators.py b/app/main/validators.py
index 216038726..b7dfb25a7 100644
--- a/app/main/validators.py
+++ b/app/main/validators.py
@@ -5,7 +5,7 @@ from notifications_utils.recipients import (
InvalidEmailError,
validate_email_address,
)
-from notifications_utils.sanitise_text import SanitiseGSM
+from notifications_utils.sanitise_text import SanitiseSMS
from wtforms import ValidationError
from wtforms.validators import Email
@@ -79,14 +79,14 @@ class NoCommasInPlaceHolders:
raise ValidationError(self.message)
-class OnlyGSMCharacters:
+class OnlySMSCharacters:
def __call__(self, form, field):
- non_gsm_characters = sorted(list(SanitiseGSM.get_non_compatible_characters(field.data)))
- if non_gsm_characters:
+ non_sms_characters = sorted(list(SanitiseSMS.get_non_compatible_characters(field.data)))
+ if non_sms_characters:
raise ValidationError(
'You can’t use {} in text messages. {} won’t show up properly on everyone’s phones.'.format(
- formatted_list(non_gsm_characters, conjunction='or', before_each='', after_each=''),
- ('It' if len(non_gsm_characters) == 1 else 'They')
+ formatted_list(non_sms_characters, conjunction='or', before_each='', after_each=''),
+ ('It' if len(non_sms_characters) == 1 else 'They')
)
)
diff --git a/app/main/views/conversation.py b/app/main/views/conversation.py
index e9d5dfeb6..e3ef576df 100644
--- a/app/main/views/conversation.py
+++ b/app/main/views/conversation.py
@@ -127,7 +127,7 @@ def get_sms_thread(service_id, user_number):
)
},
notification.get('personalisation'),
- downgrade_non_gsm_characters=(not is_inbound),
+ downgrade_non_sms_characters=(not is_inbound),
redact_missing_personalisation=redact_personalisation,
),
'created_at': notification['created_at'],
diff --git a/app/templates/views/pricing.html b/app/templates/views/pricing.html
index e54df2e7d..68073cc7b 100644
--- a/app/templates/views/pricing.html
+++ b/app/templates/views/pricing.html
@@ -40,10 +40,10 @@
See how to pay.
Long text messages
- If a text message is beyond a certain length, it’ll be charged as more than one message:
+ If a text message is longer than 160 characters (including spaces), it’ll be charged as more than one message:
{% call mapping_table(
- caption='Letter pricing',
+ caption='Text message pricing',
field_headings=['Message length', 'Charge'],
field_headings_visible=True,
caption_visible=False
@@ -61,6 +61,29 @@
{% endfor %}
{% endcall %}
+ Text messages containing Welsh characters
+ Long text messages containing Welsh characters (Â, â, Ê, ê, Î, î, Ô, ô, Û, û, Ŵ, ŵ, Ŷ, and ŷ) are charged differently:
+
+ {% call mapping_table(
+ caption='Text message pricing',
+ field_headings=['Message length', 'Charge'],
+ field_headings_visible=True,
+ caption_visible=False
+ ) %}
+ {% for message_length, charge in [
+ ('Up to 70 characters', '1 text message'),
+ ('Up to 134 characters', '2 text messages'),
+ ('Up to 201 characters', '3 text messages'),
+ ('Up to 268 characters', '4 text messages'),
+ ('Each additional 67 characters', '1 additional text message'),
+ ] %}
+ {% call row() %}
+ {{ text_field(message_length) }}
+ {{ text_field(charge) }}
+ {% endcall %}
+ {% endfor %}
+ {% endcall %}
+
Sending text messages to international numbers
It might cost more to send text messages to international numbers than UK ones, depending on the country.
diff --git a/requirements-app.txt b/requirements-app.txt
index 343b87a89..ee9fa1966 100644
--- a/requirements-app.txt
+++ b/requirements-app.txt
@@ -23,4 +23,4 @@ awscli-cwlogs>=1.4,<1.5
# Putting upgrade on hold due to v1.0.0 using sha512 instead of sha1 by default
itsdangerous==0.24 # pyup: <1.0.0
-git+https://github.com/alphagov/notifications-utils.git@31.2.6#egg=notifications-utils==31.2.6
+git+https://github.com/alphagov/notifications-utils.git@32.0.0#egg=notifications-utils==32.0.0
diff --git a/requirements.txt b/requirements.txt
index 178f9d16f..4c63dd55e 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -25,7 +25,7 @@ awscli-cwlogs>=1.4,<1.5
# Putting upgrade on hold due to v1.0.0 using sha512 instead of sha1 by default
itsdangerous==0.24 # pyup: <1.0.0
-git+https://github.com/alphagov/notifications-utils.git@31.2.6#egg=notifications-utils==31.2.6
+git+https://github.com/alphagov/notifications-utils.git@32.0.0#egg=notifications-utils==32.0.0
## The following requirements were added by pip freeze:
awscli==1.16.155
diff --git a/tests/app/main/test_validators.py b/tests/app/main/test_validators.py
index b243ccf83..7d96004cb 100644
--- a/tests/app/main/test_validators.py
+++ b/tests/app/main/test_validators.py
@@ -6,7 +6,7 @@ from wtforms import ValidationError
from app.main.forms import RegisterUserForm, ServiceSmsSenderForm
from app.main.validators import (
NoCommasInPlaceHolders,
- OnlyGSMCharacters,
+ OnlySMSCharacters,
ValidGovEmail,
)
@@ -165,8 +165,8 @@ def test_for_commas_in_placeholders(
@pytest.mark.parametrize('msg', ['The quick brown fox', 'Thé “quick” bröwn fox\u200B'])
-def test_gsm_character_validation(client, msg):
- OnlyGSMCharacters()(None, _gen_mock_field(msg))
+def test_sms_character_validation(client, msg):
+ OnlySMSCharacters()(None, _gen_mock_field(msg))
@pytest.mark.parametrize('data, err_msg', [
@@ -185,9 +185,9 @@ def test_gsm_character_validation(client, msg):
)
),
])
-def test_non_gsm_character_validation(data, err_msg, client):
+def test_non_sms_character_validation(data, err_msg, client):
with pytest.raises(ValidationError) as error:
- OnlyGSMCharacters()(None, _gen_mock_field(data))
+ OnlySMSCharacters()(None, _gen_mock_field(data))
assert str(error.value) == err_msg