mirror of
https://github.com/GSA/notifications-api.git
synced 2026-08-18 21:48:49 -04:00
Merge pull request #2972 from alphagov/broadcast-invite-template
Broadcast invite template
This commit is contained in:
@@ -151,6 +151,7 @@ class Config(object):
|
|||||||
NOTIFY_SERVICE_ID = 'd6aa2c68-a2d9-4437-ab19-3ae8eb202553'
|
NOTIFY_SERVICE_ID = 'd6aa2c68-a2d9-4437-ab19-3ae8eb202553'
|
||||||
NOTIFY_USER_ID = '6af522d0-2915-4e52-83a3-3690455a5fe6'
|
NOTIFY_USER_ID = '6af522d0-2915-4e52-83a3-3690455a5fe6'
|
||||||
INVITATION_EMAIL_TEMPLATE_ID = '4f46df42-f795-4cc4-83bb-65ca312f49cc'
|
INVITATION_EMAIL_TEMPLATE_ID = '4f46df42-f795-4cc4-83bb-65ca312f49cc'
|
||||||
|
BROADCAST_INVITATION_EMAIL_TEMPLATE_ID = '46152f7c-6901-41d5-8590-a5624d0d4359'
|
||||||
SMS_CODE_TEMPLATE_ID = '36fb0730-6259-4da1-8a80-c8de22ad4246'
|
SMS_CODE_TEMPLATE_ID = '36fb0730-6259-4da1-8a80-c8de22ad4246'
|
||||||
EMAIL_2FA_TEMPLATE_ID = '299726d2-dba6-42b8-8209-30e1d66ea164'
|
EMAIL_2FA_TEMPLATE_ID = '299726d2-dba6-42b8-8209-30e1d66ea164'
|
||||||
NEW_USER_EMAIL_VERIFICATION_TEMPLATE_ID = 'ece42649-22a8-4d06-b87f-d52d5d3f0a27'
|
NEW_USER_EMAIL_VERIFICATION_TEMPLATE_ID = 'ece42649-22a8-4d06-b87f-d52d5d3f0a27'
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ from app.dao.invited_user_dao import (
|
|||||||
get_invited_users_for_service
|
get_invited_users_for_service
|
||||||
)
|
)
|
||||||
from app.dao.templates_dao import dao_get_template_by_id
|
from app.dao.templates_dao import dao_get_template_by_id
|
||||||
from app.models import EMAIL_TYPE, KEY_TYPE_NORMAL, Service
|
from app.models import BROADCAST_TYPE, EMAIL_TYPE, KEY_TYPE_NORMAL, Service
|
||||||
from app.notifications.process_notifications import persist_notification, send_notification_to_queue
|
from app.notifications.process_notifications import persist_notification, send_notification_to_queue
|
||||||
from app.schemas import invited_user_schema
|
from app.schemas import invited_user_schema
|
||||||
from app.errors import register_errors
|
from app.errors import register_errors
|
||||||
@@ -27,7 +27,12 @@ def create_invited_user(service_id):
|
|||||||
invited_user, errors = invited_user_schema.load(request_json)
|
invited_user, errors = invited_user_schema.load(request_json)
|
||||||
save_invited_user(invited_user)
|
save_invited_user(invited_user)
|
||||||
|
|
||||||
template = dao_get_template_by_id(current_app.config['INVITATION_EMAIL_TEMPLATE_ID'])
|
if invited_user.service.has_permission(BROADCAST_TYPE):
|
||||||
|
template_id = current_app.config['BROADCAST_INVITATION_EMAIL_TEMPLATE_ID']
|
||||||
|
else:
|
||||||
|
template_id = current_app.config['INVITATION_EMAIL_TEMPLATE_ID']
|
||||||
|
|
||||||
|
template = dao_get_template_by_id(template_id)
|
||||||
service = Service.query.get(current_app.config['NOTIFY_SERVICE_ID'])
|
service = Service.query.get(current_app.config['NOTIFY_SERVICE_ID'])
|
||||||
|
|
||||||
saved_notification = persist_notification(
|
saved_notification = persist_notification(
|
||||||
|
|||||||
74
migrations/versions/0330_broadcast_invite_email.py
Normal file
74
migrations/versions/0330_broadcast_invite_email.py
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
"""
|
||||||
|
|
||||||
|
Revision ID: 0330_broadcast_invite_email
|
||||||
|
Revises: 0329_purge_broadcast_data
|
||||||
|
Create Date: 2020-09-15 14:17:01.963181
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
from alembic import op
|
||||||
|
|
||||||
|
revision = '0330_broadcast_invite_email'
|
||||||
|
down_revision = '0329_purge_broadcast_data'
|
||||||
|
|
||||||
|
user_id = '6af522d0-2915-4e52-83a3-3690455a5fe6'
|
||||||
|
service_id = 'd6aa2c68-a2d9-4437-ab19-3ae8eb202553'
|
||||||
|
template_id = '46152f7c-6901-41d5-8590-a5624d0d4359'
|
||||||
|
|
||||||
|
broadcast_invitation_template_name = 'Notify broadcast invitation email'
|
||||||
|
broadcast_invitation_subject = "((user_name)) has invited you to join ((service_name)) on GOV.UK Notify"
|
||||||
|
broadcast_invitation_content = """((user_name)) has invited you to join ((service_name)) on GOV.UK Notify.
|
||||||
|
|
||||||
|
In an emergency, use Notify to broadcast an alert, warning the public about an imminent risk to life.
|
||||||
|
|
||||||
|
Use this link to join the team:
|
||||||
|
((url))
|
||||||
|
|
||||||
|
This invitation will stop working at midnight tomorrow. This is to keep ((service_name)) secure.
|
||||||
|
|
||||||
|
Thanks
|
||||||
|
|
||||||
|
GOV.UK Notify team
|
||||||
|
https://www.gov.uk/notify
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
insert_query = """
|
||||||
|
INSERT INTO {}
|
||||||
|
(id, name, template_type, created_at, content, archived, service_id,
|
||||||
|
subject, created_by_id, version, process_type, hidden)
|
||||||
|
VALUES
|
||||||
|
('{}', '{}', 'email', '{}', '{}', False, '{}', '{}', '{}', 1, 'normal', False)
|
||||||
|
"""
|
||||||
|
|
||||||
|
op.execute(insert_query.format(
|
||||||
|
'templates_history',
|
||||||
|
template_id,
|
||||||
|
broadcast_invitation_template_name,
|
||||||
|
datetime.utcnow(),
|
||||||
|
broadcast_invitation_content,
|
||||||
|
service_id,
|
||||||
|
broadcast_invitation_subject,
|
||||||
|
user_id
|
||||||
|
))
|
||||||
|
|
||||||
|
op.execute(insert_query.format(
|
||||||
|
'templates',
|
||||||
|
template_id,
|
||||||
|
broadcast_invitation_template_name,
|
||||||
|
datetime.utcnow(),
|
||||||
|
broadcast_invitation_content,
|
||||||
|
service_id,
|
||||||
|
broadcast_invitation_subject,
|
||||||
|
user_id
|
||||||
|
))
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
op.get_bind()
|
||||||
|
op.execute("delete from templates where id = '{}'".format(template_id))
|
||||||
|
op.execute("delete from templates_history where id = '{}'".format(template_id))
|
||||||
@@ -9,8 +9,8 @@ from app.models import BROADCAST_TYPE, BroadcastStatusType, BroadcastEventMessag
|
|||||||
from tests.app.db import create_broadcast_message, create_template, create_service, create_user
|
from tests.app.db import create_broadcast_message, create_template, create_service, create_user
|
||||||
|
|
||||||
|
|
||||||
def test_get_broadcast_message(admin_request, sample_service):
|
def test_get_broadcast_message(admin_request, sample_broadcast_service):
|
||||||
t = create_template(sample_service, BROADCAST_TYPE)
|
t = create_template(sample_broadcast_service, BROADCAST_TYPE)
|
||||||
bm = create_broadcast_message(t, areas={
|
bm = create_broadcast_message(t, areas={
|
||||||
"areas": ['place A', 'region B'],
|
"areas": ['place A', 'region B'],
|
||||||
"simple_polygons": [[[50.1, 1.2], [50.12, 1.2], [50.13, 1.2]]]
|
"simple_polygons": [[[50.1, 1.2], [50.12, 1.2], [50.13, 1.2]]]
|
||||||
@@ -32,24 +32,24 @@ def test_get_broadcast_message(admin_request, sample_service):
|
|||||||
assert response['personalisation'] == {}
|
assert response['personalisation'] == {}
|
||||||
|
|
||||||
|
|
||||||
def test_get_broadcast_message_404s_if_message_doesnt_exist(admin_request, sample_service):
|
def test_get_broadcast_message_404s_if_message_doesnt_exist(admin_request, sample_broadcast_service):
|
||||||
err = admin_request.get(
|
err = admin_request.get(
|
||||||
'broadcast_message.get_broadcast_message',
|
'broadcast_message.get_broadcast_message',
|
||||||
service_id=sample_service.id,
|
service_id=sample_broadcast_service.id,
|
||||||
broadcast_message_id=uuid.uuid4(),
|
broadcast_message_id=uuid.uuid4(),
|
||||||
_expected_status=404
|
_expected_status=404
|
||||||
)
|
)
|
||||||
assert err == {'message': 'No result found', 'result': 'error'}
|
assert err == {'message': 'No result found', 'result': 'error'}
|
||||||
|
|
||||||
|
|
||||||
def test_get_broadcast_message_404s_if_message_is_for_different_service(admin_request, sample_service):
|
def test_get_broadcast_message_404s_if_message_is_for_different_service(admin_request, sample_broadcast_service):
|
||||||
other_service = create_service(service_name='other')
|
other_service = create_service(service_name='other')
|
||||||
other_template = create_template(other_service, BROADCAST_TYPE)
|
other_template = create_template(other_service, BROADCAST_TYPE)
|
||||||
bm = create_broadcast_message(other_template)
|
bm = create_broadcast_message(other_template)
|
||||||
|
|
||||||
err = admin_request.get(
|
err = admin_request.get(
|
||||||
'broadcast_message.get_broadcast_message',
|
'broadcast_message.get_broadcast_message',
|
||||||
service_id=sample_service.id,
|
service_id=sample_broadcast_service.id,
|
||||||
broadcast_message_id=bm.id,
|
broadcast_message_id=bm.id,
|
||||||
_expected_status=404
|
_expected_status=404
|
||||||
)
|
)
|
||||||
@@ -57,8 +57,8 @@ def test_get_broadcast_message_404s_if_message_is_for_different_service(admin_re
|
|||||||
|
|
||||||
|
|
||||||
@freeze_time('2020-01-01')
|
@freeze_time('2020-01-01')
|
||||||
def test_get_broadcast_messages_for_service(admin_request, sample_service):
|
def test_get_broadcast_messages_for_service(admin_request, sample_broadcast_service):
|
||||||
t = create_template(sample_service, BROADCAST_TYPE)
|
t = create_template(sample_broadcast_service, BROADCAST_TYPE)
|
||||||
|
|
||||||
with freeze_time('2020-01-01 12:00'):
|
with freeze_time('2020-01-01 12:00'):
|
||||||
bm1 = create_broadcast_message(t, personalisation={'foo': 'bar'})
|
bm1 = create_broadcast_message(t, personalisation={'foo': 'bar'})
|
||||||
@@ -76,8 +76,8 @@ def test_get_broadcast_messages_for_service(admin_request, sample_service):
|
|||||||
|
|
||||||
|
|
||||||
@freeze_time('2020-01-01')
|
@freeze_time('2020-01-01')
|
||||||
def test_create_broadcast_message(admin_request, sample_service):
|
def test_create_broadcast_message(admin_request, sample_broadcast_service):
|
||||||
t = create_template(sample_service, BROADCAST_TYPE)
|
t = create_template(sample_broadcast_service, BROADCAST_TYPE)
|
||||||
|
|
||||||
response = admin_request.post(
|
response = admin_request.post(
|
||||||
'broadcast_message.create_broadcast_message',
|
'broadcast_message.create_broadcast_message',
|
||||||
@@ -121,11 +121,11 @@ def test_create_broadcast_message(admin_request, sample_service):
|
|||||||
])
|
])
|
||||||
def test_create_broadcast_message_400s_if_json_schema_fails_validation(
|
def test_create_broadcast_message_400s_if_json_schema_fails_validation(
|
||||||
admin_request,
|
admin_request,
|
||||||
sample_service,
|
sample_broadcast_service,
|
||||||
data,
|
data,
|
||||||
expected_errors
|
expected_errors
|
||||||
):
|
):
|
||||||
t = create_template(sample_service, BROADCAST_TYPE)
|
t = create_template(sample_broadcast_service, BROADCAST_TYPE)
|
||||||
|
|
||||||
response = admin_request.post(
|
response = admin_request.post(
|
||||||
'broadcast_message.create_broadcast_message',
|
'broadcast_message.create_broadcast_message',
|
||||||
@@ -141,8 +141,8 @@ def test_create_broadcast_message_400s_if_json_schema_fails_validation(
|
|||||||
BroadcastStatusType.PENDING_APPROVAL,
|
BroadcastStatusType.PENDING_APPROVAL,
|
||||||
BroadcastStatusType.REJECTED,
|
BroadcastStatusType.REJECTED,
|
||||||
])
|
])
|
||||||
def test_update_broadcast_message_allows_edit_while_not_yet_live(admin_request, sample_service, status):
|
def test_update_broadcast_message_allows_edit_while_not_yet_live(admin_request, sample_broadcast_service, status):
|
||||||
t = create_template(sample_service, BROADCAST_TYPE)
|
t = create_template(sample_broadcast_service, BROADCAST_TYPE)
|
||||||
bm = create_broadcast_message(
|
bm = create_broadcast_message(
|
||||||
t,
|
t,
|
||||||
areas={"areas": ['manchester'], "simple_polygons": [[[50.12, 1.2], [50.13, 1.2], [50.14, 1.21]]]},
|
areas={"areas": ['manchester'], "simple_polygons": [[[50.12, 1.2], [50.13, 1.2], [50.14, 1.21]]]},
|
||||||
@@ -173,8 +173,10 @@ def test_update_broadcast_message_allows_edit_while_not_yet_live(admin_request,
|
|||||||
BroadcastStatusType.COMPLETED,
|
BroadcastStatusType.COMPLETED,
|
||||||
BroadcastStatusType.TECHNICAL_FAILURE,
|
BroadcastStatusType.TECHNICAL_FAILURE,
|
||||||
])
|
])
|
||||||
def test_update_broadcast_message_doesnt_allow_edits_after_broadcast_goes_live(admin_request, sample_service, status):
|
def test_update_broadcast_message_doesnt_allow_edits_after_broadcast_goes_live(
|
||||||
t = create_template(sample_service, BROADCAST_TYPE)
|
admin_request, sample_broadcast_service, status
|
||||||
|
):
|
||||||
|
t = create_template(sample_broadcast_service, BROADCAST_TYPE)
|
||||||
bm = create_broadcast_message(t, areas=['manchester'], status=status)
|
bm = create_broadcast_message(t, areas=['manchester'], status=status)
|
||||||
|
|
||||||
response = admin_request.post(
|
response = admin_request.post(
|
||||||
@@ -187,8 +189,8 @@ def test_update_broadcast_message_doesnt_allow_edits_after_broadcast_goes_live(a
|
|||||||
assert f'status {status}' in response['message']
|
assert f'status {status}' in response['message']
|
||||||
|
|
||||||
|
|
||||||
def test_update_broadcast_message_sets_finishes_at_separately(admin_request, sample_service):
|
def test_update_broadcast_message_sets_finishes_at_separately(admin_request, sample_broadcast_service):
|
||||||
t = create_template(sample_service, BROADCAST_TYPE)
|
t = create_template(sample_broadcast_service, BROADCAST_TYPE)
|
||||||
bm = create_broadcast_message(
|
bm = create_broadcast_message(
|
||||||
t,
|
t,
|
||||||
areas={"areas": ['london'], "simple_polygons": [[[50.12, 1.2], [50.13, 1.2], [50.14, 1.21]]]}
|
areas={"areas": ['london'], "simple_polygons": [[[50.12, 1.2], [50.13, 1.2], [50.14, 1.21]]]}
|
||||||
@@ -213,8 +215,8 @@ def test_update_broadcast_message_sets_finishes_at_separately(admin_request, sam
|
|||||||
'2020-06-01 20:00:01Z',
|
'2020-06-01 20:00:01Z',
|
||||||
'2020-06-01T20:00:01+00:00',
|
'2020-06-01T20:00:01+00:00',
|
||||||
])
|
])
|
||||||
def test_update_broadcast_message_allows_sensible_datetime_formats(admin_request, sample_service, input_dt):
|
def test_update_broadcast_message_allows_sensible_datetime_formats(admin_request, sample_broadcast_service, input_dt):
|
||||||
t = create_template(sample_service, BROADCAST_TYPE)
|
t = create_template(sample_broadcast_service, BROADCAST_TYPE)
|
||||||
bm = create_broadcast_message(t)
|
bm = create_broadcast_message(t)
|
||||||
|
|
||||||
response = admin_request.post(
|
response = admin_request.post(
|
||||||
@@ -229,8 +231,8 @@ def test_update_broadcast_message_allows_sensible_datetime_formats(admin_request
|
|||||||
assert response['updated_at'] is not None
|
assert response['updated_at'] is not None
|
||||||
|
|
||||||
|
|
||||||
def test_update_broadcast_message_doesnt_let_you_update_status(admin_request, sample_service):
|
def test_update_broadcast_message_doesnt_let_you_update_status(admin_request, sample_broadcast_service):
|
||||||
t = create_template(sample_service, BROADCAST_TYPE)
|
t = create_template(sample_broadcast_service, BROADCAST_TYPE)
|
||||||
bm = create_broadcast_message(t)
|
bm = create_broadcast_message(t)
|
||||||
|
|
||||||
response = admin_request.post(
|
response = admin_request.post(
|
||||||
@@ -255,9 +257,9 @@ def test_update_broadcast_message_doesnt_let_you_update_status(admin_request, sa
|
|||||||
{"simple_polygons": [[[51.28, -3.11], [51.29, -3.12], [51.27, -3.10]]]},
|
{"simple_polygons": [[[51.28, -3.11], [51.29, -3.12], [51.27, -3.10]]]},
|
||||||
])
|
])
|
||||||
def test_update_broadcast_message_doesnt_let_you_update_areas_but_not_polygons(
|
def test_update_broadcast_message_doesnt_let_you_update_areas_but_not_polygons(
|
||||||
admin_request, sample_service, incomplete_area_data
|
admin_request, sample_broadcast_service, incomplete_area_data
|
||||||
):
|
):
|
||||||
template = create_template(sample_service, BROADCAST_TYPE)
|
template = create_template(sample_broadcast_service, BROADCAST_TYPE)
|
||||||
broadcast_message = create_broadcast_message(template)
|
broadcast_message = create_broadcast_message(template)
|
||||||
|
|
||||||
response = admin_request.post(
|
response = admin_request.post(
|
||||||
@@ -273,8 +275,8 @@ def test_update_broadcast_message_doesnt_let_you_update_areas_but_not_polygons(
|
|||||||
] == f'Cannot update broadcast_message {broadcast_message.id}, areas or polygons are missing.'
|
] == f'Cannot update broadcast_message {broadcast_message.id}, areas or polygons are missing.'
|
||||||
|
|
||||||
|
|
||||||
def test_update_broadcast_message_status(admin_request, sample_service):
|
def test_update_broadcast_message_status(admin_request, sample_broadcast_service):
|
||||||
t = create_template(sample_service, BROADCAST_TYPE)
|
t = create_template(sample_broadcast_service, BROADCAST_TYPE)
|
||||||
bm = create_broadcast_message(t, status=BroadcastStatusType.DRAFT)
|
bm = create_broadcast_message(t, status=BroadcastStatusType.DRAFT)
|
||||||
|
|
||||||
response = admin_request.post(
|
response = admin_request.post(
|
||||||
@@ -289,8 +291,8 @@ def test_update_broadcast_message_status(admin_request, sample_service):
|
|||||||
assert response['updated_at'] is not None
|
assert response['updated_at'] is not None
|
||||||
|
|
||||||
|
|
||||||
def test_update_broadcast_message_status_doesnt_let_you_update_other_things(admin_request, sample_service):
|
def test_update_broadcast_message_status_doesnt_let_you_update_other_things(admin_request, sample_broadcast_service):
|
||||||
t = create_template(sample_service, BROADCAST_TYPE)
|
t = create_template(sample_broadcast_service, BROADCAST_TYPE)
|
||||||
bm = create_broadcast_message(t)
|
bm = create_broadcast_message(t)
|
||||||
|
|
||||||
response = admin_request.post(
|
response = admin_request.post(
|
||||||
@@ -307,11 +309,13 @@ def test_update_broadcast_message_status_doesnt_let_you_update_other_things(admi
|
|||||||
}]
|
}]
|
||||||
|
|
||||||
|
|
||||||
def test_update_broadcast_message_status_stores_cancelled_by_and_cancelled_at(admin_request, sample_service, mocker):
|
def test_update_broadcast_message_status_stores_cancelled_by_and_cancelled_at(
|
||||||
t = create_template(sample_service, BROADCAST_TYPE, content='emergency broadcast')
|
admin_request, sample_broadcast_service, mocker
|
||||||
|
):
|
||||||
|
t = create_template(sample_broadcast_service, BROADCAST_TYPE, content='emergency broadcast')
|
||||||
bm = create_broadcast_message(t, status=BroadcastStatusType.BROADCASTING)
|
bm = create_broadcast_message(t, status=BroadcastStatusType.BROADCASTING)
|
||||||
canceller = create_user(email='canceller@gov.uk')
|
canceller = create_user(email='canceller@gov.uk')
|
||||||
sample_service.users.append(canceller)
|
sample_broadcast_service.users.append(canceller)
|
||||||
mock_task = mocker.patch('app.celery.broadcast_message_tasks.send_broadcast_event.apply_async')
|
mock_task = mocker.patch('app.celery.broadcast_message_tasks.send_broadcast_event.apply_async')
|
||||||
|
|
||||||
response = admin_request.post(
|
response = admin_request.post(
|
||||||
@@ -332,7 +336,7 @@ def test_update_broadcast_message_status_stores_cancelled_by_and_cancelled_at(ad
|
|||||||
assert response['cancelled_at'] is not None
|
assert response['cancelled_at'] is not None
|
||||||
assert response['cancelled_by_id'] == str(canceller.id)
|
assert response['cancelled_by_id'] == str(canceller.id)
|
||||||
|
|
||||||
assert cancel_event.service_id == sample_service.id
|
assert cancel_event.service_id == sample_broadcast_service.id
|
||||||
assert cancel_event.transmitted_areas == bm.areas
|
assert cancel_event.transmitted_areas == bm.areas
|
||||||
assert cancel_event.message_type == BroadcastEventMessageType.CANCEL
|
assert cancel_event.message_type == BroadcastEventMessageType.CANCEL
|
||||||
assert cancel_event.transmitted_finishes_at == bm.cancelled_at
|
assert cancel_event.transmitted_finishes_at == bm.cancelled_at
|
||||||
@@ -341,17 +345,17 @@ def test_update_broadcast_message_status_stores_cancelled_by_and_cancelled_at(ad
|
|||||||
|
|
||||||
def test_update_broadcast_message_status_stores_approved_by_and_approved_at_and_queues_task(
|
def test_update_broadcast_message_status_stores_approved_by_and_approved_at_and_queues_task(
|
||||||
admin_request,
|
admin_request,
|
||||||
sample_service,
|
sample_broadcast_service,
|
||||||
mocker
|
mocker
|
||||||
):
|
):
|
||||||
t = create_template(sample_service, BROADCAST_TYPE, content='emergency broadcast')
|
t = create_template(sample_broadcast_service, BROADCAST_TYPE, content='emergency broadcast')
|
||||||
bm = create_broadcast_message(
|
bm = create_broadcast_message(
|
||||||
t,
|
t,
|
||||||
status=BroadcastStatusType.PENDING_APPROVAL,
|
status=BroadcastStatusType.PENDING_APPROVAL,
|
||||||
areas={"areas": ["london"], "simple_polygons": [[[51.30, 0.7], [51.28, 0.8], [51.25, -0.7]]]}
|
areas={"areas": ["london"], "simple_polygons": [[[51.30, 0.7], [51.28, 0.8], [51.25, -0.7]]]}
|
||||||
)
|
)
|
||||||
approver = create_user(email='approver@gov.uk')
|
approver = create_user(email='approver@gov.uk')
|
||||||
sample_service.users.append(approver)
|
sample_broadcast_service.users.append(approver)
|
||||||
mock_task = mocker.patch('app.celery.broadcast_message_tasks.send_broadcast_event.apply_async')
|
mock_task = mocker.patch('app.celery.broadcast_message_tasks.send_broadcast_event.apply_async')
|
||||||
|
|
||||||
response = admin_request.post(
|
response = admin_request.post(
|
||||||
@@ -371,7 +375,7 @@ def test_update_broadcast_message_status_stores_approved_by_and_approved_at_and_
|
|||||||
|
|
||||||
mock_task.assert_called_once_with(kwargs={'broadcast_event_id': str(alert_event.id)}, queue='notify-internal-tasks')
|
mock_task.assert_called_once_with(kwargs={'broadcast_event_id': str(alert_event.id)}, queue='notify-internal-tasks')
|
||||||
|
|
||||||
assert alert_event.service_id == sample_service.id
|
assert alert_event.service_id == sample_broadcast_service.id
|
||||||
assert alert_event.transmitted_areas == bm.areas
|
assert alert_event.transmitted_areas == bm.areas
|
||||||
assert alert_event.message_type == BroadcastEventMessageType.ALERT
|
assert alert_event.message_type == BroadcastEventMessageType.ALERT
|
||||||
assert alert_event.transmitted_finishes_at == bm.finishes_at
|
assert alert_event.transmitted_finishes_at == bm.finishes_at
|
||||||
@@ -380,10 +384,10 @@ def test_update_broadcast_message_status_stores_approved_by_and_approved_at_and_
|
|||||||
|
|
||||||
def test_update_broadcast_message_status_rejects_approval_from_creator(
|
def test_update_broadcast_message_status_rejects_approval_from_creator(
|
||||||
admin_request,
|
admin_request,
|
||||||
sample_service,
|
sample_broadcast_service,
|
||||||
mocker
|
mocker
|
||||||
):
|
):
|
||||||
t = create_template(sample_service, BROADCAST_TYPE)
|
t = create_template(sample_broadcast_service, BROADCAST_TYPE)
|
||||||
bm = create_broadcast_message(t, status=BroadcastStatusType.PENDING_APPROVAL)
|
bm = create_broadcast_message(t, status=BroadcastStatusType.PENDING_APPROVAL)
|
||||||
mock_task = mocker.patch('app.celery.broadcast_message_tasks.send_broadcast_event.apply_async')
|
mock_task = mocker.patch('app.celery.broadcast_message_tasks.send_broadcast_event.apply_async')
|
||||||
|
|
||||||
@@ -401,13 +405,13 @@ def test_update_broadcast_message_status_rejects_approval_from_creator(
|
|||||||
|
|
||||||
def test_update_broadcast_message_status_rejects_approval_of_broadcast_with_no_areas(
|
def test_update_broadcast_message_status_rejects_approval_of_broadcast_with_no_areas(
|
||||||
admin_request,
|
admin_request,
|
||||||
sample_service,
|
sample_broadcast_service,
|
||||||
mocker
|
mocker
|
||||||
):
|
):
|
||||||
template = create_template(sample_service, BROADCAST_TYPE)
|
template = create_template(sample_broadcast_service, BROADCAST_TYPE)
|
||||||
broadcast = create_broadcast_message(template, status=BroadcastStatusType.PENDING_APPROVAL)
|
broadcast = create_broadcast_message(template, status=BroadcastStatusType.PENDING_APPROVAL)
|
||||||
approver = create_user(email='approver@gov.uk')
|
approver = create_user(email='approver@gov.uk')
|
||||||
sample_service.users.append(approver)
|
sample_broadcast_service.users.append(approver)
|
||||||
mock_task = mocker.patch('app.celery.broadcast_message_tasks.send_broadcast_event.apply_async')
|
mock_task = mocker.patch('app.celery.broadcast_message_tasks.send_broadcast_event.apply_async')
|
||||||
|
|
||||||
response = admin_request.post(
|
response = admin_request.post(
|
||||||
@@ -427,12 +431,12 @@ def test_update_broadcast_message_status_rejects_approval_of_broadcast_with_no_a
|
|||||||
def test_update_broadcast_message_status_allows_platform_admin_to_approve_own_message(
|
def test_update_broadcast_message_status_allows_platform_admin_to_approve_own_message(
|
||||||
notify_db,
|
notify_db,
|
||||||
admin_request,
|
admin_request,
|
||||||
sample_service,
|
sample_broadcast_service,
|
||||||
mocker
|
mocker
|
||||||
):
|
):
|
||||||
user = sample_service.created_by
|
user = sample_broadcast_service.created_by
|
||||||
user.platform_admin = True
|
user.platform_admin = True
|
||||||
t = create_template(sample_service, BROADCAST_TYPE)
|
t = create_template(sample_broadcast_service, BROADCAST_TYPE)
|
||||||
bm = create_broadcast_message(
|
bm = create_broadcast_message(
|
||||||
t,
|
t,
|
||||||
status=BroadcastStatusType.PENDING_APPROVAL,
|
status=BroadcastStatusType.PENDING_APPROVAL,
|
||||||
@@ -461,11 +465,11 @@ def test_update_broadcast_message_status_allows_platform_admin_to_approve_own_me
|
|||||||
def test_update_broadcast_message_status_allows_trial_mode_services_to_approve_own_message(
|
def test_update_broadcast_message_status_allows_trial_mode_services_to_approve_own_message(
|
||||||
notify_db,
|
notify_db,
|
||||||
admin_request,
|
admin_request,
|
||||||
sample_service,
|
sample_broadcast_service,
|
||||||
mocker
|
mocker
|
||||||
):
|
):
|
||||||
sample_service.restricted = True
|
sample_broadcast_service.restricted = True
|
||||||
t = create_template(sample_service, BROADCAST_TYPE)
|
t = create_template(sample_broadcast_service, BROADCAST_TYPE)
|
||||||
bm = create_broadcast_message(
|
bm = create_broadcast_message(
|
||||||
t,
|
t,
|
||||||
status=BroadcastStatusType.PENDING_APPROVAL,
|
status=BroadcastStatusType.PENDING_APPROVAL,
|
||||||
@@ -490,10 +494,10 @@ def test_update_broadcast_message_status_allows_trial_mode_services_to_approve_o
|
|||||||
|
|
||||||
def test_update_broadcast_message_status_rejects_approval_from_user_not_on_that_service(
|
def test_update_broadcast_message_status_rejects_approval_from_user_not_on_that_service(
|
||||||
admin_request,
|
admin_request,
|
||||||
sample_service,
|
sample_broadcast_service,
|
||||||
mocker
|
mocker
|
||||||
):
|
):
|
||||||
t = create_template(sample_service, BROADCAST_TYPE)
|
t = create_template(sample_broadcast_service, BROADCAST_TYPE)
|
||||||
bm = create_broadcast_message(t, status=BroadcastStatusType.PENDING_APPROVAL)
|
bm = create_broadcast_message(t, status=BroadcastStatusType.PENDING_APPROVAL)
|
||||||
approver = create_user(email='approver@gov.uk')
|
approver = create_user(email='approver@gov.uk')
|
||||||
mock_task = mocker.patch('app.celery.broadcast_message_tasks.send_broadcast_event.apply_async')
|
mock_task = mocker.patch('app.celery.broadcast_message_tasks.send_broadcast_event.apply_async')
|
||||||
@@ -519,15 +523,15 @@ def test_update_broadcast_message_status_rejects_approval_from_user_not_on_that_
|
|||||||
])
|
])
|
||||||
def test_update_broadcast_message_status_restricts_status_transitions_to_explicit_list(
|
def test_update_broadcast_message_status_restricts_status_transitions_to_explicit_list(
|
||||||
admin_request,
|
admin_request,
|
||||||
sample_service,
|
sample_broadcast_service,
|
||||||
mocker,
|
mocker,
|
||||||
current_status,
|
current_status,
|
||||||
new_status
|
new_status
|
||||||
):
|
):
|
||||||
t = create_template(sample_service, BROADCAST_TYPE)
|
t = create_template(sample_broadcast_service, BROADCAST_TYPE)
|
||||||
bm = create_broadcast_message(t, status=current_status)
|
bm = create_broadcast_message(t, status=current_status)
|
||||||
approver = create_user(email='approver@gov.uk')
|
approver = create_user(email='approver@gov.uk')
|
||||||
sample_service.users.append(approver)
|
sample_broadcast_service.users.append(approver)
|
||||||
mock_task = mocker.patch('app.celery.broadcast_message_tasks.send_broadcast_event.apply_async')
|
mock_task = mocker.patch('app.celery.broadcast_message_tasks.send_broadcast_event.apply_async')
|
||||||
|
|
||||||
response = admin_request.post(
|
response = admin_request.post(
|
||||||
|
|||||||
@@ -41,7 +41,8 @@ from app.models import (
|
|||||||
SMS_TYPE,
|
SMS_TYPE,
|
||||||
LETTER_TYPE,
|
LETTER_TYPE,
|
||||||
SERVICE_PERMISSION_TYPES,
|
SERVICE_PERMISSION_TYPES,
|
||||||
ServiceEmailReplyTo
|
ServiceEmailReplyTo,
|
||||||
|
BROADCAST_TYPE
|
||||||
)
|
)
|
||||||
from tests import create_authorization_header
|
from tests import create_authorization_header
|
||||||
from tests.app.db import (
|
from tests.app.db import (
|
||||||
@@ -148,6 +149,31 @@ def sample_service(notify_db_session):
|
|||||||
return service
|
return service
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope='function')
|
||||||
|
def sample_broadcast_service(notify_db_session):
|
||||||
|
user = create_user()
|
||||||
|
service_name = 'Sample broadcast service'
|
||||||
|
email_from = service_name.lower().replace(' ', '.')
|
||||||
|
|
||||||
|
data = {
|
||||||
|
'name': service_name,
|
||||||
|
'message_limit': 1000,
|
||||||
|
'restricted': False,
|
||||||
|
'email_from': email_from,
|
||||||
|
'created_by': user,
|
||||||
|
'crown': True
|
||||||
|
}
|
||||||
|
service = Service.query.filter_by(name=service_name).first()
|
||||||
|
if not service:
|
||||||
|
service = Service(**data)
|
||||||
|
dao_create_service(service, user, service_permissions=[BROADCAST_TYPE])
|
||||||
|
else:
|
||||||
|
if user not in service.users:
|
||||||
|
dao_add_user_to_service(service, user)
|
||||||
|
|
||||||
|
return service
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope='function', name='sample_service_full_permissions')
|
@pytest.fixture(scope='function', name='sample_service_full_permissions')
|
||||||
def _sample_service_full_permissions(notify_db_session):
|
def _sample_service_full_permissions(notify_db_session):
|
||||||
service = create_service(
|
service = create_service(
|
||||||
@@ -610,8 +636,7 @@ def email_verification_template(notify_db,
|
|||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope='function')
|
@pytest.fixture(scope='function')
|
||||||
def invitation_email_template(notify_db,
|
def invitation_email_template(notify_db, notify_db_session):
|
||||||
notify_db_session):
|
|
||||||
service, user = notify_service(notify_db, notify_db_session)
|
service, user = notify_service(notify_db, notify_db_session)
|
||||||
content = '((user_name)) is invited to Notify by ((service_name)) ((url)) to complete registration',
|
content = '((user_name)) is invited to Notify by ((service_name)) ((url)) to complete registration',
|
||||||
return create_custom_template(
|
return create_custom_template(
|
||||||
@@ -624,6 +649,20 @@ def invitation_email_template(notify_db,
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope='function')
|
||||||
|
def broadcast_invitation_email_template(notify_db, notify_db_session):
|
||||||
|
service, user = notify_service(notify_db, notify_db_session)
|
||||||
|
content = '((user_name)) is invited to broadcast Notify by ((service_name)) ((url)) to complete registration',
|
||||||
|
return create_custom_template(
|
||||||
|
service=service,
|
||||||
|
user=user,
|
||||||
|
template_config_name='BROADCAST_INVITATION_EMAIL_TEMPLATE_ID',
|
||||||
|
content=content,
|
||||||
|
subject='Invitation to ((service_name))',
|
||||||
|
template_type='email'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope='function')
|
@pytest.fixture(scope='function')
|
||||||
def org_invite_email_template(notify_db, notify_db_session):
|
def org_invite_email_template(notify_db, notify_db_session):
|
||||||
service, user = notify_service(notify_db, notify_db_session)
|
service, user = notify_service(notify_db, notify_db_session)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import json
|
import json
|
||||||
import pytest
|
import pytest
|
||||||
|
from flask import current_app
|
||||||
|
|
||||||
from app.models import Notification, SMS_AUTH_TYPE, EMAIL_AUTH_TYPE
|
from app.models import Notification, SMS_AUTH_TYPE, EMAIL_AUTH_TYPE
|
||||||
from tests import create_authorization_header
|
from tests import create_authorization_header
|
||||||
@@ -62,6 +63,60 @@ def test_create_invited_user(
|
|||||||
assert notification.personalisation['user_name'] == 'Test User'
|
assert notification.personalisation['user_name'] == 'Test User'
|
||||||
assert notification.personalisation['url'].startswith(expected_start_of_invite_url)
|
assert notification.personalisation['url'].startswith(expected_start_of_invite_url)
|
||||||
assert len(notification.personalisation['url']) > len(expected_start_of_invite_url)
|
assert len(notification.personalisation['url']) > len(expected_start_of_invite_url)
|
||||||
|
assert str(notification.template_id) == current_app.config['INVITATION_EMAIL_TEMPLATE_ID']
|
||||||
|
|
||||||
|
mocked.assert_called_once_with([(str(notification.id))], queue="notify-internal-tasks")
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('extra_args, expected_start_of_invite_url', [
|
||||||
|
(
|
||||||
|
{},
|
||||||
|
'http://localhost:6012/invitation/'
|
||||||
|
),
|
||||||
|
(
|
||||||
|
{'invite_link_host': 'https://www.example.com'},
|
||||||
|
'https://www.example.com/invitation/'
|
||||||
|
),
|
||||||
|
])
|
||||||
|
def test_invited_user_for_broadcast_service_receives_broadcast_invite_email(
|
||||||
|
admin_request,
|
||||||
|
sample_broadcast_service,
|
||||||
|
mocker,
|
||||||
|
broadcast_invitation_email_template,
|
||||||
|
extra_args,
|
||||||
|
expected_start_of_invite_url,
|
||||||
|
):
|
||||||
|
mocked = mocker.patch('app.celery.provider_tasks.deliver_email.apply_async')
|
||||||
|
email_address = 'invited_user@service.gov.uk'
|
||||||
|
invite_from = sample_broadcast_service.users[0]
|
||||||
|
|
||||||
|
data = dict(
|
||||||
|
service=str(sample_broadcast_service.id),
|
||||||
|
email_address=email_address,
|
||||||
|
from_user=str(invite_from.id),
|
||||||
|
permissions='send_messages,manage_service,manage_api_keys',
|
||||||
|
auth_type=EMAIL_AUTH_TYPE,
|
||||||
|
folder_permissions=['folder_1', 'folder_2', 'folder_3'],
|
||||||
|
**extra_args
|
||||||
|
)
|
||||||
|
|
||||||
|
admin_request.post(
|
||||||
|
'invite.create_invited_user',
|
||||||
|
service_id=sample_broadcast_service.id,
|
||||||
|
_data=data,
|
||||||
|
_expected_status=201
|
||||||
|
)
|
||||||
|
|
||||||
|
notification = Notification.query.first()
|
||||||
|
|
||||||
|
assert notification.reply_to_text == invite_from.email_address
|
||||||
|
|
||||||
|
assert len(notification.personalisation.keys()) == 3
|
||||||
|
assert notification.personalisation['service_name'] == 'Sample broadcast service'
|
||||||
|
assert notification.personalisation['user_name'] == 'Test User'
|
||||||
|
assert notification.personalisation['url'].startswith(expected_start_of_invite_url)
|
||||||
|
assert len(notification.personalisation['url']) > len(expected_start_of_invite_url)
|
||||||
|
assert str(notification.template_id) == current_app.config['BROADCAST_INVITATION_EMAIL_TEMPLATE_ID']
|
||||||
|
|
||||||
mocked.assert_called_once_with([(str(notification.id))], queue="notify-internal-tasks")
|
mocked.assert_called_once_with([(str(notification.id))], queue="notify-internal-tasks")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user