From 4ca6fbc72466c3e0400343fd4c12b0e01fc9a347 Mon Sep 17 00:00:00 2001 From: Rebecca Law Date: Wed, 18 Oct 2017 13:13:23 +0100 Subject: [PATCH] Added dao methods needed to add or update multiple sms senders for a service. Remove the unique constraint for service on the ServiceSmsSender model. --- app/dao/service_sms_sender_dao.py | 77 +++++++++++ ...nt.py => 0126_remove_unique_constraint.py} | 9 +- tests/app/dao/test_service_sms_sender_dao.py | 120 +++++++++++++++++- 3 files changed, 200 insertions(+), 6 deletions(-) rename migrations/versions/{0125_remove_unique_constraint.py => 0126_remove_unique_constraint.py} (66%) diff --git a/app/dao/service_sms_sender_dao.py b/app/dao/service_sms_sender_dao.py index 18760cd29..6a084e644 100644 --- a/app/dao/service_sms_sender_dao.py +++ b/app/dao/service_sms_sender_dao.py @@ -32,3 +32,80 @@ def insert_service_sms_sender(service, sms_sender): is_default=True ) db.session.add(new_sms_sender) + + +def dao_get_service_sms_senders_by_id(service_id, service_sms_sender_id): + return ServiceSmsSender.query.filter_by( + id=service_sms_sender_id, + service_id=service_id + ).one() + + +def dao_get_sms_senders_by_service_id(service_id): + return ServiceSmsSender.query.filter_by(service_id=service_id).all() + + +@transactional +def dao_add_sms_sender_for_service(service_id, sms_sender, is_default, inbound_number_id=None): + old_default = _get_existing_default(service_id=service_id) + if is_default: + _reset_old_default_to_false(old_default) + else: + _raise_when_no_default(old_default) + + new_sms_sender = ServiceSmsSender( + service_id=service_id, + sms_sender=sms_sender, + is_default=is_default, + inbound_number_id=inbound_number_id + ) + + db.session.add(new_sms_sender) + return new_sms_sender + + +@transactional +def dao_update_service_sms_sender(service_id, service_sms_sender_id, is_default, sms_sender=None): + old_default = _get_existing_default(service_id) + if is_default: + _reset_old_default_to_false(old_default) + else: + if old_default.id == service_sms_sender_id: + raise Exception("You must have at least one SMS sender as the default") + + sms_sender_to_update = ServiceSmsSender.query.get(service_sms_sender_id) + sms_sender_to_update.is_default = is_default + if not sms_sender_to_update.inbound_number_id and sms_sender: + sms_sender_to_update.sms_sender = sms_sender + db.session.add(sms_sender_to_update) + return sms_sender_to_update + + +def _get_existing_default(service_id): + sms_senders = dao_get_sms_senders_by_service_id(service_id=service_id) + if sms_senders: + old_default = [x for x in sms_senders if x.is_default] + if len(old_default) == 1: + return old_default[0] + else: + raise Exception( + "There should only be one default sms sender for each service. Service {} has {}".format( + service_id, + len(old_default) + ) + ) + return None + + +def _reset_old_default_to_false(old_default): + if old_default: + old_default.is_default = False + db.session.add(old_default) + + +def _raise_when_no_default(old_default): + # check that the update is not updating the only default to false + if not old_default: + raise Exception("You must have at least one letter contact as the default.", 400) + + diff --git a/migrations/versions/0125_remove_unique_constraint.py b/migrations/versions/0126_remove_unique_constraint.py similarity index 66% rename from migrations/versions/0125_remove_unique_constraint.py rename to migrations/versions/0126_remove_unique_constraint.py index 0039bb931..ca7ec8ca2 100644 --- a/migrations/versions/0125_remove_unique_constraint.py +++ b/migrations/versions/0126_remove_unique_constraint.py @@ -1,15 +1,15 @@ """ -Revision ID: 0125_remove_unique_constraint -Revises: 0124_add_free_sms_fragment_limit +Revision ID: 0126_remove_unique_constraint +Revises: 0125_add_organisation_type Create Date: 2017-10-17 16:47:37.826333 """ from alembic import op import sqlalchemy as sa -revision = '0125_remove_unique_constraint' -down_revision = '0124_add_free_sms_fragment_limit' +revision = '0126_remove_unique_constraint' +down_revision = '0125_add_organisation_type' def upgrade(): @@ -20,6 +20,5 @@ def upgrade(): def downgrade(): # ### commands auto generated by Alembic - please adjust! ### - op.drop_index(op.f('ix_service_sms_senders_service_id'), table_name='service_sms_senders') op.create_index('ix_service_sms_senders_service_id', 'service_sms_senders', ['service_id'], unique=True) # ### end Alembic commands ### diff --git a/tests/app/dao/test_service_sms_sender_dao.py b/tests/app/dao/test_service_sms_sender_dao.py index 5c04629c6..ebe641786 100644 --- a/tests/app/dao/test_service_sms_sender_dao.py +++ b/tests/app/dao/test_service_sms_sender_dao.py @@ -1,4 +1,12 @@ -from app.dao.service_sms_sender_dao import insert_or_update_service_sms_sender +import uuid + +import pytest +from sqlalchemy.exc import SQLAlchemyError + +from app.dao.service_sms_sender_dao import ( + insert_or_update_service_sms_sender, + dao_add_sms_sender_for_service, + dao_update_service_sms_sender, dao_get_service_sms_senders_by_id, dao_get_sms_senders_by_service_id) from app.models import ServiceSmsSender from tests.app.db import create_service @@ -27,3 +35,113 @@ def test_create_service_inserts_new_service_sms_sender(notify_db_session): assert len(service_sms_senders) == 1 assert service_sms_senders[0].sms_sender == 'new_sms' assert service_sms_senders[0].is_default + + +def test_dao_get_service_sms_senders_id(notify_db_session): + service = create_service(sms_sender='first_sms') + second_sender = dao_add_sms_sender_for_service(service_id=service.id, + sms_sender='second', + is_default=False, + inbound_number_id=None) + result = dao_get_service_sms_senders_by_id(service_id=service.id, + service_sms_sender_id=second_sender.id) + assert result.sms_sender == "second" + assert not result.is_default + + +def test_dao_get_service_sms_senders_id_raise_exception_when_not_found(notify_db_session): + service = create_service() + with pytest.raises(expected_exception=SQLAlchemyError): + dao_get_service_sms_senders_by_id(service_id=service.id, + service_sms_sender_id=uuid.uuid4()) + + +def test_dao_get_sms_senders_by_service_id(notify_db_session): + service = create_service(sms_sender='first_sms') + second_sender = dao_add_sms_sender_for_service(service_id=service.id, + sms_sender='second', + is_default=False, + inbound_number_id=None) + results = dao_get_sms_senders_by_service_id(service_id=service.id) + assert len(results) == 2 + for x in results: + if x.is_default: + x.sms_sender = 'first_sms' + else: + x == second_sender + + +def test_dao_add_sms_sender_for_service(notify_db_session): + service = create_service(sms_sender="first_sms") + new_sms_sender = dao_add_sms_sender_for_service(service_id=service.id, + sms_sender='new_sms', + is_default=False, + inbound_number_id=None) + + service_sms_senders = ServiceSmsSender.query.order_by(ServiceSmsSender.created_at).all() + assert len(service_sms_senders) == 2 + assert service_sms_senders[0].sms_sender == 'first_sms' + assert service_sms_senders[0].is_default + assert service_sms_senders[1] == new_sms_sender + + +def test_dao_add_sms_sender_for_service_switches_default(notify_db_session): + service = create_service(sms_sender="first_sms") + new_sms_sender = dao_add_sms_sender_for_service(service_id=service.id, + sms_sender='new_sms', + is_default=True, + inbound_number_id=None) + + service_sms_senders = ServiceSmsSender.query.order_by(ServiceSmsSender.created_at).all() + assert len(service_sms_senders) == 2 + assert service_sms_senders[0].sms_sender == 'first_sms' + assert not service_sms_senders[0].is_default + assert service_sms_senders[1] == new_sms_sender + + +def test_dao_update_service_sms_sender(notify_db_session): + service = create_service(sms_sender='first_sms') + service_sms_senders = ServiceSmsSender.query.filter_by(service_id =service.id).all() + assert len(service_sms_senders) == 1 + sms_sender_to_update = service_sms_senders[0] + + dao_update_service_sms_sender(service_id=service.id, + service_sms_sender_id=sms_sender_to_update.id, + is_default=True, + sms_sender="updated") + sms_senders = ServiceSmsSender.query.filter_by(service_id=service.id).all() + assert len(sms_senders) == 1 + assert sms_senders[0].is_default + assert sms_senders[0].sms_sender == 'updated' + assert not sms_senders[0].inbound_number_id + + +def test_dao_update_service_sms_sender_switches_default(notify_db_session): + service = create_service(sms_sender='first_sms') + sms_sender = dao_add_sms_sender_for_service(service_id=service.id, + sms_sender='new_sms', + is_default=False, + inbound_number_id=None) + dao_update_service_sms_sender(service_id=service.id, + service_sms_sender_id=sms_sender.id, + is_default=True, + sms_sender="updated") + sms_senders = ServiceSmsSender.query.filter_by(service_id=service.id).order_by(ServiceSmsSender.created_at).all() + assert len(sms_senders) == 2 + assert sms_senders[0].sms_sender == 'first_sms' + assert not sms_senders[0].is_default + assert sms_senders[1].sms_sender == 'updated' + assert sms_senders[1].is_default + + +def test_dao_update_service_sms_sender_raises_exception_when_no_default_after_update(notify_db_session): + service = create_service(sms_sender='first_sms') + sms_sender = dao_add_sms_sender_for_service(service_id=service.id, + sms_sender='new_sms', + is_default=True, + inbound_number_id=None) + with pytest.raises(expected_exception=Exception) as e: + dao_update_service_sms_sender(service_id=service.id, + service_sms_sender_id=sms_sender.id, + is_default=False, + sms_sender="updated")