From 3977574ef1a862b0fb581b821a44c1c93ffd4a42 Mon Sep 17 00:00:00 2001 From: Imdad Ahad Date: Mon, 25 Sep 2017 15:46:01 +0100 Subject: [PATCH] Add methods to add/update letter contacts for a service that handle defaults properly --- app/dao/service_letter_contact_dao.py | 64 ++++++++- .../dao/test_service_letter_contact_dao.py | 136 ++++++++++++++++++ 2 files changed, 199 insertions(+), 1 deletion(-) diff --git a/app/dao/service_letter_contact_dao.py b/app/dao/service_letter_contact_dao.py index 578483f62..2d0430299 100644 --- a/app/dao/service_letter_contact_dao.py +++ b/app/dao/service_letter_contact_dao.py @@ -28,7 +28,7 @@ def create_or_update_letter_contact(service_id, contact_block): letter_contacts[0].contact_block = contact_block dao_update_letter_contact(letter_contacts[0]) else: - # Once we move allowing letter contact blocks, this method will be removed + # TODO: Once we move allowing letter contact blocks, this method will be removed raise InvalidRequest( "Multiple letter contacts were found, this method should not be used.", status_code=500 @@ -43,3 +43,65 @@ def dao_create_letter_contact(letter_contact): @transactional def dao_update_letter_contact(letter_contact): db.session.add(letter_contact) + + +@transactional +def add_letter_contact_for_service(service_id, contact_block, is_default): + old_default = _get_existing_default(service_id) + if is_default: + _reset_old_default_to_false(old_default) + else: + _raise_when_no_default(old_default) + + new_letter_contact = ServiceLetterContact( + service_id=service_id, + contact_block=contact_block, + is_default=is_default + ) + db.session.add(new_letter_contact) + return new_letter_contact + + +@transactional +def update_letter_contact(service_id, letter_contact_id, contact_block, is_default): + old_default = _get_existing_default(service_id) + # if we want to make this the default, ensure there are no other existing defaults + if is_default: + _reset_old_default_to_false(old_default) + else: + if old_default.id == letter_contact_id: + raise InvalidRequest("You must have at least one letter contact as the default.", 400) + + letter_contact_update = ServiceLetterContact.query.get(letter_contact_id) + letter_contact_update.contact_block = contact_block + letter_contact_update.is_default = is_default + db.session.add(letter_contact_update) + return letter_contact_update + + +def _get_existing_default(service_id): + letter_contacts = dao_get_letter_contacts_by_service_id(service_id=service_id) + if letter_contacts: + old_default = [x for x in letter_contacts if x.is_default] + if len(old_default) == 1: + return old_default[0] + else: + raise Exception( + "There should only be one default letter contact 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 InvalidRequest("You must have at least one letter contact as the default.", 400) diff --git a/tests/app/dao/test_service_letter_contact_dao.py b/tests/app/dao/test_service_letter_contact_dao.py index 770fdfa16..5af184547 100644 --- a/tests/app/dao/test_service_letter_contact_dao.py +++ b/tests/app/dao/test_service_letter_contact_dao.py @@ -1,8 +1,10 @@ import pytest from app.dao.service_letter_contact_dao import ( + add_letter_contact_for_service, create_or_update_letter_contact, dao_get_letter_contacts_by_service_id, + update_letter_contact ) from app.errors import InvalidRequest from app.models import ServiceLetterContact @@ -64,3 +66,137 @@ def test_create_or_update_letter_contact_raises_exception_if_multiple_contact_bl with pytest.raises(expected_exception=InvalidRequest) as e: create_or_update_letter_contact(service_id=service.id, contact_block='Swansea, SN1 3CC') assert e.value.message == "Multiple letter contacts were found, this method should not be used." + + +def test_create_or_update_letter_contact_raises_exception_if_multiple_letter_contacts_exist(notify_db_session): + service = create_service() + create_letter_contact(service=service, contact_block='Edinburgh, ED1 1AA') + create_letter_contact(service=service, contact_block='Manchester, MA1 2BB', is_default=False) + + with pytest.raises(expected_exception=InvalidRequest) as e: + create_or_update_letter_contact(service_id=service.id, contact_block='Swansea, SN1 3CC') + assert e.value.message == "Multiple letter contacts were found, this method should not be used." + + +def test_add_letter_contact_for_service_creates_additional_letter_contact_for_service(notify_db_session): + service = create_service() + + create_letter_contact(service=service, contact_block='Edinburgh, ED1 1AA') + add_letter_contact_for_service(service_id=service.id, contact_block='Swansea, SN1 3CC', is_default=False) + + results = dao_get_letter_contacts_by_service_id(service_id=service.id) + + assert len(results) == 2 + + assert results[0].contact_block == 'Edinburgh, ED1 1AA' + assert results[0].is_default + + assert results[1].contact_block == 'Swansea, SN1 3CC' + assert not results[1].is_default + + +def test_add_another_letter_contact_as_default_overrides_existing(notify_db_session): + service = create_service() + + create_letter_contact(service=service, contact_block='Edinburgh, ED1 1AA') + add_letter_contact_for_service(service_id=service.id, contact_block='Swansea, SN1 3CC', is_default=True) + + results = dao_get_letter_contacts_by_service_id(service_id=service.id) + + assert len(results) == 2 + + assert results[0].contact_block == 'Edinburgh, ED1 1AA' + assert not results[0].is_default + + assert results[1].contact_block == 'Swansea, SN1 3CC' + assert results[1].is_default + + +def test_add_letter_contact_does_not_override_default(notify_db_session): + service = create_service() + + add_letter_contact_for_service(service_id=service.id, contact_block='Edinburgh, ED1 1AA', is_default=True) + add_letter_contact_for_service(service_id=service.id, contact_block='Swansea, SN1 3CC', is_default=False) + + results = dao_get_letter_contacts_by_service_id(service_id=service.id) + + assert len(results) == 2 + + assert results[0].contact_block == 'Edinburgh, ED1 1AA' + assert results[0].is_default + + assert results[1].contact_block == 'Swansea, SN1 3CC' + assert not results[1].is_default + + +def test_add_letter_contact_with_no_default_raises_exception(notify_db_session): + service = create_service() + with pytest.raises(expected_exception=InvalidRequest): + add_letter_contact_for_service( + service_id=service.id, + contact_block='Swansea, SN1 3CC', + is_default=False + ) + + +def test_add_letter_contact_when_multiple_defaults_exist_raises_exception(notify_db_session): + service = create_service() + create_letter_contact(service=service, contact_block='Edinburgh, ED1 1AA') + create_letter_contact(service=service, contact_block='Aberdeen, AB12 23X') + + with pytest.raises(Exception): + add_letter_contact_for_service(service_id=service.id, contact_block='Swansea, SN1 3CC', is_default=False) + + +def test_can_update_letter_contact(notify_db_session): + service = create_service() + letter_contact = create_letter_contact(service=service, contact_block='Aberdeen, AB12 23X') + + update_letter_contact( + service_id=service.id, + letter_contact_id=letter_contact.id, + contact_block='Warwick, W14 TSR', + is_default=True + ) + + updated_letter_contact = ServiceLetterContact.query.get(letter_contact.id) + + assert updated_letter_contact.contact_block == 'Warwick, W14 TSR' + assert updated_letter_contact.updated_at + assert updated_letter_contact.is_default + + +def test_update_letter_contact_as_default_overides_existing_default(notify_db_session): + service = create_service() + + create_letter_contact(service=service, contact_block='Aberdeen, AB12 23X') + second_letter_contact = create_letter_contact(service=service, contact_block='Swansea, SN1 3CC', is_default=False) + + update_letter_contact( + service_id=service.id, + letter_contact_id=second_letter_contact.id, + contact_block='Warwick, W14 TSR', + is_default=True + ) + + results = dao_get_letter_contacts_by_service_id(service_id=service.id) + assert len(results) == 2 + + assert results[0].contact_block == 'Aberdeen, AB12 23X' + assert not results[0].is_default + + assert results[1].contact_block == 'Warwick, W14 TSR' + assert results[1].is_default + + +def test_update_letter_contact_unset_default_for_only_letter_contact_raises_exception(notify_db_session): + service = create_service() + only_letter_contact = create_letter_contact(service=service, contact_block='Aberdeen, AB12 23X') + + with pytest.raises(expected_exception=InvalidRequest): + update_letter_contact( + service_id=service.id, + letter_contact_id=only_letter_contact.id, + contact_block='Warwick, W14 TSR', + is_default=False + )