From a6a44987a122d194c98e2e741dc83f1ee73d2dee Mon Sep 17 00:00:00 2001 From: Chris Hill-Scott Date: Wed, 20 Dec 2017 14:38:49 +0000 Subject: [PATCH] Allow admin to domain to use for invite links MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When we’re doing user research we often: - start the task by inviting the participant to a service on Notify - have them use a prototype version of the admin app, hosted on a different domain Currently we can’t do both of these things together, because the invite emails always send people to `notifications.service.gov.uk` (because it’s the API that sends the emails, and the prototype admin app points at the production API). This commit changes the API to optionally allow an instance of the admin app to specify which domain should be used when generating invite links. --- app/invite/rest.py | 15 +++++++--- tests/app/invite/test_invite_rest.py | 43 ++++++++++++++++++++++------ 2 files changed, 46 insertions(+), 12 deletions(-) diff --git a/app/invite/rest.py b/app/invite/rest.py index ba263e1b3..c234dd5d1 100644 --- a/app/invite/rest.py +++ b/app/invite/rest.py @@ -23,7 +23,8 @@ register_errors(invite) @invite.route('', methods=['POST']) def create_invited_user(service_id): - invited_user, errors = invited_user_schema.load(request.get_json()) + request_json = request.get_json() + invited_user, errors = invited_user_schema.load(request_json) save_invited_user(invited_user) template = dao_get_template_by_id(current_app.config['INVITATION_EMAIL_TEMPLATE_ID']) @@ -37,7 +38,10 @@ def create_invited_user(service_id): personalisation={ 'user_name': invited_user.from_user.name, 'service_name': invited_user.service.name, - 'url': invited_user_url(invited_user.id) + 'url': invited_user_url( + invited_user.id, + request_json.get('invite_link_host'), + ), }, notification_type=EMAIL_TYPE, api_key_id=None, @@ -74,8 +78,11 @@ def update_invited_user(service_id, invited_user_id): return jsonify(data=invited_user_schema.dump(fetched).data), 200 -def invited_user_url(invited_user_id): +def invited_user_url(invited_user_id, invite_link_host=None): from notifications_utils.url_safe_token import generate_token token = generate_token(str(invited_user_id), current_app.config['SECRET_KEY'], current_app.config['DANGEROUS_SALT']) - return '{0}/invitation/{1}'.format(current_app.config['ADMIN_BASE_URL'], token) + if invite_link_host is None: + invite_link_host = current_app.config['ADMIN_BASE_URL'] + + return '{0}/invitation/{1}'.format(invite_link_host, token) diff --git a/tests/app/invite/test_invite_rest.py b/tests/app/invite/test_invite_rest.py index ebeeb3492..2071651a3 100644 --- a/tests/app/invite/test_invite_rest.py +++ b/tests/app/invite/test_invite_rest.py @@ -1,22 +1,41 @@ import json +import pytest import uuid from app.models import Notification, SMS_AUTH_TYPE, EMAIL_AUTH_TYPE from tests import create_authorization_header -def test_create_invited_user(admin_request, sample_service, mocker, invitation_email_template): +@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_create_invited_user( + admin_request, + sample_service, + mocker, + 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_service.users[0] - data = { - 'service': str(sample_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 - } + data = dict( + service=str(sample_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, + **extra_args + ) json_resp = admin_request.post( 'invite.create_invited_user', @@ -33,7 +52,15 @@ def test_create_invited_user(admin_request, sample_service, mocker, invitation_e assert json_resp['data']['id'] 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 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) + mocked.assert_called_once_with([(str(notification.id))], queue="notify-internal-tasks")