diff --git a/app/models.py b/app/models.py index bc1d331f0..555a27ddd 100644 --- a/app/models.py +++ b/app/models.py @@ -257,6 +257,7 @@ LETTERS_AS_PDF = 'letters_as_pdf' PRECOMPILED_LETTER = 'precompiled_letter' UPLOAD_DOCUMENT = 'upload_document' EDIT_FOLDERS = 'edit_folders' +CHOOSE_POSTAGE = 'choose_postage' SERVICE_PERMISSION_TYPES = [ EMAIL_TYPE, @@ -270,6 +271,7 @@ SERVICE_PERMISSION_TYPES = [ PRECOMPILED_LETTER, UPLOAD_DOCUMENT, EDIT_FOLDERS, + CHOOSE_POSTAGE ] @@ -762,6 +764,15 @@ class TemplateBase(db.Model): archived = db.Column(db.Boolean, nullable=False, default=False) hidden = db.Column(db.Boolean, nullable=False, default=False) subject = db.Column(db.Text) + postage = db.Column(db.String, nullable=True) + CheckConstraint(""" + CASE WHEN template_type = 'letter' THEN + postage in ('first', 'second') OR + postage is null + ELSE + postage is null + END + """) @declared_attr def service_id(cls): @@ -861,6 +872,7 @@ class TemplateBase(db.Model): } for key in self._as_utils_template().placeholders }, + "postage": self.postage, } return serialized diff --git a/migrations/versions/0248_enable_choose_postage.py b/migrations/versions/0248_enable_choose_postage.py new file mode 100644 index 000000000..b72d6749f --- /dev/null +++ b/migrations/versions/0248_enable_choose_postage.py @@ -0,0 +1,54 @@ +""" + +Revision ID: 0248_enable_choose_postage +Revises: 0247_another_letter_org +Create Date: 2018-12-14 12:09:31.375634 + +""" +from alembic import op +import sqlalchemy as sa + + +revision = '0248_enable_choose_postage' +down_revision = '0247_another_letter_org' + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.execute("INSERT INTO service_permission_types VALUES ('choose_postage')") + op.add_column('templates', sa.Column('postage', sa.String(), nullable=True)) + op.add_column('templates_history', sa.Column('postage', sa.String(), nullable=True)) + op.execute(""" + ALTER TABLE templates ADD CONSTRAINT "chk_templates_postage_null" + CHECK ( + CASE WHEN template_type = 'letter' THEN + postage in ('first', 'second') OR + postage is null + ELSE + postage is null + END + ) + """) + op.execute(""" + ALTER TABLE templates_history ADD CONSTRAINT "chk_templates_history_postage_null" + CHECK ( + CASE WHEN template_type = 'letter' THEN + postage in ('first', 'second') OR + postage is null + ELSE + postage is null + END + ) + """) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_constraint('chk_templates_history_postage_null', 'templates_history', type_='check') + op.drop_constraint('chk_templates_postage_null', 'templates', type_='check') + op.drop_column('templates_history', 'postage') + op.drop_column('templates', 'postage') + op.execute("DELETE FROM service_permissions WHERE permission = 'choose_postage'") + op.execute("DELETE FROM service_permission_types WHERE name = 'choose_postage'") + # ### end Alembic commands ### diff --git a/tests/app/dao/test_templates_dao.py b/tests/app/dao/test_templates_dao.py index b3d27a6d6..d86cec7a0 100644 --- a/tests/app/dao/test_templates_dao.py +++ b/tests/app/dao/test_templates_dao.py @@ -1,6 +1,7 @@ from datetime import datetime from freezegun import freeze_time +from sqlalchemy.exc import SQLAlchemyError from sqlalchemy.orm.exc import NoResultFound import pytest @@ -523,3 +524,37 @@ def test_get_multiple_template_details_returns_templates_for_list_of_ids(sample_ assert res[0].template_type assert res[0].name assert not res[0].is_precompiled_letter + + +@pytest.mark.parametrize("template_type,postage", [('letter', 'third'), ('sms', 'second')]) +def test_template_postage_constraint_on_create(sample_service, sample_user, template_type, postage): + data = { + 'name': 'Sample Template', + 'template_type': template_type, + 'content': "Template content", + 'service': sample_service, + 'created_by': sample_user, + 'postage': postage + } + template = Template(**data) + with pytest.raises(expected_exception=SQLAlchemyError): + dao_create_template(template) + + +def test_template_postage_constraint_on_update(sample_service, sample_user): + data = { + 'name': 'Sample Template', + 'template_type': "letter", + 'content': "Template content", + 'service': sample_service, + 'created_by': sample_user, + 'postage': 'second' + } + template = Template(**data) + dao_create_template(template) + created = dao_get_all_templates_for_service(sample_service.id)[0] + assert created.name == 'Sample Template' + + created.postage = 'third' + with pytest.raises(expected_exception=SQLAlchemyError): + dao_update_template(created) diff --git a/tests/app/v2/template/test_get_template.py b/tests/app/v2/template/test_get_template.py index 3be2ce889..900621db7 100644 --- a/tests/app/v2/template/test_get_template.py +++ b/tests/app/v2/template/test_get_template.py @@ -41,6 +41,7 @@ def test_get_template_by_id_returns_200(client, sample_service, tmp_type, expect "subject": expected_subject, 'name': expected_name, 'personalisation': {}, + 'postage': None, } assert json_response == expected_response