diff --git a/app/__init__.py b/app/__init__.py index 17bd96179..f7cecaa9b 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -147,19 +147,18 @@ def register_blueprint(application): def register_v2_blueprints(application): - from app.v2.notifications.post_notifications import v2_notification_blueprint as post_notifications - from app.v2.notifications.get_notifications import v2_notification_blueprint as get_notifications - from app.v2.template.get_template import template_blueprint - from app.authentication.auth import requires_auth + from app.v2.notifications.post_notifications import notification_blueprint as post_notifications + from app.v2.notifications.get_notifications import notification_blueprint as get_notifications + from app.v2.template.get_template import template_blueprint as get_template + from app.v2.template.post_template import template_blueprint as post_template post_notifications.before_request(requires_auth) application.register_blueprint(post_notifications) get_notifications.before_request(requires_auth) application.register_blueprint(get_notifications) - - template_blueprint.before_request(requires_auth) - application.register_blueprint(template_blueprint) + application.register_blueprint(get_template) + application.register_blueprint(post_template) def init_app(app): diff --git a/app/v2/template/post_template.py b/app/v2/template/post_template.py new file mode 100644 index 000000000..0c2292965 --- /dev/null +++ b/app/v2/template/post_template.py @@ -0,0 +1,44 @@ +import uuid + +from flask import jsonify, request +from jsonschema.exceptions import ValidationError +from werkzeug.exceptions import abort + +from app import api_user +from app.dao import templates_dao +from app.schema_validation import validate +from app.utils import get_template_instance +from app.v2.errors import BadRequestError +from app.v2.template import template_blueprint +from app.v2.template.template_schemas import post_template_preview_request, create_post_template_preview_response + + +@template_blueprint.route("//preview", methods=['POST']) +def post_template_preview(template_id): + try: + _data = request.get_json() + _data['id'] = template_id + + data = validate(_data, post_template_preview_request) + except ValueError or AttributeError: + abort(404) + + template = templates_dao.dao_get_template_by_id_and_service_id( + template_id, api_user.service_id) + + template_object = get_template_instance( + template.__dict__, values=data.get('personalisation')) + + check_placeholders(template_object) + + resp = create_post_template_preview_response(template=template, + body=str(template_object), + url_root=request.url_root) + + return jsonify(resp), 200 + + +def check_placeholders(template_object): + if template_object.missing_data: + message = 'Missing personalisation: {}'.format(", ".join(template_object.missing_data)) + raise BadRequestError(message=message, fields=[{'template': message}]) diff --git a/app/v2/template/template_schemas.py b/app/v2/template/template_schemas.py index 5a5a9ece8..be0d412bd 100644 --- a/app/v2/template/template_schemas.py +++ b/app/v2/template/template_schemas.py @@ -66,3 +66,14 @@ post_template_preview_response = { }, "required": ["id", "type", "version", "body"] } + + +def create_post_template_preview_response(template, body, url_root): + return { + "id": template.id, + "type": template.template_type, + "version": template.version, + "content": {'body': body}, + "subject": template.subject, + "uri": "{}v2/template/{}/preview".format(url_root, template.id) + } diff --git a/tests/app/v2/template/test_post_template.py b/tests/app/v2/template/test_post_template.py new file mode 100644 index 000000000..c8c8374ae --- /dev/null +++ b/tests/app/v2/template/test_post_template.py @@ -0,0 +1,83 @@ +import pytest +import uuid + +from flask import json + +from app.models import EMAIL_TYPE, SMS_TYPE, LETTER_TYPE +from tests import create_authorization_header +from tests.app.db import create_template + +valid_data = { + 'personalisation': {'Name': 'Jo'} +} + + +@pytest.mark.parametrize("tmp_type", [EMAIL_TYPE, SMS_TYPE]) +def test_valid_post_template_returns_200(client, sample_service, tmp_type): + template = create_template( + sample_service, + template_type=tmp_type, + content='Dear ((Name)), Hello. Yours Truly, The Government.') + + auth_header = create_authorization_header(service_id=sample_service.id) + + response = client.post( + path='/v2/template/{}/preview'.format(template.id), + data=json.dumps(valid_data), + headers=[('Content-Type', 'application/json'), auth_header]) + + assert response.status_code == 200 + + resp_json = json.loads(response.get_data(as_text=True)) + + assert resp_json['id'] == str(template.id) + assert 'v2/template/{}/preview'.format(template.id) in resp_json['uri'] + assert 'Dear {}'.format(valid_data['personalisation']['Name']) in resp_json['content']['body'] + + +@pytest.mark.parametrize("tmp_type", [EMAIL_TYPE, SMS_TYPE]) +def test_invalid_post_template_returns_400(client, sample_service, tmp_type): + template = create_template( + sample_service, + template_type=tmp_type, + content='Dear ((Name)), Hello ((Missing)). Yours Truly, The Government.') + + auth_header = create_authorization_header(service_id=sample_service.id) + + response = client.post( + path='/v2/template/{}/preview'.format(template.id), + data=json.dumps(valid_data), + headers=[('Content-Type', 'application/json'), auth_header]) + + assert response.status_code == 400 + + resp_json = json.loads(response.get_data(as_text=True)) + + assert resp_json['errors'][0]['error'] == 'BadRequestError' + assert 'Missing personalisation: Missing' in resp_json['errors'][0]['message'] + + +def test_post_template_with_non_existent_template_id_returns_404(client, sample_service): + auth_header = create_authorization_header(service_id=sample_service.id) + + random_template_id = str(uuid.uuid4()) + + response = client.post( + path='/v2/template/{}/preview'.format(random_template_id), + data=json.dumps(valid_data), + headers=[('Content-Type', 'application/json'), auth_header]) + + assert response.status_code == 404 + assert response.headers['Content-type'] == 'application/json' + + json_response = json.loads(response.get_data(as_text=True)) + + assert json_response == { + "errors": [ + { + "error": "NoResultFound", + "message": "No result found" + } + ], + "status_code": 404 + }