From 4849ecdf63d64755dfcc3c70eca29d7001bff78e Mon Sep 17 00:00:00 2001 From: Rebecca Law Date: Mon, 5 Nov 2018 10:54:42 +0000 Subject: [PATCH] Update the template_schema to include a parent_folder_id. When creating the Tempalte from_json, the folder is passed in. Since some validation should done, as in the folder exists and is for the same service, the folder is passed through to the Tempalte.from_json method. When the template is persisted so is the relationship to folders. TODO: If the folder is invalid a specific message should be returned. --- app/models.py | 5 +-- app/template/rest.py | 12 +++++-- app/template/template_schemas.py | 3 +- tests/app/template/test_rest.py | 58 ++++++++++++++++++++++++++++++-- 4 files changed, 71 insertions(+), 7 deletions(-) diff --git a/app/models.py b/app/models.py index bf548bd32..f5bd68eae 100644 --- a/app/models.py +++ b/app/models.py @@ -885,7 +885,7 @@ class Template(TemplateBase): ) @classmethod - def from_json(cls, data): + def from_json(cls, data, folder): """ Assumption: data has been validated appropriately. @@ -895,7 +895,8 @@ class Template(TemplateBase): fields['created_by_id'] = fields.pop('created_by') fields['service_id'] = fields.pop('service') - + if fields.pop("parent_folder_id"): + fields['folder'] = folder return cls(**fields) diff --git a/app/template/rest.py b/app/template/rest.py index 52a3497fb..2084bb674 100644 --- a/app/template/rest.py +++ b/app/template/rest.py @@ -29,7 +29,7 @@ from app.errors import ( InvalidRequest ) from app.letters.utils import get_letter_pdf -from app.models import SMS_TYPE, Template +from app.models import SMS_TYPE, Template, TemplateFolder from app.notifications.validators import service_has_permission, check_reply_to from app.schema_validation import validate from app.schemas import (template_schema, template_history_schema) @@ -48,12 +48,19 @@ def _content_count_greater_than_limit(content, template_type): return template.content_count > SMS_CHAR_COUNT_LIMIT +def validate_parent_folder(parent_folder_id, service_id): + return TemplateFolder.query.filter_by(service_id=service_id, id=parent_folder_id).one() + + @template_blueprint.route('', methods=['POST']) def create_template(service_id): fetched_service = dao_fetch_service_by_id(service_id=service_id) # permissions needs to be placed here otherwise marshmallow will interfere with versioning permissions = fetched_service.permissions - new_template = Template.from_json(validate(request.get_json(), post_create_template_schema)) + template_json = validate(request.get_json(), post_create_template_schema) + folder = validate_parent_folder(parent_folder_id=template_json['parent_folder_id'], + service_id=template_json['service']) + new_template = Template.from_json(template_json, folder) if not service_has_permission(new_template.template_type, permissions): message = "Creating {} templates is not allowed".format( @@ -72,6 +79,7 @@ def create_template(service_id): check_reply_to(service_id, new_template.reply_to, new_template.template_type) dao_create_template(new_template) + return jsonify(data=template_schema.dump(new_template).data), 201 diff --git a/app/template/template_schemas.py b/app/template/template_schemas.py index 4f13c8ced..f63ad4575 100644 --- a/app/template/template_schemas.py +++ b/app/template/template_schemas.py @@ -16,7 +16,8 @@ post_create_template_schema = { "process_type": {"emun": TEMPLATE_PROCESS_TYPE}, "content": {"type": "string"}, "subject": {"type": "string"}, - "created_by": uuid + "created_by": uuid, + "parent_folder_id": uuid }, "if": { "properties": { diff --git a/tests/app/template/test_rest.py b/tests/app/template/test_rest.py index 55e265f8b..c92545af9 100644 --- a/tests/app/template/test_rest.py +++ b/tests/app/template/test_rest.py @@ -12,7 +12,7 @@ from freezegun import freeze_time from notifications_utils import SMS_CHAR_COUNT_LIMIT -from app.models import Template, SMS_TYPE, EMAIL_TYPE, LETTER_TYPE, TemplateHistory +from app.models import Template, SMS_TYPE, EMAIL_TYPE, LETTER_TYPE, TemplateHistory, TemplateFolder from app.dao.templates_dao import dao_get_template_by_id, dao_redact_template from tests import create_authorization_header @@ -21,7 +21,10 @@ from tests.app.conftest import ( sample_template_without_email_permission, sample_template_without_letter_permission, sample_template_without_sms_permission) -from tests.app.db import create_service, create_letter_contact, create_template, create_notification +from tests.app.db import ( + create_service, create_letter_contact, create_template, create_notification, + create_template_folder, +) from tests.conftest import set_config_values @@ -71,6 +74,57 @@ def test_should_create_a_new_template_for_a_service( assert sorted(json_resp['data']) == sorted(template_schema.dump(template).data) +def test_should_create_a_new_template_for_a_service_adds_folder_relationship( + client, sample_service +): + parent_folder = create_template_folder(service=sample_service, name='parent folder') + + data = { + 'name': 'my template', + 'template_type': 'sms', + 'content': 'template content', + 'service': str(sample_service.id), + 'created_by': str(sample_service.users[0].id), + 'parent_folder_id': str(parent_folder.id) + } + data = json.dumps(data) + auth_header = create_authorization_header() + + response = client.post( + '/service/{}/template'.format(sample_service.id), + headers=[('Content-Type', 'application/json'), auth_header], + data=data + ) + assert response.status_code == 201 + template = Template.query.filter(Template.name == 'my template').first() + assert template.folder == parent_folder + + +def test_create_template_should_return_404_if_folder_is_for_a_different_service( + client, sample_service +): + service2 = create_service(service_name='second service') + parent_folder = create_template_folder(service=service2) + + data = { + 'name': 'my template', + 'template_type': 'sms', + 'content': 'template content', + 'service': str(sample_service.id), + 'created_by': str(sample_service.users[0].id), + 'parent_folder_id': str(parent_folder.id) + } + data = json.dumps(data) + auth_header = create_authorization_header() + + response = client.post( + '/service/{}/template'.format(sample_service.id), + headers=[('Content-Type', 'application/json'), auth_header], + data=data + ) + assert response.status_code == 404 + + def test_should_raise_error_if_service_does_not_exist_on_create(client, sample_user, fake_uuid): data = { 'name': 'my template',